-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
381 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
cmake_minimum_required(VERSION 3.8) | ||
project(BsonParser LANGUAGES CXX) | ||
|
||
add_library(BsonParser STATIC | ||
inc/Bson/Details/common.h | ||
inc/Bson/parser.h | ||
src/parser.cpp | ||
inc/Bson/Details/utils.h | ||
src/utils.cpp | ||
) | ||
|
||
target_include_directories(BsonParser PUBLIC inc) | ||
|
||
if(NOT MSVC) | ||
target_compile_options(BsonParser PUBLIC -Wall -Wextra -Werror -std=c++14) | ||
endif() | ||
|
||
enable_testing() | ||
|
||
add_executable(BsonParserTestUtils test/test-utils.cpp) | ||
target_link_libraries(BsonParserTestUtils PRIVATE BsonParser) | ||
|
||
add_executable(BsonParserTestEncode test/test-encode.cpp) | ||
target_link_libraries(BsonParserTestEncode PRIVATE BsonParser) | ||
|
||
add_executable(BsonParserTestDecode test/test-decode.cpp) | ||
target_link_libraries(BsonParserTestDecode PRIVATE BsonParser) | ||
|
||
add_executable(BsonParserTestEncodeDecode test/test-encode-decode.cpp) | ||
target_link_libraries(BsonParserTestEncodeDecode PRIVATE BsonParser) | ||
|
||
add_test(NAME BsonParserUtils COMMAND BsonParserTestUtils) | ||
add_test(NAME BsonParserEncode COMMAND BsonParserTestDecode) | ||
add_test(NAME BsonParserDecode COMMAND BsonParserTestEncode) | ||
add_test(NAME BsonParserEncodeDecode COMMAND BsonParserTestEncodeDecode) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#pragma once | ||
|
||
#include <vector> | ||
#include <iterator> | ||
|
||
namespace Bson | ||
{ | ||
|
||
using Byte = unsigned char; | ||
using Int32 = std::int32_t; | ||
using Int64 = std::int64_t; | ||
using Uint64 = std::uint64_t; | ||
using Double = double; | ||
|
||
#ifdef __GNUC__ | ||
using Decimal = __float128; | ||
#else | ||
#error "Unsupported platform" | ||
#endif | ||
|
||
using Bytes = std::vector<Byte>; | ||
|
||
using Istream = std::basic_istream<Byte>; | ||
using Ostream = std::basic_ostream<Byte>; | ||
|
||
} // namespace Bson |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#pragma once | ||
|
||
#include "Bson/Details/common.h" | ||
#include <cstdint> | ||
#include <string> | ||
#include <vector> | ||
#include <boost/variant.hpp> | ||
|
||
namespace Bson | ||
{ | ||
|
||
template <typename T> | ||
T read(Istream& stream); | ||
|
||
template <typename T> | ||
void write(T value, Ostream& stream); | ||
|
||
std::string readCString(Istream& stream); | ||
std::string readString(Istream& stream); | ||
|
||
void writeCString(const std::string& string, Ostream& stream); | ||
void writeString(const std::string& string, Ostream& stream); | ||
|
||
struct True {}; | ||
struct False {}; | ||
|
||
using Element = boost::variant<Double, std::string, False, True, Int32, Uint64, Int64, Uint64, Decimal>; | ||
Element readElement(Istream& stream); | ||
void writeElement(const Element& element, Ostream& stream); | ||
|
||
using List = std::vector<Element>; | ||
List readList(Istream& stream); | ||
void writeList(const List& list, Ostream& stream); | ||
|
||
|
||
} // namespace Bson |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#pragma once | ||
|
||
#include "Bson/Details/common.h" | ||
#include "Bson/Details/utils.h" | ||
|
||
#include <string> | ||
|
||
namespace Bson | ||
{ | ||
|
||
class Document | ||
{ | ||
public: | ||
|
||
private: | ||
List _list; | ||
}; | ||
|
||
Bytes encode(const Document&); | ||
Document decode(const Bytes&); | ||
|
||
} // namespace Bson |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#include "BSON/parser.h" | ||
|
||
namespace Bson | ||
{ | ||
|
||
std::vector<Byte> encode(const Document&) | ||
{ | ||
return {}; | ||
} | ||
|
||
Document decode(const std::vector<Byte>&) | ||
{ | ||
return {}; | ||
} | ||
|
||
|
||
} // namespace Bson |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#include "BSON/Details/utils.h" | ||
|
||
#include <algorithm> | ||
#include <cassert> | ||
#include <limits> | ||
|
||
#include <boost\bimap\bimap.hpp> | ||
|
||
namespace Bson | ||
{ | ||
|
||
const size_t MaxCStringBuff = 16384; | ||
|
||
//enum class ElementType { | ||
// Double = 0x01, | ||
// String = 0x02, | ||
// Int32 = 0x10, | ||
// Uint32 = 0x10, | ||
// Int64 = 0x12, | ||
// Decimal = 0x13 | ||
//}; | ||
//const boost::bimaps::bimap<int, ElementType> ElementTypes = {}; | ||
|
||
// TODO: handle endianness | ||
|
||
template <typename T> | ||
T read(Istream& stream) | ||
{ | ||
T value; | ||
stream.read(reinterpret_cast<Byte*>(&value), sizeof(value)); | ||
return value; | ||
} | ||
|
||
template <typename T> | ||
void write(const T value, Ostream& stream) | ||
{ | ||
stream.write(reinterpret_cast<const Byte*>(&value), sizeof(value)); | ||
} | ||
|
||
#define BSON_INSTANTIATE_FUNCS(type) \ | ||
template type read(Istream& iter); \ | ||
template void write(const type value, Ostream& iter); \ | ||
|
||
BSON_INSTANTIATE_FUNCS(Byte); | ||
BSON_INSTANTIATE_FUNCS(Int32); | ||
BSON_INSTANTIATE_FUNCS(Int64); | ||
BSON_INSTANTIATE_FUNCS(Uint64); | ||
BSON_INSTANTIATE_FUNCS(Double); | ||
BSON_INSTANTIATE_FUNCS(Decimal); | ||
|
||
std::string readCString(Istream& stream) | ||
{ | ||
Byte buff[MaxCStringBuff]; | ||
stream.getline(buff, MaxCStringBuff, 0); | ||
|
||
return std::string(reinterpret_cast<char*>(buff)); | ||
} | ||
|
||
std::string readString(Istream& stream) | ||
{ | ||
Int32 strLen = read<Int32>(stream); | ||
|
||
assert(strLen > 0); | ||
|
||
std::string s; | ||
s.resize(strLen - 1); | ||
stream.read(reinterpret_cast<Byte*>(&s[0]), strLen - 1); | ||
stream.ignore(1); | ||
|
||
return s; | ||
} | ||
|
||
void writeCString(const std::string& string, Ostream& stream) | ||
{ | ||
stream.write(reinterpret_cast<const Byte*>(string.c_str()), string.length() + 1); | ||
} | ||
|
||
void writeString(const std::string& string, Ostream& stream) | ||
{ | ||
write(static_cast<Int32>(string.length() + 1), stream); | ||
writeCString(string, stream); | ||
} | ||
|
||
Element readElement(Istream& stream) | ||
{ | ||
const auto elementType = read<Byte>(stream); | ||
|
||
return {}; | ||
} | ||
|
||
void writeElement(const Element& element, Ostream& stream) | ||
{ | ||
|
||
} | ||
|
||
} // namespace Bson |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#include "Bson/parser.h" | ||
|
||
int main() { | ||
|
||
const auto input = Bson::Bytes{0x16,0x00,0x00,0x00,0x02,'h','e','l','l','o',0x00,0x06,0x00,0x00,0x00,'w','o','r','l','d',0x00,0x00}; | ||
Bson::decode(input); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#include "Bson/parser.h" | ||
|
||
#include <string> | ||
#include <cassert> | ||
|
||
int main() { | ||
|
||
const auto input = Bson::Bytes{0x16,0x00,0x00,0x00,0x02,'h','e','l','l','o',0x00,0x06,0x00,0x00,0x00,'w','o','r','l','d',0x00,0x00}; | ||
const auto result = Bson::encode(Bson::decode(input)); | ||
const auto expected = input; | ||
|
||
return result == expected ? 0 : 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include "Bson/parser.h" | ||
|
||
#include <string> | ||
#include <cassert> | ||
|
||
int main() { | ||
|
||
Bson::Document doc; | ||
Bson::encode(doc); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#include "Bson/Details/utils.h" | ||
|
||
#include <cassert> | ||
#include <sstream> | ||
#include <iterator> | ||
#include <limits> | ||
#include <iostream> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include <boost\iostreams\device\array.hpp> | ||
#include <boost\iostreams\stream.hpp> | ||
|
||
template <typename T, typename WriteFunc, typename ReadFunc> | ||
bool testMemory(const T& value, size_t buffSize, WriteFunc write, ReadFunc read) | ||
{ | ||
std::vector<Bson::Byte> data(buffSize, 0); | ||
|
||
boost::iostreams::basic_array<Bson::Byte> arr(data.data(), data.size()); | ||
boost::iostreams::stream<boost::iostreams::basic_array<Bson::Byte>> istream(arr); | ||
boost::iostreams::stream<boost::iostreams::basic_array<Bson::Byte>> ostream(arr); | ||
|
||
write(value, ostream); | ||
const auto result = read(istream); | ||
|
||
return result == value; | ||
} | ||
|
||
template <typename T, typename WriteFunc, typename ReadFunc> | ||
bool testStream(T val, WriteFunc write, ReadFunc read) | ||
{ | ||
std::basic_stringstream<Bson::Byte> ss(std::ios_base::in | std::ios_base::out | std::ios_base::binary); | ||
write(val, ss); | ||
const auto result = read(ss); | ||
|
||
return val == result; | ||
} | ||
|
||
template <typename T> | ||
void test(T value) | ||
{ | ||
assert(testMemory(value, sizeof(value), Bson::write<T>, Bson::read<T>)); | ||
assert(testStream(value, Bson::write<T>, Bson::read<T>)); | ||
} | ||
|
||
void testString(const std::string& value) | ||
{ | ||
assert(testMemory(value, value.length() + sizeof(Bson::Int32) + 1, Bson::writeString, Bson::readString)); | ||
assert(testStream(value, Bson::writeString, Bson::readString)); | ||
} | ||
|
||
void test(const std::string& value) | ||
{ | ||
assert(testMemory(value, value.length() + 1, Bson::writeCString, Bson::readCString)); | ||
assert(testStream(value, Bson::writeCString, Bson::readCString)); | ||
testString(value); | ||
} | ||
|
||
int main() { | ||
|
||
test<Bson::Byte>(0); | ||
test<Bson::Byte>(1); | ||
test<Bson::Byte>(42); | ||
test<Bson::Byte>(255); | ||
|
||
test<Bson::Int32>(0); | ||
test<Bson::Int32>(1); | ||
test<Bson::Int32>(-1); | ||
test<Bson::Int32>(42); | ||
test<Bson::Int32>(-42); | ||
test<Bson::Int32>(0x01020304); | ||
test<Bson::Int32>(0xff0000ff); | ||
test<Bson::Int32>(std::numeric_limits<Bson::Int32>::min()); | ||
test<Bson::Int32>(std::numeric_limits<Bson::Int32>::max()); | ||
|
||
test<Bson::Int64>(0); | ||
test<Bson::Int64>(1); | ||
test<Bson::Int64>(-1); | ||
test<Bson::Int64>(42); | ||
test<Bson::Int64>(-42); | ||
test<Bson::Int64>(0x01020304); | ||
test<Bson::Int64>(std::numeric_limits<Bson::Int64>::min()); | ||
test<Bson::Int64>(std::numeric_limits<Bson::Int64>::max()); | ||
|
||
test<Bson::Uint64>(0); | ||
test<Bson::Uint64>(1); | ||
test<Bson::Uint64>(42); | ||
test<Bson::Uint64>(0x01020304); | ||
test<Bson::Uint64>(std::numeric_limits<Bson::Uint64>::min()); | ||
test<Bson::Uint64>(std::numeric_limits<Bson::Uint64>::max()); | ||
|
||
test<Bson::Double>(0.0); | ||
test<Bson::Double>(0.1); | ||
test<Bson::Double>(0.-1); | ||
test<Bson::Double>(1.0); | ||
test<Bson::Double>(-1.0); | ||
test<Bson::Double>(std::numeric_limits<Bson::Double>::min()); | ||
test<Bson::Double>(std::numeric_limits<Bson::Double>::max()); | ||
|
||
test<Bson::Decimal>(0.0); | ||
test<Bson::Decimal>(0.1); | ||
test<Bson::Decimal>(0.-1); | ||
test<Bson::Decimal>(1.0); | ||
test<Bson::Decimal>(-1.0); | ||
test<Bson::Decimal>(std::numeric_limits<Bson::Decimal>::min()); | ||
test<Bson::Decimal>(std::numeric_limits<Bson::Decimal>::max()); | ||
|
||
test(std::string("")); | ||
test(std::string("hello")); | ||
test(std::string("hello world")); | ||
testString(std::string("hello\0world", 11)); | ||
|
||
return 0; | ||
} |