Skip to content

Commit

Permalink
feat: support varint for msg len
Browse files Browse the repository at this point in the history
  • Loading branch information
shuai132 committed Nov 19, 2024
1 parent 3b5efd5 commit 8e829a1
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 9 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ option(RPC_CORE_SERIALIZE_USE_CUSTOM "" "")
option(RPC_CORE_SERIALIZE_USE_NLOHMANN_JSON "" OFF)
option(RPC_CORE_FEATURE_FUTURE "" OFF)
option(RPC_CORE_FEATURE_ASIO_COROUTINE "" OFF)
option(RPC_CORE_FEATURE_CODER_VARINT "" OFF)

# test
option(RPC_CORE_BUILD_TEST "" OFF)
Expand Down Expand Up @@ -46,6 +47,10 @@ if (RPC_CORE_FEATURE_ASIO_COROUTINE)
target_compile_definitions(${PROJECT_NAME} INTERFACE -DRPC_CORE_FEATURE_ASIO_COROUTINE)
endif ()

if (RPC_CORE_FEATURE_CODER_VARINT)
target_compile_definitions(${PROJECT_NAME} INTERFACE -DRPC_CORE_FEATURE_CODER_VARINT)
endif ()

if (RPC_CORE_BUILD_TEST)
set(EXAMPLE_COMPILE_DEFINE
ANDROID_STANDALONE
Expand Down
22 changes: 13 additions & 9 deletions include/rpc_core/detail/coder.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once

#ifdef RPC_CORE_FEATURE_CODER_VARINT
#include "coder_varint.hpp"
#else
#include "msg_wrapper.hpp"

namespace rpc_core {
Expand All @@ -11,9 +14,9 @@ class coder {
std::string payload;
payload.reserve(PayloadMinLen + msg.cmd.size() + msg.data.size());
payload.append((char*)&msg.seq, 4);
auto cmdLen = (uint16_t)msg.cmd.length();
payload.append((char*)&cmdLen, 2);
payload.append((char*)msg.cmd.data(), cmdLen);
auto cmd_len = (uint16_t)msg.cmd.length();
payload.append((char*)&cmd_len, 2);
payload.append((char*)msg.cmd.data(), cmd_len);
payload.append((char*)&msg.type, 1);
if (msg.request_payload) {
payload.append(*msg.request_payload);
Expand All @@ -33,24 +36,25 @@ class coder {
const char* pend = payload.data() + payload.size();
msg.seq = *(seq_type*)p;
p += 4;
uint16_t cmdLen = *(uint16_t*)p;
uint16_t cmd_len = *(uint16_t*)p;
p += 2;
if (p + cmdLen + 1 > pend) {
if (p + cmd_len + 1 > pend) {
ok = false;
return msg;
}
msg.cmd.append(p, cmdLen);
p += cmdLen;
msg.cmd.assign(p, cmd_len);
p += cmd_len;
msg.type = *(msg_wrapper::msg_type*)(p);
p += 1;
msg.data.append(p, pend - p);
msg.data.assign(p, pend - p);
ok = true;
return msg;
}

private:
static const uint8_t PayloadMinLen = 4 /*seq*/ + 2 /*cmdLen*/ + 1 /*type*/;
static const uint8_t PayloadMinLen = 4 /*seq*/ + 2 /*cmd_len*/ + 1 /*type*/;
};

} // namespace detail
} // namespace rpc_core
#endif
52 changes: 52 additions & 0 deletions include/rpc_core/detail/coder_varint.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include "msg_wrapper.hpp"
#include "varint.hpp"

namespace rpc_core {
namespace detail {

class coder {
public:
static std::string serialize(const msg_wrapper& msg) {
std::string payload;
std::string v_seq = to_varint(msg.seq);
std::string v_cmd_len = to_varint(msg.cmd.length());
payload.reserve(v_seq.size() + v_cmd_len.size() + sizeof(msg.type) + msg.cmd.size() + msg.data.size());
payload.append(v_seq);
payload.append(v_cmd_len);
payload.append(msg.cmd);
payload.append((char*)&msg.type, sizeof(msg.type));
if (msg.request_payload) {
payload.append(*msg.request_payload);
} else {
payload.append(msg.data);
}
return payload;
}

static msg_wrapper deserialize(const std::string& payload, bool& ok) {
msg_wrapper msg;
char* p = (char*)payload.data();
const char* pend = payload.data() + payload.size();
uint8_t bytes;
msg.seq = from_varint(p, &bytes);
p += bytes;
uint16_t cmd_len = from_varint(p, &bytes);
p += bytes;
if (p + cmd_len + sizeof(msg.type) > pend) {
ok = false;
return msg;
}
msg.cmd.assign(p, cmd_len);
p += cmd_len;
msg.type = *(msg_wrapper::msg_type*)(p);
p += sizeof(msg.type);
msg.data.assign(p, pend - p);
ok = true;
return msg;
}
};

} // namespace detail
} // namespace rpc_core
55 changes: 55 additions & 0 deletions include/rpc_core/detail/varint.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include <cstdint>
#include <cstring>
#include <string>

namespace rpc_core {
namespace detail {

static const uint8_t MSB = 0x80;
static const uint8_t MSB_ALL = ~0x7F;

inline uint8_t* varint_encode(unsigned long long n, uint8_t* buf, uint8_t* bytes) {
uint8_t* ptr = buf;
while (n & MSB_ALL) {
*(ptr++) = (n & 0xFF) | MSB;
n = n >> 7;
}
*ptr = n;
*bytes = ptr - buf + 1;
return buf;
}

inline unsigned long long varint_decode(uint8_t* buf, uint8_t* bytes) {
unsigned long long result = 0;
int bits = 0;
uint8_t* ptr = buf;
unsigned long long ll;
while (*ptr & MSB) {
ll = *ptr;
result += ((ll & 0x7F) << bits);
ptr++;
bits += 7;
}
ll = *ptr;
result += ((ll & 0x7F) << bits);
*bytes = ptr - buf + 1;
return result;
}

inline std::string to_varint(uint32_t var) {
uint8_t buf[sizeof(uint32_t) + 1]; // enough
std::string ret;
uint8_t bytes;
varint_encode(var, buf, &bytes);
return {(char*)buf, bytes};
}

inline uint32_t from_varint(void* data, uint8_t* bytes) {
return varint_decode((uint8_t*)data, bytes);
;
}

} // namespace detail
} // namespace rpc_core

0 comments on commit 8e829a1

Please sign in to comment.