From 603646c230585768feae218cf3998b17b37e5421 Mon Sep 17 00:00:00 2001 From: Artur Mukhamadiev Date: Thu, 12 Mar 2026 00:09:26 +0300 Subject: [PATCH] [base64] minimal encode/decode of raw string --- include/cloud_point_rpc/config.hpp | 2 +- include/cloud_point_rpc/rpc_coder.h | 27 +++++++++++++++++++ src/meson.build | 3 ++- src/rpc_coder.cpp | 42 +++++++++++++++++++++++++++++ tests/meson.build | 3 ++- tests/test_base64.cpp | 31 +++++++++++++++++++++ tests/test_integration.cpp | 2 +- 7 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 include/cloud_point_rpc/rpc_coder.h create mode 100644 src/rpc_coder.cpp create mode 100644 tests/test_base64.cpp diff --git a/include/cloud_point_rpc/config.hpp b/include/cloud_point_rpc/config.hpp index ba06840..a1a172b 100644 --- a/include/cloud_point_rpc/config.hpp +++ b/include/cloud_point_rpc/config.hpp @@ -10,7 +10,7 @@ namespace score { struct ServerConfig { std::string ip; - int port; + int port{0}; }; struct TestData { diff --git a/include/cloud_point_rpc/rpc_coder.h b/include/cloud_point_rpc/rpc_coder.h new file mode 100644 index 0000000..8076375 --- /dev/null +++ b/include/cloud_point_rpc/rpc_coder.h @@ -0,0 +1,27 @@ +// +// Created by vptyp on 11.03.2026. +// + +#pragma once + +#include +#include +namespace score { + +class IRPCCoder { +public: + virtual ~IRPCCoder() = default; + virtual std::vector decode(const std::string& encoded) = 0; + virtual std::string encode(const std::vector& data) = 0; +}; + +class Base64RPCCoder final : public IRPCCoder { +public: + Base64RPCCoder(); + ~Base64RPCCoder() override; + + std::vector decode(const std::string& encoded) override; + std::string encode(const std::vector& data) override; +}; + +} \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 9afc098..fe19d22 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,7 +3,8 @@ add_project_arguments('-DCRPC_SERVER_API_EXPORT -pthread', language: 'cpp') cloud_point_rpc_sources = files( 'rpc_server.cpp', 'service.cpp', - 'server_api.cpp' + 'server_api.cpp', + 'rpc_coder.cpp' ) libcloud_point_rpc = shared_library('cloud_point_rpc', diff --git a/src/rpc_coder.cpp b/src/rpc_coder.cpp new file mode 100644 index 0000000..ee8aa58 --- /dev/null +++ b/src/rpc_coder.cpp @@ -0,0 +1,42 @@ +// +// Created by vptyp on 11.03.2026. +// +#include "cloud_point_rpc/rpc_coder.h" + +#include "libbase64.h" +#include +namespace score { + +Base64RPCCoder::Base64RPCCoder() = default; +Base64RPCCoder::~Base64RPCCoder() = default; + +/** + * Tries to decode ASCII complained string to the + * @param encoded ASCII complained base64 encoded string + * @return vector of raw bytes << allocated on encoded.size() / 4 * 3 + 1 size + */ +std::vector Base64RPCCoder::decode(const std::string& encoded) { + DLOG(INFO) << "Base64RPCCoder::decode"; + std::vector result((encoded.length() >> 2) * 3 + 1); + size_t result_len = 0; + base64_decode(encoded.data(), encoded.size(), + result.data(), &result_len, 0); + DLOG(INFO) << "result_len: " << result_len; + return result; +} +/** + * + * @param data raw byte stream + * @return encoded base64 string + */ +std::string Base64RPCCoder::encode(const std::vector& data) { + DLOG(INFO) << "Base64RPCCoder::encode"; + size_t result_len = 0; + std::string result(data.size() / 3 * 4 + 1, 0); + base64_encode(data.data(), data.size(), + result.data(), &result_len, 0 + ); + DLOG(INFO) << "result_len: " << result_len; + return result; +} +} \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build index 997be38..2e02e8a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -3,7 +3,8 @@ test_sources = files( 'test_integration.cpp', 'test_tcp.cpp', 'test_cli.cpp', - 'test_c_api.cpp' + 'test_c_api.cpp', + 'test_base64.cpp' ) test_exe = executable('unit_tests', diff --git a/tests/test_base64.cpp b/tests/test_base64.cpp new file mode 100644 index 0000000..a7f2daa --- /dev/null +++ b/tests/test_base64.cpp @@ -0,0 +1,31 @@ +// +// Created by vptyp on 11.03.2026. +// +#include +#include +#include +#include + +#include "cloud_point_rpc/config.hpp" +#include "cloud_point_rpc/rpc_coder.h" + + +class Base64Test : public ::testing::Test { + protected: + void SetUp() override { + + } + void TearDown() override { + + } +}; + +TEST_F(Base64Test, EncodeDecode) { + std::vector raw{'H', 'e', 'l', 'l', 'o', 'w', '\0'}; + score::Base64RPCCoder coder; + auto encoded = coder.encode(raw); + LOG(INFO) << "encoded: " << encoded; + auto decoded = coder.decode(encoded); + EXPECT_EQ(std::ranges::equal(decoded, raw), true); + LOG(INFO) << "done"; +} \ No newline at end of file diff --git a/tests/test_integration.cpp b/tests/test_integration.cpp index 721e654..1acef21 100644 --- a/tests/test_integration.cpp +++ b/tests/test_integration.cpp @@ -69,7 +69,7 @@ class IntegrationTest : public ::testing::Test { std::remove("config.yaml"); } - Config config_; + Config config_{}; std::unique_ptr service_; std::unique_ptr rpc_server_; std::unique_ptr tcp_server_;