├── TODO.md ├── bin └── .gitignore ├── proto ├── trade.sbe.sbeir ├── trade.fbe ├── trade.fbs ├── trade.proto ├── trade.capnp ├── sbe │ ├── OrderSide.h │ ├── OrderType.h │ ├── VarStringEncoding.h │ ├── GroupSizeEncoding.h │ └── MessageHeader.h ├── trade.sbe.xml ├── fbe │ ├── trade.cpp │ ├── trade.h │ ├── trade_final_models.h │ ├── trade_models.h │ └── fbe.cpp └── flatbuffers │ └── trade_generated.h ├── tests ├── test.cpp ├── test.h ├── test_zpp_bits.cpp ├── test_flatbuffers.cpp ├── test_json.cpp ├── test_protobuf.cpp ├── test_capnproto.cpp ├── test_fbe.cpp └── test_sbe.cpp ├── modules ├── sbe │ └── sbe-all-1.35.6.jar ├── zpp_bits.cmake ├── rapidjson.cmake ├── CMakeLists.txt ├── CppCommon.cmake ├── CppBenchmark.cmake ├── Catch2.cmake ├── flatbuffers.cmake ├── protobuf.cmake └── capnproto.cmake ├── .gitattributes ├── .gitignore ├── include └── serialization │ ├── json │ ├── parser.inl │ ├── json.h │ ├── parser.h │ ├── deserializer.h │ ├── serializer.h │ ├── serializer.inl │ └── deserializer.inl │ ├── exceptions.h │ └── version.h ├── .github └── workflows │ ├── build-macos.yml │ ├── build-linux-gcc.yml │ ├── build-linux-clang.yml │ ├── build-windows-vs.yml │ ├── build-windows-mingw.yml │ ├── doxygen.yml │ └── build-windows-msys2.yml ├── .gitlinks ├── source └── serialization │ └── json │ └── parser.cpp ├── LICENSE ├── performance ├── final_fbe_serialize.cpp ├── zpp_bits_serialize.cpp ├── json_serialize.cpp ├── flatbuffers_serialize.cpp ├── fbe_serialize.cpp ├── json_parse.cpp ├── protobuf_serialize.cpp ├── capnproto_serialize.cpp ├── zpp_bits_deserialize.cpp ├── flatbuffers_deserialize.cpp ├── final_fbe_deserialize.cpp ├── protobuf_deserialize.cpp ├── sbe_serialize.cpp ├── json_deserialize.cpp ├── fbe_deserialize.cpp ├── capnproto_deserialize.cpp └── sbe_deserialize.cpp ├── examples ├── zpp_bits.cpp ├── flatbuffers.cpp ├── protobuf.cpp ├── capnproto.cpp ├── fbe.cpp ├── json.cpp └── sbe.cpp └── CMakeLists.txt /TODO.md: -------------------------------------------------------------------------------- 1 | # CppSerialization todo 2 | -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /proto/trade.sbe.sbeir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chronoxor/CppSerialization/HEAD/proto/trade.sbe.sbeir -------------------------------------------------------------------------------- /tests/test.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 28.02.2017 3 | // 4 | 5 | #include "test.h" 6 | -------------------------------------------------------------------------------- /tests/test.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 28.02.2017 3 | // 4 | 5 | #include 6 | -------------------------------------------------------------------------------- /modules/sbe/sbe-all-1.35.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chronoxor/CppSerialization/HEAD/modules/sbe/sbe-all-1.35.6.jar -------------------------------------------------------------------------------- /modules/zpp_bits.cmake: -------------------------------------------------------------------------------- 1 | if(NOT zpp_bits) 2 | 3 | # Module definition 4 | set(zpp_bits "${CMAKE_CURRENT_SOURCE_DIR}/zpp_bits" PARENT_SCOPE) 5 | 6 | endif() 7 | -------------------------------------------------------------------------------- /modules/rapidjson.cmake: -------------------------------------------------------------------------------- 1 | if(NOT rapidjson) 2 | 3 | # Module definition 4 | set(rapidjson "${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/include" PARENT_SCOPE) 5 | 6 | endif() 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | bin/* linguist-vendored 2 | build/* linguist-vendored 3 | cmake/* linguist-vendored 4 | documents/* linguist-vendored 5 | images/* linguist-vendored 6 | modules/* linguist-vendored 7 | temp/* linguist-vendored 8 | -------------------------------------------------------------------------------- /modules/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include("capnproto.cmake") 2 | include("Catch2.cmake") 3 | include("CppBenchmark.cmake") 4 | include("CppCommon.cmake") 5 | include("flatbuffers.cmake") 6 | include("protobuf.cmake") 7 | include("rapidjson.cmake") 8 | include("zpp_bits.cmake") 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build 2 | build 3 | 4 | # CMake 5 | build 6 | cmake 7 | cmake-build-* 8 | 9 | # Ctags files 10 | tags 11 | tags.idx 12 | 13 | # Modules 14 | modules/* 15 | !modules/CMakeLists.txt 16 | !modules/*.cmake 17 | 18 | # Temporary 19 | .idea 20 | temp 21 | -------------------------------------------------------------------------------- /modules/CppCommon.cmake: -------------------------------------------------------------------------------- 1 | if(NOT TARGET cppcommon) 2 | 3 | # Module flag 4 | set(CPPCOMMON_MODULE Y) 5 | 6 | # Module subdirectory 7 | add_subdirectory("CppCommon") 8 | 9 | # Module folder 10 | set_target_properties(cppcommon PROPERTIES FOLDER "modules/CppCommon") 11 | 12 | endif() 13 | -------------------------------------------------------------------------------- /modules/CppBenchmark.cmake: -------------------------------------------------------------------------------- 1 | if(NOT TARGET cppbenchmark) 2 | 3 | # Module flag 4 | set(CPPBENCHMARK_MODULE Y) 5 | 6 | # Module subdirectory 7 | add_subdirectory("CppBenchmark") 8 | 9 | # Module folder 10 | set_target_properties(cppbenchmark PROPERTIES FOLDER "modules/CppBenchmark") 11 | 12 | endif() 13 | -------------------------------------------------------------------------------- /modules/Catch2.cmake: -------------------------------------------------------------------------------- 1 | if(NOT TARGET Catch2) 2 | 3 | # Module library 4 | file(GLOB SOURCE_FILES "Catch2/extras/catch_amalgamated.cpp") 5 | add_library(Catch2 ${SOURCE_FILES}) 6 | target_include_directories(Catch2 PUBLIC "Catch2/extras") 7 | 8 | # Module folder 9 | set_target_properties(Catch2 PROPERTIES FOLDER "modules/Catch2") 10 | 11 | endif() 12 | -------------------------------------------------------------------------------- /include/serialization/json/parser.inl: -------------------------------------------------------------------------------- 1 | /*! 2 | \file parser.inl 3 | \brief JSON parser inline implementation 4 | \author Ivan Shynkarenka 5 | \date 27.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | namespace CppSerialization { 10 | namespace JSON { 11 | 12 | template 13 | inline Document Parser::ParseStream(InputStream& stream) 14 | { 15 | Document result; 16 | return std::move(result.ParseStream(stream)); 17 | } 18 | 19 | } // namespace JSON 20 | } // namespace CppSerialization 21 | -------------------------------------------------------------------------------- /proto/trade.fbe: -------------------------------------------------------------------------------- 1 | package trade 2 | 3 | enum OrderSide : byte 4 | { 5 | buy; 6 | sell; 7 | } 8 | 9 | enum OrderType : byte 10 | { 11 | market; 12 | limit; 13 | stop; 14 | } 15 | 16 | struct Order 17 | { 18 | [key] int32 id; 19 | string symbol; 20 | OrderSide side; 21 | OrderType type; 22 | double price = 0.0; 23 | double volume = 0.0; 24 | } 25 | 26 | struct Balance 27 | { 28 | [key] string currency; 29 | double amount = 0.0; 30 | } 31 | 32 | struct Account 33 | { 34 | [key] int32 id; 35 | string name; 36 | Balance wallet; 37 | Order[] orders; 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/build-macos.yml: -------------------------------------------------------------------------------- 1 | name: MacOS 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: macos-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: "Setup python" 15 | uses: actions/setup-python@v4 16 | with: 17 | python-version: '3.x' 18 | 19 | - name: "Setup cmake" 20 | run: cmake --version 21 | 22 | - name: "Setup gil" 23 | run: | 24 | pip3 install gil 25 | gil update 26 | 27 | - name: "Build" 28 | run: | 29 | cd build 30 | ./unix.sh 31 | -------------------------------------------------------------------------------- /include/serialization/exceptions.h: -------------------------------------------------------------------------------- 1 | /*! 2 | \file serialization/exceptions.h 3 | \brief Serialization exceptions definition 4 | \author Ivan Shynkarenka 5 | \date 25.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #ifndef CPPSERIALIZATION_EXCEPTIONS_H 10 | #define CPPSERIALIZATION_EXCEPTIONS_H 11 | 12 | #include "errors/exceptions.h" 13 | 14 | namespace CppSerialization { 15 | 16 | //! Serialization exception 17 | class SerializationException : public CppCommon::Exception 18 | { 19 | public: 20 | using Exception::Exception; 21 | }; 22 | 23 | } // namespace CppSerialization 24 | 25 | #endif // CPPSERIALIZATION_EXCEPTIONS_H 26 | -------------------------------------------------------------------------------- /proto/trade.fbs: -------------------------------------------------------------------------------- 1 | namespace Trade.flatbuf; 2 | 3 | enum OrderSide : byte 4 | { 5 | buy, 6 | sell 7 | } 8 | 9 | enum OrderType : byte 10 | { 11 | market, 12 | limit, 13 | stop 14 | } 15 | 16 | table Order 17 | { 18 | id : int; 19 | symbol : string; 20 | side : OrderSide; 21 | type : OrderType; 22 | price : double = 0.0; 23 | volume : double = 0.0; 24 | } 25 | 26 | table Balance 27 | { 28 | currency : string; 29 | amount : double = 0.0; 30 | } 31 | 32 | table Account 33 | { 34 | id : int; 35 | name : string; 36 | wallet : Balance; 37 | orders : [Order]; 38 | } 39 | 40 | root_type Account; 41 | -------------------------------------------------------------------------------- /proto/trade.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package Trade.protobuf; 3 | 4 | enum OrderSide 5 | { 6 | buy = 0; 7 | sell = 1; 8 | } 9 | 10 | enum OrderType 11 | { 12 | market = 0; 13 | limit = 1; 14 | stop = 2; 15 | } 16 | 17 | message Order 18 | { 19 | int32 id = 1; 20 | string symbol = 2; 21 | OrderSide side = 3; 22 | OrderType type = 4; 23 | double price = 5; 24 | double volume = 6; 25 | } 26 | 27 | message Balance 28 | { 29 | string currency = 1; 30 | double amount = 2; 31 | } 32 | 33 | message Account 34 | { 35 | int32 id = 1; 36 | string name = 2; 37 | Balance wallet = 3; 38 | repeated Order orders = 4; 39 | } 40 | -------------------------------------------------------------------------------- /.github/workflows/build-linux-gcc.yml: -------------------------------------------------------------------------------- 1 | name: Linux (gcc) 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: "Setup required packages" 15 | run: sudo apt-get install -y binutils-dev libssl-dev uuid-dev 16 | 17 | - name: "Setup gcc" 18 | uses: egor-tensin/setup-gcc@v1 19 | 20 | - name: "Setup cmake" 21 | run: cmake --version 22 | 23 | - name: "Setup gil" 24 | run: | 25 | pip3 install gil 26 | gil update 27 | 28 | - name: "Build" 29 | run: | 30 | cd build 31 | ./unix.sh 32 | -------------------------------------------------------------------------------- /.github/workflows/build-linux-clang.yml: -------------------------------------------------------------------------------- 1 | name: Linux (clang) 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: "Setup required packages" 15 | run: sudo apt-get install -y binutils-dev libc++-dev libssl-dev uuid-dev 16 | 17 | - name: "Setup clang" 18 | uses: egor-tensin/setup-clang@v1 19 | 20 | - name: "Setup cmake" 21 | run: cmake --version 22 | 23 | - name: "Setup gil" 24 | run: | 25 | pip3 install gil 26 | gil update 27 | 28 | - name: "Build" 29 | run: | 30 | cd build 31 | ./unix.sh 32 | -------------------------------------------------------------------------------- /.github/workflows/build-windows-vs.yml: -------------------------------------------------------------------------------- 1 | name: Windows (Visual Studio) 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: windows-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: "Setup Java" 15 | uses: actions/setup-java@v4 16 | with: 17 | distribution: 'temurin' 18 | java-version: '21' 19 | 20 | - name: "Setup Visual Studio" 21 | uses: egor-tensin/vs-shell@v2 22 | 23 | - name: "Setup cmake" 24 | run: cmake --version 25 | 26 | - name: "Setup gil" 27 | run: | 28 | pip3 install gil 29 | gil update 30 | 31 | - name: "Build" 32 | run: | 33 | cd build 34 | ./vs.bat 35 | -------------------------------------------------------------------------------- /proto/trade.capnp: -------------------------------------------------------------------------------- 1 | # Unique file ID, generated by 'capnp id' 2 | @0xd4b6e00623bed170; 3 | 4 | using Cxx = import "/capnp/c++.capnp"; 5 | $Cxx.namespace("Trade::capnproto"); 6 | 7 | enum OrderSide 8 | { 9 | buy @0; 10 | sell @1; 11 | } 12 | 13 | enum OrderType 14 | { 15 | market @0; 16 | limit @1; 17 | stop @2; 18 | } 19 | 20 | struct Order 21 | { 22 | id @0 : Int32; 23 | symbol @1 : Text; 24 | side @2 : OrderSide; 25 | type @3 : OrderType; 26 | price @4 : Float64 = 0.0; 27 | volume @5 : Float64 = 0.0; 28 | } 29 | 30 | struct Balance 31 | { 32 | currency @0 : Text; 33 | amount @1 : Float64 = 0.0; 34 | } 35 | 36 | struct Account 37 | { 38 | id @0 : Int32; 39 | name @1 : Text; 40 | wallet @2 : Balance; 41 | orders @3 : List(Order); 42 | } 43 | -------------------------------------------------------------------------------- /.gitlinks: -------------------------------------------------------------------------------- 1 | # Modules 2 | capnproto modules/capnproto https://github.com/capnproto/capnproto.git master 3 | Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git devel 4 | CppBenchmark modules/CppBenchmark https://github.com/chronoxor/CppBenchmark.git master 5 | CppCommon modules/CppCommon https://github.com/chronoxor/CppCommon.git master 6 | flatbuffers modules/flatbuffers https://github.com/google/flatbuffers.git master 7 | protobuf modules/protobuf https://github.com/google/protobuf.git main 8 | rapidjson modules/rapidjson https://github.com/miloyip/rapidjson.git master 9 | zpp_bits modules/zpp_bits https://github.com/eyalz800/zpp_bits.git main 10 | 11 | # Scripts 12 | build build https://github.com/chronoxor/CppBuildScripts.git master 13 | cmake cmake https://github.com/chronoxor/CppCMakeScripts.git master 14 | -------------------------------------------------------------------------------- /.github/workflows/build-windows-mingw.yml: -------------------------------------------------------------------------------- 1 | name: Windows (MinGW) 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: windows-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: "Setup Java" 15 | uses: actions/setup-java@v4 16 | with: 17 | distribution: 'temurin' 18 | java-version: '21' 19 | 20 | - name: "Setup cmake" 21 | run: cmake --version 22 | 23 | - name: "Setup gil" 24 | run: | 25 | pip3 install gil 26 | gil update 27 | 28 | - name: "Build" 29 | env: 30 | INCLUDE: C:\mingw64\x86_64-w64-mingw32\include 31 | LIB: C:\mingw64\x86_64-w64-mingw32\lib 32 | run: | 33 | cd build 34 | ./mingw.bat 35 | -------------------------------------------------------------------------------- /source/serialization/json/parser.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file parser.cpp 3 | \brief JSON parser implementation 4 | \author Ivan Shynkarenka 5 | \date 27.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #include "serialization/json/parser.h" 10 | 11 | namespace CppSerialization { 12 | namespace JSON { 13 | 14 | Document Parser::Parse(const char* str) 15 | { 16 | Document result; 17 | return std::move(result.Parse(str)); 18 | } 19 | 20 | Document Parser::Parse(const char* str, size_t size) 21 | { 22 | Document result; 23 | return std::move(result.Parse(str, size)); 24 | } 25 | 26 | Document Parser::Parse(const std::string& str) 27 | { 28 | Document result; 29 | return std::move(result.Parse(str)); 30 | } 31 | 32 | Document Parser::ParseInPlace(char* str) 33 | { 34 | Document result; 35 | return std::move(result.ParseInsitu(str)); 36 | } 37 | 38 | } // namespace JSON 39 | } // namespace CppSerialization 40 | -------------------------------------------------------------------------------- /modules/flatbuffers.cmake: -------------------------------------------------------------------------------- 1 | if(NOT flatbuf) 2 | 3 | # Restore origin compile flags 4 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_ORIGIN}") 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_ORIGIN}") 6 | 7 | # Set options 8 | SET(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "Enable the build of tests and samples." FORCE) 9 | SET(FLATBUFFERS_INSTALL OFF CACHE BOOL "Enable the installation of targets." FORCE) 10 | 11 | # Module subdirectory 12 | add_subdirectory("flatbuffers") 13 | 14 | # Module folder 15 | set_target_properties(flatbuffers PROPERTIES FOLDER "modules/flatbuffers/flatbuffers") 16 | set_target_properties(flatc PROPERTIES FOLDER "modules/flatbuffers/flatc") 17 | 18 | # Module definition 19 | set(flatbuf "${CMAKE_CURRENT_SOURCE_DIR}/flatbuffers/include" PARENT_SCOPE) 20 | 21 | # Restore custom compile flags 22 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_CUSTOM}") 23 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_CUSTOM}") 24 | 25 | endif() 26 | -------------------------------------------------------------------------------- /include/serialization/version.h: -------------------------------------------------------------------------------- 1 | /*! 2 | \file version.h 3 | \brief Version definition 4 | \author Ivan Shynkarenka 5 | \date 24.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #ifndef CPPSERIALIZATION_VERSION_H 10 | #define CPPSERIALIZATION_VERSION_H 11 | 12 | /*! \mainpage C++ Serialization Library 13 | 14 | C++ Serialization Library provides functionality to serialize/deserialize objects 15 | in/from different formats such as Flatbuffers, JSON. 16 | 17 | This document contains CppSerialization API references. 18 | 19 | Library description, features, requirements and usage examples can be find on 20 | GitHub: https://github.com/chronoxor/CppSerialization 21 | 22 | */ 23 | 24 | /*! 25 | \namespace CppSerialization 26 | \brief C++ Serialization project definitions 27 | */ 28 | namespace CppSerialization { 29 | 30 | //! Project version 31 | const char version[] = "1.0.5.0"; 32 | 33 | } // namespace CppSerialization 34 | 35 | #endif // CPPSERIALIZATION_VERSION_H 36 | -------------------------------------------------------------------------------- /.github/workflows/doxygen.yml: -------------------------------------------------------------------------------- 1 | name: Doxygen 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: "Setup git" 13 | run: | 14 | git config --global user.name "${{ github.actor }}" 15 | git config --global user.email "${{ github.actor }}@users.noreply.github.com" 16 | 17 | - uses: actions/checkout@v4 18 | 19 | - name: "Setup cmake" 20 | run: cmake --version 21 | 22 | - name: "Setup doxygen" 23 | run: | 24 | sudo apt-get -y install doxygen doxygen-latex graphviz binutils-dev 25 | doxygen --version 26 | dot -V 27 | 28 | - name: "Setup gil" 29 | run: | 30 | pip3 install gil 31 | gil update 32 | 33 | - name: "Doxygen" 34 | env: 35 | GITHUB_ACTOR: ${{ github.actor }} 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 37 | run: | 38 | cd build/Unix 39 | ./01-generate.sh 40 | ./05-doxygen.sh 41 | -------------------------------------------------------------------------------- /include/serialization/json/json.h: -------------------------------------------------------------------------------- 1 | /*! 2 | \file json.h 3 | \brief JSON C++ Library definition 4 | \author Ivan Shynkarenka 5 | \date 24.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #ifndef CPPSERIALIZATION_JSON_JSON_H 10 | #define CPPSERIALIZATION_JSON_JSON_H 11 | 12 | #include "../exceptions.h" 13 | 14 | #if defined(__clang__) 15 | #pragma clang system_header 16 | #elif defined(__GNUC__) 17 | #pragma GCC system_header 18 | #elif defined(_MSC_VER) 19 | #pragma system_header 20 | #endif 21 | 22 | #define RAPIDJSON_HAS_STDSTRING 1 23 | 24 | #define RAPIDJSON_NAMESPACE CppSerialization::JSON 25 | #define RAPIDJSON_NAMESPACE_BEGIN namespace CppSerialization { namespace JSON { 26 | #define RAPIDJSON_NAMESPACE_END } } 27 | 28 | #include 29 | #include 30 | 31 | namespace CppSerialization { 32 | 33 | /*! 34 | \namespace CppSerialization::JSON 35 | \brief JSON definitions 36 | */ 37 | namespace JSON { 38 | 39 | } // namespace JSON 40 | 41 | } // namespace CppSerialization 42 | 43 | #endif // CPPSERIALIZATION_JSON_JSON_H 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2026 Ivan Shynkarenka 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /performance/final_fbe_serialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 05.01.2019 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class SerializationFixture 10 | { 11 | protected: 12 | FBE::trade::AccountFinalModel writer; 13 | trade::Account account; 14 | 15 | SerializationFixture() 16 | { 17 | // Create a new account with some orders 18 | account.id = 1; 19 | account.name = "Test"; 20 | account.wallet.currency = "USD"; 21 | account.wallet.amount = 1000; 22 | account.orders.emplace_back(trade::Order(1, "EURUSD", trade::OrderSide::buy, trade::OrderType::market, 1.23456, 1000)); 23 | account.orders.emplace_back(trade::Order(2, "EURUSD", trade::OrderSide::sell, trade::OrderType::limit, 1.0, 100)); 24 | account.orders.emplace_back(trade::Order(3, "EURUSD", trade::OrderSide::buy, trade::OrderType::stop, 1.5, 10)); 25 | } 26 | }; 27 | 28 | BENCHMARK_FIXTURE(SerializationFixture, "FastBinaryEncoding-Final-Serialize") 29 | { 30 | // Serialize the account to the FBE buffer 31 | writer.reset(); 32 | size_t serialized = writer.serialize(account); 33 | 34 | context.metrics().AddBytes(serialized); 35 | context.metrics().SetCustom("Size", (unsigned)serialized); 36 | } 37 | 38 | BENCHMARK_MAIN() 39 | -------------------------------------------------------------------------------- /performance/zpp_bits_serialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 16.07.2025 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class SerializationFixture 10 | { 11 | protected: 12 | std::array buffer; 13 | TradeProto::Account account; 14 | 15 | SerializationFixture() : account(1, "Test", "USD", 1000) 16 | { 17 | // Create a new account with some orders 18 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 19 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 20 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 21 | } 22 | }; 23 | 24 | BENCHMARK_FIXTURE(SerializationFixture, "zpp::bits-Serialize") 25 | { 26 | // Serialize the account to the zpp::bits buffer 27 | zpp::bits::out out{buffer}; 28 | (void) out(account); 29 | 30 | context.metrics().AddBytes(out.position()); 31 | context.metrics().SetCustom("OriginalSize", (unsigned)account.size()); 32 | context.metrics().SetCustom("MessageSize", (unsigned)out.position()); 33 | } 34 | 35 | BENCHMARK_MAIN() 36 | -------------------------------------------------------------------------------- /.github/workflows/build-windows-msys2.yml: -------------------------------------------------------------------------------- 1 | name: Windows (MSYS2) 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: windows-latest 11 | defaults: 12 | run: 13 | shell: msys2 {0} 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: "Setup Java" 18 | uses: actions/setup-java@v4 19 | with: 20 | distribution: 'temurin' 21 | java-version: '21' 22 | 23 | - name: "Setup MSYS2" 24 | uses: msys2/setup-msys2@v2 25 | with: 26 | msystem: UCRT64 27 | release: false 28 | install: >- 29 | git 30 | make 31 | mingw-w64-ucrt-x86_64-cmake 32 | mingw-w64-ucrt-x86_64-gcc 33 | mingw-w64-ucrt-x86_64-doxygen 34 | mingw-w64-ucrt-x86_64-graphviz 35 | msys2-w32api-runtime 36 | python-pip 37 | 38 | - name: "Setup cmake" 39 | run: cmake --version 40 | 41 | - name: "Setup gil" 42 | run: | 43 | pip3 install gil --break-system-packages 44 | gil update 45 | 46 | - name: "Build" 47 | env: 48 | INCLUDE: C:\msys64\usr\include\w32api 49 | LIB: C:\msys64\usr\lib\w32api 50 | run: | 51 | cd build 52 | ./unix.sh 53 | -------------------------------------------------------------------------------- /performance/json_serialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 28.02.2017 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | using namespace CppSerialization::JSON; 10 | 11 | class SerializationFixture 12 | { 13 | protected: 14 | TradeProto::Account account; 15 | StringBuffer buffer; 16 | Serializer serializer; 17 | 18 | SerializationFixture() : account(1, "Test", "USD", 1000) 19 | { 20 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 21 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 22 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 23 | } 24 | }; 25 | 26 | BENCHMARK_FIXTURE(SerializationFixture, "JSON-Serialize") 27 | { 28 | // Serialize the account to the JSON buffer 29 | buffer.Clear(); 30 | serializer.Reset(buffer); 31 | account.Serialize(serializer); 32 | 33 | context.metrics().AddBytes(buffer.GetSize()); 34 | context.metrics().SetCustom("OriginalSize", (unsigned)account.size()); 35 | context.metrics().SetCustom("MessageSize", (unsigned)buffer.GetSize()); 36 | } 37 | 38 | BENCHMARK_MAIN() 39 | -------------------------------------------------------------------------------- /performance/flatbuffers_serialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 03.03.2017 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class SerializationFixture 10 | { 11 | protected: 12 | flatbuffers::DefaultAllocator allocator; 13 | flatbuffers::FlatBufferBuilder builder; 14 | TradeProto::Account account; 15 | 16 | SerializationFixture() : builder(1024, &allocator), account(1, "Test", "USD", 1000) 17 | { 18 | // Create a new account with some orders 19 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 20 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 21 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 22 | } 23 | }; 24 | 25 | BENCHMARK_FIXTURE(SerializationFixture, "FlatBuffers-Serialize") 26 | { 27 | // Serialize the account to the FlatBuffer buffer 28 | builder.Clear(); 29 | builder.Finish(account.Serialize(builder)); 30 | 31 | context.metrics().AddBytes(builder.GetSize()); 32 | context.metrics().SetCustom("OriginalSize", (unsigned)account.size()); 33 | context.metrics().SetCustom("MessageSize", builder.GetSize()); 34 | } 35 | 36 | BENCHMARK_MAIN() 37 | -------------------------------------------------------------------------------- /performance/fbe_serialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 08.05.2018 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class SerializationFixture 10 | { 11 | protected: 12 | FBE::trade::AccountModel writer; 13 | TradeProto::Account account; 14 | 15 | SerializationFixture() : account(1, "Test", "USD", 1000) 16 | { 17 | // Create a new account with some orders 18 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 19 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 20 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 21 | } 22 | }; 23 | 24 | BENCHMARK_FIXTURE(SerializationFixture, "FastBinaryEncoding-Serialize") 25 | { 26 | // Serialize the account to the FBE buffer 27 | writer.reset(); 28 | size_t model_begin = writer.create_begin(); 29 | account.Serialize(writer.model); 30 | size_t serialized = writer.create_end(model_begin); 31 | 32 | context.metrics().AddBytes(serialized); 33 | context.metrics().SetCustom("OriginalSize", (unsigned)account.size()); 34 | context.metrics().SetCustom("MessageSize", (unsigned)serialized); 35 | } 36 | 37 | BENCHMARK_MAIN() 38 | -------------------------------------------------------------------------------- /performance/json_parse.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 28.02.2017 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | #include "serialization/json/parser.h" 10 | 11 | using namespace CppSerialization::JSON; 12 | 13 | class ParserFixture 14 | { 15 | protected: 16 | StringBuffer buffer; 17 | 18 | ParserFixture() 19 | { 20 | // Create a new account with some orders 21 | TradeProto::Account account(1, "Test", "USD", 1000); 22 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 23 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 24 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 25 | 26 | // Serialize the account to the JSON buffer 27 | Serializer serializer(buffer); 28 | account.Serialize(serializer); 29 | } 30 | }; 31 | 32 | BENCHMARK_FIXTURE(ParserFixture, "JSON-Parse") 33 | { 34 | context.metrics().AddBytes(buffer.GetSize()); 35 | context.metrics().SetCustom("MessageSize", (unsigned)buffer.GetSize()); 36 | 37 | // Parse JSON document from the JSON buffer 38 | Document json = Parser::Parse(buffer.GetString()); 39 | } 40 | 41 | BENCHMARK_MAIN() 42 | -------------------------------------------------------------------------------- /performance/protobuf_serialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 30.03.2018 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class SerializationFixture 10 | { 11 | protected: 12 | TradeProto::Account account; 13 | std::string buffer; 14 | 15 | SerializationFixture() : account(1, "Test", "USD", 1000) 16 | { 17 | // Create a new account with some orders 18 | account.Orders.emplace_back(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000); 19 | account.Orders.emplace_back(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100); 20 | account.Orders.emplace_back(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10); 21 | } 22 | 23 | ~SerializationFixture() 24 | { 25 | // Delete all global objects allocated by Protobuf 26 | google::protobuf::ShutdownProtobufLibrary(); 27 | } 28 | }; 29 | 30 | BENCHMARK_FIXTURE(SerializationFixture, "Protobuf-Serialize") 31 | { 32 | // Serialize the account to the Protobuf buffer 33 | Trade::protobuf::Account output; 34 | account.Serialize(output); 35 | output.SerializeToString(&buffer); 36 | 37 | context.metrics().AddBytes(buffer.size()); 38 | context.metrics().SetCustom("OriginalSize", (unsigned)account.size()); 39 | context.metrics().SetCustom("MessageSize", (unsigned)buffer.size()); 40 | } 41 | 42 | BENCHMARK_MAIN() 43 | -------------------------------------------------------------------------------- /performance/capnproto_serialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 31.03.2018 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class SerializationFixture 10 | { 11 | protected: 12 | TradeProto::Account account; 13 | 14 | SerializationFixture() : account(1, "Test", "USD", 1000) 15 | { 16 | // Create a new account with some orders 17 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 18 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 19 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 20 | } 21 | }; 22 | 23 | BENCHMARK_FIXTURE(SerializationFixture, "Cap'n'Proto-Serialize") 24 | { 25 | // Serialize the account to the Cap'n'Proto buffer 26 | capnp::MallocMessageBuilder output; 27 | Trade::capnproto::Account::Builder builder = output.initRoot(); 28 | account.Serialize(builder); 29 | kj::VectorOutputStream buffer; 30 | writeMessage(buffer, output); 31 | 32 | context.metrics().AddBytes(buffer.getArray().size()); 33 | context.metrics().SetCustom("OriginalSize", (unsigned)account.size()); 34 | context.metrics().SetCustom("MessageSize", (unsigned)buffer.getArray().size()); 35 | } 36 | 37 | BENCHMARK_MAIN() 38 | -------------------------------------------------------------------------------- /performance/zpp_bits_deserialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 16.07.2025 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class DeserializationFixture 10 | { 11 | protected: 12 | std::array buffer; 13 | TradeProto::Account deserialized; 14 | 15 | DeserializationFixture() 16 | { 17 | // Create a new account with some orders 18 | TradeProto::Account account(1, "Test", "USD", 1000); 19 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 20 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 21 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 22 | 23 | // Serialize the account to the zpp::bits buffer 24 | (void) zpp::bits::out{buffer}(account); 25 | } 26 | }; 27 | 28 | BENCHMARK_FIXTURE(DeserializationFixture, "zpp::bits-Deserialize") 29 | { 30 | // Deserialize the account from the zpp::bits buffer 31 | zpp::bits::in in{buffer}; 32 | (void) in(deserialized); 33 | 34 | context.metrics().AddBytes(in.position()); 35 | context.metrics().SetCustom("MessageSize", (unsigned)in.position()); 36 | context.metrics().SetCustom("OriginalSize", (unsigned)deserialized.size()); 37 | } 38 | 39 | BENCHMARK_MAIN() 40 | -------------------------------------------------------------------------------- /include/serialization/json/parser.h: -------------------------------------------------------------------------------- 1 | /*! 2 | \file parser.h 3 | \brief JSON parser definition 4 | \author Ivan Shynkarenka 5 | \date 27.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #ifndef CPPSERIALIZATION_JSON_PARSER_H 10 | #define CPPSERIALIZATION_JSON_PARSER_H 11 | 12 | #include "json.h" 13 | 14 | namespace CppSerialization { 15 | namespace JSON { 16 | 17 | //! JSON parser 18 | /*! 19 | JSON parser is used to parse JSON from the given source (stream, string) 20 | and create a corresponding DOM document. 21 | */ 22 | class Parser 23 | { 24 | public: 25 | Parser() = delete; 26 | Parser(const Parser&) = delete; 27 | Parser(Parser&&) = delete; 28 | ~Parser() = delete; 29 | 30 | Parser& operator=(const Parser&) = delete; 31 | Parser& operator=(Parser&&) = delete; 32 | 33 | //! Parse the input stream 34 | template 35 | static Document ParseStream(InputStream& stream); 36 | 37 | //! Parse the C-string 38 | static Document Parse(const char* source); 39 | //! Parse the C-string with a given size 40 | static Document Parse(const char* source, size_t size); 41 | //! Parse the string 42 | static Document Parse(const std::string& source); 43 | 44 | //! Parse the in-place C-string in mutable mode 45 | static Document ParseInPlace(char* source); 46 | }; 47 | 48 | } // namespace JSON 49 | } // namespace CppSerialization 50 | 51 | #include "parser.inl" 52 | 53 | #endif // CPPSERIALIZATION_JSON_PARSER_H 54 | -------------------------------------------------------------------------------- /modules/protobuf.cmake: -------------------------------------------------------------------------------- 1 | if(NOT protobuf) 2 | 3 | # Restore origin compile flags 4 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_ORIGIN}") 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_ORIGIN}") 6 | 7 | # Set options 8 | SET(protobuf_BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE) 9 | SET(protobuf_BUILD_EXAMPLES OFF CACHE BOOL "Build examples" FORCE) 10 | SET(protobuf_BUILD_PROTOC_BINARIES ON CACHE BOOL "Build libprotoc and protoc compiler" FORCE) 11 | SET(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "Build Shared Libraries" FORCE) 12 | SET(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries" FORCE) 13 | SET(protobuf_WITH_ZLIB OFF CACHE BOOL "Build with zlib support" FORCE) 14 | 15 | # Module subdirectory 16 | add_subdirectory("protobuf") 17 | 18 | # Module folder 19 | set_target_properties(libprotobuf PROPERTIES FOLDER "modules/protobuf") 20 | set_target_properties(libprotobuf-lite PROPERTIES FOLDER "modules/protobuf") 21 | set_target_properties(libprotoc PROPERTIES FOLDER "modules/protobuf") 22 | set_target_properties(protoc PROPERTIES FOLDER "modules/protobuf") 23 | set_target_properties(utf8_range PROPERTIES FOLDER "modules/protobuf") 24 | set_target_properties(utf8_validity PROPERTIES FOLDER "modules/protobuf") 25 | 26 | # Module definition 27 | set(protobuf "${CMAKE_CURRENT_SOURCE_DIR}/protobuf/src" PARENT_SCOPE) 28 | 29 | # Restore custom compile flags 30 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_CUSTOM}") 31 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_CUSTOM}") 32 | 33 | endif() 34 | -------------------------------------------------------------------------------- /performance/flatbuffers_deserialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 03.03.2017 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class DeserializationFixture 10 | { 11 | protected: 12 | flatbuffers::DefaultAllocator allocator; 13 | flatbuffers::FlatBufferBuilder builder; 14 | TradeProto::Account deserialized; 15 | 16 | DeserializationFixture() : builder(1024, &allocator) 17 | { 18 | // Create a new account with some orders 19 | TradeProto::Account account(1, "Test", "USD", 1000); 20 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 21 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 22 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 23 | 24 | // Serialize the account to the FlatBuffer buffer 25 | builder.Finish(account.Serialize(builder)); 26 | } 27 | }; 28 | 29 | BENCHMARK_FIXTURE(DeserializationFixture, "FlatBuffers-Deserialize") 30 | { 31 | context.metrics().AddBytes(builder.GetSize()); 32 | context.metrics().SetCustom("MessageSize", builder.GetSize()); 33 | 34 | // Deserialize the account from the FlatBuffer buffer 35 | deserialized.Deserialize(*Trade::flatbuf::GetAccount(builder.GetBufferPointer())); 36 | 37 | context.metrics().SetCustom("OriginalSize", (unsigned)deserialized.size()); 38 | } 39 | 40 | BENCHMARK_MAIN() 41 | -------------------------------------------------------------------------------- /performance/final_fbe_deserialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 05.01.2019 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class DeserializationFixture 10 | { 11 | protected: 12 | FBE::trade::AccountFinalModel writer; 13 | FBE::trade::AccountFinalModel reader; 14 | trade::Account account; 15 | 16 | DeserializationFixture() 17 | { 18 | // Create a new account with some orders 19 | account.id = 1; 20 | account.name = "Test"; 21 | account.wallet.currency = "USD"; 22 | account.wallet.amount = 1000; 23 | account.orders.emplace_back(trade::Order(1, "EURUSD", trade::OrderSide::buy, trade::OrderType::market, 1.23456, 1000)); 24 | account.orders.emplace_back(trade::Order(2, "EURUSD", trade::OrderSide::sell, trade::OrderType::limit, 1.0, 100)); 25 | account.orders.emplace_back(trade::Order(3, "EURUSD", trade::OrderSide::buy, trade::OrderType::stop, 1.5, 10)); 26 | 27 | // Serialize the account to the FBE buffer 28 | writer.serialize(account); 29 | assert(writer.verify() && "Model is broken!"); 30 | reader.attach(writer.buffer()); 31 | assert(reader.verify() && "Model is broken!"); 32 | } 33 | }; 34 | 35 | BENCHMARK_FIXTURE(DeserializationFixture, "FastBinaryEncoding-Final-Deserialize") 36 | { 37 | // Deserialize the account from the FBE buffer 38 | size_t deserialized = reader.deserialize(account); 39 | 40 | context.metrics().AddBytes(deserialized); 41 | context.metrics().SetCustom("MessageSize", (unsigned)deserialized); 42 | } 43 | 44 | BENCHMARK_MAIN() 45 | -------------------------------------------------------------------------------- /performance/protobuf_deserialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 30.03.2018 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class DeserializationFixture 10 | { 11 | protected: 12 | std::string buffer; 13 | TradeProto::Account deserialized; 14 | 15 | DeserializationFixture() 16 | { 17 | // Create a new account with some orders 18 | TradeProto::Account account(1, "Test", "USD", 1000); 19 | account.Orders.emplace_back(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000); 20 | account.Orders.emplace_back(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100); 21 | account.Orders.emplace_back(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10); 22 | 23 | // Serialize the account to the Protobuf buffer 24 | Trade::protobuf::Account output; 25 | account.Serialize(output); 26 | buffer = output.SerializeAsString(); 27 | } 28 | 29 | ~DeserializationFixture() 30 | { 31 | // Delete all global objects allocated by Protobuf 32 | google::protobuf::ShutdownProtobufLibrary(); 33 | } 34 | }; 35 | 36 | BENCHMARK_FIXTURE(DeserializationFixture, "Protobuf-Deserialize") 37 | { 38 | context.metrics().AddBytes(buffer.size()); 39 | context.metrics().SetCustom("MessageSize", (unsigned)buffer.size()); 40 | 41 | // Deserialize the account from the Protobuf buffer 42 | Trade::protobuf::Account input; 43 | input.ParseFromString(buffer); 44 | deserialized.Deserialize(input); 45 | 46 | context.metrics().SetCustom("OriginalSize", (unsigned)deserialized.size()); 47 | } 48 | 49 | BENCHMARK_MAIN() 50 | -------------------------------------------------------------------------------- /performance/sbe_serialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 02.01.2019 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class SerializationFixture 10 | { 11 | protected: 12 | char buffer[1024]; 13 | sbe::MessageHeader header; 14 | sbe::Account message; 15 | TradeProto::Account account; 16 | 17 | SerializationFixture() : account(1, "Test", "USD", 1000) 18 | { 19 | // Create a new account with some orders 20 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 21 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 22 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 23 | } 24 | }; 25 | 26 | BENCHMARK_FIXTURE(SerializationFixture, "SimpleBinaryEncoding-Serialize") 27 | { 28 | // Serialize the account to the SBE buffer 29 | header.wrap(buffer, 0, 1, sizeof(buffer)) 30 | .blockLength(sbe::Account::sbeBlockLength()) 31 | .templateId(sbe::Account::sbeTemplateId()) 32 | .schemaId(sbe::Account::sbeSchemaId()) 33 | .version(sbe::Account::sbeSchemaVersion()); 34 | message.wrapForEncode(buffer, header.encodedLength(), sizeof(buffer)); 35 | account.Serialize(message); 36 | size_t serialized = header.encodedLength() + message.encodedLength(); 37 | 38 | context.metrics().AddBytes(serialized); 39 | context.metrics().SetCustom("OriginalSize", (unsigned)account.size()); 40 | context.metrics().SetCustom("MessageSize", (unsigned)serialized); 41 | } 42 | 43 | BENCHMARK_MAIN() 44 | -------------------------------------------------------------------------------- /performance/json_deserialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 28.02.2017 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | #include "serialization/json/parser.h" 10 | 11 | using namespace CppSerialization::JSON; 12 | 13 | class DeserializationFixture 14 | { 15 | protected: 16 | size_t size; 17 | Document json; 18 | TradeProto::Account deserialized; 19 | 20 | DeserializationFixture() 21 | { 22 | // Create a new account with some orders 23 | TradeProto::Account account(1, "Test", "USD", 1000); 24 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 25 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 26 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 27 | 28 | // Serialize the account to the JSON buffer 29 | StringBuffer buffer; 30 | Serializer serializer(buffer); 31 | account.Serialize(serializer); 32 | 33 | // Parse JSON string 34 | json = Parser::Parse(buffer.GetString()); 35 | size = buffer.GetSize(); 36 | } 37 | }; 38 | 39 | BENCHMARK_FIXTURE(DeserializationFixture, "JSON-Deserialize") 40 | { 41 | context.metrics().AddBytes(json.Size()); 42 | context.metrics().SetCustom("MessageSize", (unsigned)size); 43 | 44 | // Deserialize the account from the JSON buffer 45 | deserialized.Deserialize(json); 46 | 47 | context.metrics().SetCustom("OriginalSize", (unsigned)deserialized.size()); 48 | } 49 | 50 | BENCHMARK_MAIN() 51 | -------------------------------------------------------------------------------- /modules/capnproto.cmake: -------------------------------------------------------------------------------- 1 | if(NOT capnproto) 2 | 3 | # Restore origin compile flags 4 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_ORIGIN}") 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_ORIGIN}") 6 | 7 | # Set options 8 | SET(WITH_FIBERS OFF CACHE STRING "Whether or not to build libkj-async with fibers." FORCE) 9 | SET(WITH_OPENSSL OFF CACHE STRING "Whether or not to build libkj-tls by linking against openssl." FORCE) 10 | SET(BUILD_TESTING OFF CACHE BOOL "Build unit tests and enable CTest 'check' target." FORCE) 11 | 12 | # Module subdirectory 13 | add_subdirectory("capnproto") 14 | 15 | # Module folder 16 | set_target_properties(capnp PROPERTIES FOLDER "modules/capnproto") 17 | set_target_properties(capnp-json PROPERTIES FOLDER "modules/capnproto") 18 | set_target_properties(capnp-rpc PROPERTIES FOLDER "modules/capnproto") 19 | set_target_properties(capnp-websocket PROPERTIES FOLDER "modules/capnproto") 20 | set_target_properties(capnp_tool PROPERTIES FOLDER "modules/capnproto") 21 | set_target_properties(capnpc PROPERTIES FOLDER "modules/capnproto") 22 | set_target_properties(capnpc_capnp PROPERTIES FOLDER "modules/capnproto") 23 | set_target_properties(capnpc_cpp PROPERTIES FOLDER "modules/capnproto") 24 | set_target_properties(kj PROPERTIES FOLDER "modules/capnproto") 25 | set_target_properties(kj-async PROPERTIES FOLDER "modules/capnproto") 26 | set_target_properties(kj-http PROPERTIES FOLDER "modules/capnproto") 27 | set_target_properties(kj-test PROPERTIES FOLDER "modules/capnproto") 28 | 29 | # Module definition 30 | set(capnproto "${CMAKE_CURRENT_SOURCE_DIR}/capnproto/c++/src" PARENT_SCOPE) 31 | 32 | # Restore custom compile flags 33 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_CUSTOM}") 34 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_CUSTOM}") 35 | 36 | endif() 37 | -------------------------------------------------------------------------------- /performance/fbe_deserialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 08.05.2018 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class DeserializationFixture 10 | { 11 | protected: 12 | FBE::trade::AccountModel writer; 13 | FBE::trade::AccountModel reader; 14 | TradeProto::Account deserialized; 15 | 16 | DeserializationFixture() 17 | { 18 | // Create a new account with some orders 19 | TradeProto::Account account(1, "Test", "USD", 1000); 20 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 21 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 22 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 23 | 24 | // Serialize the account to the FBE buffer 25 | size_t model_begin = writer.create_begin(); 26 | account.Serialize(writer.model); 27 | writer.create_end(model_begin); 28 | assert(writer.verify() && "Model is broken!"); 29 | reader.attach(writer.buffer()); 30 | assert(reader.verify() && "Model is broken!"); 31 | } 32 | }; 33 | 34 | BENCHMARK_FIXTURE(DeserializationFixture, "FastBinaryEncoding-Deserialize") 35 | { 36 | context.metrics().AddBytes(reader.buffer().size()); 37 | context.metrics().SetCustom("MessageSize", (unsigned)reader.buffer().size()); 38 | 39 | // Deserialize the account from the FBE buffer 40 | deserialized.Deserialize(reader.model); 41 | 42 | context.metrics().SetCustom("OriginalSize", (unsigned)deserialized.size()); 43 | } 44 | 45 | BENCHMARK_MAIN() 46 | -------------------------------------------------------------------------------- /performance/capnproto_deserialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 31.03.2018 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | namespace local { 10 | 11 | capnp::MallocMessageBuilder output; 12 | kj::VectorOutputStream buffer; 13 | 14 | } 15 | 16 | class DeserializationFixture 17 | { 18 | protected: 19 | TradeProto::Account deserialized; 20 | 21 | DeserializationFixture() 22 | { 23 | // Create a new account with some orders 24 | TradeProto::Account account(1, "Test", "USD", 1000); 25 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 26 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 27 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 28 | 29 | // Serialize the account to the Cap'n'Proto buffer 30 | Trade::capnproto::Account::Builder builder = local::output.initRoot(); 31 | account.Serialize(builder); 32 | writeMessage(local::buffer, local::output); 33 | } 34 | }; 35 | 36 | BENCHMARK_FIXTURE(DeserializationFixture, "Cap'n'Proto-Deserialize") 37 | { 38 | context.metrics().AddBytes(local::buffer.getArray().size()); 39 | context.metrics().SetCustom("MessageSize", (unsigned)local::buffer.getArray().size()); 40 | 41 | // Deserialize the account from the Cap'n'Proto buffer 42 | kj::ArrayInputStream array(local::buffer.getArray()); 43 | capnp::InputStreamMessageReader input(array); 44 | deserialized.Deserialize(input.getRoot()); 45 | 46 | context.metrics().SetCustom("OriginalSize", (unsigned)deserialized.size()); 47 | } 48 | 49 | BENCHMARK_MAIN() 50 | -------------------------------------------------------------------------------- /examples/zpp_bits.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file zpp_bits.cpp 3 | \brief zpp::bits serialization example 4 | \author Ivan Shynkarenka 5 | \date 16.07.2025 6 | \copyright MIT License 7 | */ 8 | 9 | #include "../proto/trade.h" 10 | 11 | #include 12 | 13 | int main(int argc, char** argv) 14 | { 15 | // Create a new account with some orders 16 | TradeProto::Account account(1, "Test", "USD", 1000); 17 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 18 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 19 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 20 | 21 | // Serialize the account to the zpp::bits buffer 22 | auto [buffer, out] = zpp::bits::data_out(); 23 | (void) out(account); 24 | 25 | // Show original and zpp::bits serialized sizes 26 | std::cout << "Original size: " << account.size() << std::endl; 27 | std::cout << "zpp::bits size: " << buffer.size() << std::endl; 28 | 29 | // Deserialize the account from the zpp::bits buffer 30 | TradeProto::Account deserialized; 31 | (void) zpp::bits::in{buffer}(deserialized); 32 | 33 | // Show account content 34 | std::cout << std::endl; 35 | std::cout << "Account.Id = " << deserialized.Id << std::endl; 36 | std::cout << "Account.Name = " << deserialized.Name << std::endl; 37 | std::cout << "Account.Wallet.Currency = " << deserialized.Wallet.Currency << std::endl; 38 | std::cout << "Account.Wallet.Amount = " << deserialized.Wallet.Amount << std::endl; 39 | for (const auto& order : deserialized.Orders) 40 | { 41 | std::cout << "Account.Order => Id: " << order.Id 42 | << ", Symbol: " << order.Symbol 43 | << ", Side: " << (int)order.Side 44 | << ", Type: " << (int)order.Type 45 | << ", Price: " << order.Price 46 | << ", Volume: " << order.Volume 47 | << std::endl; 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /examples/flatbuffers.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file flatbuffers.cpp 3 | \brief FlatBuffers serialization example 4 | \author Ivan Shynkarenka 5 | \date 03.03.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #include "../proto/trade.h" 10 | 11 | #include 12 | 13 | int main(int argc, char** argv) 14 | { 15 | // Create a new account with some orders 16 | TradeProto::Account account(1, "Test", "USD", 1000); 17 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 18 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 19 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 20 | 21 | // Serialize the account to the FlatBuffer buffer 22 | flatbuffers::FlatBufferBuilder builder; 23 | builder.Finish(account.Serialize(builder)); 24 | 25 | // Show original and FlatBuffer serialized sizes 26 | std::cout << "Original size: " << account.size() << std::endl; 27 | std::cout << "FlatBuffer size: " << builder.GetSize() << std::endl; 28 | 29 | // Deserialize the account from the FlatBuffer buffer 30 | TradeProto::Account deserialized; 31 | deserialized.Deserialize(*Trade::flatbuf::GetAccount(builder.GetBufferPointer())); 32 | 33 | // Show account content 34 | std::cout << std::endl; 35 | std::cout << "Account.Id = " << deserialized.Id << std::endl; 36 | std::cout << "Account.Name = " << deserialized.Name << std::endl; 37 | std::cout << "Account.Wallet.Currency = " << deserialized.Wallet.Currency << std::endl; 38 | std::cout << "Account.Wallet.Amount = " << deserialized.Wallet.Amount << std::endl; 39 | for (const auto& order : deserialized.Orders) 40 | { 41 | std::cout << "Account.Order => Id: " << order.Id 42 | << ", Symbol: " << order.Symbol 43 | << ", Side: " << (int)order.Side 44 | << ", Type: " << (int)order.Type 45 | << ", Price: " << order.Price 46 | << ", Volume: " << order.Volume 47 | << std::endl; 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /performance/sbe_deserialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 02.01.2019 3 | // 4 | 5 | #include "benchmark/cppbenchmark.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | class DeserializationFixture 10 | { 11 | protected: 12 | char buffer[1024]; 13 | sbe::MessageHeader header; 14 | sbe::Account message; 15 | size_t serialized; 16 | TradeProto::Account deserialized; 17 | 18 | DeserializationFixture() 19 | { 20 | // Create a new account with some orders 21 | TradeProto::Account account(1, "Test", "USD", 1000); 22 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 23 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 24 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 25 | 26 | // Serialize the account to the SBE buffer 27 | header.wrap(buffer, 0, 1, sizeof(buffer)) 28 | .blockLength(sbe::Account::sbeBlockLength()) 29 | .templateId(sbe::Account::sbeTemplateId()) 30 | .schemaId(sbe::Account::sbeSchemaId()) 31 | .version(sbe::Account::sbeSchemaVersion()); 32 | message.wrapForEncode(buffer, header.encodedLength(), sizeof(buffer)); 33 | account.Serialize(message); 34 | serialized = header.encodedLength() + message.encodedLength(); 35 | } 36 | }; 37 | 38 | BENCHMARK_FIXTURE(DeserializationFixture, "SimpleBinaryEncoding-Deserialize") 39 | { 40 | context.metrics().AddBytes(serialized); 41 | context.metrics().SetCustom("MessageSize", (unsigned)serialized); 42 | 43 | // Deserialize the account from the SBE buffer 44 | header.wrap(buffer, 0, 1, sizeof(buffer)); 45 | int actingVersion = header.version(); 46 | int actingBlockLength = header.blockLength(); 47 | message.wrapForDecode(buffer, header.encodedLength(), actingBlockLength, actingVersion, sizeof(buffer)); 48 | deserialized.Deserialize(message); 49 | 50 | context.metrics().SetCustom("OriginalSize", (unsigned)deserialized.size()); 51 | } 52 | 53 | BENCHMARK_MAIN() 54 | -------------------------------------------------------------------------------- /proto/sbe/OrderSide.h: -------------------------------------------------------------------------------- 1 | /* Generated SBE (Simple Binary Encoding) message codec */ 2 | #ifndef _SBE_ORDERSIDE_CXX_H_ 3 | #define _SBE_ORDERSIDE_CXX_H_ 4 | 5 | #if !defined(__STDC_LIMIT_MACROS) 6 | # define __STDC_LIMIT_MACROS 1 7 | #endif 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define SBE_NULLVALUE_INT8 (std::numeric_limits::min)() 18 | #define SBE_NULLVALUE_INT16 (std::numeric_limits::min)() 19 | #define SBE_NULLVALUE_INT32 (std::numeric_limits::min)() 20 | #define SBE_NULLVALUE_INT64 (std::numeric_limits::min)() 21 | #define SBE_NULLVALUE_UINT8 (std::numeric_limits::max)() 22 | #define SBE_NULLVALUE_UINT16 (std::numeric_limits::max)() 23 | #define SBE_NULLVALUE_UINT32 (std::numeric_limits::max)() 24 | #define SBE_NULLVALUE_UINT64 (std::numeric_limits::max)() 25 | 26 | namespace sbe { 27 | 28 | class OrderSide 29 | { 30 | public: 31 | enum Value 32 | { 33 | buy = static_cast(0), 34 | sell = static_cast(1), 35 | NULL_VALUE = static_cast(255) 36 | }; 37 | 38 | static OrderSide::Value get(const std::uint8_t value) 39 | { 40 | switch (value) 41 | { 42 | case static_cast(0): return buy; 43 | case static_cast(1): return sell; 44 | case static_cast(255): return NULL_VALUE; 45 | } 46 | 47 | throw std::runtime_error("unknown value for enum OrderSide [E103]"); 48 | } 49 | 50 | static const char *c_str(const OrderSide::Value value) 51 | { 52 | switch (value) 53 | { 54 | case buy: return "buy"; 55 | case sell: return "sell"; 56 | case NULL_VALUE: return "NULL_VALUE"; 57 | } 58 | 59 | throw std::runtime_error("unknown value for enum OrderSide [E103]:"); 60 | } 61 | 62 | template 63 | friend std::basic_ostream & operator << ( 64 | std::basic_ostream &os, OrderSide::Value m) 65 | { 66 | return os << OrderSide::c_str(m); 67 | } 68 | }; 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /examples/protobuf.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file protobuf.cpp 3 | \brief Protobuf serialization example 4 | \author Ivan Shynkarenka 5 | \date 30.03.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #include "../proto/trade.h" 10 | 11 | #include 12 | 13 | int main(int argc, char** argv) 14 | { 15 | // Create a new account with some orders 16 | TradeProto::Account account(1, "Test", "USD", 1000); 17 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 18 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 19 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 20 | 21 | // Serialize the account to the Protobuf buffer 22 | Trade::protobuf::Account output; 23 | account.Serialize(output); 24 | auto buffer = output.SerializeAsString(); 25 | 26 | // Show original and Protobuf serialized sizes 27 | std::cout << "Original size: " << account.size() << std::endl; 28 | std::cout << "Protobuf size: " << buffer.size() << std::endl; 29 | 30 | // Deserialize the account from the Protobuf buffer 31 | Trade::protobuf::Account input; 32 | input.ParseFromString(buffer); 33 | TradeProto::Account deserialized; 34 | deserialized.Deserialize(input); 35 | 36 | // Show account content 37 | std::cout << std::endl; 38 | std::cout << "Account.Id = " << deserialized.Id << std::endl; 39 | std::cout << "Account.Name = " << deserialized.Name << std::endl; 40 | std::cout << "Account.Wallet.Currency = " << deserialized.Wallet.Currency << std::endl; 41 | std::cout << "Account.Wallet.Amount = " << deserialized.Wallet.Amount << std::endl; 42 | for (const auto& order : deserialized.Orders) 43 | { 44 | std::cout << "Account.Order => Id: " << order.Id 45 | << ", Symbol: " << order.Symbol 46 | << ", Side: " << (int)order.Side 47 | << ", Type: " << (int)order.Type 48 | << ", Price: " << order.Price 49 | << ", Volume: " << order.Volume 50 | << std::endl; 51 | } 52 | 53 | // Delete all global objects allocated by Protobuf 54 | google::protobuf::ShutdownProtobufLibrary(); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /examples/capnproto.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file capnproto.cpp 3 | \brief Cap'n'Proto serialization example 4 | \author Ivan Shynkarenka 5 | \date 31.03.2018 6 | \copyright MIT License 7 | */ 8 | 9 | #include "../proto/trade.h" 10 | 11 | #include 12 | 13 | int main(int argc, char** argv) 14 | { 15 | // Create a new account with some orders 16 | TradeProto::Account account(1, "Test", "USD", 1000); 17 | account.Orders.emplace_back(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000); 18 | account.Orders.emplace_back(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100); 19 | account.Orders.emplace_back(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10); 20 | 21 | // Serialize the account to the Cap'n'Proto buffer 22 | capnp::MallocMessageBuilder output; 23 | Trade::capnproto::Account::Builder builder = output.initRoot(); 24 | account.Serialize(builder); 25 | kj::VectorOutputStream buffer; 26 | writeMessage(buffer, output); 27 | 28 | // Show original and Cap'n'Proto serialized sizes 29 | std::cout << "Original size: " << account.size() << std::endl; 30 | std::cout << "Cap'n'Proto size: " << buffer.getArray().size() << std::endl; 31 | 32 | // Deserialize the account from the Cap'n'Proto buffer 33 | kj::ArrayInputStream array(buffer.getArray()); 34 | capnp::InputStreamMessageReader input(array); 35 | TradeProto::Account deserialized; 36 | deserialized.Deserialize(input.getRoot()); 37 | 38 | // Show account content 39 | std::cout << std::endl; 40 | std::cout << "Account.Id = " << deserialized.Id << std::endl; 41 | std::cout << "Account.Name = " << deserialized.Name << std::endl; 42 | std::cout << "Account.Wallet.Currency = " << deserialized.Wallet.Currency << std::endl; 43 | std::cout << "Account.Wallet.Amount = " << deserialized.Wallet.Amount << std::endl; 44 | for (const auto& order : deserialized.Orders) 45 | { 46 | std::cout << "Account.Order => Id: " << order.Id 47 | << ", Symbol: " << order.Symbol 48 | << ", Side: " << (int)order.Side 49 | << ", Type: " << (int)order.Type 50 | << ", Price: " << order.Price 51 | << ", Volume: " << order.Volume 52 | << std::endl; 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /examples/fbe.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file fbe.cpp 3 | \brief FastBinaryEncoding serialization example 4 | \author Ivan Shynkarenka 5 | \date 08.05.2018 6 | \copyright MIT License 7 | */ 8 | 9 | #include "../proto/trade.h" 10 | 11 | #include 12 | 13 | int main(int argc, char** argv) 14 | { 15 | // Create a new account with some orders 16 | TradeProto::Account account(1, "Test", "USD", 1000); 17 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 18 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 19 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 20 | 21 | // Serialize the account to the FBE buffer 22 | FBE::trade::AccountModel writer; 23 | size_t model_begin = writer.create_begin(); 24 | account.Serialize(writer.model); 25 | size_t serialized = writer.create_end(model_begin); 26 | assert(writer.verify() && "Model is broken!"); 27 | 28 | // Show original and FBE serialized sizes 29 | std::cout << "Original size: " << account.size() << std::endl; 30 | std::cout << "FBE size: " << serialized << std::endl; 31 | 32 | // Deserialize the account from the FBE buffer 33 | TradeProto::Account deserialized; 34 | FBE::trade::AccountModel reader; 35 | reader.attach(writer.buffer()); 36 | assert(reader.verify() && "Model is broken!"); 37 | deserialized.Deserialize(reader.model); 38 | 39 | // Show account content 40 | std::cout << std::endl; 41 | std::cout << "Account.Id = " << deserialized.Id << std::endl; 42 | std::cout << "Account.Name = " << deserialized.Name << std::endl; 43 | std::cout << "Account.Wallet.Currency = " << deserialized.Wallet.Currency << std::endl; 44 | std::cout << "Account.Wallet.Amount = " << deserialized.Wallet.Amount << std::endl; 45 | for (const auto& order : deserialized.Orders) 46 | { 47 | std::cout << "Account.Order => Id: " << order.Id 48 | << ", Symbol: " << order.Symbol 49 | << ", Side: " << (int)order.Side 50 | << ", Type: " << (int)order.Type 51 | << ", Price: " << order.Price 52 | << ", Volume: " << order.Volume 53 | << std::endl; 54 | } 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /examples/json.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file json.cpp 3 | \brief JSON serialization example 4 | \author Ivan Shynkarenka 5 | \date 24.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #include "../proto/trade.h" 10 | 11 | #include "serialization/json/parser.h" 12 | 13 | #include 14 | 15 | int main(int argc, char** argv) 16 | { 17 | // Create a new account with some orders 18 | TradeProto::Account account(1, "Test", "USD", 1000); 19 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 20 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 21 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 22 | 23 | // Serialize the account to the JSON buffer 24 | CppSerialization::JSON::StringBuffer buffer; 25 | CppSerialization::JSON::Serializer serializer(buffer); 26 | account.Serialize(serializer); 27 | 28 | // Show original and JSON serialized sizes 29 | std::cout << "Original size: " << account.size() << std::endl; 30 | std::cout << "JSON content: " << buffer.GetString() << std::endl; 31 | std::cout << "JSON size: " << buffer.GetSize() << std::endl; 32 | 33 | // Parse JSON string 34 | CppSerialization::JSON::Document json = CppSerialization::JSON::Parser::Parse(buffer.GetString()); 35 | 36 | // Deserialize the account from the JSON buffer 37 | TradeProto::Account deserialized; 38 | deserialized.Deserialize(json); 39 | 40 | // Show account content 41 | std::cout << std::endl; 42 | std::cout << "Account.Id = " << deserialized.Id << std::endl; 43 | std::cout << "Account.Name = " << deserialized.Name << std::endl; 44 | std::cout << "Account.Wallet.Currency = " << deserialized.Wallet.Currency << std::endl; 45 | std::cout << "Account.Wallet.Amount = " << deserialized.Wallet.Amount << std::endl; 46 | for (const auto& order : deserialized.Orders) 47 | { 48 | std::cout << "Account.Order => Id: " << order.Id 49 | << ", Symbol: " << order.Symbol 50 | << ", Side: " << (int)order.Side 51 | << ", Type: " << (int)order.Type 52 | << ", Price: " << order.Price 53 | << ", Volume: " << order.Volume 54 | << std::endl; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /proto/sbe/OrderType.h: -------------------------------------------------------------------------------- 1 | /* Generated SBE (Simple Binary Encoding) message codec */ 2 | #ifndef _SBE_ORDERTYPE_CXX_H_ 3 | #define _SBE_ORDERTYPE_CXX_H_ 4 | 5 | #if !defined(__STDC_LIMIT_MACROS) 6 | # define __STDC_LIMIT_MACROS 1 7 | #endif 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define SBE_NULLVALUE_INT8 (std::numeric_limits::min)() 18 | #define SBE_NULLVALUE_INT16 (std::numeric_limits::min)() 19 | #define SBE_NULLVALUE_INT32 (std::numeric_limits::min)() 20 | #define SBE_NULLVALUE_INT64 (std::numeric_limits::min)() 21 | #define SBE_NULLVALUE_UINT8 (std::numeric_limits::max)() 22 | #define SBE_NULLVALUE_UINT16 (std::numeric_limits::max)() 23 | #define SBE_NULLVALUE_UINT32 (std::numeric_limits::max)() 24 | #define SBE_NULLVALUE_UINT64 (std::numeric_limits::max)() 25 | 26 | namespace sbe { 27 | 28 | class OrderType 29 | { 30 | public: 31 | enum Value 32 | { 33 | market = static_cast(0), 34 | limit = static_cast(1), 35 | stop = static_cast(2), 36 | NULL_VALUE = static_cast(255) 37 | }; 38 | 39 | static OrderType::Value get(const std::uint8_t value) 40 | { 41 | switch (value) 42 | { 43 | case static_cast(0): return market; 44 | case static_cast(1): return limit; 45 | case static_cast(2): return stop; 46 | case static_cast(255): return NULL_VALUE; 47 | } 48 | 49 | throw std::runtime_error("unknown value for enum OrderType [E103]"); 50 | } 51 | 52 | static const char *c_str(const OrderType::Value value) 53 | { 54 | switch (value) 55 | { 56 | case market: return "market"; 57 | case limit: return "limit"; 58 | case stop: return "stop"; 59 | case NULL_VALUE: return "NULL_VALUE"; 60 | } 61 | 62 | throw std::runtime_error("unknown value for enum OrderType [E103]:"); 63 | } 64 | 65 | template 66 | friend std::basic_ostream & operator << ( 67 | std::basic_ostream &os, OrderType::Value m) 68 | { 69 | return os << OrderType::c_str(m); 70 | } 71 | }; 72 | 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /tests/test_zpp_bits.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 16.07.2025 3 | // 4 | 5 | #include "test.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | using namespace CppCommon; 10 | using namespace CppSerialization; 11 | 12 | TEST_CASE("zpp::bits", "[CppSerialization]") 13 | { 14 | // Create a new account with some orders 15 | TradeProto::Account account(1, "Test", "USD", 1000); 16 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 17 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 18 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 19 | 20 | // Serialize the account to the zpp::bits buffer 21 | auto [buffer, in, out] = zpp::bits::data_in_out(); 22 | (void) out(account); 23 | 24 | REQUIRE(!buffer.empty()); 25 | 26 | // Deserialize the account from the zpp::bits buffer 27 | TradeProto::Account deserialized; 28 | (void) in(deserialized); 29 | 30 | REQUIRE(deserialized.Id == 1); 31 | REQUIRE(deserialized.Name == "Test"); 32 | REQUIRE(std::string(deserialized.Wallet.Currency) == "USD"); 33 | REQUIRE(deserialized.Wallet.Amount == 1000); 34 | REQUIRE(deserialized.Orders.size() == 3); 35 | REQUIRE(deserialized.Orders[0].Id == 1); 36 | REQUIRE(std::string(deserialized.Orders[0].Symbol) == "EURUSD"); 37 | REQUIRE(deserialized.Orders[0].Side == TradeProto::OrderSide::BUY); 38 | REQUIRE(deserialized.Orders[0].Type == TradeProto::OrderType::MARKET); 39 | REQUIRE(deserialized.Orders[0].Price == 1.23456); 40 | REQUIRE(deserialized.Orders[0].Volume == 1000); 41 | REQUIRE(deserialized.Orders[1].Id == 2); 42 | REQUIRE(std::string(deserialized.Orders[1].Symbol) == "EURUSD"); 43 | REQUIRE(deserialized.Orders[1].Side == TradeProto::OrderSide::SELL); 44 | REQUIRE(deserialized.Orders[1].Type == TradeProto::OrderType::LIMIT); 45 | REQUIRE(deserialized.Orders[1].Price == 1.0); 46 | REQUIRE(deserialized.Orders[1].Volume == 100); 47 | REQUIRE(deserialized.Orders[2].Id == 3); 48 | REQUIRE(std::string(deserialized.Orders[2].Symbol) == "EURUSD"); 49 | REQUIRE(deserialized.Orders[2].Side == TradeProto::OrderSide::BUY); 50 | REQUIRE(deserialized.Orders[2].Type == TradeProto::OrderType::STOP); 51 | REQUIRE(deserialized.Orders[2].Price == 1.5); 52 | REQUIRE(deserialized.Orders[2].Volume == 10); 53 | } 54 | -------------------------------------------------------------------------------- /tests/test_flatbuffers.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 03.03.2017 3 | // 4 | 5 | #include "test.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | using namespace CppCommon; 10 | using namespace CppSerialization; 11 | 12 | TEST_CASE("FlatBuffers", "[CppSerialization]") 13 | { 14 | // Create a new account with some orders 15 | TradeProto::Account account(1, "Test", "USD", 1000); 16 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 17 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 18 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 19 | 20 | // Serialize the account to the FlatBuffer buffer 21 | flatbuffers::FlatBufferBuilder builder; 22 | builder.Finish(account.Serialize(builder)); 23 | 24 | REQUIRE(builder.GetSize() > 0); 25 | REQUIRE(builder.GetBufferPointer() != nullptr); 26 | 27 | // Deserialize the account from the FlatBuffer buffer 28 | TradeProto::Account deserialized; 29 | deserialized.Deserialize(*Trade::flatbuf::GetAccount(builder.GetBufferPointer())); 30 | 31 | REQUIRE(deserialized.Id == 1); 32 | REQUIRE(deserialized.Name == "Test"); 33 | REQUIRE(std::string(deserialized.Wallet.Currency) == "USD"); 34 | REQUIRE(deserialized.Wallet.Amount == 1000); 35 | REQUIRE(deserialized.Orders.size() == 3); 36 | REQUIRE(deserialized.Orders[0].Id == 1); 37 | REQUIRE(std::string(deserialized.Orders[0].Symbol) == "EURUSD"); 38 | REQUIRE(deserialized.Orders[0].Side == TradeProto::OrderSide::BUY); 39 | REQUIRE(deserialized.Orders[0].Type == TradeProto::OrderType::MARKET); 40 | REQUIRE(deserialized.Orders[0].Price == 1.23456); 41 | REQUIRE(deserialized.Orders[0].Volume == 1000); 42 | REQUIRE(deserialized.Orders[1].Id == 2); 43 | REQUIRE(std::string(deserialized.Orders[1].Symbol) == "EURUSD"); 44 | REQUIRE(deserialized.Orders[1].Side == TradeProto::OrderSide::SELL); 45 | REQUIRE(deserialized.Orders[1].Type == TradeProto::OrderType::LIMIT); 46 | REQUIRE(deserialized.Orders[1].Price == 1.0); 47 | REQUIRE(deserialized.Orders[1].Volume == 100); 48 | REQUIRE(deserialized.Orders[2].Id == 3); 49 | REQUIRE(std::string(deserialized.Orders[2].Symbol) == "EURUSD"); 50 | REQUIRE(deserialized.Orders[2].Side == TradeProto::OrderSide::BUY); 51 | REQUIRE(deserialized.Orders[2].Type == TradeProto::OrderType::STOP); 52 | REQUIRE(deserialized.Orders[2].Price == 1.5); 53 | REQUIRE(deserialized.Orders[2].Volume == 10); 54 | } 55 | -------------------------------------------------------------------------------- /proto/trade.sbe.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 0 22 | 1 23 | 24 | 25 | 0 26 | 1 27 | 2 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /tests/test_json.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 28.02.2017 3 | // 4 | 5 | #include "test.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | #include "serialization/json/parser.h" 10 | 11 | using namespace CppCommon; 12 | using namespace CppSerialization::JSON; 13 | 14 | TEST_CASE("JSON", "[CppSerialization]") 15 | { 16 | // Create a new account with some orders 17 | TradeProto::Account account(1, "Test", "USD", 1000); 18 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 19 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 20 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 21 | 22 | // Serialize the account to the JSON file buffer 23 | StringBuffer buffer; 24 | Serializer serializer(buffer); 25 | account.Serialize(serializer); 26 | 27 | REQUIRE(buffer.GetLength() > 0); 28 | REQUIRE(buffer.GetString() != nullptr); 29 | 30 | // Parse JSON string 31 | Document json = Parser::Parse(buffer.GetString()); 32 | 33 | // Deserialize the account from the JSON file buffer 34 | TradeProto::Account deserialized; 35 | deserialized.Deserialize(json); 36 | 37 | REQUIRE(deserialized.Id == 1); 38 | REQUIRE(deserialized.Name == "Test"); 39 | REQUIRE(std::string(deserialized.Wallet.Currency) == "USD"); 40 | REQUIRE(deserialized.Wallet.Amount == 1000); 41 | REQUIRE(deserialized.Orders.size() == 3); 42 | REQUIRE(deserialized.Orders[0].Id == 1); 43 | REQUIRE(std::string(deserialized.Orders[0].Symbol) == "EURUSD"); 44 | REQUIRE(deserialized.Orders[0].Side == TradeProto::OrderSide::BUY); 45 | REQUIRE(deserialized.Orders[0].Type == TradeProto::OrderType::MARKET); 46 | REQUIRE(deserialized.Orders[0].Price == 1.23456); 47 | REQUIRE(deserialized.Orders[0].Volume == 1000); 48 | REQUIRE(deserialized.Orders[1].Id == 2); 49 | REQUIRE(std::string(deserialized.Orders[1].Symbol) == "EURUSD"); 50 | REQUIRE(deserialized.Orders[1].Side == TradeProto::OrderSide::SELL); 51 | REQUIRE(deserialized.Orders[1].Type == TradeProto::OrderType::LIMIT); 52 | REQUIRE(deserialized.Orders[1].Price == 1.0); 53 | REQUIRE(deserialized.Orders[1].Volume == 100); 54 | REQUIRE(deserialized.Orders[2].Id == 3); 55 | REQUIRE(std::string(deserialized.Orders[2].Symbol) == "EURUSD"); 56 | REQUIRE(deserialized.Orders[2].Side == TradeProto::OrderSide::BUY); 57 | REQUIRE(deserialized.Orders[2].Type == TradeProto::OrderType::STOP); 58 | REQUIRE(deserialized.Orders[2].Price == 1.5); 59 | REQUIRE(deserialized.Orders[2].Volume == 10); 60 | } 61 | -------------------------------------------------------------------------------- /tests/test_protobuf.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 30.03.2017 3 | // 4 | 5 | #include "test.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | using namespace CppCommon; 10 | using namespace CppSerialization; 11 | 12 | TEST_CASE("Protobuf", "[CppSerialization]") 13 | { 14 | // Create a new account with some orders 15 | TradeProto::Account account(1, "Test", "USD", 1000); 16 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 17 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 18 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 19 | 20 | // Serialize the account to the Protobuf buffer 21 | Trade::protobuf::Account output; 22 | account.Serialize(output); 23 | auto buffer = output.SerializeAsString(); 24 | 25 | REQUIRE(!buffer.empty()); 26 | 27 | // Deserialize the account from the Protobuf buffer 28 | Trade::protobuf::Account input; 29 | input.ParseFromString(buffer); 30 | TradeProto::Account deserialized; 31 | deserialized.Deserialize(input); 32 | 33 | REQUIRE(deserialized.Id == 1); 34 | REQUIRE(deserialized.Name == "Test"); 35 | REQUIRE(std::string(deserialized.Wallet.Currency) == "USD"); 36 | REQUIRE(deserialized.Wallet.Amount == 1000); 37 | REQUIRE(deserialized.Orders.size() == 3); 38 | REQUIRE(deserialized.Orders[0].Id == 1); 39 | REQUIRE(std::string(deserialized.Orders[0].Symbol) == "EURUSD"); 40 | REQUIRE(deserialized.Orders[0].Side == TradeProto::OrderSide::BUY); 41 | REQUIRE(deserialized.Orders[0].Type == TradeProto::OrderType::MARKET); 42 | REQUIRE(deserialized.Orders[0].Price == 1.23456); 43 | REQUIRE(deserialized.Orders[0].Volume == 1000); 44 | REQUIRE(deserialized.Orders[1].Id == 2); 45 | REQUIRE(std::string(deserialized.Orders[1].Symbol) == "EURUSD"); 46 | REQUIRE(deserialized.Orders[1].Side == TradeProto::OrderSide::SELL); 47 | REQUIRE(deserialized.Orders[1].Type == TradeProto::OrderType::LIMIT); 48 | REQUIRE(deserialized.Orders[1].Price == 1.0); 49 | REQUIRE(deserialized.Orders[1].Volume == 100); 50 | REQUIRE(deserialized.Orders[2].Id == 3); 51 | REQUIRE(std::string(deserialized.Orders[2].Symbol) == "EURUSD"); 52 | REQUIRE(deserialized.Orders[2].Side == TradeProto::OrderSide::BUY); 53 | REQUIRE(deserialized.Orders[2].Type == TradeProto::OrderType::STOP); 54 | REQUIRE(deserialized.Orders[2].Price == 1.5); 55 | REQUIRE(deserialized.Orders[2].Volume == 10); 56 | 57 | // Delete all global objects allocated by Protobuf 58 | google::protobuf::ShutdownProtobufLibrary(); 59 | } 60 | -------------------------------------------------------------------------------- /examples/sbe.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file sbe.cpp 3 | \brief SimpleBinaryEncoding serialization example 4 | \author Ivan Shynkarenka 5 | \date 02.01.2019 6 | \copyright MIT License 7 | */ 8 | 9 | #include "../proto/trade.h" 10 | 11 | #include 12 | 13 | int main(int argc, char** argv) 14 | { 15 | // Create a new account with some orders 16 | TradeProto::Account account(1, "Test", "USD", 1000); 17 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 18 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 19 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 20 | 21 | // Serialize the account to the SBE buffer 22 | char buffer[1024]; 23 | sbe::MessageHeader header; 24 | header.wrap(buffer, 0, 1, sizeof(buffer)) 25 | .blockLength(sbe::Account::sbeBlockLength()) 26 | .templateId(sbe::Account::sbeTemplateId()) 27 | .schemaId(sbe::Account::sbeSchemaId()) 28 | .version(sbe::Account::sbeSchemaVersion()); 29 | sbe::Account message; 30 | message.wrapForEncode(buffer, header.encodedLength(), sizeof(buffer)); 31 | account.Serialize(message); 32 | 33 | // Show original and SBE serialized sizes 34 | std::cout << "Original size: " << account.size() << std::endl; 35 | std::cout << "SBE size: " << header.encodedLength() + message.encodedLength() << std::endl; 36 | 37 | // Deserialize the account from the SBE buffer 38 | header.wrap(buffer, 0, 1, sizeof(buffer)); 39 | int actingVersion = header.version(); 40 | int actingBlockLength = header.blockLength(); 41 | message.wrapForDecode(buffer, header.encodedLength(), actingBlockLength, actingVersion, sizeof(buffer)); 42 | TradeProto::Account deserialized; 43 | deserialized.Deserialize(message); 44 | 45 | // Show account content 46 | std::cout << std::endl; 47 | std::cout << "Account.Id = " << deserialized.Id << std::endl; 48 | std::cout << "Account.Name = " << deserialized.Name << std::endl; 49 | std::cout << "Account.Wallet.Currency = " << deserialized.Wallet.Currency << std::endl; 50 | std::cout << "Account.Wallet.Amount = " << deserialized.Wallet.Amount << std::endl; 51 | for (const auto& order : deserialized.Orders) 52 | { 53 | std::cout << "Account.Order => Id: " << order.Id 54 | << ", Symbol: " << order.Symbol 55 | << ", Side: " << (int)order.Side 56 | << ", Type: " << (int)order.Type 57 | << ", Price: " << order.Price 58 | << ", Volume: " << order.Volume 59 | << std::endl; 60 | } 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /tests/test_capnproto.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 31.03.2018 3 | // 4 | 5 | #include "test.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | using namespace CppCommon; 10 | using namespace CppSerialization; 11 | 12 | TEST_CASE("Cap'n'Proto", "[CppSerialization]") 13 | { 14 | // Create a new account with some orders 15 | TradeProto::Account account(1, "Test", "USD", 1000); 16 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 17 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 18 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 19 | 20 | // Serialize the account to the Cap'n'Proto buffer 21 | capnp::MallocMessageBuilder output; 22 | Trade::capnproto::Account::Builder builder = output.initRoot(); 23 | account.Serialize(builder); 24 | kj::VectorOutputStream buffer; 25 | writeMessage(buffer, output); 26 | 27 | REQUIRE(buffer.getArray().size() > 0); 28 | 29 | // Deserialize the account from the Cap'n'Proto buffer 30 | kj::ArrayInputStream array(buffer.getArray()); 31 | capnp::InputStreamMessageReader input(array); 32 | TradeProto::Account deserialized; 33 | deserialized.Deserialize(input.getRoot()); 34 | 35 | REQUIRE(deserialized.Id == 1); 36 | REQUIRE(deserialized.Name == "Test"); 37 | REQUIRE(std::string(deserialized.Wallet.Currency) == "USD"); 38 | REQUIRE(deserialized.Wallet.Amount == 1000); 39 | REQUIRE(deserialized.Orders.size() == 3); 40 | REQUIRE(deserialized.Orders[0].Id == 1); 41 | REQUIRE(std::string(deserialized.Orders[0].Symbol) == "EURUSD"); 42 | REQUIRE(deserialized.Orders[0].Side == TradeProto::OrderSide::BUY); 43 | REQUIRE(deserialized.Orders[0].Type == TradeProto::OrderType::MARKET); 44 | REQUIRE(deserialized.Orders[0].Price == 1.23456); 45 | REQUIRE(deserialized.Orders[0].Volume == 1000); 46 | REQUIRE(deserialized.Orders[1].Id == 2); 47 | REQUIRE(std::string(deserialized.Orders[1].Symbol) == "EURUSD"); 48 | REQUIRE(deserialized.Orders[1].Side == TradeProto::OrderSide::SELL); 49 | REQUIRE(deserialized.Orders[1].Type == TradeProto::OrderType::LIMIT); 50 | REQUIRE(deserialized.Orders[1].Price == 1.0); 51 | REQUIRE(deserialized.Orders[1].Volume == 100); 52 | REQUIRE(deserialized.Orders[2].Id == 3); 53 | REQUIRE(std::string(deserialized.Orders[2].Symbol) == "EURUSD"); 54 | REQUIRE(deserialized.Orders[2].Side == TradeProto::OrderSide::BUY); 55 | REQUIRE(deserialized.Orders[2].Type == TradeProto::OrderType::STOP); 56 | REQUIRE(deserialized.Orders[2].Price == 1.5); 57 | REQUIRE(deserialized.Orders[2].Volume == 10); 58 | } 59 | -------------------------------------------------------------------------------- /tests/test_fbe.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 08.05.2018 3 | // 4 | 5 | #include "test.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | using namespace CppCommon; 10 | using namespace CppSerialization; 11 | 12 | TEST_CASE("FastBinaryEncoding", "[CppSerialization]") 13 | { 14 | // Create a new account with some orders 15 | TradeProto::Account account(1, "Test", "USD", 1000); 16 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 17 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 18 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 19 | 20 | // Serialize the account to the FBE buffer 21 | FBE::trade::AccountModel writer; 22 | size_t model_begin = writer.create_begin(); 23 | account.Serialize(writer.model); 24 | size_t serialized = writer.create_end(model_begin); 25 | assert(writer.verify() && "Model is broken!"); 26 | 27 | REQUIRE(serialized > 0); 28 | REQUIRE(writer.buffer().size() > 0); 29 | 30 | // Deserialize the account from the FBE buffer 31 | TradeProto::Account deserialized; 32 | FBE::trade::AccountModel reader; 33 | reader.attach(writer.buffer()); 34 | assert(reader.verify() && "Model is broken!"); 35 | deserialized.Deserialize(reader.model); 36 | 37 | REQUIRE(deserialized.Id == 1); 38 | REQUIRE(deserialized.Name == "Test"); 39 | REQUIRE(std::string(deserialized.Wallet.Currency) == "USD"); 40 | REQUIRE(deserialized.Wallet.Amount == 1000); 41 | REQUIRE(deserialized.Orders.size() == 3); 42 | REQUIRE(deserialized.Orders[0].Id == 1); 43 | REQUIRE(std::string(deserialized.Orders[0].Symbol) == "EURUSD"); 44 | REQUIRE(deserialized.Orders[0].Side == TradeProto::OrderSide::BUY); 45 | REQUIRE(deserialized.Orders[0].Type == TradeProto::OrderType::MARKET); 46 | REQUIRE(deserialized.Orders[0].Price == 1.23456); 47 | REQUIRE(deserialized.Orders[0].Volume == 1000); 48 | REQUIRE(deserialized.Orders[1].Id == 2); 49 | REQUIRE(std::string(deserialized.Orders[1].Symbol) == "EURUSD"); 50 | REQUIRE(deserialized.Orders[1].Side == TradeProto::OrderSide::SELL); 51 | REQUIRE(deserialized.Orders[1].Type == TradeProto::OrderType::LIMIT); 52 | REQUIRE(deserialized.Orders[1].Price == 1.0); 53 | REQUIRE(deserialized.Orders[1].Volume == 100); 54 | REQUIRE(deserialized.Orders[2].Id == 3); 55 | REQUIRE(std::string(deserialized.Orders[2].Symbol) == "EURUSD"); 56 | REQUIRE(deserialized.Orders[2].Side == TradeProto::OrderSide::BUY); 57 | REQUIRE(deserialized.Orders[2].Type == TradeProto::OrderType::STOP); 58 | REQUIRE(deserialized.Orders[2].Price == 1.5); 59 | REQUIRE(deserialized.Orders[2].Volume == 10); 60 | } 61 | -------------------------------------------------------------------------------- /tests/test_sbe.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Ivan Shynkarenka on 02.01.2019 3 | // 4 | 5 | #include "test.h" 6 | 7 | #include "../proto/trade.h" 8 | 9 | using namespace CppCommon; 10 | using namespace CppSerialization; 11 | 12 | TEST_CASE("SimpleBinaryEncoding", "[CppSerialization]") 13 | { 14 | // Create a new account with some orders 15 | TradeProto::Account account(1, "Test", "USD", 1000); 16 | account.Orders.emplace_back(TradeProto::Order(1, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::MARKET, 1.23456, 1000)); 17 | account.Orders.emplace_back(TradeProto::Order(2, "EURUSD", TradeProto::OrderSide::SELL, TradeProto::OrderType::LIMIT, 1.0, 100)); 18 | account.Orders.emplace_back(TradeProto::Order(3, "EURUSD", TradeProto::OrderSide::BUY, TradeProto::OrderType::STOP, 1.5, 10)); 19 | 20 | // Serialize the account to the SBE buffer 21 | char buffer[1024]; 22 | sbe::MessageHeader header; 23 | header.wrap(buffer, 0, 1, sizeof(buffer)) 24 | .blockLength(sbe::Account::sbeBlockLength()) 25 | .templateId(sbe::Account::sbeTemplateId()) 26 | .schemaId(sbe::Account::sbeSchemaId()) 27 | .version(sbe::Account::sbeSchemaVersion()); 28 | sbe::Account message; 29 | message.wrapForEncode(buffer, header.encodedLength(), sizeof(buffer)); 30 | account.Serialize(message); 31 | size_t serialized = header.encodedLength() + message.encodedLength(); 32 | 33 | REQUIRE(serialized > 0); 34 | 35 | // Deserialize the account from the SBE buffer 36 | header.wrap(buffer, 0, 1, sizeof(buffer)); 37 | int actingVersion = header.version(); 38 | int actingBlockLength = header.blockLength(); 39 | message.wrapForDecode(buffer, header.encodedLength(), actingBlockLength, actingVersion, sizeof(buffer)); 40 | TradeProto::Account deserialized; 41 | deserialized.Deserialize(message); 42 | 43 | REQUIRE(deserialized.Id == 1); 44 | REQUIRE(deserialized.Name == "Test"); 45 | REQUIRE(std::string(deserialized.Wallet.Currency) == "USD"); 46 | REQUIRE(deserialized.Wallet.Amount == 1000); 47 | REQUIRE(deserialized.Orders.size() == 3); 48 | REQUIRE(deserialized.Orders[0].Id == 1); 49 | REQUIRE(std::string(deserialized.Orders[0].Symbol) == "EURUSD"); 50 | REQUIRE(deserialized.Orders[0].Side == TradeProto::OrderSide::BUY); 51 | REQUIRE(deserialized.Orders[0].Type == TradeProto::OrderType::MARKET); 52 | REQUIRE(deserialized.Orders[0].Price == 1.23456); 53 | REQUIRE(deserialized.Orders[0].Volume == 1000); 54 | REQUIRE(deserialized.Orders[1].Id == 2); 55 | REQUIRE(std::string(deserialized.Orders[1].Symbol) == "EURUSD"); 56 | REQUIRE(deserialized.Orders[1].Side == TradeProto::OrderSide::SELL); 57 | REQUIRE(deserialized.Orders[1].Type == TradeProto::OrderType::LIMIT); 58 | REQUIRE(deserialized.Orders[1].Price == 1.0); 59 | REQUIRE(deserialized.Orders[1].Volume == 100); 60 | REQUIRE(deserialized.Orders[2].Id == 3); 61 | REQUIRE(std::string(deserialized.Orders[2].Symbol) == "EURUSD"); 62 | REQUIRE(deserialized.Orders[2].Side == TradeProto::OrderSide::BUY); 63 | REQUIRE(deserialized.Orders[2].Type == TradeProto::OrderType::STOP); 64 | REQUIRE(deserialized.Orders[2].Price == 1.5); 65 | REQUIRE(deserialized.Orders[2].Volume == 10); 66 | } 67 | -------------------------------------------------------------------------------- /include/serialization/json/deserializer.h: -------------------------------------------------------------------------------- 1 | /*! 2 | \file deserializer.h 3 | \brief JSON deserializer definition 4 | \author Ivan Shynkarenka 5 | \date 27.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #ifndef CPPSERIALIZATION_JSON_DESERIALIZER_H 10 | #define CPPSERIALIZATION_JSON_DESERIALIZER_H 11 | 12 | #include "json.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | namespace CppSerialization { 19 | namespace JSON { 20 | 21 | //! JSON deserializer 22 | /*! 23 | JSON deserializer is used to deserialize objects from the JSON document. 24 | */ 25 | class Deserializer 26 | { 27 | public: 28 | Deserializer() = delete; 29 | Deserializer(const Deserializer&) = delete; 30 | Deserializer(Deserializer&&) = delete; 31 | ~Deserializer() = delete; 32 | 33 | Deserializer& operator=(const Deserializer&) = delete; 34 | Deserializer& operator=(Deserializer&&) = delete; 35 | 36 | //! Try to get the boolean key/value pair 37 | template 38 | static bool Find(const JSON& json, const char* key, bool& value); 39 | //! Try to get the integer key/value pair 40 | template 41 | static bool Find(const JSON& json, const char* key, int& value); 42 | //! Try to get the unsigned key/value pair 43 | template 44 | static bool Find(const JSON& json, const char* key, unsigned& value); 45 | //! Try to get the 64-bit integer key/value pair 46 | template 47 | static bool Find(const JSON& json, const char* key, int64_t& value); 48 | //! Try to get the 64-bit unsigned key/value pair 49 | template 50 | static bool Find(const JSON& json, const char* key, uint64_t& value); 51 | //! Try to get the double key/value pair 52 | template 53 | static bool Find(const JSON& json, const char* key, double& value); 54 | //! Try to get the C-string key/value pair with a given size 55 | template 56 | static bool Find(const JSON& json, const char* key, char* value, size_t size); 57 | //! Try to get the string key/value pair 58 | template 59 | static bool Find(const JSON& json, const char* key, std::string& value); 60 | //! Try to get the fixed string array key/value pair 61 | template 62 | static bool Find(const JSON& json, const char* key, char (&value)[N]); 63 | 64 | //! Try to get the array key/value pair 65 | template 66 | static bool FindArray(const JSON& json, const char* key, const std::function& handler); 67 | //! Try to get the array key/value pair with array initialize handler 68 | template 69 | static bool FindArray(const JSON& json, const char* key, const std::function& initialize, const std::function& handler); 70 | 71 | //! Try to get the object key/value pair 72 | template 73 | static bool FindObject(const JSON& json, const char* key, const std::function& handler); 74 | }; 75 | 76 | } // namespace JSON 77 | } // namespace CppSerialization 78 | 79 | #include "deserializer.inl" 80 | 81 | #endif // CPPSERIALIZATION_JSON_DESERIALIZER_H 82 | -------------------------------------------------------------------------------- /include/serialization/json/serializer.h: -------------------------------------------------------------------------------- 1 | /*! 2 | \file serializer.h 3 | \brief JSON serializer definition 4 | \author Ivan Shynkarenka 5 | \date 25.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | #ifndef CPPSERIALIZATION_JSON_SERIALIZER_H 10 | #define CPPSERIALIZATION_JSON_SERIALIZER_H 11 | 12 | #include "json.h" 13 | 14 | namespace CppSerialization { 15 | namespace JSON { 16 | 17 | //! JSON serializer 18 | /*! 19 | JSON serializer is parametrized with an output stream and 20 | is used to serialize objects into JSON format. 21 | */ 22 | template 23 | class Serializer : public Writer 24 | { 25 | public: 26 | Serializer() = default; 27 | explicit Serializer(OutputStream& stream) : Writer(stream) {} 28 | Serializer(const Serializer&) = delete; 29 | Serializer(Serializer&&) = default; 30 | ~Serializer() = default; 31 | 32 | Serializer& operator=(const Serializer&) = delete; 33 | Serializer& operator=(Serializer&&) = default; 34 | 35 | //! Start new object 36 | void StartObject(); 37 | //! End the current object 38 | void EndObject(); 39 | 40 | //! Start new array 41 | void StartArray(); 42 | //! End the current array 43 | void EndArray(); 44 | 45 | //! Put the C-string key 46 | void Key(const char* key); 47 | //! Put the C-string key with a given size 48 | void Key(const char* key, size_t size); 49 | //! Put the string key 50 | void Key(const std::string& key); 51 | //! Put the fixed string array key 52 | template 53 | void Key(const char (&key)[N]); 54 | 55 | //! Put the null value 56 | void Value(std::nullptr_t value); 57 | //! Put the boolean value 58 | void Value(bool value); 59 | //! Put the integer value 60 | void Value(int value); 61 | //! Put the unsigned integer value 62 | void Value(unsigned value); 63 | //! Put the 64-bit integer value 64 | void Value(int64_t value); 65 | //! Put the 64-bit unsigned integer value 66 | void Value(uint64_t value); 67 | //! Put the double value 68 | void Value(double value); 69 | //! Put the C-string value 70 | void Value(const char* value); 71 | //! Put the C-string value with a given size 72 | void Value(const char* value, size_t size); 73 | //! Put the string value 74 | void Value(const std::string& value); 75 | //! Put the fixed string array value 76 | template 77 | void Value(const char (&value)[N]); 78 | 79 | //! Put the null key/value pair 80 | void Pair(const char* key, std::nullptr_t value) 81 | { Key(key); Value(value); } 82 | //! Put the boolean key/value pair 83 | void Pair(const char* key, bool value) 84 | { Key(key); Value(value); } 85 | //! Put the integer key/value pair 86 | void Pair(const char* key, int value) 87 | { Key(key); Value(value); } 88 | //! Put the unsigned integer key/value pair 89 | void Pair(const char* key, unsigned value) 90 | { Key(key); Value(value); } 91 | //! Put the 64-bit integer key/value pair 92 | void Pair(const char* key, int64_t value) 93 | { Key(key); Value(value); } 94 | //! Put the 64-bit unsigned integer key/value pair 95 | void Pair(const char* key, uint64_t value) 96 | { Key(key); Value(value); } 97 | //! Put the double key/value pair 98 | void Pair(const char* key, double value) 99 | { Key(key); Value(value); } 100 | //! Put the C-string key/value pair 101 | void Pair(const char* key, const char* value) 102 | { Key(key); Value(value); } 103 | //! Put the C-string key/value pair with a given size 104 | void Pair(const char* key, const char* value, size_t size) 105 | { Key(key); Value(value, size); } 106 | //! Put the string key/value pair 107 | void Pair(const char* key, const std::string& value) 108 | { Key(key); Value(value); } 109 | //! Put the fixed string array key/value pair 110 | template 111 | void Pair(const char* key, const char (&value)[N]) 112 | { Key(key); Value(value); } 113 | }; 114 | 115 | } // namespace JSON 116 | } // namespace CppSerialization 117 | 118 | #include "serializer.inl" 119 | 120 | #endif // CPPSERIALIZATION_JSON_SERIALIZER_H 121 | -------------------------------------------------------------------------------- /include/serialization/json/serializer.inl: -------------------------------------------------------------------------------- 1 | /*! 2 | \file serializer.inl 3 | \brief JSON serializer inline implementation 4 | \author Ivan Shynkarenka 5 | \date 25.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | namespace CppSerialization { 10 | namespace JSON { 11 | 12 | template 13 | inline void Serializer::StartObject() 14 | { 15 | if (!Writer::StartObject()) 16 | throwex SerializationException("Cannot start to serialize JSON object!"); 17 | } 18 | 19 | template 20 | inline void Serializer::EndObject() 21 | { 22 | if (!Writer::EndObject()) 23 | throwex SerializationException("Cannot end to serialize JSON object!"); 24 | } 25 | 26 | template 27 | inline void Serializer::StartArray() 28 | { 29 | if (!Writer::StartArray()) 30 | throwex SerializationException("Cannot start to serialize JSON array!"); 31 | } 32 | 33 | template 34 | inline void Serializer::EndArray() 35 | { 36 | if (!Writer::EndArray()) 37 | throwex SerializationException("Cannot end to serialize JSON array!"); 38 | } 39 | 40 | template 41 | inline void Serializer::Key(const char* key) 42 | { 43 | if (!Writer::Key(key)) 44 | throwex SerializationException("Cannot serialize JSON key!"); 45 | } 46 | 47 | template 48 | inline void Serializer::Key(const char* key, size_t size) 49 | { 50 | if (!Writer::Key(key, size)) 51 | throwex SerializationException("Cannot serialize JSON key!"); 52 | } 53 | 54 | template 55 | inline void Serializer::Key(const std::string& key) 56 | { 57 | if (!Writer::Key(key)) 58 | throwex SerializationException("Cannot serialize JSON key!"); 59 | } 60 | 61 | template 62 | template 63 | inline void Serializer::Key(const char (&key)[N]) 64 | { 65 | if (!Writer::Key(key, N)) 66 | throwex SerializationException("Cannot serialize JSON key!"); 67 | } 68 | 69 | template 70 | inline void Serializer::Value(std::nullptr_t value) 71 | { 72 | if (!Writer::Null()) 73 | throwex SerializationException("Cannot serialize JSON null value!"); 74 | } 75 | 76 | template 77 | inline void Serializer::Value(bool value) 78 | { 79 | if (!Writer::Bool(value)) 80 | throwex SerializationException("Cannot serialize JSON bool value!"); 81 | } 82 | 83 | template 84 | inline void Serializer::Value(int value) 85 | { 86 | if (!Writer::Int(value)) 87 | throwex SerializationException("Cannot serialize JSON integer value!"); 88 | } 89 | 90 | template 91 | inline void Serializer::Value(unsigned value) 92 | { 93 | if (!Writer::UInt(value)) 94 | throwex SerializationException("Cannot serialize JSON unsigned value!"); 95 | } 96 | 97 | template 98 | inline void Serializer::Value(int64_t value) 99 | { 100 | if (!Writer::Int64(value)) 101 | throwex SerializationException("Cannot serialize JSON 64-bit integer value!"); 102 | } 103 | 104 | template 105 | inline void Serializer::Value(uint64_t value) 106 | { 107 | if (!Writer::UInt64(value)) 108 | throwex SerializationException("Cannot serialize JSON 64-bit unsigned value!"); 109 | } 110 | 111 | template 112 | inline void Serializer::Value(double value) 113 | { 114 | if (!Writer::Double(value)) 115 | throwex SerializationException("Cannot serialize JSON double value!"); 116 | } 117 | 118 | template 119 | inline void Serializer::Value(const char* value) 120 | { 121 | if (!Writer::String(value)) 122 | throwex SerializationException("Cannot serialize JSON C-string value!"); 123 | } 124 | 125 | template 126 | inline void Serializer::Value(const char* value, size_t size) 127 | { 128 | if (!Writer::String(value, size)) 129 | throwex SerializationException("Cannot serialize JSON C-string value with a given size!"); 130 | } 131 | 132 | template 133 | inline void Serializer::Value(const std::string& value) 134 | { 135 | if (!Writer::String(value)) 136 | throwex SerializationException("Cannot serialize JSON string value!"); 137 | } 138 | 139 | template 140 | template 141 | inline void Serializer::Value(const char (&value)[N]) 142 | { 143 | if (!Writer::String(value, N)) 144 | throwex SerializationException("Cannot serialize JSON string array value!"); 145 | } 146 | 147 | } // namespace JSON 148 | } // namespace CppSerialization 149 | -------------------------------------------------------------------------------- /proto/fbe/trade.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Automatically generated by the Fast Binary Encoding compiler, do not modify! 3 | // https://github.com/chronoxor/FastBinaryEncoding 4 | // Source: trade.fbe 5 | // FBE version: 1.15.0.0 6 | //------------------------------------------------------------------------------ 7 | 8 | #include "trade.h" 9 | 10 | namespace trade { 11 | 12 | std::ostream& operator<<(std::ostream& stream, OrderSide value) 13 | { 14 | if (value == OrderSide::buy) return stream << "buy"; 15 | if (value == OrderSide::sell) return stream << "sell"; 16 | return stream << ""; 17 | } 18 | 19 | std::ostream& operator<<(std::ostream& stream, OrderType value) 20 | { 21 | if (value == OrderType::market) return stream << "market"; 22 | if (value == OrderType::limit) return stream << "limit"; 23 | if (value == OrderType::stop) return stream << "stop"; 24 | return stream << ""; 25 | } 26 | 27 | Order::Order() 28 | : id((int32_t)0ll) 29 | , symbol() 30 | , side() 31 | , type() 32 | , price((double)0.0) 33 | , volume((double)0.0) 34 | {} 35 | 36 | Order::Order(int32_t arg_id, const std::string& arg_symbol, const ::trade::OrderSide& arg_side, const ::trade::OrderType& arg_type, double arg_price, double arg_volume) 37 | : id(arg_id) 38 | , symbol(arg_symbol) 39 | , side(arg_side) 40 | , type(arg_type) 41 | , price(arg_price) 42 | , volume(arg_volume) 43 | {} 44 | 45 | bool Order::operator==(const Order& other) const noexcept 46 | { 47 | return ( 48 | (id == other.id) 49 | ); 50 | } 51 | 52 | bool Order::operator<(const Order& other) const noexcept 53 | { 54 | if (id < other.id) 55 | return true; 56 | if (other.id < id) 57 | return false; 58 | return false; 59 | } 60 | 61 | void Order::swap(Order& other) noexcept 62 | { 63 | using std::swap; 64 | swap(id, other.id); 65 | swap(symbol, other.symbol); 66 | swap(side, other.side); 67 | swap(type, other.type); 68 | swap(price, other.price); 69 | swap(volume, other.volume); 70 | } 71 | 72 | std::ostream& operator<<(std::ostream& stream, const Order& value) 73 | { 74 | stream << "Order("; 75 | stream << "id="; stream << value.id; 76 | stream << ",symbol="; stream << "\"" << value.symbol << "\""; 77 | stream << ",side="; stream << value.side; 78 | stream << ",type="; stream << value.type; 79 | stream << ",price="; stream << value.price; 80 | stream << ",volume="; stream << value.volume; 81 | stream << ")"; 82 | return stream; 83 | } 84 | 85 | Balance::Balance() 86 | : currency() 87 | , amount((double)0.0) 88 | {} 89 | 90 | Balance::Balance(const std::string& arg_currency, double arg_amount) 91 | : currency(arg_currency) 92 | , amount(arg_amount) 93 | {} 94 | 95 | bool Balance::operator==(const Balance& other) const noexcept 96 | { 97 | return ( 98 | (currency == other.currency) 99 | ); 100 | } 101 | 102 | bool Balance::operator<(const Balance& other) const noexcept 103 | { 104 | if (currency < other.currency) 105 | return true; 106 | if (other.currency < currency) 107 | return false; 108 | return false; 109 | } 110 | 111 | void Balance::swap(Balance& other) noexcept 112 | { 113 | using std::swap; 114 | swap(currency, other.currency); 115 | swap(amount, other.amount); 116 | } 117 | 118 | std::ostream& operator<<(std::ostream& stream, const Balance& value) 119 | { 120 | stream << "Balance("; 121 | stream << "currency="; stream << "\"" << value.currency << "\""; 122 | stream << ",amount="; stream << value.amount; 123 | stream << ")"; 124 | return stream; 125 | } 126 | 127 | Account::Account() 128 | : id((int32_t)0ll) 129 | , name() 130 | , wallet() 131 | , orders() 132 | {} 133 | 134 | Account::Account(int32_t arg_id, const std::string& arg_name, const ::trade::Balance& arg_wallet, const std::vector<::trade::Order>& arg_orders) 135 | : id(arg_id) 136 | , name(arg_name) 137 | , wallet(arg_wallet) 138 | , orders(arg_orders) 139 | {} 140 | 141 | bool Account::operator==(const Account& other) const noexcept 142 | { 143 | return ( 144 | (id == other.id) 145 | ); 146 | } 147 | 148 | bool Account::operator<(const Account& other) const noexcept 149 | { 150 | if (id < other.id) 151 | return true; 152 | if (other.id < id) 153 | return false; 154 | return false; 155 | } 156 | 157 | void Account::swap(Account& other) noexcept 158 | { 159 | using std::swap; 160 | swap(id, other.id); 161 | swap(name, other.name); 162 | swap(wallet, other.wallet); 163 | swap(orders, other.orders); 164 | } 165 | 166 | std::ostream& operator<<(std::ostream& stream, const Account& value) 167 | { 168 | stream << "Account("; 169 | stream << "id="; stream << value.id; 170 | stream << ",name="; stream << "\"" << value.name << "\""; 171 | stream << ",wallet="; stream << value.wallet; 172 | { 173 | bool first = true; 174 | stream << ",orders=[" << value.orders.size() << "]["; 175 | for (const auto& it : value.orders) 176 | { 177 | stream << std::string(first ? "" : ",") << it; 178 | first = false; 179 | } 180 | stream << "]"; 181 | } 182 | stream << ")"; 183 | return stream; 184 | } 185 | 186 | } // namespace trade 187 | -------------------------------------------------------------------------------- /proto/fbe/trade.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Automatically generated by the Fast Binary Encoding compiler, do not modify! 3 | // https://github.com/chronoxor/FastBinaryEncoding 4 | // Source: trade.fbe 5 | // FBE version: 1.15.0.0 6 | //------------------------------------------------------------------------------ 7 | 8 | #pragma once 9 | 10 | #if defined(__clang__) 11 | #pragma clang system_header 12 | #elif defined(__GNUC__) 13 | #pragma GCC system_header 14 | #elif defined(_MSC_VER) 15 | #pragma system_header 16 | #endif 17 | 18 | #include "fbe.h" 19 | 20 | namespace trade { 21 | using namespace FBE; 22 | } // namespace trade 23 | 24 | namespace FBE { 25 | using namespace ::trade; 26 | } // namespace FBE 27 | 28 | namespace trade { 29 | 30 | enum class OrderSide : uint8_t 31 | { 32 | buy, 33 | sell, 34 | }; 35 | 36 | std::ostream& operator<<(std::ostream& stream, OrderSide value); 37 | 38 | #if defined(FMT_VERSION) && (FMT_VERSION >= 90000) 39 | } template <> struct fmt::formatter : ostream_formatter {}; namespace trade { 40 | #endif 41 | 42 | #if defined(LOGGING_PROTOCOL) 43 | CppLogging::Record& operator<<(CppLogging::Record& record, OrderSide value); 44 | #endif 45 | 46 | enum class OrderType : uint8_t 47 | { 48 | market, 49 | limit, 50 | stop, 51 | }; 52 | 53 | std::ostream& operator<<(std::ostream& stream, OrderType value); 54 | 55 | #if defined(FMT_VERSION) && (FMT_VERSION >= 90000) 56 | } template <> struct fmt::formatter : ostream_formatter {}; namespace trade { 57 | #endif 58 | 59 | #if defined(LOGGING_PROTOCOL) 60 | CppLogging::Record& operator<<(CppLogging::Record& record, OrderType value); 61 | #endif 62 | 63 | struct Order 64 | { 65 | int32_t id; 66 | std::string symbol; 67 | ::trade::OrderSide side; 68 | ::trade::OrderType type; 69 | double price; 70 | double volume; 71 | 72 | size_t fbe_type() const noexcept { return 1; } 73 | 74 | Order(); 75 | Order(int32_t arg_id, const std::string& arg_symbol, const ::trade::OrderSide& arg_side, const ::trade::OrderType& arg_type, double arg_price, double arg_volume); 76 | Order(const Order& other) = default; 77 | Order(Order&& other) = default; 78 | ~Order() = default; 79 | 80 | Order& operator=(const Order& other) = default; 81 | Order& operator=(Order&& other) = default; 82 | 83 | bool operator==(const Order& other) const noexcept; 84 | bool operator!=(const Order& other) const noexcept { return !operator==(other); } 85 | bool operator<(const Order& other) const noexcept; 86 | bool operator<=(const Order& other) const noexcept { return operator<(other) || operator==(other); } 87 | bool operator>(const Order& other) const noexcept { return !operator<=(other); } 88 | bool operator>=(const Order& other) const noexcept { return !operator<(other); } 89 | 90 | std::string string() const { std::stringstream ss; ss << *this; return ss.str(); } 91 | 92 | friend std::ostream& operator<<(std::ostream& stream, const Order& value); 93 | 94 | void swap(Order& other) noexcept; 95 | friend void swap(Order& value1, Order& value2) noexcept { value1.swap(value2); } 96 | }; 97 | 98 | } // namespace trade 99 | 100 | #if defined(FMT_VERSION) && (FMT_VERSION >= 90000) 101 | template <> struct fmt::formatter : ostream_formatter {}; 102 | #endif 103 | 104 | template<> 105 | struct std::hash 106 | { 107 | typedef trade::Order argument_type; 108 | typedef size_t result_type; 109 | 110 | result_type operator() (const argument_type& value) const 111 | { 112 | result_type result = 17; 113 | result = result * 31 + std::hash()(value.id); 114 | return result; 115 | } 116 | }; 117 | 118 | namespace trade { 119 | 120 | struct Balance 121 | { 122 | std::string currency; 123 | double amount; 124 | 125 | size_t fbe_type() const noexcept { return 2; } 126 | 127 | Balance(); 128 | Balance(const std::string& arg_currency, double arg_amount); 129 | Balance(const Balance& other) = default; 130 | Balance(Balance&& other) = default; 131 | ~Balance() = default; 132 | 133 | Balance& operator=(const Balance& other) = default; 134 | Balance& operator=(Balance&& other) = default; 135 | 136 | bool operator==(const Balance& other) const noexcept; 137 | bool operator!=(const Balance& other) const noexcept { return !operator==(other); } 138 | bool operator<(const Balance& other) const noexcept; 139 | bool operator<=(const Balance& other) const noexcept { return operator<(other) || operator==(other); } 140 | bool operator>(const Balance& other) const noexcept { return !operator<=(other); } 141 | bool operator>=(const Balance& other) const noexcept { return !operator<(other); } 142 | 143 | std::string string() const { std::stringstream ss; ss << *this; return ss.str(); } 144 | 145 | friend std::ostream& operator<<(std::ostream& stream, const Balance& value); 146 | 147 | void swap(Balance& other) noexcept; 148 | friend void swap(Balance& value1, Balance& value2) noexcept { value1.swap(value2); } 149 | }; 150 | 151 | } // namespace trade 152 | 153 | #if defined(FMT_VERSION) && (FMT_VERSION >= 90000) 154 | template <> struct fmt::formatter : ostream_formatter {}; 155 | #endif 156 | 157 | template<> 158 | struct std::hash 159 | { 160 | typedef trade::Balance argument_type; 161 | typedef size_t result_type; 162 | 163 | result_type operator() (const argument_type& value) const 164 | { 165 | result_type result = 17; 166 | result = result * 31 + std::hash()(value.currency); 167 | return result; 168 | } 169 | }; 170 | 171 | namespace trade { 172 | 173 | struct Account 174 | { 175 | int32_t id; 176 | std::string name; 177 | ::trade::Balance wallet; 178 | std::vector<::trade::Order> orders; 179 | 180 | size_t fbe_type() const noexcept { return 3; } 181 | 182 | Account(); 183 | Account(int32_t arg_id, const std::string& arg_name, const ::trade::Balance& arg_wallet, const std::vector<::trade::Order>& arg_orders); 184 | Account(const Account& other) = default; 185 | Account(Account&& other) = default; 186 | ~Account() = default; 187 | 188 | Account& operator=(const Account& other) = default; 189 | Account& operator=(Account&& other) = default; 190 | 191 | bool operator==(const Account& other) const noexcept; 192 | bool operator!=(const Account& other) const noexcept { return !operator==(other); } 193 | bool operator<(const Account& other) const noexcept; 194 | bool operator<=(const Account& other) const noexcept { return operator<(other) || operator==(other); } 195 | bool operator>(const Account& other) const noexcept { return !operator<=(other); } 196 | bool operator>=(const Account& other) const noexcept { return !operator<(other); } 197 | 198 | std::string string() const { std::stringstream ss; ss << *this; return ss.str(); } 199 | 200 | friend std::ostream& operator<<(std::ostream& stream, const Account& value); 201 | 202 | void swap(Account& other) noexcept; 203 | friend void swap(Account& value1, Account& value2) noexcept { value1.swap(value2); } 204 | }; 205 | 206 | } // namespace trade 207 | 208 | #if defined(FMT_VERSION) && (FMT_VERSION >= 90000) 209 | template <> struct fmt::formatter : ostream_formatter {}; 210 | #endif 211 | 212 | template<> 213 | struct std::hash 214 | { 215 | typedef trade::Account argument_type; 216 | typedef size_t result_type; 217 | 218 | result_type operator() (const argument_type& value) const 219 | { 220 | result_type result = 17; 221 | result = result * 31 + std::hash()(value.id); 222 | return result; 223 | } 224 | }; 225 | 226 | namespace trade { 227 | 228 | } // namespace trade 229 | -------------------------------------------------------------------------------- /include/serialization/json/deserializer.inl: -------------------------------------------------------------------------------- 1 | /*! 2 | \file deserializer.inl 3 | \brief JSON deserializer inline implementation 4 | \author Ivan Shynkarenka 5 | \date 27.02.2017 6 | \copyright MIT License 7 | */ 8 | 9 | namespace CppSerialization { 10 | namespace JSON { 11 | 12 | template 13 | inline bool Deserializer::Find(const JSON& json, const char* key, bool& value) 14 | { 15 | // Try to find a member with the given key 16 | Value::ConstMemberIterator member = json.FindMember(key); 17 | if ((member == json.MemberEnd()) || member->value.IsNull()) 18 | return false; 19 | 20 | // Schema validation 21 | if (!member->value.IsBool()) 22 | throwex SerializationException("Cannot deserialize JSON bool value!"); 23 | 24 | // Save the member value 25 | value = member->value.GetBool(); 26 | return true; 27 | } 28 | 29 | template 30 | inline bool Deserializer::Find(const JSON& json, const char* key, int& value) 31 | { 32 | // Try to find a member with the given key 33 | Value::ConstMemberIterator member = json.FindMember(key); 34 | if ((member == json.MemberEnd()) || member->value.IsNull()) 35 | return false; 36 | 37 | // Schema validation 38 | if (!member->value.IsInt()) 39 | throwex SerializationException("Cannot deserialize JSON integer value!"); 40 | 41 | // Save the member value 42 | value = member->value.GetInt(); 43 | return true; 44 | } 45 | 46 | template 47 | inline bool Deserializer::Find(const JSON& json, const char* key, unsigned& value) 48 | { 49 | // Try to find a member with the given key 50 | Value::ConstMemberIterator member = json.FindMember(key); 51 | if ((member == json.MemberEnd()) || member->value.IsNull()) 52 | return false; 53 | 54 | // Schema validation 55 | if (!member->value.IsUint()) 56 | throwex SerializationException("Cannot deserialize JSON unsigned value!"); 57 | 58 | // Save the member value 59 | value = member->value.GetUint(); 60 | return true; 61 | } 62 | 63 | template 64 | inline bool Deserializer::Find(const JSON& json, const char* key, int64_t& value) 65 | { 66 | // Try to find a member with the given key 67 | Value::ConstMemberIterator member = json.FindMember(key); 68 | if ((member == json.MemberEnd()) || member->value.IsNull()) 69 | return false; 70 | 71 | // Schema validation 72 | if (!member->value.IsInt64()) 73 | throwex SerializationException("Cannot deserialize JSON 64-bit integer value!"); 74 | 75 | // Save the member value 76 | value = member->value.GetInt64(); 77 | return true; 78 | } 79 | 80 | template 81 | inline bool Deserializer::Find(const JSON& json, const char* key, uint64_t& value) 82 | { 83 | // Try to find a member with the given key 84 | Value::ConstMemberIterator member = json.FindMember(key); 85 | if ((member == json.MemberEnd()) || member->value.IsNull()) 86 | return false; 87 | 88 | // Schema validation 89 | if (!member->value.IsUint64()) 90 | throwex SerializationException("Cannot deserialize JSON 64-bit unsigned value!"); 91 | 92 | // Save the member value 93 | value = member->value.GetUint64(); 94 | return true; 95 | } 96 | 97 | template 98 | inline bool Deserializer::Find(const JSON& json, const char* key, double& value) 99 | { 100 | // Try to find a member with the given key 101 | Value::ConstMemberIterator member = json.FindMember(key); 102 | if ((member == json.MemberEnd()) || member->value.IsNull()) 103 | return false; 104 | 105 | // Schema validation 106 | if (!member->value.IsDouble()) 107 | throwex SerializationException("Cannot deserialize JSON double value!"); 108 | 109 | // Save the member value 110 | value = member->value.GetDouble(); 111 | return true; 112 | } 113 | 114 | template 115 | inline bool Deserializer::Find(const JSON& json, const char* key, char* value, size_t size) 116 | { 117 | // Try to find a member with the given key 118 | Value::ConstMemberIterator member = json.FindMember(key); 119 | if ((member == json.MemberEnd()) || member->value.IsNull()) 120 | return false; 121 | 122 | // Schema validation 123 | if (!member->value.IsString()) 124 | throwex SerializationException("Cannot deserialize JSON C-string value with a given size!"); 125 | 126 | // Save the member value 127 | size_t length = std::min((size_t)member->value.GetStringLength(), size); 128 | std::memcpy(value, member->value.GetString(), length); 129 | // Write the end of string character if possible 130 | if (length < size) 131 | value[length] = '\0'; 132 | return true; 133 | } 134 | 135 | template 136 | inline bool Deserializer::Find(const JSON& json, const char* key, std::string& value) 137 | { 138 | // Try to find a member with the given key 139 | Value::ConstMemberIterator member = json.FindMember(key); 140 | if ((member == json.MemberEnd()) || member->value.IsNull()) 141 | return false; 142 | 143 | // Schema validation 144 | if (!member->value.IsString()) 145 | throwex SerializationException("Cannot deserialize JSON string value!"); 146 | 147 | // Save the member value 148 | value.assign(member->value.GetString(), (size_t)member->value.GetStringLength()); 149 | return true; 150 | } 151 | 152 | template 153 | inline bool Deserializer::Find(const JSON& json, const char* key, char (&value)[N]) 154 | { 155 | // Try to find a member with the given key 156 | Value::ConstMemberIterator member = json.FindMember(key); 157 | if ((member == json.MemberEnd()) || member->value.IsNull()) 158 | return false; 159 | 160 | // Schema validation 161 | if (!member->value.IsString()) 162 | throwex SerializationException("Cannot deserialize JSON string array value!"); 163 | 164 | // Save the member value 165 | size_t length = std::min((size_t)member->value.GetStringLength(), N); 166 | std::memcpy(value, member->value.GetString(), length); 167 | // Write the end of string character if possible 168 | if (length < N) 169 | value[length] = '\0'; 170 | return true; 171 | } 172 | 173 | template 174 | inline bool Deserializer::FindArray(const JSON& json, const char* key, const std::function& handler) 175 | { 176 | return FindArray(json, key, [](size_t){}, handler); 177 | } 178 | 179 | 180 | template 181 | inline bool Deserializer::FindArray(const JSON& json, const char* key, const std::function& initialize, const std::function& handler) 182 | { 183 | assert((initialize) && "JSON initialize array handler must be valid!"); 184 | assert((handler) && "JSON array handler must be valid!"); 185 | if (!initialize || !handler) 186 | return false; 187 | 188 | // Try to find a member with the given key 189 | Value::ConstMemberIterator member = json.FindMember(key); 190 | if ((member == json.MemberEnd()) || member->value.IsNull()) 191 | return false; 192 | 193 | // Schema validation 194 | if (!member->value.IsArray()) 195 | throwex SerializationException("Cannot deserialize JSON array!"); 196 | 197 | // Handle array items 198 | initialize(member->value.GetArray().Size()); 199 | for (const auto& item : member->value.GetArray()) 200 | handler(item); 201 | return true; 202 | } 203 | 204 | template 205 | inline bool Deserializer::FindObject(const JSON& json, const char* key, const std::function& handler) 206 | { 207 | assert((handler) && "JSON array handler must be valid!"); 208 | if (!handler) 209 | return false; 210 | 211 | // Try to find a member with the given key 212 | Value::ConstMemberIterator member = json.FindMember(key); 213 | if ((member == json.MemberEnd()) || member->value.IsNull()) 214 | return false; 215 | 216 | // Schema validation 217 | if (!member->value.IsObject()) 218 | throwex SerializationException("Cannot deserialize JSON object!"); 219 | 220 | // Handle object 221 | handler(member->value.GetObj()); 222 | return true; 223 | } 224 | 225 | } // namespace JSON 226 | } // namespace CppSerialization 227 | -------------------------------------------------------------------------------- /proto/fbe/trade_final_models.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Automatically generated by the Fast Binary Encoding compiler, do not modify! 3 | // https://github.com/chronoxor/FastBinaryEncoding 4 | // Source: trade.fbe 5 | // FBE version: 1.15.0.0 6 | //------------------------------------------------------------------------------ 7 | 8 | #pragma once 9 | 10 | #if defined(__clang__) 11 | #pragma clang system_header 12 | #elif defined(__GNUC__) 13 | #pragma GCC system_header 14 | #elif defined(_MSC_VER) 15 | #pragma system_header 16 | #endif 17 | 18 | #include "fbe_final_models.h" 19 | 20 | #include "trade.h" 21 | 22 | namespace FBE { 23 | 24 | // Fast Binary Encoding ::trade::OrderSide final model 25 | template <> 26 | class FinalModel<::trade::OrderSide> : public FinalModelBase<::trade::OrderSide, uint8_t> 27 | { 28 | public: 29 | using FinalModelBase<::trade::OrderSide, uint8_t>::FinalModelBase; 30 | }; 31 | 32 | // Fast Binary Encoding ::trade::OrderType final model 33 | template <> 34 | class FinalModel<::trade::OrderType> : public FinalModelBase<::trade::OrderType, uint8_t> 35 | { 36 | public: 37 | using FinalModelBase<::trade::OrderType, uint8_t>::FinalModelBase; 38 | }; 39 | 40 | // Fast Binary Encoding ::trade::Order final model 41 | template <> 42 | class FinalModel<::trade::Order> 43 | { 44 | public: 45 | FinalModel(FBEBuffer& buffer, size_t offset) noexcept; 46 | 47 | // Get the allocation size 48 | size_t fbe_allocation_size(const ::trade::Order& fbe_value) const noexcept; 49 | // Get the final offset 50 | size_t fbe_offset() const noexcept { return _offset; } 51 | // Set the final offset 52 | size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; } 53 | // Get the final type 54 | static constexpr size_t fbe_type() noexcept { return 1; } 55 | 56 | // Shift the current final offset 57 | void fbe_shift(size_t size) noexcept { _offset += size; } 58 | // Unshift the current final offset 59 | void fbe_unshift(size_t size) noexcept { _offset -= size; } 60 | 61 | // Check if the struct value is valid 62 | size_t verify() const noexcept; 63 | // Check if the struct fields are valid 64 | size_t verify_fields() const noexcept; 65 | 66 | // Get the struct value 67 | size_t get(::trade::Order& fbe_value) const noexcept; 68 | // Get the struct fields values 69 | size_t get_fields(::trade::Order& fbe_value) const noexcept; 70 | 71 | // Set the struct value 72 | size_t set(const ::trade::Order& fbe_value) noexcept; 73 | // Set the struct fields values 74 | size_t set_fields(const ::trade::Order& fbe_value) noexcept; 75 | 76 | private: 77 | FBEBuffer& _buffer; 78 | mutable size_t _offset; 79 | 80 | public: 81 | FinalModel id; 82 | FinalModel symbol; 83 | FinalModel<::trade::OrderSide> side; 84 | FinalModel<::trade::OrderType> type; 85 | FinalModel price; 86 | FinalModel volume; 87 | }; 88 | 89 | namespace trade { 90 | 91 | // Fast Binary Encoding Order final model 92 | class OrderFinalModel : public FBE::Model 93 | { 94 | public: 95 | OrderFinalModel() : _model(this->buffer(), 8) {} 96 | OrderFinalModel(const std::shared_ptr& buffer) : FBE::Model(buffer), _model(this->buffer(), 8) {} 97 | 98 | // Get the model type 99 | static constexpr size_t fbe_type() noexcept { return FinalModel<::trade::Order>::fbe_type(); } 100 | 101 | // Check if the struct value is valid 102 | bool verify(); 103 | 104 | // Serialize the struct value 105 | size_t serialize(const ::trade::Order& value); 106 | // Deserialize the struct value 107 | size_t deserialize(::trade::Order& value) const noexcept; 108 | 109 | // Move to the next struct value 110 | void next(size_t prev) noexcept { _model.fbe_shift(prev); } 111 | 112 | private: 113 | FinalModel<::trade::Order> _model; 114 | }; 115 | 116 | } // namespace trade 117 | 118 | // Fast Binary Encoding ::trade::Balance final model 119 | template <> 120 | class FinalModel<::trade::Balance> 121 | { 122 | public: 123 | FinalModel(FBEBuffer& buffer, size_t offset) noexcept; 124 | 125 | // Get the allocation size 126 | size_t fbe_allocation_size(const ::trade::Balance& fbe_value) const noexcept; 127 | // Get the final offset 128 | size_t fbe_offset() const noexcept { return _offset; } 129 | // Set the final offset 130 | size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; } 131 | // Get the final type 132 | static constexpr size_t fbe_type() noexcept { return 2; } 133 | 134 | // Shift the current final offset 135 | void fbe_shift(size_t size) noexcept { _offset += size; } 136 | // Unshift the current final offset 137 | void fbe_unshift(size_t size) noexcept { _offset -= size; } 138 | 139 | // Check if the struct value is valid 140 | size_t verify() const noexcept; 141 | // Check if the struct fields are valid 142 | size_t verify_fields() const noexcept; 143 | 144 | // Get the struct value 145 | size_t get(::trade::Balance& fbe_value) const noexcept; 146 | // Get the struct fields values 147 | size_t get_fields(::trade::Balance& fbe_value) const noexcept; 148 | 149 | // Set the struct value 150 | size_t set(const ::trade::Balance& fbe_value) noexcept; 151 | // Set the struct fields values 152 | size_t set_fields(const ::trade::Balance& fbe_value) noexcept; 153 | 154 | private: 155 | FBEBuffer& _buffer; 156 | mutable size_t _offset; 157 | 158 | public: 159 | FinalModel currency; 160 | FinalModel amount; 161 | }; 162 | 163 | namespace trade { 164 | 165 | // Fast Binary Encoding Balance final model 166 | class BalanceFinalModel : public FBE::Model 167 | { 168 | public: 169 | BalanceFinalModel() : _model(this->buffer(), 8) {} 170 | BalanceFinalModel(const std::shared_ptr& buffer) : FBE::Model(buffer), _model(this->buffer(), 8) {} 171 | 172 | // Get the model type 173 | static constexpr size_t fbe_type() noexcept { return FinalModel<::trade::Balance>::fbe_type(); } 174 | 175 | // Check if the struct value is valid 176 | bool verify(); 177 | 178 | // Serialize the struct value 179 | size_t serialize(const ::trade::Balance& value); 180 | // Deserialize the struct value 181 | size_t deserialize(::trade::Balance& value) const noexcept; 182 | 183 | // Move to the next struct value 184 | void next(size_t prev) noexcept { _model.fbe_shift(prev); } 185 | 186 | private: 187 | FinalModel<::trade::Balance> _model; 188 | }; 189 | 190 | } // namespace trade 191 | 192 | // Fast Binary Encoding ::trade::Account final model 193 | template <> 194 | class FinalModel<::trade::Account> 195 | { 196 | public: 197 | FinalModel(FBEBuffer& buffer, size_t offset) noexcept; 198 | 199 | // Get the allocation size 200 | size_t fbe_allocation_size(const ::trade::Account& fbe_value) const noexcept; 201 | // Get the final offset 202 | size_t fbe_offset() const noexcept { return _offset; } 203 | // Set the final offset 204 | size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; } 205 | // Get the final type 206 | static constexpr size_t fbe_type() noexcept { return 3; } 207 | 208 | // Shift the current final offset 209 | void fbe_shift(size_t size) noexcept { _offset += size; } 210 | // Unshift the current final offset 211 | void fbe_unshift(size_t size) noexcept { _offset -= size; } 212 | 213 | // Check if the struct value is valid 214 | size_t verify() const noexcept; 215 | // Check if the struct fields are valid 216 | size_t verify_fields() const noexcept; 217 | 218 | // Get the struct value 219 | size_t get(::trade::Account& fbe_value) const noexcept; 220 | // Get the struct fields values 221 | size_t get_fields(::trade::Account& fbe_value) const noexcept; 222 | 223 | // Set the struct value 224 | size_t set(const ::trade::Account& fbe_value) noexcept; 225 | // Set the struct fields values 226 | size_t set_fields(const ::trade::Account& fbe_value) noexcept; 227 | 228 | private: 229 | FBEBuffer& _buffer; 230 | mutable size_t _offset; 231 | 232 | public: 233 | FinalModel id; 234 | FinalModel name; 235 | FinalModel<::trade::Balance> wallet; 236 | FinalModelVector<::trade::Order> orders; 237 | }; 238 | 239 | namespace trade { 240 | 241 | // Fast Binary Encoding Account final model 242 | class AccountFinalModel : public FBE::Model 243 | { 244 | public: 245 | AccountFinalModel() : _model(this->buffer(), 8) {} 246 | AccountFinalModel(const std::shared_ptr& buffer) : FBE::Model(buffer), _model(this->buffer(), 8) {} 247 | 248 | // Get the model type 249 | static constexpr size_t fbe_type() noexcept { return FinalModel<::trade::Account>::fbe_type(); } 250 | 251 | // Check if the struct value is valid 252 | bool verify(); 253 | 254 | // Serialize the struct value 255 | size_t serialize(const ::trade::Account& value); 256 | // Deserialize the struct value 257 | size_t deserialize(::trade::Account& value) const noexcept; 258 | 259 | // Move to the next struct value 260 | void next(size_t prev) noexcept { _model.fbe_shift(prev); } 261 | 262 | private: 263 | FinalModel<::trade::Account> _model; 264 | }; 265 | 266 | } // namespace trade 267 | 268 | } // namespace FBE 269 | -------------------------------------------------------------------------------- /proto/sbe/VarStringEncoding.h: -------------------------------------------------------------------------------- 1 | /* Generated SBE (Simple Binary Encoding) message codec */ 2 | #ifndef _SBE_VARSTRINGENCODING_CXX_H_ 3 | #define _SBE_VARSTRINGENCODING_CXX_H_ 4 | 5 | #if __cplusplus >= 201103L 6 | # define SBE_CONSTEXPR constexpr 7 | # define SBE_NOEXCEPT noexcept 8 | #else 9 | # define SBE_CONSTEXPR 10 | # define SBE_NOEXCEPT 11 | #endif 12 | 13 | #if __cplusplus >= 201703L 14 | # include 15 | # define SBE_NODISCARD [[nodiscard]] 16 | # if !defined(SBE_USE_STRING_VIEW) 17 | # define SBE_USE_STRING_VIEW 1 18 | # endif 19 | #else 20 | # define SBE_NODISCARD 21 | #endif 22 | 23 | #if __cplusplus >= 202002L 24 | # include 25 | # if !defined(SBE_USE_SPAN) 26 | # define SBE_USE_SPAN 1 27 | # endif 28 | #endif 29 | 30 | #if !defined(__STDC_LIMIT_MACROS) 31 | # define __STDC_LIMIT_MACROS 1 32 | #endif 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #if defined(WIN32) || defined(_WIN32) 46 | # define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v) 47 | # define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v) 48 | # define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v) 49 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v) 50 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v) 51 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v) 52 | #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 53 | # define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v) 54 | # define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v) 55 | # define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v) 56 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v) 57 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v) 58 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v) 59 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 60 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v) 61 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v) 62 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v) 63 | # define SBE_BIG_ENDIAN_ENCODE_16(v) (v) 64 | # define SBE_BIG_ENDIAN_ENCODE_32(v) (v) 65 | # define SBE_BIG_ENDIAN_ENCODE_64(v) (v) 66 | #else 67 | # error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file." 68 | #endif 69 | 70 | #if !defined(SBE_BOUNDS_CHECK_EXPECT) 71 | # if defined(SBE_NO_BOUNDS_CHECK) 72 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (false) 73 | # elif defined(_MSC_VER) 74 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (exp) 75 | # else 76 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (__builtin_expect(exp, c)) 77 | # endif 78 | 79 | #endif 80 | 81 | #define SBE_FLOAT_NAN std::numeric_limits::quiet_NaN() 82 | #define SBE_DOUBLE_NAN std::numeric_limits::quiet_NaN() 83 | #define SBE_NULLVALUE_INT8 (std::numeric_limits::min)() 84 | #define SBE_NULLVALUE_INT16 (std::numeric_limits::min)() 85 | #define SBE_NULLVALUE_INT32 (std::numeric_limits::min)() 86 | #define SBE_NULLVALUE_INT64 (std::numeric_limits::min)() 87 | #define SBE_NULLVALUE_UINT8 (std::numeric_limits::max)() 88 | #define SBE_NULLVALUE_UINT16 (std::numeric_limits::max)() 89 | #define SBE_NULLVALUE_UINT32 (std::numeric_limits::max)() 90 | #define SBE_NULLVALUE_UINT64 (std::numeric_limits::max)() 91 | 92 | 93 | namespace sbe { 94 | 95 | class VarStringEncoding 96 | { 97 | private: 98 | char *m_buffer = nullptr; 99 | std::uint64_t m_bufferLength = 0; 100 | std::uint64_t m_offset = 0; 101 | std::uint64_t m_actingVersion = 0; 102 | 103 | public: 104 | enum MetaAttribute 105 | { 106 | EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE 107 | }; 108 | 109 | union sbe_float_as_uint_u 110 | { 111 | float fp_value; 112 | std::uint32_t uint_value; 113 | }; 114 | 115 | union sbe_double_as_uint_u 116 | { 117 | double fp_value; 118 | std::uint64_t uint_value; 119 | }; 120 | 121 | VarStringEncoding() = default; 122 | 123 | VarStringEncoding( 124 | char *buffer, 125 | const std::uint64_t offset, 126 | const std::uint64_t bufferLength, 127 | const std::uint64_t actingVersion) : 128 | m_buffer(buffer), 129 | m_bufferLength(bufferLength), 130 | m_offset(offset), 131 | m_actingVersion(actingVersion) 132 | { 133 | if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + -1) > m_bufferLength), false)) 134 | { 135 | throw std::runtime_error("buffer too short for flyweight [E107]"); 136 | } 137 | } 138 | 139 | VarStringEncoding( 140 | char *buffer, 141 | const std::uint64_t bufferLength, 142 | const std::uint64_t actingVersion) : 143 | VarStringEncoding(buffer, 0, bufferLength, actingVersion) 144 | { 145 | } 146 | 147 | VarStringEncoding( 148 | char *buffer, 149 | const std::uint64_t bufferLength) : 150 | VarStringEncoding(buffer, 0, bufferLength, sbeSchemaVersion()) 151 | { 152 | } 153 | 154 | VarStringEncoding &wrap( 155 | char *buffer, 156 | const std::uint64_t offset, 157 | const std::uint64_t actingVersion, 158 | const std::uint64_t bufferLength) 159 | { 160 | m_buffer = buffer; 161 | m_bufferLength = bufferLength; 162 | m_offset = offset; 163 | m_actingVersion = actingVersion; 164 | 165 | if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + -1) > m_bufferLength), false)) 166 | { 167 | throw std::runtime_error("buffer too short for flyweight [E107]"); 168 | } 169 | 170 | return *this; 171 | } 172 | 173 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT 174 | { 175 | return -1; 176 | } 177 | 178 | SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT 179 | { 180 | return m_offset; 181 | } 182 | 183 | SBE_NODISCARD const char *buffer() const SBE_NOEXCEPT 184 | { 185 | return m_buffer; 186 | } 187 | 188 | SBE_NODISCARD char *buffer() SBE_NOEXCEPT 189 | { 190 | return m_buffer; 191 | } 192 | 193 | SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT 194 | { 195 | return m_bufferLength; 196 | } 197 | 198 | SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT 199 | { 200 | return m_actingVersion; 201 | } 202 | 203 | SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT 204 | { 205 | return static_cast(1); 206 | } 207 | 208 | SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT 209 | { 210 | return static_cast(1); 211 | } 212 | 213 | SBE_NODISCARD static const char *lengthMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT 214 | { 215 | switch (metaAttribute) 216 | { 217 | case MetaAttribute::PRESENCE: return "required"; 218 | default: return ""; 219 | } 220 | } 221 | 222 | static SBE_CONSTEXPR std::uint16_t lengthId() SBE_NOEXCEPT 223 | { 224 | return -1; 225 | } 226 | 227 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t lengthSinceVersion() SBE_NOEXCEPT 228 | { 229 | return 0; 230 | } 231 | 232 | SBE_NODISCARD bool lengthInActingVersion() SBE_NOEXCEPT 233 | { 234 | return true; 235 | } 236 | 237 | SBE_NODISCARD static SBE_CONSTEXPR std::size_t lengthEncodingOffset() SBE_NOEXCEPT 238 | { 239 | return 0; 240 | } 241 | 242 | static SBE_CONSTEXPR std::uint32_t lengthNullValue() SBE_NOEXCEPT 243 | { 244 | return SBE_NULLVALUE_UINT32; 245 | } 246 | 247 | static SBE_CONSTEXPR std::uint32_t lengthMinValue() SBE_NOEXCEPT 248 | { 249 | return UINT32_C(0x0); 250 | } 251 | 252 | static SBE_CONSTEXPR std::uint32_t lengthMaxValue() SBE_NOEXCEPT 253 | { 254 | return UINT32_C(0x40000000); 255 | } 256 | 257 | static SBE_CONSTEXPR std::size_t lengthEncodingLength() SBE_NOEXCEPT 258 | { 259 | return 4; 260 | } 261 | 262 | SBE_NODISCARD std::uint32_t length() const SBE_NOEXCEPT 263 | { 264 | std::uint32_t val; 265 | std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::uint32_t)); 266 | return SBE_LITTLE_ENDIAN_ENCODE_32(val); 267 | } 268 | 269 | VarStringEncoding &length(const std::uint32_t value) SBE_NOEXCEPT 270 | { 271 | std::uint32_t val = SBE_LITTLE_ENDIAN_ENCODE_32(value); 272 | std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::uint32_t)); 273 | return *this; 274 | } 275 | 276 | SBE_NODISCARD static const char *varDataMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT 277 | { 278 | switch (metaAttribute) 279 | { 280 | case MetaAttribute::PRESENCE: return "required"; 281 | default: return ""; 282 | } 283 | } 284 | 285 | static SBE_CONSTEXPR std::uint16_t varDataId() SBE_NOEXCEPT 286 | { 287 | return -1; 288 | } 289 | 290 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t varDataSinceVersion() SBE_NOEXCEPT 291 | { 292 | return 0; 293 | } 294 | 295 | SBE_NODISCARD bool varDataInActingVersion() SBE_NOEXCEPT 296 | { 297 | return true; 298 | } 299 | 300 | SBE_NODISCARD static SBE_CONSTEXPR std::size_t varDataEncodingOffset() SBE_NOEXCEPT 301 | { 302 | return 4; 303 | } 304 | 305 | static SBE_CONSTEXPR std::uint8_t varDataNullValue() SBE_NOEXCEPT 306 | { 307 | return SBE_NULLVALUE_UINT8; 308 | } 309 | 310 | static SBE_CONSTEXPR std::uint8_t varDataMinValue() SBE_NOEXCEPT 311 | { 312 | return static_cast(0); 313 | } 314 | 315 | static SBE_CONSTEXPR std::uint8_t varDataMaxValue() SBE_NOEXCEPT 316 | { 317 | return static_cast(254); 318 | } 319 | 320 | static SBE_CONSTEXPR std::size_t varDataEncodingLength() SBE_NOEXCEPT 321 | { 322 | return -1; 323 | } 324 | 325 | template 326 | friend std::basic_ostream & operator << ( 327 | std::basic_ostream &builder, VarStringEncoding &writer) 328 | { 329 | builder << '{'; 330 | builder << R"("length": )"; 331 | builder << +writer.length(); 332 | 333 | builder << '}'; 334 | 335 | return builder; 336 | } 337 | 338 | }; 339 | 340 | } 341 | 342 | #endif 343 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | 3 | # Global properties 4 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 5 | 6 | # Project name 7 | project(cppserialization) 8 | 9 | # Doxygen 10 | find_package(Doxygen) 11 | if(DOXYGEN_FOUND) 12 | set(DOXYGEN "doxygen") 13 | if(NOT TARGET ${DOXYGEN}) 14 | add_custom_command(OUTPUT "Doxyfile" COMMAND ${DOXYGEN_EXECUTABLE} "Doxyfile" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/documents") 15 | add_custom_target(${DOXYGEN} DEPENDS "Doxyfile") 16 | set_target_properties(${DOXYGEN} PROPERTIES FOLDER "doxygen") 17 | endif() 18 | endif() 19 | 20 | # CMake module path 21 | set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 22 | 23 | # Compiler features 24 | include(SetCompilerFeatures) 25 | include(SetCompilerWarnings) 26 | include(SetPlatformFeatures) 27 | include(SystemInformation) 28 | 29 | # External packages 30 | find_package(Java REQUIRED) 31 | 32 | # Modules 33 | add_subdirectory("modules") 34 | 35 | # Link libraries 36 | list(APPEND LINKLIBS capnp) 37 | list(APPEND LINKLIBS libprotobuf) 38 | list(APPEND LINKLIBS cppcommon) 39 | 40 | # System directories 41 | include_directories(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/modules") 42 | include_directories(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/modules/protobuf/third_party/abseil-cpp") 43 | 44 | # Library 45 | file(GLOB_RECURSE LIB_HEADER_FILES "include/*.h" "source/*.h") 46 | file(GLOB_RECURSE LIB_INLINE_FILES "include/*.inl" "source/*.inl") 47 | file(GLOB_RECURSE LIB_SOURCE_FILES "include/*.cpp" "source/*.cpp") 48 | add_library(cppserialization ${LIB_HEADER_FILES} ${LIB_INLINE_FILES} ${LIB_SOURCE_FILES}) 49 | set_target_properties(cppserialization PROPERTIES COMPILE_FLAGS "${PEDANTIC_COMPILE_FLAGS}" FOLDER "libraries") 50 | target_include_directories(cppserialization PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/proto" PUBLIC ${capnproto} PUBLIC ${flatbuf} PUBLIC ${protobuf} PUBLIC ${rapidjson} PUBLIC ${zpp_bits}) 51 | target_link_libraries(cppserialization ${LINKLIBS}) 52 | list(APPEND INSTALL_TARGETS cppserialization) 53 | list(APPEND LINKLIBS cppserialization) 54 | 55 | # Additional module components: benchmarks, examples, plugins, tests, tools and install 56 | if(NOT CPPSERIALIZATION_MODULE) 57 | 58 | # Proto Flatbuffers models 59 | file(GLOB FLATBUFFERS_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/proto" "proto/*.fbs") 60 | foreach(FLATBUFFERS_FILE ${FLATBUFFERS_FILES}) 61 | string(REGEX REPLACE "(.*)\\.fbs" "\\1_generated.h" FLATBUFFERS_HEADER ${FLATBUFFERS_FILE}) 62 | set(FLATBUFFERS_INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto") 63 | set(FLATBUFFERS_INPUT_FILE "${FLATBUFFERS_INPUT_DIR}/${FLATBUFFERS_FILE}") 64 | set(FLATBUFFERS_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto/flatbuffers") 65 | set(FLATBUFFERS_OUTPUT_FILE "${FLATBUFFERS_OUTPUT_DIR}/${FLATBUFFERS_HEADER}") 66 | set(FLATBUFFERS_TARGET "${FLATBUFFERS_FILE}_TARGET") 67 | add_custom_command( 68 | OUTPUT ${FLATBUFFERS_OUTPUT_FILE} DEPENDS ${FLATBUFFERS_INPUT_FILE} 69 | COMMAND $ --cpp --scoped-enums -o ${FLATBUFFERS_OUTPUT_DIR} ${FLATBUFFERS_INPUT_FILE} COMMENT "Generating ${FLATBUFFERS_OUTPUT_FILE}..." VERBATIM 70 | ) 71 | add_custom_target(${FLATBUFFERS_TARGET} DEPENDS ${FLATBUFFERS_OUTPUT_FILE}) 72 | set_target_properties(${FLATBUFFERS_TARGET} PROPERTIES FOLDER "proto") 73 | list(APPEND PROTO_DEPENDENCIES ${FLATBUFFERS_TARGET}) 74 | list(APPEND PROTO_FILES ${FLATBUFFERS_OUTPUT_FILE}) 75 | endforeach() 76 | 77 | # Proto Protobuf models 78 | file(GLOB PROTOBUF_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/proto" "proto/*.proto") 79 | foreach(PROTOBUF_FILE ${PROTOBUF_FILES}) 80 | string(REGEX REPLACE "(.*)\\.proto" "\\1.pb.cc" PROTOBUF_SOURCE ${PROTOBUF_FILE}) 81 | set(PROTOBUF_INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto") 82 | set(PROTOBUF_INPUT_FILE "${PROTOBUF_INPUT_DIR}/${PROTOBUF_FILE}") 83 | set(PROTOBUF_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto/protobuf") 84 | set(PROTOBUF_OUTPUT_FILE "${PROTOBUF_OUTPUT_DIR}/${PROTOBUF_SOURCE}") 85 | set(PROTOBUF_TARGET "${PROTOBUF_FILE}_TARGET") 86 | add_custom_command( 87 | OUTPUT ${PROTOBUF_OUTPUT_FILE} DEPENDS ${PROTOBUF_INPUT_FILE} 88 | COMMAND $ --proto_path=${PROTOBUF_INPUT_DIR} --cpp_out=${PROTOBUF_OUTPUT_DIR} ${PROTOBUF_INPUT_FILE} COMMENT "Generating ${PROTOBUF_OUTPUT_FILE}..." VERBATIM 89 | ) 90 | add_custom_target(${PROTOBUF_TARGET} DEPENDS ${PROTOBUF_OUTPUT_FILE}) 91 | set_target_properties(${PROTOBUF_TARGET} PROPERTIES FOLDER "proto") 92 | list(APPEND PROTO_DEPENDENCIES ${PROTOBUF_TARGET}) 93 | list(APPEND PROTO_FILES ${PROTOBUF_OUTPUT_FILE}) 94 | endforeach() 95 | 96 | # Proto Cap'n'Proto models 97 | file(GLOB CAPNP_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/proto" "proto/*.capnp") 98 | foreach(CAPNP_FILE ${CAPNP_FILES}) 99 | string(REGEX REPLACE "(.*)\\.capnp" "\\1.capnp.c++" CAPNP_SOURCE ${CAPNP_FILE}) 100 | set(CAPNP_INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto") 101 | set(CAPNP_INPUT_FILE "${CAPNP_INPUT_DIR}/${CAPNP_FILE}") 102 | set(CAPNPC_SRC_PREFIX "${CAPNP_INPUT_DIR}") 103 | set(CAPNPC_OUTPUT_DIR "${CAPNP_INPUT_DIR}/capnproto") 104 | if(MSYS OR DEFINED ENV{MSYSTEM}) 105 | set(CAPNP_SOURCES "${CAPNPC_OUTPUT_DIR}/${CAPNP_SOURCE}") 106 | else() 107 | capnp_generate_cpp(CAPNP_HEADERS CAPNP_SOURCES ${CAPNP_INPUT_FILE}) 108 | endif() 109 | list(APPEND PROTO_FILES ${CAPNP_HEADERS} ${CAPNP_SOURCES}) 110 | endforeach() 111 | 112 | # Proto SBE models 113 | file(GLOB SBE_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/proto" "proto/*.sbe.xml") 114 | foreach(SBE_FILE ${SBE_FILES}) 115 | string(REGEX REPLACE "(.*)\\.sbe.xml" "\\1.sbe.sbeir" SBE_HEADER ${SBE_FILE}) 116 | set(SBE_INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto") 117 | set(SBE_INPUT_FILE "${SBE_INPUT_DIR}/${SBE_FILE}") 118 | set(SBE_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto") 119 | set(SBE_OUTPUT_FILE "${SBE_OUTPUT_DIR}/${SBE_HEADER}") 120 | set(SBE_TARGET "${SBE_FILE}_TARGET") 121 | add_custom_command( 122 | OUTPUT ${SBE_OUTPUT_FILE} DEPENDS ${SBE_INPUT_FILE} 123 | COMMAND ${Java_JAVA_EXECUTABLE} -Dsbe.generate.ir=true -Dsbe.target.language=Cpp -Dsbe.target.namespace=sbe -Dsbe.output.dir=${SBE_OUTPUT_DIR} -Dsbe.errorLog=yes --add-opens java.base/jdk.internal.misc=ALL-UNNAMED -jar ${CMAKE_CURRENT_SOURCE_DIR}/modules/sbe/sbe-all-1.35.6.jar ${SBE_INPUT_FILE} COMMENT "Generating ${SBE_OUTPUT_FILE}..." VERBATIM 124 | ) 125 | add_custom_target(${SBE_TARGET} DEPENDS ${SBE_OUTPUT_FILE}) 126 | set_target_properties(${SBE_TARGET} PROPERTIES FOLDER "proto") 127 | list(APPEND PROTO_DEPENDENCIES ${SBE_TARGET}) 128 | list(APPEND PROTO_FILES ${SBE_OUTPUT_FILE}) 129 | endforeach() 130 | 131 | # Proto FBE models 132 | file(GLOB FBE_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/proto/fbe" "proto/fbe/*.cpp") 133 | foreach(FBE_FILE ${FBE_FILES}) 134 | set(FBE_PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto/fbe") 135 | set(FBE_SOURCE_FILE "${FBE_PROTO_DIR}/${FBE_FILE}") 136 | list(APPEND PROTO_FILES ${FBE_SOURCE_FILE}) 137 | endforeach() 138 | 139 | # Proto library 140 | add_library(proto ${PROTO_FILES}) 141 | add_dependencies(proto ${PROTO_DEPENDENCIES}) 142 | if(MSVC) 143 | # C4125: decimal digit terminates octal escape sequence 144 | # C4127: conditional expression is constant 145 | # C4244: 'conversion' conversion from 'type1' to 'type2', possible loss of data 146 | # C4245: 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch 147 | # C4267: 'var' : conversion from 'size_t' to 'type', possible loss of data 148 | # C4251: 'type' : class 'type1' needs to have dll-interface to be used by clients of class 'type2' 149 | # C5054: operator 'operator-name': deprecated between enumerations of different types 150 | set_target_properties(proto PROPERTIES COMPILE_FLAGS "${PEDANTIC_COMPILE_FLAGS} /wd4125 /wd4127 /wd4244 /wd4245 /wd4251 /wd4267 /wd5054" FOLDER "proto") 151 | else() 152 | set_target_properties(proto PROPERTIES COMPILE_FLAGS "${PEDANTIC_COMPILE_FLAGS} -Wno-pedantic -Wno-array-bounds -Wno-shadow" FOLDER "proto") 153 | endif() 154 | target_link_libraries(proto ${LINKLIBS}) 155 | list(APPEND LINKLIBS proto) 156 | 157 | # Examples 158 | file(GLOB EXAMPLE_HEADER_FILES "examples/*.h") 159 | file(GLOB EXAMPLE_INLINE_FILES "examples/*.inl") 160 | file(GLOB EXAMPLE_SOURCE_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/examples" "examples/*.cpp") 161 | foreach(EXAMPLE_SOURCE_FILE ${EXAMPLE_SOURCE_FILES}) 162 | string(REGEX REPLACE "(.*)\\.cpp" "\\1" EXAMPLE_NAME ${EXAMPLE_SOURCE_FILE}) 163 | set(EXAMPLE_TARGET "cppserialization-example-${EXAMPLE_NAME}") 164 | add_executable(${EXAMPLE_TARGET} ${EXAMPLE_HEADER_FILES} ${EXAMPLE_INLINE_FILES} "examples/${EXAMPLE_SOURCE_FILE}") 165 | set_target_properties(${EXAMPLE_TARGET} PROPERTIES COMPILE_FLAGS "${PEDANTIC_COMPILE_FLAGS}" FOLDER "examples") 166 | target_link_libraries(${EXAMPLE_TARGET} ${LINKLIBS}) 167 | list(APPEND INSTALL_TARGETS ${EXAMPLE_TARGET}) 168 | list(APPEND INSTALL_TARGETS_PDB ${EXAMPLE_TARGET}) 169 | endforeach() 170 | 171 | # Benchmarks 172 | file(GLOB BENCHMARK_HEADER_FILES "performance/*.h") 173 | file(GLOB BENCHMARK_INLINE_FILES "performance/*.inl") 174 | file(GLOB BENCHMARK_SOURCE_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/performance" "performance/*.cpp") 175 | foreach(BENCHMARK_SOURCE_FILE ${BENCHMARK_SOURCE_FILES}) 176 | string(REGEX REPLACE "(.*)\\.cpp" "\\1" BENCHMARK_NAME ${BENCHMARK_SOURCE_FILE}) 177 | set(BENCHMARK_TARGET "cppserialization-performance-${BENCHMARK_NAME}") 178 | add_executable(${BENCHMARK_TARGET} ${BENCHMARK_HEADER_FILES} ${BENCHMARK_INLINE_FILES} "performance/${BENCHMARK_SOURCE_FILE}") 179 | set_target_properties(${BENCHMARK_TARGET} PROPERTIES COMPILE_FLAGS "${PEDANTIC_COMPILE_FLAGS}" FOLDER "performance") 180 | target_link_libraries(${BENCHMARK_TARGET} ${LINKLIBS} cppbenchmark) 181 | list(APPEND INSTALL_TARGETS ${BENCHMARK_TARGET}) 182 | list(APPEND INSTALL_TARGETS_PDB ${BENCHMARK_TARGET}) 183 | endforeach() 184 | 185 | # Tests 186 | file(GLOB TESTS_HEADER_FILES "tests/*.h") 187 | file(GLOB TESTS_INLINE_FILES "tests/*.inl") 188 | file(GLOB TESTS_SOURCE_FILES "tests/*.cpp") 189 | add_executable(cppserialization-tests ${TESTS_HEADER_FILES} ${TESTS_INLINE_FILES} ${TESTS_SOURCE_FILES}) 190 | set_target_properties(cppserialization-tests PROPERTIES COMPILE_FLAGS "${PEDANTIC_COMPILE_FLAGS}" FOLDER "tests") 191 | target_include_directories(cppserialization-tests PRIVATE Catch2) 192 | target_link_libraries(cppserialization-tests ${LINKLIBS} Catch2) 193 | list(APPEND INSTALL_TARGETS cppserialization-tests) 194 | list(APPEND INSTALL_TARGETS_PDB cppserialization-tests) 195 | 196 | # CTest 197 | enable_testing() 198 | add_test(cppserialization-tests cppserialization-tests --durations yes --order lex) 199 | 200 | # Install 201 | install(TARGETS ${INSTALL_TARGETS} 202 | RUNTIME DESTINATION "${PROJECT_SOURCE_DIR}/bin" 203 | LIBRARY DESTINATION "${PROJECT_SOURCE_DIR}/bin" 204 | ARCHIVE DESTINATION "${PROJECT_SOURCE_DIR}/bin") 205 | 206 | # Install *.pdb files 207 | if(MSVC) 208 | foreach(INSTALL_TARGET_PDB ${INSTALL_TARGETS_PDB}) 209 | install(FILES $ DESTINATION "${PROJECT_SOURCE_DIR}/bin") 210 | endforeach() 211 | endif() 212 | 213 | endif() 214 | -------------------------------------------------------------------------------- /proto/sbe/GroupSizeEncoding.h: -------------------------------------------------------------------------------- 1 | /* Generated SBE (Simple Binary Encoding) message codec */ 2 | #ifndef _SBE_GROUPSIZEENCODING_CXX_H_ 3 | #define _SBE_GROUPSIZEENCODING_CXX_H_ 4 | 5 | #if __cplusplus >= 201103L 6 | # define SBE_CONSTEXPR constexpr 7 | # define SBE_NOEXCEPT noexcept 8 | #else 9 | # define SBE_CONSTEXPR 10 | # define SBE_NOEXCEPT 11 | #endif 12 | 13 | #if __cplusplus >= 201703L 14 | # include 15 | # define SBE_NODISCARD [[nodiscard]] 16 | # if !defined(SBE_USE_STRING_VIEW) 17 | # define SBE_USE_STRING_VIEW 1 18 | # endif 19 | #else 20 | # define SBE_NODISCARD 21 | #endif 22 | 23 | #if __cplusplus >= 202002L 24 | # include 25 | # if !defined(SBE_USE_SPAN) 26 | # define SBE_USE_SPAN 1 27 | # endif 28 | #endif 29 | 30 | #if !defined(__STDC_LIMIT_MACROS) 31 | # define __STDC_LIMIT_MACROS 1 32 | #endif 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #if defined(WIN32) || defined(_WIN32) 46 | # define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v) 47 | # define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v) 48 | # define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v) 49 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v) 50 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v) 51 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v) 52 | #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 53 | # define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v) 54 | # define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v) 55 | # define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v) 56 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v) 57 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v) 58 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v) 59 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 60 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v) 61 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v) 62 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v) 63 | # define SBE_BIG_ENDIAN_ENCODE_16(v) (v) 64 | # define SBE_BIG_ENDIAN_ENCODE_32(v) (v) 65 | # define SBE_BIG_ENDIAN_ENCODE_64(v) (v) 66 | #else 67 | # error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file." 68 | #endif 69 | 70 | #if !defined(SBE_BOUNDS_CHECK_EXPECT) 71 | # if defined(SBE_NO_BOUNDS_CHECK) 72 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (false) 73 | # elif defined(_MSC_VER) 74 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (exp) 75 | # else 76 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (__builtin_expect(exp, c)) 77 | # endif 78 | 79 | #endif 80 | 81 | #define SBE_FLOAT_NAN std::numeric_limits::quiet_NaN() 82 | #define SBE_DOUBLE_NAN std::numeric_limits::quiet_NaN() 83 | #define SBE_NULLVALUE_INT8 (std::numeric_limits::min)() 84 | #define SBE_NULLVALUE_INT16 (std::numeric_limits::min)() 85 | #define SBE_NULLVALUE_INT32 (std::numeric_limits::min)() 86 | #define SBE_NULLVALUE_INT64 (std::numeric_limits::min)() 87 | #define SBE_NULLVALUE_UINT8 (std::numeric_limits::max)() 88 | #define SBE_NULLVALUE_UINT16 (std::numeric_limits::max)() 89 | #define SBE_NULLVALUE_UINT32 (std::numeric_limits::max)() 90 | #define SBE_NULLVALUE_UINT64 (std::numeric_limits::max)() 91 | 92 | 93 | namespace sbe { 94 | 95 | class GroupSizeEncoding 96 | { 97 | private: 98 | char *m_buffer = nullptr; 99 | std::uint64_t m_bufferLength = 0; 100 | std::uint64_t m_offset = 0; 101 | std::uint64_t m_actingVersion = 0; 102 | 103 | public: 104 | enum MetaAttribute 105 | { 106 | EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE 107 | }; 108 | 109 | union sbe_float_as_uint_u 110 | { 111 | float fp_value; 112 | std::uint32_t uint_value; 113 | }; 114 | 115 | union sbe_double_as_uint_u 116 | { 117 | double fp_value; 118 | std::uint64_t uint_value; 119 | }; 120 | 121 | GroupSizeEncoding() = default; 122 | 123 | GroupSizeEncoding( 124 | char *buffer, 125 | const std::uint64_t offset, 126 | const std::uint64_t bufferLength, 127 | const std::uint64_t actingVersion) : 128 | m_buffer(buffer), 129 | m_bufferLength(bufferLength), 130 | m_offset(offset), 131 | m_actingVersion(actingVersion) 132 | { 133 | if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 4) > m_bufferLength), false)) 134 | { 135 | throw std::runtime_error("buffer too short for flyweight [E107]"); 136 | } 137 | } 138 | 139 | GroupSizeEncoding( 140 | char *buffer, 141 | const std::uint64_t bufferLength, 142 | const std::uint64_t actingVersion) : 143 | GroupSizeEncoding(buffer, 0, bufferLength, actingVersion) 144 | { 145 | } 146 | 147 | GroupSizeEncoding( 148 | char *buffer, 149 | const std::uint64_t bufferLength) : 150 | GroupSizeEncoding(buffer, 0, bufferLength, sbeSchemaVersion()) 151 | { 152 | } 153 | 154 | GroupSizeEncoding &wrap( 155 | char *buffer, 156 | const std::uint64_t offset, 157 | const std::uint64_t actingVersion, 158 | const std::uint64_t bufferLength) 159 | { 160 | m_buffer = buffer; 161 | m_bufferLength = bufferLength; 162 | m_offset = offset; 163 | m_actingVersion = actingVersion; 164 | 165 | if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 4) > m_bufferLength), false)) 166 | { 167 | throw std::runtime_error("buffer too short for flyweight [E107]"); 168 | } 169 | 170 | return *this; 171 | } 172 | 173 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT 174 | { 175 | return 4; 176 | } 177 | 178 | SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT 179 | { 180 | return m_offset; 181 | } 182 | 183 | SBE_NODISCARD const char *buffer() const SBE_NOEXCEPT 184 | { 185 | return m_buffer; 186 | } 187 | 188 | SBE_NODISCARD char *buffer() SBE_NOEXCEPT 189 | { 190 | return m_buffer; 191 | } 192 | 193 | SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT 194 | { 195 | return m_bufferLength; 196 | } 197 | 198 | SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT 199 | { 200 | return m_actingVersion; 201 | } 202 | 203 | SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT 204 | { 205 | return static_cast(1); 206 | } 207 | 208 | SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT 209 | { 210 | return static_cast(1); 211 | } 212 | 213 | SBE_NODISCARD static const char *blockLengthMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT 214 | { 215 | switch (metaAttribute) 216 | { 217 | case MetaAttribute::PRESENCE: return "required"; 218 | default: return ""; 219 | } 220 | } 221 | 222 | static SBE_CONSTEXPR std::uint16_t blockLengthId() SBE_NOEXCEPT 223 | { 224 | return -1; 225 | } 226 | 227 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t blockLengthSinceVersion() SBE_NOEXCEPT 228 | { 229 | return 0; 230 | } 231 | 232 | SBE_NODISCARD bool blockLengthInActingVersion() SBE_NOEXCEPT 233 | { 234 | return true; 235 | } 236 | 237 | SBE_NODISCARD static SBE_CONSTEXPR std::size_t blockLengthEncodingOffset() SBE_NOEXCEPT 238 | { 239 | return 0; 240 | } 241 | 242 | static SBE_CONSTEXPR std::uint16_t blockLengthNullValue() SBE_NOEXCEPT 243 | { 244 | return SBE_NULLVALUE_UINT16; 245 | } 246 | 247 | static SBE_CONSTEXPR std::uint16_t blockLengthMinValue() SBE_NOEXCEPT 248 | { 249 | return static_cast(0); 250 | } 251 | 252 | static SBE_CONSTEXPR std::uint16_t blockLengthMaxValue() SBE_NOEXCEPT 253 | { 254 | return static_cast(65534); 255 | } 256 | 257 | static SBE_CONSTEXPR std::size_t blockLengthEncodingLength() SBE_NOEXCEPT 258 | { 259 | return 2; 260 | } 261 | 262 | SBE_NODISCARD std::uint16_t blockLength() const SBE_NOEXCEPT 263 | { 264 | std::uint16_t val; 265 | std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::uint16_t)); 266 | return SBE_LITTLE_ENDIAN_ENCODE_16(val); 267 | } 268 | 269 | GroupSizeEncoding &blockLength(const std::uint16_t value) SBE_NOEXCEPT 270 | { 271 | std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value); 272 | std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::uint16_t)); 273 | return *this; 274 | } 275 | 276 | SBE_NODISCARD static const char *numInGroupMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT 277 | { 278 | switch (metaAttribute) 279 | { 280 | case MetaAttribute::PRESENCE: return "required"; 281 | default: return ""; 282 | } 283 | } 284 | 285 | static SBE_CONSTEXPR std::uint16_t numInGroupId() SBE_NOEXCEPT 286 | { 287 | return -1; 288 | } 289 | 290 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t numInGroupSinceVersion() SBE_NOEXCEPT 291 | { 292 | return 0; 293 | } 294 | 295 | SBE_NODISCARD bool numInGroupInActingVersion() SBE_NOEXCEPT 296 | { 297 | return true; 298 | } 299 | 300 | SBE_NODISCARD static SBE_CONSTEXPR std::size_t numInGroupEncodingOffset() SBE_NOEXCEPT 301 | { 302 | return 2; 303 | } 304 | 305 | static SBE_CONSTEXPR std::uint16_t numInGroupNullValue() SBE_NOEXCEPT 306 | { 307 | return SBE_NULLVALUE_UINT16; 308 | } 309 | 310 | static SBE_CONSTEXPR std::uint16_t numInGroupMinValue() SBE_NOEXCEPT 311 | { 312 | return static_cast(0); 313 | } 314 | 315 | static SBE_CONSTEXPR std::uint16_t numInGroupMaxValue() SBE_NOEXCEPT 316 | { 317 | return static_cast(65534); 318 | } 319 | 320 | static SBE_CONSTEXPR std::size_t numInGroupEncodingLength() SBE_NOEXCEPT 321 | { 322 | return 2; 323 | } 324 | 325 | SBE_NODISCARD std::uint16_t numInGroup() const SBE_NOEXCEPT 326 | { 327 | std::uint16_t val; 328 | std::memcpy(&val, m_buffer + m_offset + 2, sizeof(std::uint16_t)); 329 | return SBE_LITTLE_ENDIAN_ENCODE_16(val); 330 | } 331 | 332 | GroupSizeEncoding &numInGroup(const std::uint16_t value) SBE_NOEXCEPT 333 | { 334 | std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value); 335 | std::memcpy(m_buffer + m_offset + 2, &val, sizeof(std::uint16_t)); 336 | return *this; 337 | } 338 | 339 | template 340 | friend std::basic_ostream & operator << ( 341 | std::basic_ostream &builder, GroupSizeEncoding &writer) 342 | { 343 | builder << '{'; 344 | builder << R"("blockLength": )"; 345 | builder << +writer.blockLength(); 346 | 347 | builder << ", "; 348 | builder << R"("numInGroup": )"; 349 | builder << +writer.numInGroup(); 350 | 351 | builder << '}'; 352 | 353 | return builder; 354 | } 355 | 356 | }; 357 | 358 | } 359 | 360 | #endif 361 | -------------------------------------------------------------------------------- /proto/fbe/trade_models.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Automatically generated by the Fast Binary Encoding compiler, do not modify! 3 | // https://github.com/chronoxor/FastBinaryEncoding 4 | // Source: trade.fbe 5 | // FBE version: 1.15.0.0 6 | //------------------------------------------------------------------------------ 7 | 8 | #pragma once 9 | 10 | #if defined(__clang__) 11 | #pragma clang system_header 12 | #elif defined(__GNUC__) 13 | #pragma GCC system_header 14 | #elif defined(_MSC_VER) 15 | #pragma system_header 16 | #endif 17 | 18 | #include "fbe_models.h" 19 | 20 | #include "trade.h" 21 | 22 | namespace FBE { 23 | 24 | // Fast Binary Encoding ::trade::OrderSide field model 25 | template <> 26 | class FieldModel<::trade::OrderSide> : public FieldModelBase<::trade::OrderSide, uint8_t> 27 | { 28 | public: 29 | using FieldModelBase<::trade::OrderSide, uint8_t>::FieldModelBase; 30 | }; 31 | 32 | // Fast Binary Encoding ::trade::OrderType field model 33 | template <> 34 | class FieldModel<::trade::OrderType> : public FieldModelBase<::trade::OrderType, uint8_t> 35 | { 36 | public: 37 | using FieldModelBase<::trade::OrderType, uint8_t>::FieldModelBase; 38 | }; 39 | 40 | // Fast Binary Encoding ::trade::Order field model 41 | template <> 42 | class FieldModel<::trade::Order> 43 | { 44 | public: 45 | FieldModel(FBEBuffer& buffer, size_t offset) noexcept; 46 | 47 | // Get the field offset 48 | size_t fbe_offset() const noexcept { return _offset; } 49 | // Get the field size 50 | size_t fbe_size() const noexcept { return 4; } 51 | // Get the field body size 52 | size_t fbe_body() const noexcept; 53 | // Get the field extra size 54 | size_t fbe_extra() const noexcept; 55 | // Get the field type 56 | static constexpr size_t fbe_type() noexcept { return 1; } 57 | 58 | // Shift the current field offset 59 | void fbe_shift(size_t size) noexcept { _offset += size; } 60 | // Unshift the current field offset 61 | void fbe_unshift(size_t size) noexcept { _offset -= size; } 62 | 63 | // Check if the struct value is valid 64 | bool verify(bool fbe_verify_type = true) const noexcept; 65 | // Check if the struct fields are valid 66 | bool verify_fields(size_t fbe_struct_size) const noexcept; 67 | 68 | // Get the struct value (begin phase) 69 | size_t get_begin() const noexcept; 70 | // Get the struct value (end phase) 71 | void get_end(size_t fbe_begin) const noexcept; 72 | 73 | // Get the struct value 74 | void get(::trade::Order& fbe_value) const noexcept; 75 | // Get the struct fields values 76 | void get_fields(::trade::Order& fbe_value, size_t fbe_struct_size) const noexcept; 77 | 78 | // Set the struct value (begin phase) 79 | size_t set_begin(); 80 | // Set the struct value (end phase) 81 | void set_end(size_t fbe_begin); 82 | 83 | // Set the struct value 84 | void set(const ::trade::Order& fbe_value) noexcept; 85 | // Set the struct fields values 86 | void set_fields(const ::trade::Order& fbe_value) noexcept; 87 | 88 | private: 89 | FBEBuffer& _buffer; 90 | size_t _offset; 91 | 92 | public: 93 | FieldModel id; 94 | FieldModel symbol; 95 | FieldModel<::trade::OrderSide> side; 96 | FieldModel<::trade::OrderType> type; 97 | FieldModel price; 98 | FieldModel volume; 99 | }; 100 | 101 | namespace trade { 102 | 103 | // Fast Binary Encoding Order model 104 | class OrderModel : public FBE::Model 105 | { 106 | public: 107 | OrderModel() : model(this->buffer(), 4) {} 108 | OrderModel(const std::shared_ptr& buffer) : FBE::Model(buffer), model(this->buffer(), 4) {} 109 | 110 | // Get the model size 111 | size_t fbe_size() const noexcept { return model.fbe_size() + model.fbe_extra(); } 112 | // Get the model type 113 | static constexpr size_t fbe_type() noexcept { return FieldModel<::trade::Order>::fbe_type(); } 114 | 115 | // Check if the struct value is valid 116 | bool verify(); 117 | 118 | // Create a new model (begin phase) 119 | size_t create_begin(); 120 | // Create a new model (end phase) 121 | size_t create_end(size_t fbe_begin); 122 | 123 | // Serialize the struct value 124 | size_t serialize(const ::trade::Order& value); 125 | // Deserialize the struct value 126 | size_t deserialize(::trade::Order& value) const noexcept; 127 | 128 | // Move to the next struct value 129 | void next(size_t prev) noexcept { model.fbe_shift(prev); } 130 | 131 | public: 132 | FieldModel<::trade::Order> model; 133 | }; 134 | 135 | } // namespace trade 136 | 137 | // Fast Binary Encoding ::trade::Balance field model 138 | template <> 139 | class FieldModel<::trade::Balance> 140 | { 141 | public: 142 | FieldModel(FBEBuffer& buffer, size_t offset) noexcept; 143 | 144 | // Get the field offset 145 | size_t fbe_offset() const noexcept { return _offset; } 146 | // Get the field size 147 | size_t fbe_size() const noexcept { return 4; } 148 | // Get the field body size 149 | size_t fbe_body() const noexcept; 150 | // Get the field extra size 151 | size_t fbe_extra() const noexcept; 152 | // Get the field type 153 | static constexpr size_t fbe_type() noexcept { return 2; } 154 | 155 | // Shift the current field offset 156 | void fbe_shift(size_t size) noexcept { _offset += size; } 157 | // Unshift the current field offset 158 | void fbe_unshift(size_t size) noexcept { _offset -= size; } 159 | 160 | // Check if the struct value is valid 161 | bool verify(bool fbe_verify_type = true) const noexcept; 162 | // Check if the struct fields are valid 163 | bool verify_fields(size_t fbe_struct_size) const noexcept; 164 | 165 | // Get the struct value (begin phase) 166 | size_t get_begin() const noexcept; 167 | // Get the struct value (end phase) 168 | void get_end(size_t fbe_begin) const noexcept; 169 | 170 | // Get the struct value 171 | void get(::trade::Balance& fbe_value) const noexcept; 172 | // Get the struct fields values 173 | void get_fields(::trade::Balance& fbe_value, size_t fbe_struct_size) const noexcept; 174 | 175 | // Set the struct value (begin phase) 176 | size_t set_begin(); 177 | // Set the struct value (end phase) 178 | void set_end(size_t fbe_begin); 179 | 180 | // Set the struct value 181 | void set(const ::trade::Balance& fbe_value) noexcept; 182 | // Set the struct fields values 183 | void set_fields(const ::trade::Balance& fbe_value) noexcept; 184 | 185 | private: 186 | FBEBuffer& _buffer; 187 | size_t _offset; 188 | 189 | public: 190 | FieldModel currency; 191 | FieldModel amount; 192 | }; 193 | 194 | namespace trade { 195 | 196 | // Fast Binary Encoding Balance model 197 | class BalanceModel : public FBE::Model 198 | { 199 | public: 200 | BalanceModel() : model(this->buffer(), 4) {} 201 | BalanceModel(const std::shared_ptr& buffer) : FBE::Model(buffer), model(this->buffer(), 4) {} 202 | 203 | // Get the model size 204 | size_t fbe_size() const noexcept { return model.fbe_size() + model.fbe_extra(); } 205 | // Get the model type 206 | static constexpr size_t fbe_type() noexcept { return FieldModel<::trade::Balance>::fbe_type(); } 207 | 208 | // Check if the struct value is valid 209 | bool verify(); 210 | 211 | // Create a new model (begin phase) 212 | size_t create_begin(); 213 | // Create a new model (end phase) 214 | size_t create_end(size_t fbe_begin); 215 | 216 | // Serialize the struct value 217 | size_t serialize(const ::trade::Balance& value); 218 | // Deserialize the struct value 219 | size_t deserialize(::trade::Balance& value) const noexcept; 220 | 221 | // Move to the next struct value 222 | void next(size_t prev) noexcept { model.fbe_shift(prev); } 223 | 224 | public: 225 | FieldModel<::trade::Balance> model; 226 | }; 227 | 228 | } // namespace trade 229 | 230 | // Fast Binary Encoding ::trade::Account field model 231 | template <> 232 | class FieldModel<::trade::Account> 233 | { 234 | public: 235 | FieldModel(FBEBuffer& buffer, size_t offset) noexcept; 236 | 237 | // Get the field offset 238 | size_t fbe_offset() const noexcept { return _offset; } 239 | // Get the field size 240 | size_t fbe_size() const noexcept { return 4; } 241 | // Get the field body size 242 | size_t fbe_body() const noexcept; 243 | // Get the field extra size 244 | size_t fbe_extra() const noexcept; 245 | // Get the field type 246 | static constexpr size_t fbe_type() noexcept { return 3; } 247 | 248 | // Shift the current field offset 249 | void fbe_shift(size_t size) noexcept { _offset += size; } 250 | // Unshift the current field offset 251 | void fbe_unshift(size_t size) noexcept { _offset -= size; } 252 | 253 | // Check if the struct value is valid 254 | bool verify(bool fbe_verify_type = true) const noexcept; 255 | // Check if the struct fields are valid 256 | bool verify_fields(size_t fbe_struct_size) const noexcept; 257 | 258 | // Get the struct value (begin phase) 259 | size_t get_begin() const noexcept; 260 | // Get the struct value (end phase) 261 | void get_end(size_t fbe_begin) const noexcept; 262 | 263 | // Get the struct value 264 | void get(::trade::Account& fbe_value) const noexcept; 265 | // Get the struct fields values 266 | void get_fields(::trade::Account& fbe_value, size_t fbe_struct_size) const noexcept; 267 | 268 | // Set the struct value (begin phase) 269 | size_t set_begin(); 270 | // Set the struct value (end phase) 271 | void set_end(size_t fbe_begin); 272 | 273 | // Set the struct value 274 | void set(const ::trade::Account& fbe_value) noexcept; 275 | // Set the struct fields values 276 | void set_fields(const ::trade::Account& fbe_value) noexcept; 277 | 278 | private: 279 | FBEBuffer& _buffer; 280 | size_t _offset; 281 | 282 | public: 283 | FieldModel id; 284 | FieldModel name; 285 | FieldModel<::trade::Balance> wallet; 286 | FieldModelVector<::trade::Order> orders; 287 | }; 288 | 289 | namespace trade { 290 | 291 | // Fast Binary Encoding Account model 292 | class AccountModel : public FBE::Model 293 | { 294 | public: 295 | AccountModel() : model(this->buffer(), 4) {} 296 | AccountModel(const std::shared_ptr& buffer) : FBE::Model(buffer), model(this->buffer(), 4) {} 297 | 298 | // Get the model size 299 | size_t fbe_size() const noexcept { return model.fbe_size() + model.fbe_extra(); } 300 | // Get the model type 301 | static constexpr size_t fbe_type() noexcept { return FieldModel<::trade::Account>::fbe_type(); } 302 | 303 | // Check if the struct value is valid 304 | bool verify(); 305 | 306 | // Create a new model (begin phase) 307 | size_t create_begin(); 308 | // Create a new model (end phase) 309 | size_t create_end(size_t fbe_begin); 310 | 311 | // Serialize the struct value 312 | size_t serialize(const ::trade::Account& value); 313 | // Deserialize the struct value 314 | size_t deserialize(::trade::Account& value) const noexcept; 315 | 316 | // Move to the next struct value 317 | void next(size_t prev) noexcept { model.fbe_shift(prev); } 318 | 319 | public: 320 | FieldModel<::trade::Account> model; 321 | }; 322 | 323 | } // namespace trade 324 | 325 | } // namespace FBE 326 | -------------------------------------------------------------------------------- /proto/fbe/fbe.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Automatically generated by the Fast Binary Encoding compiler, do not modify! 3 | // https://github.com/chronoxor/FastBinaryEncoding 4 | // Source: FBE 5 | // FBE version: 1.15.0.0 6 | //------------------------------------------------------------------------------ 7 | 8 | #include "fbe.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | #include 13 | #undef DELETE 14 | #undef ERROR 15 | #undef Yield 16 | #undef min 17 | #undef max 18 | #undef uuid_t 19 | #endif 20 | 21 | namespace FBE { 22 | 23 | std::string buffer_t::base64encode() const 24 | { 25 | const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 26 | std::string result; 27 | 28 | int val = 0; 29 | int valb = -6; 30 | for (auto c : _data) 31 | { 32 | val = (val << 8) + c; 33 | valb += 8; 34 | while (valb >= 0) 35 | { 36 | result.push_back(base64[(val >> valb) & 0x3F]); 37 | valb -= 6; 38 | } 39 | } 40 | 41 | if (valb > -6) 42 | result.push_back(base64[((val << 8) >> (valb + 8)) & 0x3F]); 43 | 44 | while (result.size() % 4) 45 | result.push_back('='); 46 | 47 | return result; 48 | } 49 | 50 | buffer_t buffer_t::base64decode(const std::string& str) 51 | { 52 | const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 53 | buffer_t result; 54 | 55 | std::vector pattern(256, -1); 56 | for (int i = 0; i < 64; ++i) 57 | pattern[base64[i]] = i; 58 | 59 | int val = 0; 60 | int valb = -8; 61 | for (auto c : str) 62 | { 63 | if (pattern[c] == -1) 64 | break; 65 | 66 | val = (val << 6) + pattern[c]; 67 | valb += 6; 68 | 69 | if (valb >= 0) 70 | { 71 | result.push_back((uint8_t)((val >> valb) & 0xFF)); 72 | valb -= 8; 73 | } 74 | } 75 | 76 | return result; 77 | } 78 | 79 | uint64_t utc() 80 | { 81 | #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) 82 | struct timespec timestamp; 83 | if (clock_gettime(CLOCK_REALTIME, ×tamp) != 0) 84 | throw std::runtime_error("Cannot get value of CLOCK_REALTIME timer!"); 85 | return (timestamp.tv_sec * 1000000000) + timestamp.tv_nsec; 86 | #elif defined(_WIN32) || defined(_WIN64) 87 | FILETIME ft; 88 | GetSystemTimePreciseAsFileTime(&ft); 89 | 90 | ULARGE_INTEGER result; 91 | result.LowPart = ft.dwLowDateTime; 92 | result.HighPart = ft.dwHighDateTime; 93 | return (result.QuadPart - 116444736000000000ull) * 100; 94 | #endif 95 | } 96 | 97 | uint8_t unhex(char ch) 98 | { 99 | if ((ch >= '0') && (ch <= '9')) 100 | return ch - '0'; 101 | else if ((ch >= 'a') && (ch <= 'f')) 102 | return 10 + ch - 'a'; 103 | else if ((ch >= 'A') && (ch <= 'F')) 104 | return 10 + ch - 'A'; 105 | else 106 | return 255; 107 | } 108 | 109 | uuid_t::uuid_t(const std::string& uuid) 110 | { 111 | char v1 = 0; 112 | char v2 = 0; 113 | bool pack = false; 114 | size_t index = 0; 115 | 116 | // Parse UUID string 117 | for (auto ch : uuid) 118 | { 119 | if ((ch == '-') || (ch == '{') || (ch == '}')) 120 | continue; 121 | 122 | if (pack) 123 | { 124 | v2 = ch; 125 | pack = false; 126 | uint8_t ui1 = unhex(v1); 127 | uint8_t ui2 = unhex(v2); 128 | if ((ui1 > 15) || (ui2 > 15)) 129 | throw std::invalid_argument("Invalid UUID string: " + uuid); 130 | _data[index++] = ui1 * 16 + ui2; 131 | if (index >= 16) 132 | break; 133 | } 134 | else 135 | { 136 | v1 = ch; 137 | pack = true; 138 | } 139 | } 140 | 141 | // Fill remaining data with zeros 142 | for (; index < 16; ++index) 143 | _data[index++] = 0; 144 | } 145 | 146 | std::string uuid_t::string() const 147 | { 148 | const char* digits = "0123456789abcdef"; 149 | 150 | std::string result(36, '0'); 151 | 152 | int index = 0; 153 | for (auto value : _data) 154 | { 155 | result[index++] = digits[(value >> 4) & 0x0F]; 156 | result[index++] = digits[(value >> 0) & 0x0F]; 157 | if ((index == 8) || (index == 13) || (index == 18) || (index == 23)) 158 | result[index++] = '-'; 159 | } 160 | 161 | return result; 162 | } 163 | 164 | uuid_t uuid_t::sequential() 165 | { 166 | uuid_t result; 167 | #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) 168 | ::uuid_t uuid; 169 | uuid_generate_time(uuid); 170 | result._data[0] = uuid[0]; 171 | result._data[1] = uuid[1]; 172 | result._data[2] = uuid[2]; 173 | result._data[3] = uuid[3]; 174 | result._data[4] = uuid[4]; 175 | result._data[5] = uuid[5]; 176 | result._data[6] = uuid[6]; 177 | result._data[7] = uuid[7]; 178 | result._data[8] = uuid[8]; 179 | result._data[9] = uuid[9]; 180 | result._data[10] = uuid[10]; 181 | result._data[11] = uuid[11]; 182 | result._data[12] = uuid[12]; 183 | result._data[13] = uuid[13]; 184 | result._data[14] = uuid[14]; 185 | result._data[15] = uuid[15]; 186 | #elif defined(_WIN32) || defined(_WIN64) 187 | ::UUID uuid; 188 | if (UuidCreateSequential(&uuid) != RPC_S_OK) 189 | throw std::runtime_error("Cannot generate sequential UUID!"); 190 | 191 | result._data[0] = (uuid.Data1 >> 24) & 0xFF; 192 | result._data[1] = (uuid.Data1 >> 16) & 0xFF; 193 | result._data[2] = (uuid.Data1 >> 8) & 0xFF; 194 | result._data[3] = (uuid.Data1 >> 0) & 0xFF; 195 | result._data[4] = (uuid.Data2 >> 8) & 0xFF; 196 | result._data[5] = (uuid.Data2 >> 0) & 0xFF; 197 | 198 | result._data[6] = (uuid.Data3 >> 8) & 0xFF; 199 | result._data[7] = (uuid.Data3 >> 0) & 0xFF; 200 | 201 | result._data[8] = uuid.Data4[0]; 202 | result._data[9] = uuid.Data4[1]; 203 | 204 | result._data[10] = uuid.Data4[2]; 205 | result._data[11] = uuid.Data4[3]; 206 | result._data[12] = uuid.Data4[4]; 207 | result._data[13] = uuid.Data4[5]; 208 | result._data[14] = uuid.Data4[6]; 209 | result._data[15] = uuid.Data4[7]; 210 | #endif 211 | return result; 212 | } 213 | 214 | uuid_t uuid_t::random() 215 | { 216 | uuid_t result; 217 | #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) 218 | ::uuid_t uuid; 219 | uuid_generate_random(uuid); 220 | result._data[0] = uuid[0]; 221 | result._data[1] = uuid[1]; 222 | result._data[2] = uuid[2]; 223 | result._data[3] = uuid[3]; 224 | result._data[4] = uuid[4]; 225 | result._data[5] = uuid[5]; 226 | result._data[6] = uuid[6]; 227 | result._data[7] = uuid[7]; 228 | result._data[8] = uuid[8]; 229 | result._data[9] = uuid[9]; 230 | result._data[10] = uuid[10]; 231 | result._data[11] = uuid[11]; 232 | result._data[12] = uuid[12]; 233 | result._data[13] = uuid[13]; 234 | result._data[14] = uuid[14]; 235 | result._data[15] = uuid[15]; 236 | #elif defined(_WIN32) || defined(_WIN64) 237 | ::UUID uuid; 238 | if (UuidCreate(&uuid) != RPC_S_OK) 239 | throw std::runtime_error("Cannot generate random UUID!"); 240 | 241 | result._data[0] = (uuid.Data1 >> 24) & 0xFF; 242 | result._data[1] = (uuid.Data1 >> 16) & 0xFF; 243 | result._data[2] = (uuid.Data1 >> 8) & 0xFF; 244 | result._data[3] = (uuid.Data1 >> 0) & 0xFF; 245 | result._data[4] = (uuid.Data2 >> 8) & 0xFF; 246 | result._data[5] = (uuid.Data2 >> 0) & 0xFF; 247 | 248 | result._data[6] = (uuid.Data3 >> 8) & 0xFF; 249 | result._data[7] = (uuid.Data3 >> 0) & 0xFF; 250 | 251 | result._data[8] = uuid.Data4[0]; 252 | result._data[9] = uuid.Data4[1]; 253 | 254 | result._data[10] = uuid.Data4[2]; 255 | result._data[11] = uuid.Data4[3]; 256 | result._data[12] = uuid.Data4[4]; 257 | result._data[13] = uuid.Data4[5]; 258 | result._data[14] = uuid.Data4[6]; 259 | result._data[15] = uuid.Data4[7]; 260 | #endif 261 | return result; 262 | } 263 | 264 | #if defined(LOGGING_PROTOCOL) 265 | CppLogging::Record& operator<<(CppLogging::Record& record, const uuid_t& uuid) 266 | { 267 | const char* digits = "0123456789abcdef"; 268 | 269 | std::array result; 270 | 271 | int index = 0; 272 | for (auto value : uuid.data()) 273 | { 274 | result[index++] = digits[(value >> 4) & 0x0F]; 275 | result[index++] = digits[(value >> 0) & 0x0F]; 276 | if ((index == 8) || (index == 13) || (index == 18) || (index == 23)) 277 | result[index++] = '-'; 278 | } 279 | 280 | return record.StoreCustom(std::string_view(result.data(), result.size())); 281 | } 282 | #endif 283 | 284 | void FBEBuffer::attach(const void* data, size_t size, size_t offset) 285 | { 286 | assert((data != nullptr) && "Invalid buffer!"); 287 | if (data == nullptr) 288 | throw std::invalid_argument("Invalid buffer!"); 289 | assert((size > 0) && "Invalid size!"); 290 | if (size == 0) 291 | throw std::invalid_argument("Invalid size!"); 292 | assert((offset <= size) && "Invalid offset!"); 293 | if (offset > size) 294 | throw std::invalid_argument("Invalid offset!"); 295 | 296 | _data = (uint8_t*)data; 297 | _capacity = 0; 298 | _size = size; 299 | _offset = offset; 300 | } 301 | 302 | void FBEBuffer::attach(const std::vector& buffer, size_t offset) 303 | { 304 | assert((buffer.data() != nullptr) && "Invalid buffer!"); 305 | if (buffer.data() == nullptr) 306 | throw std::invalid_argument("Invalid buffer!"); 307 | assert((buffer.size() > 0) && "Invalid size!"); 308 | if (buffer.size() == 0) 309 | throw std::invalid_argument("Invalid size!"); 310 | assert((offset <= buffer.size()) && "Invalid offset!"); 311 | if (offset > buffer.size()) 312 | throw std::invalid_argument("Invalid offset!"); 313 | 314 | _data = (uint8_t*)buffer.data(); 315 | _capacity = 0; 316 | _size = buffer.size(); 317 | _offset = offset; 318 | } 319 | 320 | void FBEBuffer::clone(const void* data, size_t size, size_t offset) 321 | { 322 | assert((offset <= size) && "Invalid offset!"); 323 | if (offset > size) 324 | throw std::invalid_argument("Invalid offset!"); 325 | 326 | reserve(size); 327 | std::memcpy(_data, data, size); 328 | _capacity = size; 329 | _size = size; 330 | _offset = offset; 331 | } 332 | 333 | void FBEBuffer::clone(const std::vector& buffer, size_t offset) 334 | { 335 | assert((offset <= buffer.size()) && "Invalid offset!"); 336 | if (offset > buffer.size()) 337 | throw std::invalid_argument("Invalid offset!"); 338 | 339 | size_t size = buffer.size(); 340 | 341 | reserve(size); 342 | std::memcpy(_data, buffer.data(), size); 343 | _capacity = size; 344 | _size = size; 345 | _offset = offset; 346 | } 347 | 348 | size_t FBEBuffer::allocate(size_t size) 349 | { 350 | size_t offset = _size; 351 | 352 | // Calculate a new buffer size 353 | size_t total = _size + size; 354 | 355 | if (total <= _capacity) 356 | { 357 | _size = total; 358 | return offset; 359 | } 360 | 361 | _capacity = std::max(total, 2 * _capacity); 362 | uint8_t* data = (uint8_t*)std::malloc(_capacity); 363 | std::memcpy(data, _data, _size); 364 | std::free(_data); 365 | _data = data; 366 | _size = total; 367 | return offset; 368 | } 369 | 370 | void FBEBuffer::remove(size_t offset, size_t size) 371 | { 372 | assert(((offset + size) <= _size) && "Invalid offset & size!"); 373 | if ((offset + size) > _size) 374 | throw std::invalid_argument("Invalid offset & size!"); 375 | 376 | std::memcpy(_data + offset, _data + offset + size, _size - size - offset); 377 | _size -= size; 378 | if (_offset >= (offset + size)) 379 | _offset -= size; 380 | else if (_offset >= offset) 381 | { 382 | _offset -= _offset - offset; 383 | if (_offset > _size) 384 | _offset = _size; 385 | } 386 | } 387 | 388 | void FBEBuffer::reserve(size_t capacity) 389 | { 390 | if (capacity > _capacity) 391 | { 392 | _capacity = std::max(capacity, 2 * _capacity); 393 | uint8_t* data = (uint8_t*)std::malloc(_capacity); 394 | std::memcpy(data, _data, _size); 395 | std::free(_data); 396 | _data = data; 397 | } 398 | } 399 | 400 | void FBEBuffer::resize(size_t size) 401 | { 402 | reserve(size); 403 | _size = size; 404 | if (_offset > _size) 405 | _offset = _size; 406 | } 407 | 408 | void FBEBuffer::reset() 409 | { 410 | _size = 0; 411 | _offset = 0; 412 | } 413 | 414 | } // namespace FBE 415 | -------------------------------------------------------------------------------- /proto/flatbuffers/trade_generated.h: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | 4 | #ifndef FLATBUFFERS_GENERATED_TRADE_TRADE_FLATBUF_H_ 5 | #define FLATBUFFERS_GENERATED_TRADE_TRADE_FLATBUF_H_ 6 | 7 | #include "flatbuffers/flatbuffers.h" 8 | 9 | // Ensure the included flatbuffers.h is the same version as when this file was 10 | // generated, otherwise it may not be compatible. 11 | static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && 12 | FLATBUFFERS_VERSION_MINOR == 2 && 13 | FLATBUFFERS_VERSION_REVISION == 10, 14 | "Non-compatible flatbuffers version included"); 15 | 16 | namespace Trade { 17 | namespace flatbuf { 18 | 19 | struct Order; 20 | struct OrderBuilder; 21 | 22 | struct Balance; 23 | struct BalanceBuilder; 24 | 25 | struct Account; 26 | struct AccountBuilder; 27 | 28 | enum class OrderSide : int8_t { 29 | buy = 0, 30 | sell = 1, 31 | MIN = buy, 32 | MAX = sell 33 | }; 34 | 35 | inline const OrderSide (&EnumValuesOrderSide())[2] { 36 | static const OrderSide values[] = { 37 | OrderSide::buy, 38 | OrderSide::sell 39 | }; 40 | return values; 41 | } 42 | 43 | inline const char * const *EnumNamesOrderSide() { 44 | static const char * const names[3] = { 45 | "buy", 46 | "sell", 47 | nullptr 48 | }; 49 | return names; 50 | } 51 | 52 | inline const char *EnumNameOrderSide(OrderSide e) { 53 | if (::flatbuffers::IsOutRange(e, OrderSide::buy, OrderSide::sell)) return ""; 54 | const size_t index = static_cast(e); 55 | return EnumNamesOrderSide()[index]; 56 | } 57 | 58 | enum class OrderType : int8_t { 59 | market = 0, 60 | limit = 1, 61 | stop = 2, 62 | MIN = market, 63 | MAX = stop 64 | }; 65 | 66 | inline const OrderType (&EnumValuesOrderType())[3] { 67 | static const OrderType values[] = { 68 | OrderType::market, 69 | OrderType::limit, 70 | OrderType::stop 71 | }; 72 | return values; 73 | } 74 | 75 | inline const char * const *EnumNamesOrderType() { 76 | static const char * const names[4] = { 77 | "market", 78 | "limit", 79 | "stop", 80 | nullptr 81 | }; 82 | return names; 83 | } 84 | 85 | inline const char *EnumNameOrderType(OrderType e) { 86 | if (::flatbuffers::IsOutRange(e, OrderType::market, OrderType::stop)) return ""; 87 | const size_t index = static_cast(e); 88 | return EnumNamesOrderType()[index]; 89 | } 90 | 91 | struct Order FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { 92 | typedef OrderBuilder Builder; 93 | enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { 94 | VT_ID = 4, 95 | VT_SYMBOL = 6, 96 | VT_SIDE = 8, 97 | VT_TYPE = 10, 98 | VT_PRICE = 12, 99 | VT_VOLUME = 14 100 | }; 101 | int32_t id() const { 102 | return GetField(VT_ID, 0); 103 | } 104 | const ::flatbuffers::String *symbol() const { 105 | return GetPointer(VT_SYMBOL); 106 | } 107 | Trade::flatbuf::OrderSide side() const { 108 | return static_cast(GetField(VT_SIDE, 0)); 109 | } 110 | Trade::flatbuf::OrderType type() const { 111 | return static_cast(GetField(VT_TYPE, 0)); 112 | } 113 | double price() const { 114 | return GetField(VT_PRICE, 0.0); 115 | } 116 | double volume() const { 117 | return GetField(VT_VOLUME, 0.0); 118 | } 119 | bool Verify(::flatbuffers::Verifier &verifier) const { 120 | return VerifyTableStart(verifier) && 121 | VerifyField(verifier, VT_ID, 4) && 122 | VerifyOffset(verifier, VT_SYMBOL) && 123 | verifier.VerifyString(symbol()) && 124 | VerifyField(verifier, VT_SIDE, 1) && 125 | VerifyField(verifier, VT_TYPE, 1) && 126 | VerifyField(verifier, VT_PRICE, 8) && 127 | VerifyField(verifier, VT_VOLUME, 8) && 128 | verifier.EndTable(); 129 | } 130 | }; 131 | 132 | struct OrderBuilder { 133 | typedef Order Table; 134 | ::flatbuffers::FlatBufferBuilder &fbb_; 135 | ::flatbuffers::uoffset_t start_; 136 | void add_id(int32_t id) { 137 | fbb_.AddElement(Order::VT_ID, id, 0); 138 | } 139 | void add_symbol(::flatbuffers::Offset<::flatbuffers::String> symbol) { 140 | fbb_.AddOffset(Order::VT_SYMBOL, symbol); 141 | } 142 | void add_side(Trade::flatbuf::OrderSide side) { 143 | fbb_.AddElement(Order::VT_SIDE, static_cast(side), 0); 144 | } 145 | void add_type(Trade::flatbuf::OrderType type) { 146 | fbb_.AddElement(Order::VT_TYPE, static_cast(type), 0); 147 | } 148 | void add_price(double price) { 149 | fbb_.AddElement(Order::VT_PRICE, price, 0.0); 150 | } 151 | void add_volume(double volume) { 152 | fbb_.AddElement(Order::VT_VOLUME, volume, 0.0); 153 | } 154 | explicit OrderBuilder(::flatbuffers::FlatBufferBuilder &_fbb) 155 | : fbb_(_fbb) { 156 | start_ = fbb_.StartTable(); 157 | } 158 | ::flatbuffers::Offset Finish() { 159 | const auto end = fbb_.EndTable(start_); 160 | auto o = ::flatbuffers::Offset(end); 161 | return o; 162 | } 163 | }; 164 | 165 | inline ::flatbuffers::Offset CreateOrder( 166 | ::flatbuffers::FlatBufferBuilder &_fbb, 167 | int32_t id = 0, 168 | ::flatbuffers::Offset<::flatbuffers::String> symbol = 0, 169 | Trade::flatbuf::OrderSide side = Trade::flatbuf::OrderSide::buy, 170 | Trade::flatbuf::OrderType type = Trade::flatbuf::OrderType::market, 171 | double price = 0.0, 172 | double volume = 0.0) { 173 | OrderBuilder builder_(_fbb); 174 | builder_.add_volume(volume); 175 | builder_.add_price(price); 176 | builder_.add_symbol(symbol); 177 | builder_.add_id(id); 178 | builder_.add_type(type); 179 | builder_.add_side(side); 180 | return builder_.Finish(); 181 | } 182 | 183 | inline ::flatbuffers::Offset CreateOrderDirect( 184 | ::flatbuffers::FlatBufferBuilder &_fbb, 185 | int32_t id = 0, 186 | const char *symbol = nullptr, 187 | Trade::flatbuf::OrderSide side = Trade::flatbuf::OrderSide::buy, 188 | Trade::flatbuf::OrderType type = Trade::flatbuf::OrderType::market, 189 | double price = 0.0, 190 | double volume = 0.0) { 191 | auto symbol__ = symbol ? _fbb.CreateString(symbol) : 0; 192 | return Trade::flatbuf::CreateOrder( 193 | _fbb, 194 | id, 195 | symbol__, 196 | side, 197 | type, 198 | price, 199 | volume); 200 | } 201 | 202 | struct Balance FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { 203 | typedef BalanceBuilder Builder; 204 | enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { 205 | VT_CURRENCY = 4, 206 | VT_AMOUNT = 6 207 | }; 208 | const ::flatbuffers::String *currency() const { 209 | return GetPointer(VT_CURRENCY); 210 | } 211 | double amount() const { 212 | return GetField(VT_AMOUNT, 0.0); 213 | } 214 | bool Verify(::flatbuffers::Verifier &verifier) const { 215 | return VerifyTableStart(verifier) && 216 | VerifyOffset(verifier, VT_CURRENCY) && 217 | verifier.VerifyString(currency()) && 218 | VerifyField(verifier, VT_AMOUNT, 8) && 219 | verifier.EndTable(); 220 | } 221 | }; 222 | 223 | struct BalanceBuilder { 224 | typedef Balance Table; 225 | ::flatbuffers::FlatBufferBuilder &fbb_; 226 | ::flatbuffers::uoffset_t start_; 227 | void add_currency(::flatbuffers::Offset<::flatbuffers::String> currency) { 228 | fbb_.AddOffset(Balance::VT_CURRENCY, currency); 229 | } 230 | void add_amount(double amount) { 231 | fbb_.AddElement(Balance::VT_AMOUNT, amount, 0.0); 232 | } 233 | explicit BalanceBuilder(::flatbuffers::FlatBufferBuilder &_fbb) 234 | : fbb_(_fbb) { 235 | start_ = fbb_.StartTable(); 236 | } 237 | ::flatbuffers::Offset Finish() { 238 | const auto end = fbb_.EndTable(start_); 239 | auto o = ::flatbuffers::Offset(end); 240 | return o; 241 | } 242 | }; 243 | 244 | inline ::flatbuffers::Offset CreateBalance( 245 | ::flatbuffers::FlatBufferBuilder &_fbb, 246 | ::flatbuffers::Offset<::flatbuffers::String> currency = 0, 247 | double amount = 0.0) { 248 | BalanceBuilder builder_(_fbb); 249 | builder_.add_amount(amount); 250 | builder_.add_currency(currency); 251 | return builder_.Finish(); 252 | } 253 | 254 | inline ::flatbuffers::Offset CreateBalanceDirect( 255 | ::flatbuffers::FlatBufferBuilder &_fbb, 256 | const char *currency = nullptr, 257 | double amount = 0.0) { 258 | auto currency__ = currency ? _fbb.CreateString(currency) : 0; 259 | return Trade::flatbuf::CreateBalance( 260 | _fbb, 261 | currency__, 262 | amount); 263 | } 264 | 265 | struct Account FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { 266 | typedef AccountBuilder Builder; 267 | enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { 268 | VT_ID = 4, 269 | VT_NAME = 6, 270 | VT_WALLET = 8, 271 | VT_ORDERS = 10 272 | }; 273 | int32_t id() const { 274 | return GetField(VT_ID, 0); 275 | } 276 | const ::flatbuffers::String *name() const { 277 | return GetPointer(VT_NAME); 278 | } 279 | const Trade::flatbuf::Balance *wallet() const { 280 | return GetPointer(VT_WALLET); 281 | } 282 | const ::flatbuffers::Vector<::flatbuffers::Offset> *orders() const { 283 | return GetPointer> *>(VT_ORDERS); 284 | } 285 | bool Verify(::flatbuffers::Verifier &verifier) const { 286 | return VerifyTableStart(verifier) && 287 | VerifyField(verifier, VT_ID, 4) && 288 | VerifyOffset(verifier, VT_NAME) && 289 | verifier.VerifyString(name()) && 290 | VerifyOffset(verifier, VT_WALLET) && 291 | verifier.VerifyTable(wallet()) && 292 | VerifyOffset(verifier, VT_ORDERS) && 293 | verifier.VerifyVector(orders()) && 294 | verifier.VerifyVectorOfTables(orders()) && 295 | verifier.EndTable(); 296 | } 297 | }; 298 | 299 | struct AccountBuilder { 300 | typedef Account Table; 301 | ::flatbuffers::FlatBufferBuilder &fbb_; 302 | ::flatbuffers::uoffset_t start_; 303 | void add_id(int32_t id) { 304 | fbb_.AddElement(Account::VT_ID, id, 0); 305 | } 306 | void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { 307 | fbb_.AddOffset(Account::VT_NAME, name); 308 | } 309 | void add_wallet(::flatbuffers::Offset wallet) { 310 | fbb_.AddOffset(Account::VT_WALLET, wallet); 311 | } 312 | void add_orders(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> orders) { 313 | fbb_.AddOffset(Account::VT_ORDERS, orders); 314 | } 315 | explicit AccountBuilder(::flatbuffers::FlatBufferBuilder &_fbb) 316 | : fbb_(_fbb) { 317 | start_ = fbb_.StartTable(); 318 | } 319 | ::flatbuffers::Offset Finish() { 320 | const auto end = fbb_.EndTable(start_); 321 | auto o = ::flatbuffers::Offset(end); 322 | return o; 323 | } 324 | }; 325 | 326 | inline ::flatbuffers::Offset CreateAccount( 327 | ::flatbuffers::FlatBufferBuilder &_fbb, 328 | int32_t id = 0, 329 | ::flatbuffers::Offset<::flatbuffers::String> name = 0, 330 | ::flatbuffers::Offset wallet = 0, 331 | ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> orders = 0) { 332 | AccountBuilder builder_(_fbb); 333 | builder_.add_orders(orders); 334 | builder_.add_wallet(wallet); 335 | builder_.add_name(name); 336 | builder_.add_id(id); 337 | return builder_.Finish(); 338 | } 339 | 340 | inline ::flatbuffers::Offset CreateAccountDirect( 341 | ::flatbuffers::FlatBufferBuilder &_fbb, 342 | int32_t id = 0, 343 | const char *name = nullptr, 344 | ::flatbuffers::Offset wallet = 0, 345 | const std::vector<::flatbuffers::Offset> *orders = nullptr) { 346 | auto name__ = name ? _fbb.CreateString(name) : 0; 347 | auto orders__ = orders ? _fbb.CreateVector<::flatbuffers::Offset>(*orders) : 0; 348 | return Trade::flatbuf::CreateAccount( 349 | _fbb, 350 | id, 351 | name__, 352 | wallet, 353 | orders__); 354 | } 355 | 356 | inline const Trade::flatbuf::Account *GetAccount(const void *buf) { 357 | return ::flatbuffers::GetRoot(buf); 358 | } 359 | 360 | inline const Trade::flatbuf::Account *GetSizePrefixedAccount(const void *buf) { 361 | return ::flatbuffers::GetSizePrefixedRoot(buf); 362 | } 363 | 364 | inline bool VerifyAccountBuffer( 365 | ::flatbuffers::Verifier &verifier) { 366 | return verifier.VerifyBuffer(nullptr); 367 | } 368 | 369 | inline bool VerifySizePrefixedAccountBuffer( 370 | ::flatbuffers::Verifier &verifier) { 371 | return verifier.VerifySizePrefixedBuffer(nullptr); 372 | } 373 | 374 | inline void FinishAccountBuffer( 375 | ::flatbuffers::FlatBufferBuilder &fbb, 376 | ::flatbuffers::Offset root) { 377 | fbb.Finish(root); 378 | } 379 | 380 | inline void FinishSizePrefixedAccountBuffer( 381 | ::flatbuffers::FlatBufferBuilder &fbb, 382 | ::flatbuffers::Offset root) { 383 | fbb.FinishSizePrefixed(root); 384 | } 385 | 386 | } // namespace flatbuf 387 | } // namespace Trade 388 | 389 | #endif // FLATBUFFERS_GENERATED_TRADE_TRADE_FLATBUF_H_ 390 | -------------------------------------------------------------------------------- /proto/sbe/MessageHeader.h: -------------------------------------------------------------------------------- 1 | /* Generated SBE (Simple Binary Encoding) message codec */ 2 | #ifndef _SBE_MESSAGEHEADER_CXX_H_ 3 | #define _SBE_MESSAGEHEADER_CXX_H_ 4 | 5 | #if __cplusplus >= 201103L 6 | # define SBE_CONSTEXPR constexpr 7 | # define SBE_NOEXCEPT noexcept 8 | #else 9 | # define SBE_CONSTEXPR 10 | # define SBE_NOEXCEPT 11 | #endif 12 | 13 | #if __cplusplus >= 201703L 14 | # include 15 | # define SBE_NODISCARD [[nodiscard]] 16 | # if !defined(SBE_USE_STRING_VIEW) 17 | # define SBE_USE_STRING_VIEW 1 18 | # endif 19 | #else 20 | # define SBE_NODISCARD 21 | #endif 22 | 23 | #if __cplusplus >= 202002L 24 | # include 25 | # if !defined(SBE_USE_SPAN) 26 | # define SBE_USE_SPAN 1 27 | # endif 28 | #endif 29 | 30 | #if !defined(__STDC_LIMIT_MACROS) 31 | # define __STDC_LIMIT_MACROS 1 32 | #endif 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #if defined(WIN32) || defined(_WIN32) 46 | # define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v) 47 | # define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v) 48 | # define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v) 49 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v) 50 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v) 51 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v) 52 | #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 53 | # define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v) 54 | # define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v) 55 | # define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v) 56 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v) 57 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v) 58 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v) 59 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 60 | # define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v) 61 | # define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v) 62 | # define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v) 63 | # define SBE_BIG_ENDIAN_ENCODE_16(v) (v) 64 | # define SBE_BIG_ENDIAN_ENCODE_32(v) (v) 65 | # define SBE_BIG_ENDIAN_ENCODE_64(v) (v) 66 | #else 67 | # error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file." 68 | #endif 69 | 70 | #if !defined(SBE_BOUNDS_CHECK_EXPECT) 71 | # if defined(SBE_NO_BOUNDS_CHECK) 72 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (false) 73 | # elif defined(_MSC_VER) 74 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (exp) 75 | # else 76 | # define SBE_BOUNDS_CHECK_EXPECT(exp, c) (__builtin_expect(exp, c)) 77 | # endif 78 | 79 | #endif 80 | 81 | #define SBE_FLOAT_NAN std::numeric_limits::quiet_NaN() 82 | #define SBE_DOUBLE_NAN std::numeric_limits::quiet_NaN() 83 | #define SBE_NULLVALUE_INT8 (std::numeric_limits::min)() 84 | #define SBE_NULLVALUE_INT16 (std::numeric_limits::min)() 85 | #define SBE_NULLVALUE_INT32 (std::numeric_limits::min)() 86 | #define SBE_NULLVALUE_INT64 (std::numeric_limits::min)() 87 | #define SBE_NULLVALUE_UINT8 (std::numeric_limits::max)() 88 | #define SBE_NULLVALUE_UINT16 (std::numeric_limits::max)() 89 | #define SBE_NULLVALUE_UINT32 (std::numeric_limits::max)() 90 | #define SBE_NULLVALUE_UINT64 (std::numeric_limits::max)() 91 | 92 | 93 | namespace sbe { 94 | 95 | class MessageHeader 96 | { 97 | private: 98 | char *m_buffer = nullptr; 99 | std::uint64_t m_bufferLength = 0; 100 | std::uint64_t m_offset = 0; 101 | std::uint64_t m_actingVersion = 0; 102 | 103 | public: 104 | enum MetaAttribute 105 | { 106 | EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE 107 | }; 108 | 109 | union sbe_float_as_uint_u 110 | { 111 | float fp_value; 112 | std::uint32_t uint_value; 113 | }; 114 | 115 | union sbe_double_as_uint_u 116 | { 117 | double fp_value; 118 | std::uint64_t uint_value; 119 | }; 120 | 121 | MessageHeader() = default; 122 | 123 | MessageHeader( 124 | char *buffer, 125 | const std::uint64_t offset, 126 | const std::uint64_t bufferLength, 127 | const std::uint64_t actingVersion) : 128 | m_buffer(buffer), 129 | m_bufferLength(bufferLength), 130 | m_offset(offset), 131 | m_actingVersion(actingVersion) 132 | { 133 | if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 8) > m_bufferLength), false)) 134 | { 135 | throw std::runtime_error("buffer too short for flyweight [E107]"); 136 | } 137 | } 138 | 139 | MessageHeader( 140 | char *buffer, 141 | const std::uint64_t bufferLength, 142 | const std::uint64_t actingVersion) : 143 | MessageHeader(buffer, 0, bufferLength, actingVersion) 144 | { 145 | } 146 | 147 | MessageHeader( 148 | char *buffer, 149 | const std::uint64_t bufferLength) : 150 | MessageHeader(buffer, 0, bufferLength, sbeSchemaVersion()) 151 | { 152 | } 153 | 154 | MessageHeader &wrap( 155 | char *buffer, 156 | const std::uint64_t offset, 157 | const std::uint64_t actingVersion, 158 | const std::uint64_t bufferLength) 159 | { 160 | m_buffer = buffer; 161 | m_bufferLength = bufferLength; 162 | m_offset = offset; 163 | m_actingVersion = actingVersion; 164 | 165 | if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 8) > m_bufferLength), false)) 166 | { 167 | throw std::runtime_error("buffer too short for flyweight [E107]"); 168 | } 169 | 170 | return *this; 171 | } 172 | 173 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT 174 | { 175 | return 8; 176 | } 177 | 178 | SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT 179 | { 180 | return m_offset; 181 | } 182 | 183 | SBE_NODISCARD const char *buffer() const SBE_NOEXCEPT 184 | { 185 | return m_buffer; 186 | } 187 | 188 | SBE_NODISCARD char *buffer() SBE_NOEXCEPT 189 | { 190 | return m_buffer; 191 | } 192 | 193 | SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT 194 | { 195 | return m_bufferLength; 196 | } 197 | 198 | SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT 199 | { 200 | return m_actingVersion; 201 | } 202 | 203 | SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT 204 | { 205 | return static_cast(1); 206 | } 207 | 208 | SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT 209 | { 210 | return static_cast(1); 211 | } 212 | 213 | SBE_NODISCARD static const char *blockLengthMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT 214 | { 215 | switch (metaAttribute) 216 | { 217 | case MetaAttribute::PRESENCE: return "required"; 218 | default: return ""; 219 | } 220 | } 221 | 222 | static SBE_CONSTEXPR std::uint16_t blockLengthId() SBE_NOEXCEPT 223 | { 224 | return -1; 225 | } 226 | 227 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t blockLengthSinceVersion() SBE_NOEXCEPT 228 | { 229 | return 0; 230 | } 231 | 232 | SBE_NODISCARD bool blockLengthInActingVersion() SBE_NOEXCEPT 233 | { 234 | return true; 235 | } 236 | 237 | SBE_NODISCARD static SBE_CONSTEXPR std::size_t blockLengthEncodingOffset() SBE_NOEXCEPT 238 | { 239 | return 0; 240 | } 241 | 242 | static SBE_CONSTEXPR std::uint16_t blockLengthNullValue() SBE_NOEXCEPT 243 | { 244 | return SBE_NULLVALUE_UINT16; 245 | } 246 | 247 | static SBE_CONSTEXPR std::uint16_t blockLengthMinValue() SBE_NOEXCEPT 248 | { 249 | return static_cast(0); 250 | } 251 | 252 | static SBE_CONSTEXPR std::uint16_t blockLengthMaxValue() SBE_NOEXCEPT 253 | { 254 | return static_cast(65534); 255 | } 256 | 257 | static SBE_CONSTEXPR std::size_t blockLengthEncodingLength() SBE_NOEXCEPT 258 | { 259 | return 2; 260 | } 261 | 262 | SBE_NODISCARD std::uint16_t blockLength() const SBE_NOEXCEPT 263 | { 264 | std::uint16_t val; 265 | std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::uint16_t)); 266 | return SBE_LITTLE_ENDIAN_ENCODE_16(val); 267 | } 268 | 269 | MessageHeader &blockLength(const std::uint16_t value) SBE_NOEXCEPT 270 | { 271 | std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value); 272 | std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::uint16_t)); 273 | return *this; 274 | } 275 | 276 | SBE_NODISCARD static const char *templateIdMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT 277 | { 278 | switch (metaAttribute) 279 | { 280 | case MetaAttribute::PRESENCE: return "required"; 281 | default: return ""; 282 | } 283 | } 284 | 285 | static SBE_CONSTEXPR std::uint16_t templateIdId() SBE_NOEXCEPT 286 | { 287 | return -1; 288 | } 289 | 290 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t templateIdSinceVersion() SBE_NOEXCEPT 291 | { 292 | return 0; 293 | } 294 | 295 | SBE_NODISCARD bool templateIdInActingVersion() SBE_NOEXCEPT 296 | { 297 | return true; 298 | } 299 | 300 | SBE_NODISCARD static SBE_CONSTEXPR std::size_t templateIdEncodingOffset() SBE_NOEXCEPT 301 | { 302 | return 2; 303 | } 304 | 305 | static SBE_CONSTEXPR std::uint16_t templateIdNullValue() SBE_NOEXCEPT 306 | { 307 | return SBE_NULLVALUE_UINT16; 308 | } 309 | 310 | static SBE_CONSTEXPR std::uint16_t templateIdMinValue() SBE_NOEXCEPT 311 | { 312 | return static_cast(0); 313 | } 314 | 315 | static SBE_CONSTEXPR std::uint16_t templateIdMaxValue() SBE_NOEXCEPT 316 | { 317 | return static_cast(65534); 318 | } 319 | 320 | static SBE_CONSTEXPR std::size_t templateIdEncodingLength() SBE_NOEXCEPT 321 | { 322 | return 2; 323 | } 324 | 325 | SBE_NODISCARD std::uint16_t templateId() const SBE_NOEXCEPT 326 | { 327 | std::uint16_t val; 328 | std::memcpy(&val, m_buffer + m_offset + 2, sizeof(std::uint16_t)); 329 | return SBE_LITTLE_ENDIAN_ENCODE_16(val); 330 | } 331 | 332 | MessageHeader &templateId(const std::uint16_t value) SBE_NOEXCEPT 333 | { 334 | std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value); 335 | std::memcpy(m_buffer + m_offset + 2, &val, sizeof(std::uint16_t)); 336 | return *this; 337 | } 338 | 339 | SBE_NODISCARD static const char *schemaIdMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT 340 | { 341 | switch (metaAttribute) 342 | { 343 | case MetaAttribute::PRESENCE: return "required"; 344 | default: return ""; 345 | } 346 | } 347 | 348 | static SBE_CONSTEXPR std::uint16_t schemaIdId() SBE_NOEXCEPT 349 | { 350 | return -1; 351 | } 352 | 353 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t schemaIdSinceVersion() SBE_NOEXCEPT 354 | { 355 | return 0; 356 | } 357 | 358 | SBE_NODISCARD bool schemaIdInActingVersion() SBE_NOEXCEPT 359 | { 360 | return true; 361 | } 362 | 363 | SBE_NODISCARD static SBE_CONSTEXPR std::size_t schemaIdEncodingOffset() SBE_NOEXCEPT 364 | { 365 | return 4; 366 | } 367 | 368 | static SBE_CONSTEXPR std::uint16_t schemaIdNullValue() SBE_NOEXCEPT 369 | { 370 | return SBE_NULLVALUE_UINT16; 371 | } 372 | 373 | static SBE_CONSTEXPR std::uint16_t schemaIdMinValue() SBE_NOEXCEPT 374 | { 375 | return static_cast(0); 376 | } 377 | 378 | static SBE_CONSTEXPR std::uint16_t schemaIdMaxValue() SBE_NOEXCEPT 379 | { 380 | return static_cast(65534); 381 | } 382 | 383 | static SBE_CONSTEXPR std::size_t schemaIdEncodingLength() SBE_NOEXCEPT 384 | { 385 | return 2; 386 | } 387 | 388 | SBE_NODISCARD std::uint16_t schemaId() const SBE_NOEXCEPT 389 | { 390 | std::uint16_t val; 391 | std::memcpy(&val, m_buffer + m_offset + 4, sizeof(std::uint16_t)); 392 | return SBE_LITTLE_ENDIAN_ENCODE_16(val); 393 | } 394 | 395 | MessageHeader &schemaId(const std::uint16_t value) SBE_NOEXCEPT 396 | { 397 | std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value); 398 | std::memcpy(m_buffer + m_offset + 4, &val, sizeof(std::uint16_t)); 399 | return *this; 400 | } 401 | 402 | SBE_NODISCARD static const char *versionMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT 403 | { 404 | switch (metaAttribute) 405 | { 406 | case MetaAttribute::PRESENCE: return "required"; 407 | default: return ""; 408 | } 409 | } 410 | 411 | static SBE_CONSTEXPR std::uint16_t versionId() SBE_NOEXCEPT 412 | { 413 | return -1; 414 | } 415 | 416 | SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t versionSinceVersion() SBE_NOEXCEPT 417 | { 418 | return 0; 419 | } 420 | 421 | SBE_NODISCARD bool versionInActingVersion() SBE_NOEXCEPT 422 | { 423 | return true; 424 | } 425 | 426 | SBE_NODISCARD static SBE_CONSTEXPR std::size_t versionEncodingOffset() SBE_NOEXCEPT 427 | { 428 | return 6; 429 | } 430 | 431 | static SBE_CONSTEXPR std::uint16_t versionNullValue() SBE_NOEXCEPT 432 | { 433 | return SBE_NULLVALUE_UINT16; 434 | } 435 | 436 | static SBE_CONSTEXPR std::uint16_t versionMinValue() SBE_NOEXCEPT 437 | { 438 | return static_cast(0); 439 | } 440 | 441 | static SBE_CONSTEXPR std::uint16_t versionMaxValue() SBE_NOEXCEPT 442 | { 443 | return static_cast(65534); 444 | } 445 | 446 | static SBE_CONSTEXPR std::size_t versionEncodingLength() SBE_NOEXCEPT 447 | { 448 | return 2; 449 | } 450 | 451 | SBE_NODISCARD std::uint16_t version() const SBE_NOEXCEPT 452 | { 453 | std::uint16_t val; 454 | std::memcpy(&val, m_buffer + m_offset + 6, sizeof(std::uint16_t)); 455 | return SBE_LITTLE_ENDIAN_ENCODE_16(val); 456 | } 457 | 458 | MessageHeader &version(const std::uint16_t value) SBE_NOEXCEPT 459 | { 460 | std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value); 461 | std::memcpy(m_buffer + m_offset + 6, &val, sizeof(std::uint16_t)); 462 | return *this; 463 | } 464 | 465 | template 466 | friend std::basic_ostream & operator << ( 467 | std::basic_ostream &builder, MessageHeader &writer) 468 | { 469 | builder << '{'; 470 | builder << R"("blockLength": )"; 471 | builder << +writer.blockLength(); 472 | 473 | builder << ", "; 474 | builder << R"("templateId": )"; 475 | builder << +writer.templateId(); 476 | 477 | builder << ", "; 478 | builder << R"("schemaId": )"; 479 | builder << +writer.schemaId(); 480 | 481 | builder << ", "; 482 | builder << R"("version": )"; 483 | builder << +writer.version(); 484 | 485 | builder << '}'; 486 | 487 | return builder; 488 | } 489 | 490 | }; 491 | 492 | } 493 | 494 | #endif 495 | --------------------------------------------------------------------------------