97 lines
2.4 KiB
C
97 lines
2.4 KiB
C
#ifndef __RESP_H__
|
|
#define __RESP_H__
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#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_SSYNC,
|
|
KVS_CMD_SREADY,
|
|
KVS_CMD_MEM_PRINT,
|
|
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);
|
|
|
|
void __ssync(const uint8_t *ip, uint32_t ip_len, int port, unsigned long long seq);
|
|
void __sready();
|
|
|
|
#endif |