Esempio n. 1
0
static inline void
pack_scalar(msgpack_packer *pk, const JsonValueScalar scalar)
{
	switch (scalar.token_type) {
		case JSON_TOKEN_STRING:
			pack_string(pk, scalar.token);
			break;
		case JSON_TOKEN_NUMBER:
			pack_number(pk, scalar.token);
			break;
		case JSON_TOKEN_TRUE:
			msgpack_pack_true(pk);
			break;
		case JSON_TOKEN_FALSE:
			msgpack_pack_false(pk);
			break;
		case JSON_TOKEN_NULL:
			msgpack_pack_nil(pk);
			break;
		default:
			/* TODO: parse error */
			break;
	}
}
Esempio n. 2
0
void msgpack_rpc_from_object(Object result, msgpack_packer *res)
{
  switch (result.type) {
    case kObjectTypeNil:
      msgpack_pack_nil(res);
      break;

    case kObjectTypeBoolean:
      msgpack_rpc_from_boolean(result.data.boolean, res);
      break;

    case kObjectTypeInteger:
      msgpack_rpc_from_integer(result.data.integer, res);
      break;

    case kObjectTypeFloat:
      msgpack_rpc_from_float(result.data.floating, res);
      break;

    case kObjectTypeString:
      msgpack_rpc_from_string(result.data.string, res);
      break;

    case kObjectTypeArray:
      msgpack_rpc_from_array(result.data.array, res);
      break;

    case kObjectTypePosition:
      msgpack_rpc_from_position(result.data.position, res);
      break;

    case kObjectTypeBuffer:
      msgpack_rpc_from_buffer(result.data.buffer, res);
      break;

    case kObjectTypeWindow:
      msgpack_rpc_from_window(result.data.window, res);
      break;

    case kObjectTypeTabpage:
      msgpack_rpc_from_tabpage(result.data.tabpage, res);
      break;

    case kObjectTypeStringArray:
      msgpack_rpc_from_stringarray(result.data.stringarray, res);
      break;

    case kObjectTypeBufferArray:
      msgpack_rpc_from_bufferarray(result.data.bufferarray, res);
      break;

    case kObjectTypeWindowArray:
      msgpack_rpc_from_windowarray(result.data.windowarray, res);
      break;

    case kObjectTypeTabpageArray:
      msgpack_rpc_from_tabpagearray(result.data.tabpagearray, res);
      break;

    case kObjectTypeDictionary:
      msgpack_rpc_from_dictionary(result.data.dictionary, res);
      break;
  }
}
Esempio n. 3
0
/*
 * Document-method: NilClass#to_msgpack
 *
 * call-seq:
 *   nil.to_msgpack(out = '') -> String
 *
 * Serializes the nil into raw bytes.
 */
static VALUE MessagePack_NilClass_to_msgpack(int argc, VALUE *argv, VALUE self)
{
    ARG_BUFFER(out, argc, argv);
    msgpack_pack_nil(out);
    return out;
}
Esempio n. 4
0
static void
msgpack_wrap_redis_reply(const struct cmd *cmd, struct msg_out *out, const redisReply *r) {

	unsigned int i;
	msgpack_packer* pk = msgpack_packer_new(out, on_msgpack_write);

	/* copy verb, as jansson only takes a char* but not its length. */
	char *verb = "";
	size_t verb_sz = 0;
	if(cmd->count) {
		verb_sz = cmd->argv_len[0];
		verb = cmd->argv[0];
	}

	/* Create map object */
	msgpack_pack_map(pk, 1);

	/* The single element is the verb */
	msgpack_pack_raw(pk, verb_sz);
	msgpack_pack_raw_body(pk, verb, verb_sz);

	switch(r->type) {
		case REDIS_REPLY_STATUS:
		case REDIS_REPLY_ERROR:
			msgpack_pack_array(pk, 2);

			/* first element: book */
			if(r->type == REDIS_REPLY_ERROR)
				msgpack_pack_false(pk);
			else
				msgpack_pack_true(pk);

			/* second element: message */
			msgpack_pack_raw(pk, r->len);
			msgpack_pack_raw_body(pk, r->str, r->len);
			break;

		case REDIS_REPLY_STRING:
			if(verb_sz ==4 && strncasecmp(verb, "INFO", 4) == 0) {
				msg_info_reply(pk, r->str, r->len);
			} else {
				msgpack_pack_raw(pk, r->len);
				msgpack_pack_raw_body(pk, r->str, r->len);
			}
			break;

		case REDIS_REPLY_INTEGER:
			msgpack_pack_int(pk, r->integer);
			break;

		case REDIS_REPLY_ARRAY:
			if(verb_sz == 7 && strncasecmp(verb, "HGETALL", 7) == 0) {
				msg_hgetall_reply(pk, r);
				break;
			}

			msgpack_pack_array(pk, r->elements);

			for(i = 0; i < r->elements; ++i) {
				redisReply *e = r->element[i];
				switch(e->type) {
					case REDIS_REPLY_STRING:
						msgpack_pack_raw(pk, e->len);
						msgpack_pack_raw_body(pk, e->str, e->len);
						break;
					case REDIS_REPLY_INTEGER:
						msgpack_pack_int(pk, e->integer);
						break;
					default:
						msgpack_pack_nil(pk);
						break;
				}
			}

			break;

		default:
			msgpack_pack_nil(pk);
			break;
	}

	msgpack_packer_free(pk);
}
void unit_message_deserialize_response(UNUSED(void **state))
{
  struct api_error error = ERROR_INIT;
  msgpack_sbuffer sbuf;
  msgpack_packer pk;
  msgpack_zone mempool;
  msgpack_object deserialized;
  struct message_response response;

  msgpack_sbuffer_init(&sbuf);
  msgpack_zone_init(&mempool, 2048);

  /* positiv test */
  msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
  msgpack_pack_array(&pk, 4);
  msgpack_pack_uint8(&pk, 1);
  msgpack_pack_uint32(&pk, 1234);
  msgpack_pack_nil(&pk);
  msgpack_pack_array(&pk, 1);
  msgpack_pack_uint8(&pk, 0);
  msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);

  assert_int_equal(0, message_deserialize_response(&response, &deserialized,
      &error));

  msgpack_sbuffer_clear(&sbuf);

  free_params(response.params);

  /* wrong type type */
  msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
  msgpack_pack_array(&pk, 4);
  msgpack_pack_nil(&pk);
  msgpack_pack_uint32(&pk, 1234);
  msgpack_pack_nil(&pk);
  msgpack_pack_array(&pk, 1);
  msgpack_pack_uint8(&pk, 0);
  msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);

  assert_int_not_equal(0, message_deserialize_response(&response, &deserialized,
      &error));

  msgpack_sbuffer_clear(&sbuf);

  /* wrong type */
  msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
  msgpack_pack_array(&pk, 4);
  msgpack_pack_uint8(&pk, 0);
  msgpack_pack_uint32(&pk, 1234);
  msgpack_pack_nil(&pk);
  msgpack_pack_array(&pk, 1);
  msgpack_pack_uint8(&pk, 0);
  msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);

  assert_int_not_equal(0, message_deserialize_response(&response, &deserialized,
      &error));

  msgpack_sbuffer_clear(&sbuf);

  /* wrong msgid */
  msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
  msgpack_pack_array(&pk, 4);
  msgpack_pack_uint8(&pk, 1);
  msgpack_pack_int(&pk, -1234);
  msgpack_pack_nil(&pk);
  msgpack_pack_array(&pk, 1);
  msgpack_pack_uint8(&pk, 0);
  msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);

  assert_int_not_equal(0, message_deserialize_response(&response, &deserialized,
      &error));

  msgpack_sbuffer_clear(&sbuf);

  /* wrong msgid value*/
  msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
  msgpack_pack_array(&pk, 4);
  msgpack_pack_uint8(&pk, 1);
  msgpack_pack_uint32(&pk, UINT32_MAX);
  msgpack_pack_nil(&pk);
  msgpack_pack_array(&pk, 1);
  msgpack_pack_uint8(&pk, 0);
  msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);

  assert_int_not_equal(0, message_deserialize_response(&response, &deserialized,
      &error));

  msgpack_sbuffer_clear(&sbuf);

  /* wrong nil */
  msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
  msgpack_pack_array(&pk, 4);
  msgpack_pack_uint8(&pk, 1);
  msgpack_pack_uint32(&pk, 1234);
  msgpack_pack_uint8(&pk, 1);
  msgpack_pack_array(&pk, 1);
  msgpack_pack_uint8(&pk, 0);
  msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);

  assert_int_not_equal(0, message_deserialize_response(&response, &deserialized,
      &error));

  msgpack_sbuffer_clear(&sbuf);

  /* wrong params */
  msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
  msgpack_pack_array(&pk, 4);
  msgpack_pack_uint8(&pk, 1);
  msgpack_pack_uint32(&pk, 1234);
  msgpack_pack_nil(&pk);
  msgpack_pack_nil(&pk);
  msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);

  assert_int_not_equal(0, message_deserialize_response(&response, &deserialized,
      &error));

  msgpack_sbuffer_clear(&sbuf);

  /* null input params */
  assert_int_not_equal(0, message_deserialize_response(&response, &deserialized,
      NULL));
  assert_int_not_equal(0, message_deserialize_response(&response, NULL,
      &error));
  assert_int_not_equal(0, message_deserialize_response(NULL, &deserialized,
      &error));

  msgpack_zone_destroy(&mempool);
  msgpack_sbuffer_destroy(&sbuf);
}
Esempio n. 6
0
static void pack_object_space_dump_event(rbkit_object_space_dump_event *event, msgpack_packer *packer) {
  size_t objects_in_batch;
  size_t objects_left;
  size_t count = 0;
  size_t i = 0;
  rbkit_object_dump_page *prev;
  rbkit_object_data *data;
  rbkit_object_dump_page * page;

  msgpack_pack_map(packer, 5);
  pack_event_header(packer, event->event_header.event_type);

  // Incrementing integer holding the correlation_id
  // indicating the event which the message belongs to
  msgpack_pack_int(packer, rbkit_message_field_correlation_id);
  msgpack_pack_int(packer, event->correlation_id);
  
  // dump total number of messages in batch
  msgpack_pack_int(packer, rbkit_message_field_complete_message_count);
  msgpack_pack_unsigned_long(packer, event->object_count);

  msgpack_pack_int(packer, rbkit_message_field_payload);

  // Find the batch size
  objects_in_batch = MAX_OBJECT_DUMPS_IN_MESSAGE ;
  objects_left = event->object_count - event->packed_objects;
  if(objects_left < MAX_OBJECT_DUMPS_IN_MESSAGE)
    objects_in_batch = objects_left;

  // Set size of array to hold all objects
  msgpack_pack_array(packer, objects_in_batch);

  // Iterate through all object data
  while(count < objects_in_batch) {
    if(event->current_page_index == RBKIT_OBJECT_DUMP_PAGE_SIZE) {
      event->current_page_index = 0;
      prev = event->current_page;
      event->current_page = event->current_page->next;
      free(prev);
    }
    page = event->current_page;
    i = event->current_page_index;
    data = &(page->data[i]);
    /* Object dump is a map that looks like this :
     * {
     *   object_id: <OBJECT_ID_IN_HEX>,
     *   class: <CLASS_NAME>,
     *   references: [<OBJECT_ID_IN_HEX>, <OBJECT_ID_IN_HEX>, ...],
     *   file: <FILE_PATH>,
     *   line: <LINE_NO>,
     *   size: <SIZE>
     * }
     */

    msgpack_pack_map(packer, 6);

    // Key1 : rbkit_message_field_object_id
    msgpack_pack_int(packer, rbkit_message_field_object_id);

    // Value1 : pointer address of object
    msgpack_pack_unsigned_long_long(packer, data->object_id);

    // Key2 : rbkit_message_field_class_name
    msgpack_pack_int(packer, rbkit_message_field_class_name);

    // Value2 : Class name of object
    pack_string(packer, data->class_name);

    // Key3 : rbkit_message_field_references
    msgpack_pack_int(packer, rbkit_message_field_references);

    // Value3 : References held by the object
    msgpack_pack_array(packer, data->reference_count);
    if(data->reference_count != 0) {
      size_t count = 0;
      for(; count < data->reference_count; count++ )
        msgpack_pack_unsigned_long_long(packer, data->references[count]);
      free(data->references);
    }

    // Key4 : rbkit_message_field_file
    msgpack_pack_int(packer, rbkit_message_field_file);

    // Value4 : File path where object is defined
    pack_string(packer, data->file);

    // Key5 : rbkit_message_field_line
    msgpack_pack_int(packer, rbkit_message_field_line);

    // Value5 : Line no where object is defined
    if(data->line == 0)
      msgpack_pack_nil(packer);
    else
      msgpack_pack_unsigned_long(packer, data->line);

    // Key6 : rbkit_message_field_size
    msgpack_pack_int(packer, rbkit_message_field_size);

    // Value6 : Size of the object in memory
    if(data->size == 0)
      msgpack_pack_nil(packer);
    else
      msgpack_pack_unsigned_long(packer, data->size);

    event->current_page_index++;
    event->packed_objects++;
    count++;
  }
}
Esempio n. 7
0
void publish_proc_event(process_t *process, const char *name) {
  /* TODO(sissel): move this to a separate file for 'event' streaming */
  zmq_msg_t event;
  int rc;
  size_t msgsize;
  program_t *program = pn_proc_program(process);
  procnanny_t *pn = program->data;

  /* Fields:
   *  - program name
   *  - process instance
   *  - exit status
   *  - duration ?
   */

  msgpack_sbuffer *buffer = msgpack_sbuffer_new();
  msgpack_packer *output_msg = msgpack_packer_new(buffer, msgpack_sbuffer_write);

  msgpack_pack_map(output_msg, 5);
  msgpack_pack_string(output_msg, "event", -1);
  msgpack_pack_string(output_msg, name, -1);

  msgpack_pack_string(output_msg, "program", -1);
  msgpack_pack_string(output_msg, program->name, program->name_len);

  msgpack_pack_string(output_msg, "instance", -1);
  msgpack_pack_int(output_msg, process->instance);

  msgpack_pack_string(output_msg, "state", -1);
  switch (process->state) {
    case PROCESS_STATE_STARTING: msgpack_pack_string(output_msg, "starting", -1); break;
    case PROCESS_STATE_RUNNING: msgpack_pack_string(output_msg, "running", -1); break;
    case PROCESS_STATE_STOPPING: msgpack_pack_string(output_msg, "stopping", -1); break;
    case PROCESS_STATE_EXITED: msgpack_pack_string(output_msg, "exited", -1); break;
    case PROCESS_STATE_BACKOFF: msgpack_pack_string(output_msg, "backoff", -1); break;
    case PROCESS_STATE_NEW: msgpack_pack_string(output_msg, "new", -1); break;
    default: msgpack_pack_string(output_msg, "unknown", -1); break;
  }

  if (process->state == PROCESS_STATE_EXITED
      || process->state == PROCESS_STATE_BACKOFF) {
    msgpack_pack_string(output_msg, "code", -1);
    msgpack_pack_nil(output_msg);
  } else if (process->exit_signal == 0) {
    msgpack_pack_string(output_msg, "code", -1);
    msgpack_pack_int(output_msg, process->exit_status);
  } else {
    msgpack_pack_string(output_msg, "signal", -1);

    /* lol. */
    switch (process->exit_signal) {
      case SIGHUP: msgpack_pack_string(output_msg, "HUP", 3); break;
      case SIGINT: msgpack_pack_string(output_msg, "INT", 3); break;
      case SIGQUIT: msgpack_pack_string(output_msg, "QUIT", 4); break;
      case SIGILL: msgpack_pack_string(output_msg, "ILL", 3); break;
      case SIGTRAP: msgpack_pack_string(output_msg, "TRAP", 4); break;
      case SIGABRT: msgpack_pack_string(output_msg, "ABRT", 4); break;
      case SIGBUS: msgpack_pack_string(output_msg, "BUS", 3); break;
      case SIGFPE: msgpack_pack_string(output_msg, "FPE", 3); break;
      case SIGKILL: msgpack_pack_string(output_msg, "KILL", 4); break;
      case SIGUSR1: msgpack_pack_string(output_msg, "USR1", 4); break;
      case SIGSEGV: msgpack_pack_string(output_msg, "SEGV", 4); break;
      case SIGUSR2: msgpack_pack_string(output_msg, "USR2", 4); break;
      case SIGPIPE: msgpack_pack_string(output_msg, "PIPE", 4); break;
      case SIGALRM: msgpack_pack_string(output_msg, "ALRM", 4); break;
      case SIGTERM: msgpack_pack_string(output_msg, "TERM", 4); break;
      case SIGSTKFLT: msgpack_pack_string(output_msg, "STKFLT", 6); break;
      case SIGCHLD: msgpack_pack_string(output_msg, "CHLD", 4); break;
      case SIGCONT: msgpack_pack_string(output_msg, "CONT", 4); break;
      case SIGSTOP: msgpack_pack_string(output_msg, "STOP", 4); break;
      case SIGTSTP: msgpack_pack_string(output_msg, "TSTP", 4); break;
      case SIGTTIN: msgpack_pack_string(output_msg, "TTIN", 4); break;
      case SIGTTOU: msgpack_pack_string(output_msg, "TTOU", 4); break;
      case SIGURG: msgpack_pack_string(output_msg, "URG", 3); break;
      case SIGXCPU: msgpack_pack_string(output_msg, "XCPU", 4); break;
      case SIGXFSZ: msgpack_pack_string(output_msg, "XFSZ", 4); break;
      case SIGVTALRM: msgpack_pack_string(output_msg, "VTALRM", 5); break;
      case SIGPROF: msgpack_pack_string(output_msg, "PROF", 4); break;
      case SIGWINCH: msgpack_pack_string(output_msg, "WINCH", 5); break;
      case SIGPOLL: msgpack_pack_string(output_msg, "POLL", 4); break;
      case SIGPWR: msgpack_pack_string(output_msg, "PWR", 3); break;
      case SIGSYS: msgpack_pack_string(output_msg, "SYS", 3); break;
      default: msgpack_pack_string(output_msg, "unknown", -1); break;
    } /* switch process->exit_signal */
  } /* if process was killed by a signal */

  zmq_msg_init_data(&event, buffer->data, buffer->size, free_msgpack_buffer, buffer); 
  zmq_send(pn->eventsocket, &event, 0);
  zmq_msg_close(&event);

  msgpack_packer_free(output_msg);
} /* publish_output */
Esempio n. 8
0
static void msgpack_null(CTX ctx, void *pkp)
{
	kpackAPI_t *pk = (kpackAPI_t *)pkp;
	msgpack_pack_nil(pk->pk);
}
Esempio n. 9
0
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
{
    switch(d.type) {
    case MSGPACK_OBJECT_NIL:
        return msgpack_pack_nil(pk);

    case MSGPACK_OBJECT_BOOLEAN:
        if(d.via.boolean) {
            return msgpack_pack_true(pk);
        } else {
            return msgpack_pack_false(pk);
        }

    case MSGPACK_OBJECT_POSITIVE_INTEGER:
        return msgpack_pack_uint64(pk, d.via.u64);

    case MSGPACK_OBJECT_NEGATIVE_INTEGER:
        return msgpack_pack_int64(pk, d.via.i64);

    case MSGPACK_OBJECT_FLOAT32:
        return msgpack_pack_float(pk, (float)d.via.f64);

    case MSGPACK_OBJECT_FLOAT64:
        return msgpack_pack_double(pk, d.via.f64);

    case MSGPACK_OBJECT_STR:
        {
            int ret = msgpack_pack_str(pk, d.via.str.size);
            if(ret < 0) { return ret; }
            return msgpack_pack_str_body(pk, d.via.str.ptr, d.via.str.size);
        }

    case MSGPACK_OBJECT_BIN:
        {
            int ret = msgpack_pack_bin(pk, d.via.bin.size);
            if(ret < 0) { return ret; }
            return msgpack_pack_bin_body(pk, d.via.bin.ptr, d.via.bin.size);
        }

    case MSGPACK_OBJECT_EXT:
        {
            int ret = msgpack_pack_ext(pk, d.via.ext.size, d.via.ext.type);
            if(ret < 0) { return ret; }
            return msgpack_pack_ext_body(pk, d.via.ext.ptr, d.via.ext.size);
        }

    case MSGPACK_OBJECT_ARRAY:
        {
            int ret = msgpack_pack_array(pk, d.via.array.size);
            if(ret < 0) {
                return ret;
            }
            else {
                msgpack_object* o = d.via.array.ptr;
                msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
                for(; o != oend; ++o) {
                    ret = msgpack_pack_object(pk, *o);
                    if(ret < 0) { return ret; }
                }

                return 0;
            }
        }

    case MSGPACK_OBJECT_MAP:
        {
            int ret = msgpack_pack_map(pk, d.via.map.size);
            if(ret < 0) {
                return ret;
            }
            else {
                msgpack_object_kv* kv = d.via.map.ptr;
                msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
                for(; kv != kvend; ++kv) {
                    ret = msgpack_pack_object(pk, kv->key);
                    if(ret < 0) { return ret; }
                    ret = msgpack_pack_object(pk, kv->val);
                    if(ret < 0) { return ret; }
                }

                return 0;
            }
        }

    default:
        return -1;
    }
}
Esempio n. 10
0
int msgpack_pack_nil_wrap(msgpack_packer* pk)
{
  return msgpack_pack_nil(pk);
}
Esempio n. 11
0
/* Receive a tokenized JSON message and convert it to MsgPack */
static char *tokens_to_msgpack(char *js,
                               jsmntok_t *tokens, int arr_size, int *out_size)
{
    int i;
    int flen;
    char *p;
    char *buf;
    jsmntok_t *t;
    msgpack_packer pck;
    msgpack_sbuffer sbuf;

    /* initialize buffers */
    msgpack_sbuffer_init(&sbuf);
    msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);

    for (i = 0; i < arr_size ; i++) {
        t = &tokens[i];
        if (t->start == -1 || t->end == -1 || (t->start == 0 && t->end == 0)) {
            break;
        }
        flen = (t->end - t->start);

        switch (t->type) {
        case JSMN_OBJECT:
            msgpack_pack_map(&pck, t->size);
            break;
        case JSMN_ARRAY:
            msgpack_pack_array(&pck, t->size);
            break;
        case JSMN_STRING:
            msgpack_pack_bin(&pck, flen);
            msgpack_pack_bin_body(&pck, js + t->start, flen);
            break;
        case JSMN_PRIMITIVE:
            p = js + t->start;
            if (*p == 'f') {
                msgpack_pack_false(&pck);
            }
            else if (*p == 't') {
                msgpack_pack_true(&pck);
            }
            else if (*p == 'n') {
                msgpack_pack_nil(&pck);
            }
            else {
                if (is_float(p, flen)) {
                    msgpack_pack_double(&pck, atof(p));
                }
                else {
                    msgpack_pack_int64(&pck, atol(p));
                }
            }
            break;
        case JSMN_UNDEFINED:
            msgpack_sbuffer_destroy(&sbuf);
            return NULL;
        }
    }

    /* dump data back to a new buffer */
    *out_size = sbuf.size;
    buf = malloc(sbuf.size);
    memcpy(buf, sbuf.data, sbuf.size);
    msgpack_sbuffer_destroy(&sbuf);

    return buf;
}
Esempio n. 12
0
void rpc_service_handle(rpc_service_t *service, zmq_msg_t *request) {
  /* Parse the msgpack */
  zmq_msg_t response;
  int rc;
  msgpack_unpacked request_msg;
  msgpack_unpacked_init(&request_msg);
  rc = msgpack_unpack_next(&request_msg, zmq_msg_data(request),
                           zmq_msg_size(request), NULL);
  insist_return(rc, (void)(0), "Failed to unpack message '%.*s'",
                (int)zmq_msg_size(request), (char *)zmq_msg_data(request));

  msgpack_object request_obj = request_msg.data;

  /* Find the method name */
  char *method = NULL;
  size_t method_len = -1;
  rc = obj_get(&request_obj, "method", MSGPACK_OBJECT_RAW, &method, &method_len);

  msgpack_sbuffer *response_buffer = msgpack_sbuffer_new();
  msgpack_sbuffer *result_buffer = msgpack_sbuffer_new();
  msgpack_sbuffer *error_buffer = msgpack_sbuffer_new();

  msgpack_packer *response_msg = msgpack_packer_new(response_buffer, msgpack_sbuffer_write);
  msgpack_packer *result = msgpack_packer_new(result_buffer, msgpack_sbuffer_write);
  msgpack_packer *error = msgpack_packer_new(error_buffer, msgpack_sbuffer_write);

  //printf("Method: %.*s\n", method_len, method);

  void *clock = zmq_stopwatch_start();
  double duration;

  if (rc != 0) { /* method not found */
    msgpack_pack_nil(result); /* result is nil on error */
    msgpack_pack_map(error, 2);
    msgpack_pack_string(error, "error", -1);
    msgpack_pack_string(error, "Message had no 'method' field", -1);
    msgpack_pack_string(error, "request", -1);
    msgpack_pack_object(error, request_obj);
  } else { /* valid method, keep going */
    //printf("The method is: '%.*s'\n", (int)method_len, method);
    rpc_name name;
    name.name = method;
    name.len = method_len;

    rpc_method *rpcmethod = g_tree_lookup(service->methods, &name);

    /* if we found a valid rpc method and the args check passed ... */
    if (rpcmethod != NULL) {
      /* the callback is responsible for filling in the 'result' and 'error' 
       * objects. */
      rpcmethod->callback(NULL, &request_obj, result, error, rpcmethod->data);
    } else {
      msgpack_pack_nil(result); /* result is nil on error */

      /* TODO(sissel): allow methods to register themselves */
      //fprintf(stderr, "Invalid request '%.*s' (unknown method): ",
              //method_len, method);
      //msgpack_object_print(stderr, request_obj);
      //fprintf(stderr, "\n");

      msgpack_pack_map(error, 2);
      msgpack_pack_string(error, "error", -1);
      msgpack_pack_string(error, "No such method requested", -1);
      msgpack_pack_string(error, "request", -1);
      msgpack_pack_object(error, request_obj);
    }
  } /* valid/invalid method handling */

  duration = zmq_stopwatch_stop(clock) / 1000000.;
  //printf("method '%.*s' took %lf seconds\n", (int)method_len, method);

  msgpack_unpacked result_unpacked;
  msgpack_unpacked error_unpacked;
  msgpack_unpacked response_unpacked;
  msgpack_unpacked_init(&result_unpacked);
  msgpack_unpacked_init(&error_unpacked);
  msgpack_unpacked_init(&response_unpacked);

  /* TODO(sissel): If this unpack test fails, we should return an error to the calling
   * client indicating that some internal error has occurred */
  //fprintf(stderr, "Result payload: '%.*s'\n", result_buffer->size,
  //result_buffer->data);
  rc = msgpack_unpack_next(&result_unpacked, result_buffer->data,
                           result_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on 'result' buffer"
         " of request '%.*s'", (int)method_len, method);
  rc = msgpack_unpack_next(&error_unpacked, error_buffer->data,
                           error_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on 'error' buffer"
         " of request '%.*s'", (int)method_len, method);

  msgpack_pack_map(response_msg, 3); /* result, error, duration */
  msgpack_pack_string(response_msg, "result", 6);
  msgpack_pack_object(response_msg, result_unpacked.data);
  msgpack_pack_string(response_msg, "error", 5);
  msgpack_pack_object(response_msg, error_unpacked.data);
  msgpack_pack_string(response_msg, "duration", 8);
  msgpack_pack_double(response_msg, duration);

  rc = msgpack_unpack_next(&response_unpacked, response_buffer->data,
                           response_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on full response buffer"
         " of request '%.*s'", (int)method_len, method);

  //printf("request: ");
  //msgpack_object_print(stdout, request_obj);
  //printf("\n");
  //printf("response: ");
  //msgpack_object_print(stdout, response_unpacked.data);
  //printf("\n");

  zmq_msg_init_data(&response, response_buffer->data, response_buffer->size,
                    free_msgpack_buffer, response_buffer);
  zmq_send(service->socket, &response, 0);
  zmq_msg_close(&response);

  msgpack_packer_free(error);
  msgpack_packer_free(result);
  msgpack_sbuffer_free(error_buffer);
  msgpack_sbuffer_free(result_buffer);
  msgpack_packer_free(response_msg);
  msgpack_unpacked_destroy(&request_msg);
} /* rpc_service_handle */
Esempio n. 13
0
/* It parse a JSON string and convert it to MessagePack format */
char *flb_pack_json(char *js, size_t len, int *size)
{
    int i;
    int flen;
    int arr_size;
    char *p;
    char *buf;
    jsmntok_t *t;
    jsmntok_t *tokens;
    msgpack_packer pck;
    msgpack_sbuffer sbuf;

    if (!js) {
        return NULL;
    }

    tokens = json_tokenise(js, len, &arr_size);
    if (!tokens) {
        return NULL;
    }

    flb_debug("JSON to pack: '%s'", js);

    /* initialize buffers */
    msgpack_sbuffer_init(&sbuf);
    msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);

    for (i = 0; i < arr_size ; i++) {
        t = &tokens[i];
        if (t->start == -1 || t->end == -1 || (t->start == 0 && t->end == 0)) {
            break;
        }
        flen = (t->end - t->start);

        switch (t->type) {
        case JSMN_OBJECT:
            flb_debug("json_pack: token=%i is OBJECT (size=%i)", i, t->size);
            msgpack_pack_map(&pck, t->size);
            break;
        case JSMN_ARRAY:
            flb_debug("json_pack: token=%i is ARRAY (size=%i)", i, t->size);
            msgpack_pack_array(&pck, t->size);
            break;
        case JSMN_STRING:
            flb_debug("json_pack: token=%i is STRING (len=%i)\n", i, flen);
            msgpack_pack_bin(&pck, flen);
            msgpack_pack_bin_body(&pck, js + t->start, flen);
            break;
        case JSMN_PRIMITIVE:
            p = js + t->start;
            if (strncmp(p, "false", 5) == 0) {
                flb_debug("json_pack: token=%i is FALSE", i);
                msgpack_pack_false(&pck);
            }
            else if (strncmp(p, "true", 4) == 0) {
                flb_debug("json_pack: token=%i is TRUE", i);
                msgpack_pack_true(&pck);
            }
            else if (strncmp(p, "null", 4) == 0) {
                flb_debug("json_pack: token=%i is NULL", i);
                msgpack_pack_nil(&pck);
            }
            else {
                flb_debug("json_pack: token=%i is INT64", i);
                msgpack_pack_int64(&pck, atol(p));
            }
            break;
        }
    }

    /* dump data back to a new buffer */
    *size = sbuf.size;
    buf = malloc(sbuf.size);
    memcpy(buf, sbuf.data, sbuf.size);
    msgpack_sbuffer_destroy(&sbuf);

    free(tokens);
    return buf;
}
Esempio n. 14
0
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
{
	switch(d.type) {
	case MSGPACK_OBJECT_NIL:
		return msgpack_pack_nil(pk);

	case MSGPACK_OBJECT_BOOLEAN:
		if(d.via.boolean) {
			return msgpack_pack_true(pk);
		} else {
			return msgpack_pack_false(pk);
		}

	case MSGPACK_OBJECT_POSITIVE_INTEGER:
		return msgpack_pack_uint64(pk, d.via.u64);

	case MSGPACK_OBJECT_NEGATIVE_INTEGER:
		return msgpack_pack_int64(pk, d.via.i64);

	case MSGPACK_OBJECT_DOUBLE:
		return msgpack_pack_double(pk, d.via.dec);

	case MSGPACK_OBJECT_RAW:
		{
			int ret = msgpack_pack_raw(pk, d.via.raw.size);
			if(ret < 0) { return ret; }
			return msgpack_pack_raw_body(pk, d.via.raw.ptr, d.via.raw.size);
		}

	case MSGPACK_OBJECT_ARRAY:
		{
			int ret = msgpack_pack_array(pk, d.via.array.size);
			if(ret < 0) { return ret; }

			msgpack_object* o = d.via.array.ptr;
			msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
			for(; o != oend; ++o) {
				ret = msgpack_pack_object(pk, *o);
				if(ret < 0) { return ret; }
			}

			return 0;
		}

	case MSGPACK_OBJECT_MAP:
		{
			int ret = msgpack_pack_map(pk, d.via.map.size);
			if(ret < 0) { return ret; }

			msgpack_object_kv* kv = d.via.map.ptr;
			msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
			for(; kv != kvend; ++kv) {
				ret = msgpack_pack_object(pk, kv->key);
				if(ret < 0) { return ret; }
				ret = msgpack_pack_object(pk, kv->val);
				if(ret < 0) { return ret; }
			}

			return 0;
		}

	default:
		return -1;
	}
}