void yaz_url_destroy(yaz_url_t p) { if (p) { odr_destroy(p->odr_in); odr_destroy(p->odr_out); xfree(p->proxy); wrbuf_destroy(p->w_error); yaz_cookies_destroy(p->cookies); xfree(p); } }
/** \brief build a 100 level query */ void test1(void) { ODR odr = odr_createmem(ODR_ENCODE); YAZ_PQF_Parser parser = yaz_pqf_create(); Z_RPNQuery *rpn_query; char qstr[10000]; int i; int ret; YAZ_CHECK(odr); YAZ_CHECK(parser); *qstr = '\0'; for (i = 0; i<100; i++) strcat(qstr, "@and 1 "); strcat(qstr, "1"); rpn_query = yaz_pqf_parse (parser, odr, qstr); YAZ_CHECK(rpn_query); ret = z_RPNQuery(odr, &rpn_query, 0, 0); YAZ_CHECK(ret); yaz_pqf_destroy(parser); odr_destroy(odr); }
static void tst_srw(void) { const char *charset = 0; char *content_buf = 0; int content_len; int ret; ODR o = odr_createmem(ODR_ENCODE); Z_SOAP_Handler h[2] = { {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} }; Z_SRW_PDU *sr = yaz_srw_get(o, Z_SRW_searchRetrieve_request); Z_SOAP *p = (Z_SOAP *) odr_malloc(o, sizeof(*p)); YAZ_CHECK(o); YAZ_CHECK(sr); YAZ_CHECK(p); #if 0 sr->u.request->query = "jordb" "\xe6" "r"; #else sr->u.request->query = "jordbaer"; #endif p->which = Z_SOAP_generic; p->u.generic = (Z_SOAP_Generic *) odr_malloc(o, sizeof(*p->u.generic)); p->u.generic->no = 0; p->u.generic->ns = 0; p->u.generic->p = sr; p->ns = "http://schemas.xmlsoap.org/soap/envelope/"; ret = z_soap_codec_enc(o, &p, &content_buf, &content_len, h, charset); odr_destroy(o); YAZ_CHECK(ret == 0); /* codec failed ? */ }
static int compare(cql_transform_t ct, const char *pqf, const char *cql) { int ret = 0; ODR odr = odr_createmem(ODR_ENCODE); WRBUF w = wrbuf_alloc(); Z_RPNQuery *q = p_query_rpn(odr, pqf); if (q) { int r = cql_transform_rpn2cql_wrbuf(ct, w, q); if (r != 0) { /* transform error */ yaz_log(YLOG_LOG, "%s -> Error %d", pqf, r); if (!cql) /* also expected error? */ ret = 1; } else if (r == 0) { yaz_log(YLOG_LOG, "%s -> %s", pqf, wrbuf_cstr(w)); if (cql && !strcmp(wrbuf_cstr(w), cql)) { ret = 1; } } } wrbuf_destroy(w); odr_destroy(odr); return ret; }
Z_External *zget_init_diagnostics_octet(ODR odr, int error, const char *addinfo) { Z_External *x, *x2; Z_OtherInformation *u; Z_OtherInformationUnit *l; Z_DiagnosticFormat *d; Z_DiagnosticFormat_s *e; char *octet_buf; int octet_len; ODR encode; u = (Z_OtherInformation *) odr_malloc(odr, sizeof *u); u->num_elements = 1; u->list = (Z_OtherInformationUnit**) odr_malloc(odr, sizeof *u->list); u->list[0] = (Z_OtherInformationUnit*) odr_malloc(odr, sizeof *u->list[0]); l = u->list[0]; l->category = 0; l->which = Z_OtherInfo_externallyDefinedInfo; x2 = (Z_External*) odr_malloc(odr, sizeof *x); l->information.externallyDefinedInfo = x2; x2->descriptor = 0; x2->indirect_reference = 0; x2->direct_reference = odr_oiddup(odr, yaz_oid_diagset_diag_1); x2->which = Z_External_diag1; d = (Z_DiagnosticFormat*) odr_malloc(odr, sizeof *d); x2->u.diag1 = d; d->num = 1; d->elements = (Z_DiagnosticFormat_s**) odr_malloc(odr, sizeof *d->elements); d->elements[0] = (Z_DiagnosticFormat_s*) odr_malloc(odr, sizeof *d->elements[0]); e = d->elements[0]; e->which = Z_DiagnosticFormat_s_defaultDiagRec; e->u.defaultDiagRec = zget_DefaultDiagFormat(odr, error, addinfo); e->message = 0; encode = odr_createmem(ODR_ENCODE); z_OtherInformation(encode, &u, 0, 0); octet_buf = odr_getbuf(encode, &octet_len, 0); x = (Z_External*) odr_malloc(odr, sizeof *x); x->descriptor = 0; x->indirect_reference = 0; x->direct_reference = odr_oiddup(odr, yaz_oid_userinfo_userinfo_1); x->which = Z_External_octet; x->u.octet_aligned = (Odr_oct *) odr_malloc(odr, sizeof(Odr_oct)); x->u.octet_aligned->buf = (unsigned char *) odr_malloc(odr, octet_len); memcpy(x->u.octet_aligned->buf, octet_buf, octet_len); x->u.octet_aligned->len = octet_len; odr_destroy(encode); return x; }
static int compare_attr(Z_AttributeElement *a, Z_AttributeElement *b) { ODR odr_a = odr_createmem(ODR_ENCODE); ODR odr_b = odr_createmem(ODR_ENCODE); int len_a, len_b; char *buf_a, *buf_b; int ret; z_AttributeElement(odr_a, &a, 0, 0); z_AttributeElement(odr_b, &b, 0, 0); buf_a = odr_getbuf(odr_a, &len_a, 0); buf_b = odr_getbuf(odr_b, &len_b, 0); ret = yaz_memcmp(buf_a, buf_b, len_a, len_b); odr_destroy(odr_a); odr_destroy(odr_b); return ret; }
static int compare2(cql_transform_t ct, const char *pqf, const char *cql, int expected_error) { int ret = 0; ODR odr = odr_createmem(ODR_ENCODE); WRBUF w = wrbuf_alloc(); Z_RPNQuery *q = p_query_rpn(odr, pqf); if (q) { int r = cql_transform_rpn2cql_wrbuf(ct, w, q); if (r != 0) { const char *addinfo = 0; int err = cql_transform_error(ct, &addinfo); /* transform error */ yaz_log(YLOG_LOG, "%s -> Error %d", pqf, r); if (err == 0) ; else if (err == expected_error) { if (addinfo && cql && !strcmp(addinfo, cql)) ret = 1; else if (!addinfo && !cql) ret = 1; } } else if (r == 0) { yaz_log(YLOG_LOG, "%s -> %s", pqf, wrbuf_cstr(w)); if (!expected_error) ret = 1; else if (cql && !strcmp(wrbuf_cstr(w), cql)) { ret = 1; } else { yaz_log(YLOG_WARN, " expected: %s", cql ? cql : "null"); yaz_log(YLOG_WARN, " got: %s", wrbuf_cstr(w)); } } } wrbuf_destroy(w); odr_destroy(odr); return ret; }
void xmlquerytopqf(const char *xmlstr) { xmlDocPtr doc; doc = xmlParseMemory(xmlstr, strlen(xmlstr)); if (!doc) { fprintf(stderr, "%s: xml parse error for XML:\n%s\n", prog, xmlstr); exit(1); } else { int error_code = 0; const char *addinfo = 0; Z_Query *query = 0; ODR odr = odr_createmem(ODR_ENCODE); const xmlNode *root_element = xmlDocGetRootElement(doc); yaz_xml2query(root_element, &query, odr, &error_code, &addinfo); if (error_code) { fprintf(stderr, "%s: yaz_xml2query failed code=%d addinfo=%s\n", prog, error_code, addinfo); exit(1); } else if (!query) { fprintf(stderr, "%s: yaz_xml2query no query result\n", prog); exit(1); } else { WRBUF w = wrbuf_alloc(); yaz_query_to_wrbuf(w, query); printf("%s\n", wrbuf_cstr(w)); wrbuf_destroy(w); } odr_destroy(odr); xmlFreeDoc(doc); } }
int expect_pqf(const char *pqf, const char *expect_pqf, int expect_error) { YAZ_PQF_Parser parser = yaz_pqf_create(); int res = 0; ODR odr = odr_createmem(ODR_ENCODE); Z_RPNQuery *rpn; if (!parser) return 0; if (!odr) return 0; rpn = yaz_pqf_parse(parser, odr, pqf); if (!rpn) { const char *msg; size_t offset; int got_error = yaz_pqf_error (parser, &msg, &offset); if (expect_error == got_error) res = 1; } else if (expect_error == YAZ_PQF_ERROR_NONE) { WRBUF wrbuf = wrbuf_alloc(); if (wrbuf) { yaz_rpnquery_to_wrbuf(wrbuf, rpn); if (!strcmp(wrbuf_cstr(wrbuf), expect_pqf)) res = 1; wrbuf_destroy(wrbuf); } } yaz_pqf_destroy(parser); odr_destroy(odr); return res; }
/** \brief build a circular referenced query */ void test2(void) { ODR odr = odr_createmem(ODR_ENCODE); YAZ_PQF_Parser parser = yaz_pqf_create(); Z_RPNQuery *rpn_query; int ret; YAZ_CHECK(odr); rpn_query = yaz_pqf_parse (parser, odr, "@and @and a b c"); YAZ_CHECK(rpn_query); /* make the circular reference */ rpn_query->RPNStructure->u.complex->s1 = rpn_query->RPNStructure; ret = z_RPNQuery(odr, &rpn_query, 0, 0); /* should fail */ YAZ_CHECK(!ret); yaz_pqf_destroy(parser); odr_destroy(odr); }
static void tst_array_to_uri(void) { ODR odr = odr_createmem(ODR_ENCODE); char **names; char **values; char *query_string; int r; r = yaz_uri_to_array("&", odr, &names, &values); YAZ_CHECK_EQ(r, 0); if (r == 0) { YAZ_CHECK(names[0] == 0); YAZ_CHECK(values[0] == 0); } r = yaz_uri_to_array("&&", odr, &names, &values); YAZ_CHECK_EQ(r, 0); if (r == 0) { yaz_array_to_uri(&query_string, odr, names, values); YAZ_CHECK(!strcmp(query_string, "")); YAZ_CHECK(names[0] == 0); YAZ_CHECK(values[0] == 0); } r = yaz_uri_to_array("a=AA&bb=%42B", odr, &names, &values); YAZ_CHECK_EQ(r, 2); if (r == 2) { YAZ_CHECK(names[0] && !strcmp(names[0], "a")); YAZ_CHECK(values[0] && !strcmp(values[0], "AA")); YAZ_CHECK(names[1] && !strcmp(names[1], "bb")); YAZ_CHECK(values[1] && !strcmp(values[1], "BB")); YAZ_CHECK(names[2] == 0); YAZ_CHECK(values[2] == 0); yaz_array_to_uri(&query_string, odr, names, values); YAZ_CHECK(!strcmp(query_string, "a=AA&bb=BB")); } r = yaz_uri_to_array("a=AA&bb&x", odr, &names, &values); YAZ_CHECK_EQ(r, 3); if (r == 3) { YAZ_CHECK(names[0] && !strcmp(names[0], "a")); YAZ_CHECK(values[0] && !strcmp(values[0], "AA")); YAZ_CHECK(names[1] && !strcmp(names[1], "bb")); YAZ_CHECK(values[1] && !strcmp(values[1], "")); YAZ_CHECK(names[2] && !strcmp(names[2], "x")); YAZ_CHECK(values[2] && !strcmp(values[1], "")); YAZ_CHECK(names[3] == 0); YAZ_CHECK(values[3] == 0); yaz_array_to_uri(&query_string, odr, names, values); YAZ_CHECK(!strcmp(query_string, "a=AA&bb=&x=")); } r = yaz_uri_to_array("a=AA&bb=&x=", odr, &names, &values); YAZ_CHECK_EQ(r, 3); if (r == 3) { YAZ_CHECK(names[0] && !strcmp(names[0], "a")); YAZ_CHECK(values[0] && !strcmp(values[0], "AA")); YAZ_CHECK(names[1] && !strcmp(names[1], "bb")); YAZ_CHECK(values[1] && !strcmp(values[1], "")); YAZ_CHECK(names[2] && !strcmp(names[2], "x")); YAZ_CHECK(values[2] && !strcmp(values[1], "")); YAZ_CHECK(names[3] == 0); YAZ_CHECK(values[3] == 0); yaz_array_to_uri(&query_string, odr, names, values); YAZ_CHECK(!strcmp(query_string, "a=AA&bb=&x=")); } r = yaz_uri_to_array("a=AA&&&bb&x&&", odr, &names, &values); YAZ_CHECK_EQ(r, 3); if (r == 3) { YAZ_CHECK(names[0] && !strcmp(names[0], "a")); YAZ_CHECK(values[0] && !strcmp(values[0], "AA")); YAZ_CHECK(names[1] && !strcmp(names[1], "bb")); YAZ_CHECK(values[1] && !strcmp(values[1], "")); YAZ_CHECK(names[2] && !strcmp(names[2], "x")); YAZ_CHECK(values[2] && !strcmp(values[2], "")); YAZ_CHECK(names[3] == 0); YAZ_CHECK(values[3] == 0); yaz_array_to_uri(&query_string, odr, names, values); YAZ_CHECK(!strcmp(query_string, "a=AA&bb=&x=")); } odr_destroy(odr); }
static int cql_transform_parse_tok_line(cql_transform_t ct, const char *pattern, yaz_tok_parse_t tp) { int ae_num = 0; Z_AttributeElement *ae[20]; int ret = 0; /* 0=OK, != 0 FAIL */ int t; t = yaz_tok_move(tp); while (t == YAZ_TOK_STRING && ae_num < 20) { WRBUF type_str = wrbuf_alloc(); WRBUF set_str = 0; Z_AttributeElement *elem = 0; const char *value_str = 0; /* attset type=value OR type=value */ elem = (Z_AttributeElement *) nmem_malloc(ct->nmem, sizeof(*elem)); elem->attributeSet = 0; ae[ae_num] = elem; wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); wrbuf_puts(type_str, yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); if (t == YAZ_TOK_EOF) { wrbuf_destroy(type_str); if (set_str) wrbuf_destroy(set_str); break; } if (t == YAZ_TOK_STRING) { wrbuf_puts(ct->w, " "); wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); set_str = type_str; elem->attributeSet = yaz_string_to_oid_nmem(yaz_oid_std(), CLASS_ATTSET, wrbuf_cstr(set_str), ct->nmem); type_str = wrbuf_alloc(); wrbuf_puts(type_str, yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); } elem->attributeType = nmem_intdup(ct->nmem, 0); if (sscanf(wrbuf_cstr(type_str), ODR_INT_PRINTF, elem->attributeType) != 1) { wrbuf_destroy(type_str); if (set_str) wrbuf_destroy(set_str); yaz_log(YLOG_WARN, "Expected numeric attribute type"); ret = -1; break; } wrbuf_destroy(type_str); if (set_str) wrbuf_destroy(set_str); if (t != '=') { yaz_log(YLOG_WARN, "Expected = after after attribute type"); ret = -1; break; } t = yaz_tok_move(tp); if (t != YAZ_TOK_STRING) /* value */ { yaz_log(YLOG_WARN, "Missing attribute value"); ret = -1; break; } value_str = yaz_tok_parse_string(tp); if (yaz_isdigit(*value_str)) { elem->which = Z_AttributeValue_numeric; elem->value.numeric = nmem_intdup(ct->nmem, atoi(value_str)); } else { Z_ComplexAttribute *ca = (Z_ComplexAttribute *) nmem_malloc(ct->nmem, sizeof(*ca)); elem->which = Z_AttributeValue_complex; elem->value.complex = ca; ca->num_list = 1; ca->list = (Z_StringOrNumeric **) nmem_malloc(ct->nmem, sizeof(Z_StringOrNumeric *)); ca->list[0] = (Z_StringOrNumeric *) nmem_malloc(ct->nmem, sizeof(Z_StringOrNumeric)); ca->list[0]->which = Z_StringOrNumeric_string; ca->list[0]->u.string = nmem_strdup(ct->nmem, value_str); ca->num_semanticAction = 0; ca->semanticAction = 0; } wrbuf_puts(ct->w, "="); wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); wrbuf_puts(ct->w, " "); ae_num++; } if (ret == 0) /* OK? */ { struct cql_prop_entry **pp = &ct->entry; while (*pp) pp = &(*pp)->next; *pp = (struct cql_prop_entry *) xmalloc(sizeof(**pp)); (*pp)->pattern = xstrdup(pattern); (*pp)->value = xstrdup(wrbuf_cstr(ct->w)); (*pp)->attr_list.num_attributes = ae_num; if (ae_num == 0) (*pp)->attr_list.attributes = 0; else { (*pp)->attr_list.attributes = (Z_AttributeElement **) nmem_malloc(ct->nmem, ae_num * sizeof(Z_AttributeElement *)); memcpy((*pp)->attr_list.attributes, ae, ae_num * sizeof(Z_AttributeElement *)); } (*pp)->next = 0; if (0) { ODR pr = odr_createmem(ODR_PRINT); Z_AttributeList *alp = &(*pp)->attr_list; odr_setprint(pr, yaz_log_file()); z_AttributeList(pr, &alp, 0, 0); odr_setprint(pr, 0); odr_destroy(pr); } } return ret; }
void pqftoxmlquery(const char *pqf) { YAZ_PQF_Parser parser = yaz_pqf_create(); ODR odr = odr_createmem(ODR_ENCODE); Z_RPNQuery *rpn; if (!parser) { fprintf(stderr, "%s: cannot create parser\n", prog); exit(1); } if (!odr) { fprintf(stderr, "%s: cannot create parser\n", prog); exit(1); } rpn = yaz_pqf_parse(parser, odr, pqf); yaz_pqf_destroy(parser); if (!rpn) { fprintf(stderr, "%s: pqf parse error for query %s\n", prog, pqf); exit(2); } else { xmlDocPtr doc = 0; yaz_rpnquery2xml(rpn, &doc); if (!doc) { fprintf(stderr, "%s: yaz_rpnquery2xml failed for query %s\n", prog, pqf); exit(3); } else { xmlChar *buf_out = 0; int len_out = 0; xmlDocDumpMemory(doc, &buf_out, &len_out); if (!len_out || !buf_out) { fprintf(stderr, "%s: xmlDocDumpMemory failed for query %s\n", prog, pqf); exit(4); } else { if (fwrite(buf_out, len_out, 1, stdout) != 1) { fprintf(stderr, "%s: write failed\n", prog); exit(5); } } xmlFreeDoc(doc); } } odr_destroy(odr); }
int main(int argc, char **argv) { cql_transform_t ct; int i, iterations = 1; char *query = 0; char *fname = 0; int reverse = 0; int ret; char *arg; while ((ret = options("n:r", argv, argc, &arg)) != -2) { switch (ret) { case 0: if (!fname) fname = arg; else query = arg; break; case 'r': reverse = 1; break; case 'n': iterations = atoi(arg); break; default: usage(); } } if (!fname) usage(); if (!strcmp(fname, "-")) ct = cql_transform_create(); else ct = cql_transform_open_fname(fname); if (!ct) { fprintf(stderr, "failed to read properties %s\n", fname); exit(1); } if (reverse) { if (!query) usage(); else { ODR odr = odr_createmem(ODR_ENCODE); YAZ_PQF_Parser pp = yaz_pqf_create(); Z_RPNQuery *rpn = yaz_pqf_parse(pp, odr, query); if (!rpn) { fprintf(stderr, "PQF syntax error\n"); } else { int ret = cql_transform_rpn2cql_stream(ct, cql_fputs, stdout, rpn); if (ret) { const char *addinfo; int r = cql_transform_error(ct, &addinfo); printf("Transform error %d %s\n", r, addinfo ? addinfo : ""); } else printf("\n"); } yaz_pqf_destroy(pp); odr_destroy(odr); } } else { CQL_parser cp = cql_parser_create(); int r = 0; if (query) { for (i = 0; i<iterations; i++) r = cql_parser_string(cp, query); } else r = cql_parser_stdio(cp, stdin); if (r) fprintf(stderr, "Syntax error\n"); else { r = cql_transform_FILE(ct, cql_parser_result(cp), stdout); printf("\n"); if (r) { const char *addinfo; r = cql_transform_error(ct, &addinfo); printf("Transform error %d %s\n", r, addinfo ? addinfo : ""); } else { FILE *null = fopen("/dev/null", "w"); for (i = 1; i<iterations; i++) cql_transform_FILE(ct, cql_parser_result(cp), null); fclose(null); } } cql_parser_destroy(cp); } cql_transform_close(ct); return 0; }
enum pqf2xml_status pqf2xml_text(const char *pqf, const char *expect_xml, const char *expect_pqf) { YAZ_PQF_Parser parser = yaz_pqf_create(); ODR odr = odr_createmem(ODR_ENCODE); Z_RPNQuery *rpn; enum pqf2xml_status status = XML_NO_ERROR; YAZ_CHECK(parser); YAZ_CHECK(odr); rpn = yaz_pqf_parse(parser, odr, pqf); yaz_pqf_destroy(parser); if (!rpn) status = PQF_FAILED; else { #if YAZ_HAVE_XML2 xmlDocPtr doc = 0; yaz_rpnquery2xml(rpn, &doc); if (!doc) status = QUERY2XML_FAILED; else { char *buf_out; int len_out; xmlDocDumpMemory(doc, (xmlChar **) &buf_out, &len_out); if (len_out == (int) strlen(expect_xml) && memcmp(buf_out, expect_xml, len_out) == 0) { Z_Query *query2 = 0; int error_code = 0; const char *addinfo = 0; const xmlNode *root_element = xmlDocGetRootElement(doc); ODR odr2 = odr_createmem(ODR_ENCODE); yaz_xml2query(root_element, &query2, odr2, &error_code, &addinfo); if (error_code || !query2) status = XML_NO_MATCH; else { WRBUF w = wrbuf_alloc(); yaz_query_to_wrbuf(w, query2); if (!expect_pqf || strcmp(expect_pqf, wrbuf_cstr(w)) == 0) status = XML_MATCH; else { status = XML_NO_MATCH; printf("Result: %s\n", wrbuf_cstr(w)); } wrbuf_destroy(w); } odr_destroy(odr2); } else { printf("%.*s\n", len_out, buf_out); status = XML_NO_MATCH; } xmlFreeDoc(doc); xmlFree(buf_out); } #else status = QUERY2XML_FAILED; #endif } odr_destroy(odr); return status; }
int main(int argc, char **argv) { char buf[163840]; char *content_buf = buf; int content_len; size_t no; Z_SOAP *soap_package = 0; ODR decode, encode; int debug = 0; if (argc == 2 && !strcmp(argv[1], "debug")) debug = 1; no = fread(buf, 1, sizeof(buf), stdin); if (no < 1 || no == sizeof(buf)) { fprintf(stderr, "Bad file or too big\n"); exit (1); } decode = odr_createmem(ODR_DECODE); encode = odr_createmem(ODR_ENCODE); content_len = no; z_soap_codec(decode, &soap_package, &content_buf, &content_len, h); if (!soap_package) { fprintf(stderr, "Decoding seriously failed\n"); exit(1); } if (debug) { fprintf(stderr, "got NS = %s\n", soap_package->ns); if (soap_package->which == Z_SOAP_generic && soap_package->u.generic->no == 0) { Z_SRW_PDU *sr = (Z_SRW_PDU *) soap_package->u.generic->p; if (sr->which == Z_SRW_searchRetrieve_request) { Z_SRW_searchRetrieveRequest *req = sr->u.request; switch(req->query_type) { case Z_SRW_query_type_cql: fprintf(stderr, "CQL: %s\n", req->query.cql); break; case Z_SRW_query_type_xcql: fprintf(stderr, "XCQL\n"); break; case Z_SRW_query_type_pqf: fprintf(stderr, "PQF: %s\n", req->query.pqf); break; } } else if (sr->which == Z_SRW_searchRetrieve_response) { Z_SRW_searchRetrieveResponse *res = sr->u.response; if (res->records && res->num_records) { int i; for (i = 0; i<res->num_records; i++) { fprintf (stderr, "%d\n", i); if (res->records[i].recordData_buf) { fprintf(stderr, "%.*s", res->records[i].recordData_len, res->records[i].recordData_buf); } } } } } } z_soap_codec(encode, &soap_package, &content_buf, &content_len, h); if (content_buf && content_len) { printf("%.*s", content_len, content_buf); } else { fprintf(stderr, "No output!\n"); exit(1); } odr_destroy(decode); odr_destroy(encode); exit(0); }