#include <assert.h>
#include "command.h"
#include "../common.h"
static char *memcache_cmd_names[MEMCACHE_CMD_MAX] = {
NULL, // MEMCACHE_CMD_INVALID
"get", // MEMCACHE_CMD_FETCH_GET
"set", // MEMCACHE_CMD_STORE_SET
"add", // MEMCACHE_CMD_STORE_ADD
"replace", // MEMCACHE_CMD_STORE_REPLACE
"append", // MEMCACHE_CMD_STORE_APPEND
"prepend" // MEMCACHE_CMD_STORE_PREPEND
};
/*
static struct memcache_reply_info {
enum memcache_reply type;
char *name;
int has_data;
} *memcache_cmd_replies[MEMCACHE_RPL_MAX] = {
MEMCACHE_RPL_INVALID,
MEMCACHE_RPL_ERROR,
MEMCACHE_RPL_CLIENT_ERROR,
MEMCACHE_RPL_SERVER_ERROR,
// MEMCACHE_CMD_FETCH_*
MEMCACHE_RPL_VALUE,
MEMCACHE_RPL_END,
// MEMCACHE_CMD_STORE_*
MEMCACHE_RPL_STORED,
MEMCACHE_RPL_NOT_STORED,
MEMCACHE_RPL_EXISTS,
MEMCACHE_RPL_NOT_FOUND,
};
*/
int memcache_cmd_init (struct memcache_cmd *cmd, enum memcache_command cmd_type, struct memcache_key *key, struct memcache_obj *obj) {
// shouldn't already have a request header yet?
assert(cmd->req_header == NULL);
// allocate the request header
if ((cmd->req_header = evbuffer_new()) == NULL)
ERROR("evbuffer_new");
// format the command
if (memcache_cmd_format_header(cmd->req_header, cmd_type, key, obj))
goto error;
// XXX: prepare the rest
// success
return 0;
error:
if (cmd->req_header)
evbuffer_free(cmd->req_header);
return -1;
}
int memcache_cmd_format_header (struct evbuffer *buf, enum memcache_command cmd_type, struct memcache_key *key, struct memcache_obj *obj) {
char *cmd_name;
// valid command
assert(cmd_type < MEMCACHE_CMD_MAX);
if (cmd_type == MEMCACHE_CMD_INVALID)
ERROR("invalid command");
// map the command to a string
cmd_name = memcache_cmd_names[cmd_type];
// format the request header
switch (cmd_type) {
case MEMCACHE_CMD_FETCH_GET:
assert(key != NULL && obj == NULL);
assert(key->len > 0 && key->buf != NULL);
if (evbuffer_add_printf(buf, "%s %*s\r\n", cmd_name, (int) key->len, key->buf) == -1)
ERROR("evbuffer_add_printf");
break;
case MEMCACHE_CMD_STORE_SET:
case MEMCACHE_CMD_STORE_ADD:
case MEMCACHE_CMD_STORE_REPLACE:
case MEMCACHE_CMD_STORE_APPEND:
case MEMCACHE_CMD_STORE_PREPEND:
assert(key != NULL && obj != NULL);
assert(key->len > 0 && key->buf != NULL);
assert(obj->bytes > 0);
if (evbuffer_add_printf(buf, "%s %*s %u %lu %zu\r\n", cmd_name, (int) key->len, key->buf, obj->flags, obj->exptime, obj->bytes))
ERROR("evbuffer_add_printf");
break;
case MEMCACHE_CMD_STORE_CAS:
default:
// XXX: not supported yet/invalid
assert(0);
};
// success
return 0;
error:
return -1;
}
int memcache_cmd_parse_header (struct evbuffer *buf, char **header_data, enum memcache_reply *reply_type, struct memcache_key *key, struct memcache_obj *obj, int *has_data) {
// XXX: implement
assert(0);
}