memcache/command.c
changeset 41 540737bf6bac
child 42 0e503189af2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memcache/command.c	Wed Aug 27 21:30:32 2008 +0300
@@ -0,0 +1,123 @@
+
+#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);
+}
+