+static void resultset_destroy(ZOOM_resultset r)
+{
+ if (!r)
+ return;
+ (r->refcount)--;
+ yaz_log(log_details, "%p ZOOM_resultset_destroy r=%p count=%d",
+ r, r, r->refcount);
+ if (r->refcount == 0)
+ {
+ ZOOM_resultset_cache_reset(r);
+
+ if (r->connection)
+ {
+ /* remove ourselves from the resultsets in connection */
+ ZOOM_resultset *rp = &r->connection->resultsets;
+ while (1)
+ {
+ assert(*rp); /* we must be in this list!! */
+ if (*rp == r)
+ { /* OK, we're here - take us out of it */
+ *rp = (*rp)->next;
+ break;
+ }
+ rp = &(*rp)->next;
+ }
+ }
+ ZOOM_query_destroy(r->query);
+ ZOOM_options_destroy(r->options);
+ odr_destroy(r->odr);
+ xfree(r->setname);
+ xfree(r->schema);
+ xfree(r);
+ }
+}
+
+ZOOM_API(size_t)
+ ZOOM_resultset_size(ZOOM_resultset r)
+{
+ yaz_log(log_details, "ZOOM_resultset_size r=%p count=" ODR_INT_PRINTF,
+ r, r->size);
+ return r->size;
+}
+
+static void do_close(ZOOM_connection c)
+{
+ if (c->cs)
+ cs_close(c->cs);
+ c->cs = 0;
+ ZOOM_connection_set_mask(c, 0);
+ c->state = STATE_IDLE;
+}
+
+static int ZOOM_test_reconnect(ZOOM_connection c)
+{
+ ZOOM_Event event;
+
+ if (!c->reconnect_ok)
+ return 0;
+ do_close(c);
+ c->reconnect_ok = 0;
+ c->tasks->running = 0;
+ ZOOM_connection_insert_task(c, ZOOM_TASK_CONNECT);
+
+ event = ZOOM_Event_create(ZOOM_EVENT_CONNECT);
+ ZOOM_connection_put_event(c, event);
+
+ return 1;
+}
+
+static void ZOOM_resultset_retrieve(ZOOM_resultset r,
+ int force_sync, int start, int count)
+{
+ ZOOM_task task;
+ ZOOM_connection c;
+ const char *cp;
+ const char *syntax, *elementSetName;
+
+ if (!r)
+ return;
+ yaz_log(log_details, "%p ZOOM_resultset_retrieve force_sync=%d start=%d"
+ " count=%d", r, force_sync, start, count);
+ c = r->connection;
+ if (!c)
+ return;
+
+ if (c->host_port && c->proto == PROTO_HTTP)
+ {
+ if (!c->cs)
+ {
+ yaz_log(log_details, "%p ZOOM_resultset_retrieve: no comstack", r);
+ ZOOM_connection_add_task(c, ZOOM_TASK_CONNECT);
+ }
+ else
+ {
+ yaz_log(log_details, "%p ZOOM_resultset_retrieve: prepare "
+ "reconnect", r);
+ c->reconnect_ok = 1;
+ }
+ }
+ task = ZOOM_connection_add_task(c, ZOOM_TASK_RETRIEVE);
+ task->u.retrieve.resultset = r;
+ task->u.retrieve.start = start;
+ task->u.retrieve.count = count;
+
+ syntax = ZOOM_options_get(r->options, "preferredRecordSyntax");
+ task->u.retrieve.syntax = syntax ? xstrdup(syntax) : 0;
+ elementSetName = ZOOM_options_get(r->options, "elementSetName");
+ task->u.retrieve.elementSetName = elementSetName
+ ? xstrdup(elementSetName) : 0;
+
+ cp = ZOOM_options_get(r->options, "schema");
+ if (cp)
+ {
+ if (!r->schema || strcmp(r->schema, cp))
+ {
+ xfree(r->schema);
+ r->schema = xstrdup(cp);
+ }
+ }
+
+ ZOOM_resultset_addref(r);
+
+ if (!r->connection->async || force_sync)
+ while (r->connection && ZOOM_event(1, &r->connection))
+ ;
+}
+
+ZOOM_API(void)
+ ZOOM_resultset_records(ZOOM_resultset r, ZOOM_record *recs,
+ size_t start, size_t count)
+{
+ int force_present = 0;
+
+ if (!r)
+ return ;
+ yaz_log(log_api, "%p ZOOM_resultset_records r=%p start=%ld count=%ld",
+ r, r, (long) start, (long) count);
+ if (count && recs)
+ force_present = 1;
+ ZOOM_resultset_retrieve(r, force_present, start, count);
+ if (force_present)
+ {
+ size_t i;
+ for (i = 0; i< count; i++)
+ recs[i] = ZOOM_resultset_record_immediate(r, i+start);
+ }
+}
+
+static void get_cert(ZOOM_connection c)
+{
+ char *cert_buf;
+ int cert_len;
+
+ if (cs_get_peer_certificate_x509(c->cs, &cert_buf, &cert_len))
+ {
+ ZOOM_connection_option_setl(c, "sslPeerCert",
+ cert_buf, cert_len);
+ xfree(cert_buf);
+ }
+}