#ifndef __RESP_H__ #define __RESP_H__ #include #include #include "kvstore.h" #define RESP_MAX_ARGC 16 #define RESP_MAX_LINE 1024 #define RESP_MAX_BULK (16u * 1024u * 1024u) /* 16MB default */ int ascii_casecmp(const uint8_t *a, uint32_t alen, const char *b); /** * SET */ typedef enum { KVS_CMD_START = 0, // array KVS_CMD_SET = KVS_CMD_START, KVS_CMD_GET, KVS_CMD_DEL, KVS_CMD_MOD, KVS_CMD_EXIST, // rbtree KVS_CMD_RSET, KVS_CMD_RGET, KVS_CMD_RDEL, KVS_CMD_RMOD, KVS_CMD_REXIST, // hash KVS_CMD_HSET, KVS_CMD_HGET, KVS_CMD_HDEL, KVS_CMD_HMOD, KVS_CMD_HEXIST, KVS_CMD_SAVE, KVS_CMD_PSYNC, KVS_CMD_COUNT, }kvs_cmd_t; typedef struct resp_slice_s { const uint8_t *ptr; uint32_t len; } resp_slice_t; typedef struct resp_cmd_s { uint32_t argc; resp_slice_t argv[RESP_MAX_ARGC]; /* argv[0] is command name */ } resp_cmd_t; typedef enum resp_type_e { RESP_T_SIMPLE_STR, RESP_T_ERROR, RESP_T_INTEGER, RESP_T_BULK_STR, RESP_T_NIL, /* nil bulk string ($-1\r\n) */ } resp_type_t; typedef struct resp_value_s { resp_type_t type; int64_t i64; /* for integer */ resp_slice_t bulk; /* for simple/error/bulk string (bytes) */ } resp_value_t; /* ----------------- parsing ----------------- */ /* Parse one RESP command from [buf, buf+len). * return: -1 protocol error, 0 need more data, >0 bytes consumed */ int resp_parse_one_cmd(const uint8_t *buf, int len, resp_cmd_t *out_cmd); /* ----------------- response building ----------------- */ /* Build RESP value into out buffer. return bytes written, -1 on error/capacity. */ int resp_build_value(const resp_value_t *v, uint8_t *out, size_t cap); /* Convenience helpers */ resp_value_t resp_simple(const char *s); /* +s\r\n */ resp_value_t resp_error(const char *s); /* -s\r\n */ resp_value_t resp_int(int64_t x); /* :x\r\n */ resp_value_t resp_bulk(const uint8_t *p, uint32_t n); /* $n\r\n...\r\n */ resp_value_t resp_nil(void); /* $-1\r\n */ /* ----------------- dispatcher ----------------- */ /* Execute one command and return a RESP value. * NOTE: output value may reference storage memory (for GET), so build response * promptly after this call. */ int resp_dispatch(const resp_cmd_t *cmd, resp_value_t *out_value); #endif