#include "test_client.h" #include #include #include int kvs_need(const uint8_t *p, const uint8_t *end, size_t n) { return (p + n <= end) ? 0 : -1; } // 注意u8类型不需要ntoh或者hton int kvs_read_u8(const uint8_t **pp, const uint8_t *end, uint8_t *out) { const uint8_t *p = *pp; if (kvs_need(p, end, 1) < 0) return -1; *out = *p; *pp = p + 1; return 0; } int kvs_read_u16(const uint8_t **pp, const uint8_t *end, uint16_t *out) { const uint8_t *p = *pp; if (kvs_need(p, end, 2) < 0) return -1; uint16_t v; memcpy(&v, p, 2); *out = ntohs(v); *pp = p + 2; return 0; } int kvs_read_u32(const uint8_t **pp, const uint8_t *end, uint32_t *out) { const uint8_t *p = *pp; if (kvs_need(p, end, 4) < 0) return -1; uint32_t v; memcpy(&v, p, 4); *out = ntohl(v); *pp = p + 4; return 0; } int kvs_write_u8(uint8_t **pp, const uint8_t *end, uint8_t v) { uint8_t *p = *pp; if (kvs_need(p, end, 1) < 0) return -1; *p = v; *pp = p + 1; return 0; } int kvs_write_u16(uint8_t **pp, const uint8_t *end, uint16_t v) { uint8_t *p = *pp; if (kvs_need(p, end, 2) < 0) return -1; uint16_t be = htons(v); memcpy(p, &be, 2); *pp = p + 2; return 0; } int kvs_write_u32(uint8_t **pp, const uint8_t *end, uint32_t v) { uint8_t *p = *pp; if (kvs_need(p, end, 4) < 0) return -1; uint32_t be = htonl(v); memcpy(p, &be, 4); *pp = p + 4; return 0; } int getcmd(uint8_t op, const char *key, const char *value, uint8_t *buf){ if(!buf) return -1; uint8_t *end = buf + CMD_SIZE; uint8_t *p = buf; uint8_t argc = (key == NULL)?0:1; argc += (value == NULL)?0:1; if (kvs_write_u8(&p, end, op) < 0) return -1; if (kvs_write_u8(&p, end, argc) < 0) return -1; // 写入 key if(key){ int keylen = strlen(key); if (kvs_write_u32(&p, end, keylen) < 0) return -1; if (kvs_need(p, end, keylen) < 0) return -1; if (keylen > 0) { memcpy(p, key, keylen); p += keylen; } } if(value){ int vallen = strlen(value); if (kvs_write_u32(&p, end, vallen) < 0) return -1; if (kvs_need(p, end, vallen) < 0) return -1; if (vallen > 0) { memcpy(p, value, vallen); p += vallen; } } return (p - buf); } int parse_response(const uint8_t *buf, int buflen, kvs_response_t *rsp) { const uint8_t *p = buf; const uint8_t *end = buf + buflen; // 读取 OP if (kvs_read_u8(&p, end, &rsp->op) < 0) { fprintf(stderr, "Failed to read op\n"); return -1; } // 读取 status if (kvs_read_u8(&p, end, &rsp->status) < 0) { fprintf(stderr, "Failed to read status\n"); return -1; } // 读取 datalen if (kvs_read_u32(&p, end, &rsp->datalen) < 0) { fprintf(stderr, "Failed to read datalen\n"); return -1; } // 检查数据长度 if (kvs_need(p, end, rsp->datalen) < 0) { fprintf(stderr, "Data length mismatch: expected %u bytes, but only %ld available\n", rsp->datalen, end - p); return -1; } // 指向数据部分 rsp->data = (uint8_t *)p; return (p - buf) + rsp->datalen; } void print_response(const char *cmd_name, const kvs_response_t *rsp) { printf("\n=== %s Response ===\n", cmd_name); printf("OP: %u\n", rsp->op); printf("Status: %u ", rsp->status); switch (rsp->status) { case KVS_STATUS_OK: printf("(OK)\n"); break; case KVS_STATUS_ERROR: printf("(ERROR)\n"); break; case KVS_STATUS_NO_EXIST: printf("(NO_EXIST)\n"); break; case KVS_STATUS_EXIST: printf("(EXISTS)\n"); break; default: printf("(UNKNOWN)\n"); break; } printf("Data Length: %u\n", rsp->datalen); if (rsp->datalen > 0 && rsp->data != NULL) { printf("Data: "); // 尝试以字符串形式打印(如果是可打印字符) int is_printable = 1; for (uint32_t i = 0; i < rsp->datalen; i++) { if (rsp->data[i] < 32 || rsp->data[i] > 126) { is_printable = 0; break; } } if (is_printable) { printf("\""); for (uint32_t i = 0; i < rsp->datalen; i++) { printf("%c", rsp->data[i]); } printf("\"\n"); } else { // 以十六进制打印 printf("0x"); for (uint32_t i = 0; i < rsp->datalen; i++) { printf("%02x", rsp->data[i]); } printf("\n"); } } else { printf("Data: (empty)\n"); } printf("==================\n"); } int verify_response(const kvs_response_t *rsp, uint8_t expected_op, uint8_t expected_status, const char *expected_data) { if (rsp->op != expected_op) { printf("❌ OP mismatch: expected %u, got %u\n", expected_op, rsp->op); return 0; } if (rsp->status != expected_status) { printf("❌ Status mismatch: expected %u, got %u\n", expected_status, rsp->status); return 0; } if (expected_data != NULL) { uint32_t expected_len = strlen(expected_data); if (rsp->datalen != expected_len) { printf("❌ Data length mismatch: expected %u, got %u\n", expected_len, rsp->datalen); return 0; } if (memcmp(rsp->data, expected_data, expected_len) != 0) { printf("❌ Data content mismatch\n"); return 0; } } return 1; }