int pn_transform_apply(pn_transform_t *transform, const char *src, pn_string_t *dst) { for (size_t i = 0; i < pn_list_size(transform->rules); i++) { pn_rule_t *rule = (pn_rule_t *) pn_list_get(transform->rules, i); if (pni_match(&transform->matcher, pn_string_get(rule->pattern), src)) { transform->matched = true; if (!pn_string_get(rule->substitution)) { return pn_string_set(dst, NULL); } while (true) { size_t capacity = pn_string_capacity(dst); size_t n = pni_substitute(&transform->matcher, pn_string_get(rule->substitution), pn_string_buffer(dst), capacity); int err = pn_string_resize(dst, n); if (err) return err; if (n <= capacity) { return 0; } } } } transform->matched = false; return pn_string_set(dst, src); }
static void test_build_map_odd(void) { pn_map_t *m = build_map(0, 0.75, pn_string("key"), pn_string("value"), pn_string("key2"), pn_string("value2"), pn_string("key3"), END); assert(pn_map_size(m) == 3); pn_string_t *key = pn_string(NULL); pn_string_set(key, "key"); assert(pn_strequals(pn_string_get((pn_string_t *) pn_map_get(m, key)), "value")); pn_string_set(key, "key2"); assert(pn_strequals(pn_string_get((pn_string_t *) pn_map_get(m, key)), "value2")); pn_string_set(key, "key3"); assert(pn_map_get(m, key) == NULL); pn_free(m); pn_free(key); }
int pni_subscription_set_address(pn_subscription_t *sub, const char *address) { assert(sub); if (!address) return 0; bool absolute = strncmp(address, "amqp:", 5) == 0; if (absolute) { return pn_string_set(sub->address, address); } else { pn_string_set(sub->address, ""); bool scheme = pn_string_get(sub->scheme); if (scheme) { int e = pn_string_addf(sub->address, "%s:", pn_string_get(sub->scheme)); if (e) return e; } if (pn_string_get(sub->host)) { int e = pn_string_addf(sub->address, scheme ? "//%s" : "%s", pn_string_get(sub->host)); if (e) return e; } if (pn_string_get(sub->port)) { int e = pn_string_addf(sub->address, ":%s", pn_string_get(sub->port)); if (e) return e; } return pn_string_addf(sub->address, "/%s", address); } }
pn_subscription_t *pn_subscription(pn_messenger_t *messenger, const char *scheme, const char *host, const char *port) { static const pn_class_t clazz = PN_CLASS(pn_subscription); pn_subscription_t *sub = (pn_subscription_t *) pn_class_new(&clazz, sizeof(pn_subscription_t)); sub->messenger = messenger; pn_string_set(sub->scheme, scheme); pn_string_set(sub->host, host); pn_string_set(sub->port, port); pni_messenger_add_subscription(messenger, sub); pn_class_decref(PN_OBJECT, sub); return sub; }
int pn_post_frame(pn_dispatcher_t *disp, uint16_t ch, const char *fmt, ...) { va_list ap; va_start(ap, fmt); pn_data_clear(disp->output_args); int err = pn_data_vfill(disp->output_args, fmt, ap); va_end(ap); if (err) { pn_transport_logf(disp->transport, "error posting frame: %s, %s: %s", fmt, pn_code(err), pn_error_text(pn_data_error(disp->output_args))); return PN_ERR; } pn_do_trace(disp, ch, OUT, disp->output_args, disp->output_payload, disp->output_size); encode_performatives: pn_buffer_clear( disp->frame ); pn_bytes_t buf = pn_buffer_bytes( disp->frame ); buf.size = pn_buffer_available( disp->frame ); ssize_t wr = pn_data_encode( disp->output_args, buf.start, buf.size ); if (wr < 0) { if (wr == PN_OVERFLOW) { pn_buffer_ensure( disp->frame, pn_buffer_available( disp->frame ) * 2 ); goto encode_performatives; } pn_transport_logf(disp->transport, "error posting frame: %s", pn_code(wr)); return PN_ERR; } pn_frame_t frame = {disp->frame_type}; frame.channel = ch; frame.payload = buf.start; frame.size = wr; size_t n; while (!(n = pn_write_frame(disp->output + disp->available, disp->capacity - disp->available, frame))) { disp->capacity *= 2; disp->output = (char *) realloc(disp->output, disp->capacity); } disp->output_frames_ct += 1; if (disp->trace & PN_TRACE_RAW) { pn_string_set(disp->scratch, "RAW: \""); pn_quote(disp->scratch, disp->output + disp->available, n); pn_string_addf(disp->scratch, "\""); pn_transport_log(disp->transport, pn_string_get(disp->scratch)); } disp->available += n; return 0; }
/** Return the string form of a URL. */ PN_EXTERN const char *pn_url_str(pn_url_t *url) { if (pn_string_get(url->str) == NULL) { pn_string_set(url->str, ""); if (url->scheme) pn_string_addf(url->str, "%s://", url->scheme); if (url->username) pni_urlencode(url->str, url->username); if (url->password) { pn_string_addf(url->str, ":"); pni_urlencode(url->str, url->password); } if (url->username || url->password) pn_string_addf(url->str, "@"); if (url->host) { if (strchr(url->host, ':')) pn_string_addf(url->str, "[%s]", url->host); else pn_string_addf(url->str, "%s", url->host); } if (url->port) pn_string_addf(url->str, ":%s", url->port); if (url->path) pn_string_addf(url->str, "/%s", url->path); } return pn_string_get(url->str); }
static void test_string(const char *value) { size_t size = value ? strlen(value) : 0; pn_string_t *str = pn_string(value); assert(equals(pn_string_get(str), value)); assert(pn_string_size(str) == size); pn_string_t *strn = pn_stringn(value, size); assert(equals(pn_string_get(strn), value)); assert(pn_string_size(strn) == size); pn_string_t *strset = pn_string(NULL); pn_string_set(strset, value); assert(equals(pn_string_get(strset), value)); assert(pn_string_size(strset) == size); pn_string_t *strsetn = pn_string(NULL); pn_string_setn(strsetn, value, size); assert(equals(pn_string_get(strsetn), value)); assert(pn_string_size(strsetn) == size); assert(pn_hashcode(str) == pn_hashcode(strn)); assert(pn_hashcode(str) == pn_hashcode(strset)); assert(pn_hashcode(str) == pn_hashcode(strsetn)); assert(!pn_compare(str, str)); assert(!pn_compare(str, strn)); assert(!pn_compare(str, strset)); assert(!pn_compare(str, strsetn)); pn_free(str); pn_free(strn); pn_free(strset); pn_free(strsetn); }
int pn_post_transfer_frame(pn_dispatcher_t *disp, uint16_t ch, uint32_t handle, pn_sequence_t id, const pn_bytes_t *tag, uint32_t message_format, bool settled, bool more, pn_sequence_t frame_limit) { bool more_flag = more; int framecount = 0; // create preformatives, assuming 'more' flag need not change compute_performatives: pn_data_clear(disp->output_args); int err = pn_data_fill(disp->output_args, "DL[IIzIoo]", TRANSFER, handle, id, tag->size, tag->start, message_format, settled, more_flag); if (err) { pn_transport_logf(disp->transport, "error posting transfer frame: %s: %s", pn_code(err), pn_error_text(pn_data_error(disp->output_args))); return PN_ERR; } do { // send as many frames as possible without changing the 'more' flag... encode_performatives: pn_buffer_clear( disp->frame ); pn_bytes_t buf = pn_buffer_bytes( disp->frame ); buf.size = pn_buffer_available( disp->frame ); ssize_t wr = pn_data_encode(disp->output_args, buf.start, buf.size); if (wr < 0) { if (wr == PN_OVERFLOW) { pn_buffer_ensure( disp->frame, pn_buffer_available( disp->frame ) * 2 ); goto encode_performatives; } pn_transport_logf(disp->transport, "error posting frame: %s", pn_code(wr)); return PN_ERR; } buf.size = wr; // check if we need to break up the outbound frame size_t available = disp->output_size; if (disp->remote_max_frame) { if ((available + buf.size) > disp->remote_max_frame - 8) { available = disp->remote_max_frame - 8 - buf.size; if (more_flag == false) { more_flag = true; goto compute_performatives; // deal with flag change } } else if (more_flag == true && more == false) { // caller has no more, and this is the last frame more_flag = false; goto compute_performatives; } } if (pn_buffer_available( disp->frame ) < (available + buf.size)) { // not enough room for payload - try again... pn_buffer_ensure( disp->frame, available + buf.size ); goto encode_performatives; } pn_do_trace(disp, ch, OUT, disp->output_args, disp->output_payload, available); memmove( buf.start + buf.size, disp->output_payload, available); disp->output_payload += available; disp->output_size -= available; buf.size += available; pn_frame_t frame = {disp->frame_type}; frame.channel = ch; frame.payload = buf.start; frame.size = buf.size; size_t n; while (!(n = pn_write_frame(disp->output + disp->available, disp->capacity - disp->available, frame))) { disp->capacity *= 2; disp->output = (char *) realloc(disp->output, disp->capacity); } disp->output_frames_ct += 1; framecount++; if (disp->trace & PN_TRACE_RAW) { pn_string_set(disp->scratch, "RAW: \""); pn_quote(disp->scratch, disp->output + disp->available, n); pn_string_addf(disp->scratch, "\""); pn_transport_log(disp->transport, pn_string_get(disp->scratch)); } disp->available += n; } while (disp->output_size > 0 && framecount < frame_limit); disp->output_payload = NULL; return framecount; }