Пример #1
0
int pn_message_load_amqp(pn_message_t *msg, const char *data, size_t size)
{
  if (!msg) return PN_ARG_ERR;

  if (!msg->body) {
    msg->body = pn_data(64);
  }

  pn_parser_t *parser = pn_message_parser(msg);

  while (true) {
    pn_data_clear(msg->body);
    pn_atoms_t atoms = pn_data_available(msg->body);
    int err = pn_parser_parse(parser, data, &atoms);
    if (err == PN_OVERFLOW) {
      err = pn_data_grow(msg->body);
      if (err) return err;
      continue;
    } else if (err) {
      return err;
    } else {
      return pn_data_resize(msg->body, atoms.size);
    }
  }
}
Пример #2
0
static pn_message_t *build_request_message(pn_message_t *message,
                                           const char *command,
                                           const char *to,
                                           const char *reply_to,
                                           const char *new_fortune,
                                           unsigned int ttl)
{
    int rc;

    pn_message_set_address( message, to );
    if (reply_to) {
        LOG("setting reply-to %s\n", reply_to);
        rc = pn_message_set_reply_to( message, reply_to );
        check(rc == 0, "pn_message_set_reply_to() failed");
    }
    pn_message_set_delivery_count( message, 0 );
    if (ttl)
        pn_message_set_ttl( message, ttl * 1000 );


    pn_data_t *body = pn_message_body(message);
    pn_data_clear( body );
    rc = pn_data_fill( body, "{SSSSSS}",
                       "type", "request",
                       "command", command,
                       "value", (new_fortune) ? new_fortune : "" );
    check( rc == 0, "Failure to create request message" );
    return message;
}
Пример #3
0
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;
}
Пример #4
0
int buffer(int argc, char **argv)
{
  pn_buffer_t *buf = pn_buffer(16);

  pn_buffer_append(buf, "abcd", 4);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_prepend(buf, "012", 3);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_prepend(buf, "z", 1);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_append(buf, "efg", 3);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_append(buf, "hijklm", 6);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_defrag(buf);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_trim(buf, 1, 1);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_trim(buf, 4, 0);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_clear(buf);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_free(buf);

  pn_data_t *data = pn_data(16);
  int err = pn_data_fill(data, "Ds[iSi]", "desc", 1, "two", 3);
  if (err) {
    printf("%s\n", pn_code(err));
  }
  pn_data_print(data); printf("\n");
  pn_bytes_t str;
  err = pn_data_scan(data, "D.[.S.]", &str);
  if (err) {
    printf("%s\n", pn_code(err));
  } else {
    printf("%.*s\n", (int) str.size, str.start);
  }

  pn_data_clear(data);
  pn_data_fill(data, "DL[SIonn?DL[S]?DL[S]nnI]", ATTACH, "asdf", 1, true,
               true, SOURCE, "queue",
               true, TARGET, "queue",
               0);

  pn_data_print(data); printf("\n");


  pn_data_free(data);

  return 0;
}
Пример #5
0
int pn_message_encode(pn_message_t *msg, char *bytes, size_t *size)
{
  if (!msg || !bytes || !size || !*size) return PN_ARG_ERR;
  if (!msg->data) {
    msg->data = pn_data(64);
  }
  if (!msg->body) {
    msg->body = pn_data(64);
  }

  int err = pn_data_clear(msg->data);
  if (err) return err;

  err = pn_data_fill(msg->data, "DL[oBIoI]", HEADER, msg->durable,
                     msg->priority, msg->ttl, msg->first_acquirer,
                     msg->delivery_count);
  if (err) return err;

  err = pn_data_fill(msg->data, "DL[nzSSSnssLLSiS]", PROPERTIES,
                     pn_buffer_bytes(msg->user_id),
                     pn_buffer_str(msg->address),
                     pn_buffer_str(msg->subject),
                     pn_buffer_str(msg->reply_to),
                     pn_buffer_str(msg->content_type),
                     pn_buffer_str(msg->content_encoding),
                     msg->expiry_time,
                     msg->creation_time,
                     pn_buffer_str(msg->group_id),
                     msg->group_sequence,
                     pn_buffer_str(msg->reply_to_group_id));
  if (err) return err;

  size_t remaining = *size;
  size_t encoded = remaining;

  err = pn_data_encode(msg->data, bytes, &encoded);
  if (err) return err;

  bytes += encoded;
  remaining -= encoded;

  encoded = remaining;
  err = pn_data_encode(msg->body, bytes, &encoded);
  if (err) return err;
  bytes += encoded;
  remaining -= encoded;

  *size -= remaining;

  return 0;
}
Пример #6
0
void pn_message_clear(pn_message_t *msg)
{
  msg->durable = false;
  msg->priority = PN_DEFAULT_PRIORITY;
  msg->ttl = 0;
  msg->first_acquirer = false;
  msg->delivery_count = 0;
  msg->id.type = PN_NULL;
  if (msg->user_id) pn_buffer_clear(msg->user_id);
  if (msg->address) pn_buffer_clear(msg->address);
  if (msg->subject) pn_buffer_clear(msg->subject);
  if (msg->reply_to) pn_buffer_clear(msg->reply_to);
  msg->correlation_id.type = PN_NULL;
  if (msg->content_type) pn_buffer_clear(msg->content_type);
  if (msg->content_encoding) pn_buffer_clear(msg->content_encoding);
  msg->expiry_time = 0;
  msg->creation_time = 0;
  if (msg->group_id) pn_buffer_clear(msg->group_id);
  msg->group_sequence = 0;
  if (msg->reply_to_group_id) pn_buffer_clear(msg->reply_to_group_id);
  if (msg->data) pn_data_clear(msg->data);
  if (msg->body) pn_data_clear(msg->body);
}
Пример #7
0
int pn_dispatch_frame(pn_dispatcher_t *disp, pn_frame_t frame)
{
  if (frame.size == 0) { // ignore null frames
    if (disp->trace & PN_TRACE_FRM)
      pn_transport_logf(disp->transport, "%u <- (EMPTY FRAME)\n", frame.channel);
    return 0;
  }

  ssize_t dsize = pn_data_decode(disp->args, frame.payload, frame.size);
  if (dsize < 0) {
    pn_string_format(disp->scratch,
                     "Error decoding frame: %s %s\n", pn_code(dsize),
                     pn_error_text(pn_data_error(disp->args)));
    pn_quote(disp->scratch, frame.payload, frame.size);
    pn_transport_log(disp->transport, pn_string_get(disp->scratch));
    return dsize;
  }

  disp->channel = frame.channel;
  // XXX: assuming numeric
  uint64_t lcode;
  bool scanned;
  int e = pn_data_scan(disp->args, "D?L.", &scanned, &lcode);
  if (e) {
    pn_transport_log(disp->transport, "Scan error");
    return e;
  }
  if (!scanned) {
    pn_transport_log(disp->transport, "Error dispatching frame");
    return PN_ERR;
  }
  uint8_t code = lcode;
  disp->code = code;
  disp->size = frame.size - dsize;
  if (disp->size)
    disp->payload = frame.payload + dsize;

  pn_do_trace(disp, disp->channel, IN, disp->args, disp->payload, disp->size);

  pn_action_t *action = disp->actions[code];
  int err = action(disp);

  disp->channel = 0;
  disp->code = 0;
  pn_data_clear(disp->args);
  disp->size = 0;
  disp->payload = NULL;

  return err;
}
Пример #8
0
bool encoder::encode(char* buffer, size_t& size) {
    save_state ss(pn_cast(this)); // In case of error
    ssize_t result = pn_data_encode(pn_cast(this), buffer, size);
    if (result == PN_OVERFLOW) {
        result = pn_data_encoded_size(pn_cast(this));
        if (result >= 0) {
            size = result;
            return false;
        }
    }
    check(result, pn_cast(this));
    size = result;
    ss.cancel();                // Don't restore state, all is well.
    pn_data_clear(pn_cast(this));
    return true;
}
Пример #9
0
int pn_message_decode(pn_message_t *msg, const char *bytes, size_t size)
{
  if (!msg || !bytes || !size) return PN_ARG_ERR;

  if (!msg->data) {
    msg->data = pn_data(64);
  }
  if (!msg->body) {
    msg->body = pn_data(64);
  }

  pn_data_clear(msg->body);

  while (size) {
    size_t copy = size;
    pn_data_clear(msg->data);
    int err = pn_data_decode(msg->data, (char *) bytes, &copy);
    if (err) return err;
    size -= copy;
    bytes += copy;
    bool scanned;
    uint64_t desc;
    err = pn_data_scan(msg->data, "D?L.", &scanned, &desc);
    if (err) return err;
    if (!scanned){
      desc = 0;
    }

    switch (desc) {
    case HEADER:
      pn_data_scan(msg->data, "D.[oBIoI]", &msg->durable, &msg->priority,
                   &msg->ttl, &msg->first_acquirer, &msg->delivery_count);
      break;
    case PROPERTIES:
      {
        pn_bytes_t user_id, address, subject, reply_to, ctype, cencoding,
          group_id, reply_to_group_id;
        err = pn_data_scan(msg->data, "D.[.zSSS.ssLLSiS]", &user_id, &address,
                           &subject, &reply_to, &ctype, &cencoding,
                           &msg->expiry_time, &msg->creation_time, &group_id,
                           &msg->group_sequence, &reply_to_group_id);
        if (err) return err;
        err = pn_buffer_set_bytes(&msg->user_id, user_id);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->address, address.start, address.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->subject, subject.start, subject.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->reply_to, reply_to.start, reply_to.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->content_type, ctype.start, ctype.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->content_encoding, cencoding.start,
                                 cencoding.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->group_id, group_id.start, group_id.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->reply_to_group_id, reply_to_group_id.start,
                                 reply_to_group_id.size);
        if (err) return err;
      }
      break;
    case DELIVERY_ANNOTATIONS:
    case MESSAGE_ANNOTATIONS:
      break;
    default:
      {
        pn_data_t *data = msg->body;
        msg->body = msg->data;
        msg->data = data;
        err = pn_data_intern(msg->body);
        if (err) return err;
      }
      break;
    }
  }

  return pn_data_clear(msg->data);
}
Пример #10
0
int main(int argc, char** argv)
{
    const char *address = "localhost";
    const char *msgtext = "Hello World!";
    const char *container = "SendExample";
    int c;
    pn_message_t *message = NULL;
    pn_data_t *body = NULL;
    pn_reactor_t *reactor = NULL;
    pn_url_t *url = NULL;
    pn_connection_t *conn = NULL;

    /* Create a handler for the connection's events.  event_handler() will be
     * called for each event and delete_handler will be called when the
     * connection is released.  The handler will allocate an app_data_t
     * instance which can be accessed when the event_handler is called.
     */
    pn_handler_t *handler = pn_handler_new(event_handler,
                                           sizeof(app_data_t),
                                           delete_handler);

    /* set up the application data with defaults */
    app_data_t *app_data = GET_APP_DATA(handler);
    memset(app_data, 0, sizeof(app_data_t));
    app_data->count = 1;
    app_data->target = "examples";

    /* Attach the pn_handshaker() handler.  This handler deals with endpoint
     * events from the peer so we don't have to.
     */
    {
        pn_handler_t *handshaker = pn_handshaker();
        pn_handler_add(handler, handshaker);
        pn_decref(handshaker);
    }

    /* command line options */
    opterr = 0;
    while((c = getopt(argc, argv, "i:a:c:t:nhq")) != -1) {
        switch(c) {
        case 'h': usage(); break;
        case 'a': address = optarg; break;
        case 'c':
            app_data->count = atoi(optarg);
            if (app_data->count < 1) usage();
            break;
        case 't': app_data->target = optarg; break;
        case 'n': app_data->anon = 1; break;
        case 'i': container = optarg; break;
        case 'q': quiet = 1; break;
        default:
            usage();
            break;
        }
    }
    if (optind < argc) msgtext = argv[optind];


    // create a single message and pre-encode it so we only have to do that
    // once.  All transmits will use the same pre-encoded message simply for
    // speed.
    //
    message = pn_message();
    pn_message_set_address(message, app_data->target);
    body = pn_message_body(message);
    pn_data_clear(body);

    // This message's body contains a single string
    if (pn_data_fill(body, "S", msgtext)) {
        fprintf(stderr, "Error building message!\n");
        exit(1);
    }
    pn_data_rewind(body);
    {
        // encode the message, expanding the encode buffer as needed
        //
        size_t len = 128;
        char *buf = (char *)malloc(len);
        int rc = 0;
        do {
            rc = pn_message_encode(message, buf, &len);
            if (rc == PN_OVERFLOW) {
                free(buf);
                len *= 2;
                buf = (char *)malloc(len);
            }
        } while (rc == PN_OVERFLOW);
        app_data->msg_len = len;
        app_data->msg_data = buf;
    }
    pn_decref(message);   // message no longer needed

    reactor = pn_reactor();

    url = pn_url_parse(address);
    if (url == NULL) {
        fprintf(stderr, "Invalid host address %s\n", address);
        exit(1);
    }
    conn = pn_reactor_connection_to_host(reactor,
                                         pn_url_get_host(url),
                                         pn_url_get_port(url),
                                         handler);
    pn_decref(url);
    pn_decref(handler);

    // the container name should be unique for each client
    pn_connection_set_container(conn, container);

    // wait up to 5 seconds for activity before returning from
    // pn_reactor_process()
    pn_reactor_set_timeout(reactor, 5000);

    pn_reactor_start(reactor);

    while (pn_reactor_process(reactor)) {
        /* Returns 'true' until the connection is shut down.
         * pn_reactor_process() will return true at least once every 5 seconds
         * (due to the timeout).  If no timeout was configured,
         * pn_reactor_process() returns as soon as it finishes processing all
         * pending I/O and events. Once the connection has closed,
         * pn_reactor_process() will return false.
         */
    }
    pn_decref(reactor);

    return 0;
}
Пример #11
0
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;
}