#ifndef __KVS_RW_TOOLS_H__ #define __KVS_RW_TOOLS_H__ #include #include int kvs_need(const uint8_t *p, const uint8_t *end, size_t n); int kvs_read_u8(const uint8_t **pp, const uint8_t *end, uint8_t *out); int kvs_read_u16(const uint8_t **pp, const uint8_t *end, uint16_t *out); int kvs_read_u32(const uint8_t **pp, const uint8_t *end, uint32_t *out); int kvs_write_u8(uint8_t **pp, const uint8_t *end, uint8_t v); int kvs_write_u16(uint8_t **pp, const uint8_t *end, uint16_t v); int kvs_write_u32(uint8_t **pp, const uint8_t *end, uint32_t v); /** * Header: | magic(4) | type(1) | payloadLen(4) | reqId(4) | flag1(1) | flag2(2) | * * Request * Payload: | opcount(4) | repeat Cmd | * Cmd: | OP(1) | argc(4) | repeat Arg | * Arg: | arglen(4) | arg | * * Response * Payload: | opcount(4) | repeat Cmd | * Cmd: | status(1) | datalen(4) | data | */ #define KVS_HDR_LEN 16 // | magic(4) | type(1) | payloadLen(4) | reqId(4) | flag1(1) | flag2(2) | #define KVS_MAGIC 0x4B565331u #define KVS_TYPE_REQ 1 #define KVS_TYPE_RESP 2 #define KVS_MAX_OPCOUNT 1024 #define KVS_MAX_RESPONSE (64 * 1024) enum { KVS_STATUS_OK = 0, KVS_STATUS_ERROR = 1, KVS_STATUS_NO_EXIST = 2, KVS_STATUS_EXIST = 3, KVS_STATUS_BADREQ = 4 }; typedef struct { uint8_t op; uint32_t argc; char **argv; } kvs_op_t; typedef struct { uint32_t magic; uint8_t type; uint32_t payloadLen; uint32_t reqId; uint8_t flag1; uint16_t flag2; // payload ops uint32_t opcount; kvs_op_t *ops; // consumed bytes (header+payload) uint32_t consumed; } kvs_request_t; typedef struct { uint8_t status; uint32_t datalen; const char *data_ptr; } kvs_response_t; int kvs_parse_request(const uint8_t *msg, int length, kvs_request_t *req_out); int kvs_execute_request(const kvs_request_t *req, kvs_response_t *results); int kvs_build_response(const kvs_request_t *req, const kvs_response_t *results, uint8_t *response, int response_cap); void kvs_free_request(kvs_request_t *req); void kvs_exec_one_op(uint8_t op, uint32_t argc, char **argv, uint8_t *status_out, const char **data_out, uint32_t *dlen_out); #endif