mc_msg_t *mc_msg_new_with_key_and_value_full(const char *key, size_t nkey, const char *value, size_t nvalue) { // add + 2 for '\0' for both key & value mc_msg_t *msg = mc_msg_new(nkey + nvalue + 2); char *ptr = (char*)msg; ptr += sizeof(mc_msg_t); // copy the key and set the pointers memcpy(ptr, key, nkey); ptr[nkey] = '\0'; msg->key.str = ptr; msg->key.len = nkey; // move past the key ptr += nkey + 1; // copy the value and set the pointers memcpy(ptr, value, nvalue); ptr[nvalue] = '\0'; msg->value.str = ptr; msg->value.len = nvalue; return msg; }
static Object mcr_int(ObjectData* this_, int64_t val) { mcr::mcrouter_msg_t msg; msg.req = mc_msg_new(0); msg.req->number = val; msg.req->op = op; return Native::data<MCRouter>(this_)->issue(msg); }
mc_msg_t* mc_msg_dup(const mc_msg_t *msg) { FBI_ASSERT(msg); FBI_ASSERT(msg->_refcount > 0 || msg->_refcount == MSG_NOT_REFCOUNTED); mc_msg_t *msg_copy = mc_msg_new(msg->_extra_size); if (msg_copy == NULL) { return NULL; } _msgcpy(msg_copy, msg); return msg_copy; }
mc_msg_t *mc_msg_new_with_key_full(const char *key, size_t nkey) { mc_msg_t *msg = mc_msg_new(nkey + 1); // + 1 for '\0'. char *ptr = (char*)msg; ptr += sizeof(mc_msg_t); memcpy(ptr, key, nkey); msg->key.str = ptr; msg->key.str[nkey] = '\0'; msg->key.len = nkey; return msg; }
/* reallocate a mc_msg_t * for deep/shallow copying semantics, see _msgcpy * For more on why we do it this way, see Task #689247 and D314525 */ mc_msg_t* mc_msg_realloc(mc_msg_t *msg, size_t new_extra_size) { if (msg == NULL) { // Same behavior as realloc, malloc on NULL return mc_msg_new(new_extra_size); } if (new_extra_size <= msg->_extra_size) { return msg; } mc_msg_t *msg_copy = mc_msg_new(new_extra_size); if (msg_copy == NULL) { // Same behavior as realloc, don't clean up msg return NULL; } _msgcpy(msg_copy, msg); msg_copy->_extra_size = new_extra_size; // "free" it mc_msg_decref(msg); return msg_copy; }
mc_msg_t* mc_msg_dup_append_key_full(const mc_msg_t *msg, const char* key_append, size_t nkey_append) { FBI_ASSERT(msg); FBI_ASSERT(msg->_refcount > 0 || msg->_refcount == MSG_NOT_REFCOUNTED); FBI_ASSERT(key_append); // Stats are not supported. if (msg->stats) { return NULL; } if (!nkey_append) { return mc_msg_dup(msg); } size_t new_extra_size = msg->_extra_size + nkey_append; if (!_in_msg(msg, msg->key.str, msg->key.len)) { new_extra_size += msg->key.len + 1; // +1 for null terminator } mc_msg_t* const msg_copy = mc_msg_new(new_extra_size); if (msg_copy == NULL) { return NULL; } mc_msg_shallow_copy(msg_copy, msg); // The new message's key is always embedded. msg_copy->key.len = msg->key.len + nkey_append; msg_copy->key.str = (void*) msg_copy + sizeof(*msg_copy); memcpy(msg_copy->key.str, msg->key.str, msg->key.len); memcpy(msg_copy->key.str + msg->key.len, key_append, nkey_append); msg_copy->key.str[msg_copy->key.len] = 0; if (_in_msg(msg, msg->value.str, msg->value.len)) { // The value starts after the key, including the null terminator. msg_copy->value.str = msg_copy->key.str + msg_copy->key.len + 1; memcpy(msg_copy->value.str, msg->value.str, msg_copy->value.len); } return msg_copy; }
static Object mcr_void(ObjectData* this_) { mcr::mcrouter_msg_t msg; msg.req = mc_msg_new(0); msg.req->op = op; return Native::data<MCRouter>(this_)->issue(msg); }
static mc_msg_t *_msg_create(mc_msg_t *base, entry_list_t *elist, _parse_info_t* parse_info) { size_t msg_size = 0; mc_msg_t *msg = NULL; size_t stats_offset = 0; size_t body_offset = 0; void *body = NULL; // Make sure we're not screwing up alignment here FBI_ASSERT(sizeof(mc_msg_t) % sizeof(void *) == 0); // Construct a message of the following format // __________________ // | | // | mc_msg_t | <- base message // |___________________| // | | // | nstring_t array | <- stats array (optional) // |___________________| // | | // | key string | <- key (optional) // |___________________| // | | // | value string | <- value (optional) // |___________________| // | | // | stats[0] | <- stats[0] (and so on...) // |___________________| // msg_size = sizeof(mc_msg_t); if (parse_info->stats_count > 0) { stats_offset = msg_size; msg_size += (sizeof(nstring_t) * parse_info->stats_count); } body_offset = msg_size; msg_size += elist->nbody; FBI_ASSERT(msg_size >= sizeof(*base)); msg = mc_msg_new(msg_size - sizeof(mc_msg_t)); if (msg == NULL) { goto error; } // Copy base mc_msg_copy(msg, base); // Copy body memcpy((void*)msg + body_offset, elist->body, elist->nbody); body = (void*)msg + body_offset; if (parse_info->stats_count > 0) { FBI_ASSERT(stats_offset > 0); nstring_t *stats = (nstring_t*) ((void*)msg + stats_offset); uint64_t i; int sidx; for (i = 0, sidx = 0; i < elist->nentries && sidx < parse_info->stats_count; i++) { um_elist_entry_t *entry = &elist->entries[i]; if (ntoh16(entry->tag) == msg_stats) { _set_str(&stats[sidx], body, entry); sidx++; } } msg->stats = stats; } _fill_msg_strs(msg, elist, body, parse_info); return msg; error: if (msg != NULL) { mc_msg_decref(msg); msg = NULL; } return NULL; }