forked from organicmaps/organicmaps
Add string that optimized for integer positive values serialization.
This commit is contained in:
parent
0e8efdd557
commit
76ddd0f420
5 changed files with 137 additions and 10 deletions
|
@ -76,3 +76,4 @@ HEADERS += \
|
|||
bit_shift.hpp \
|
||||
base64.hpp \
|
||||
sha2.hpp \
|
||||
value_opt_string.hpp \
|
||||
|
|
|
@ -33,7 +33,8 @@ SOURCES += ../../testing/testingmain.cpp \
|
|||
coder_util_test.cpp \
|
||||
bit_shift_test.cpp \
|
||||
base64_test.cpp \
|
||||
sha2_test.cpp
|
||||
sha2_test.cpp \
|
||||
value_opt_string_test.cpp \
|
||||
|
||||
HEADERS += \
|
||||
reader_test.hpp \
|
||||
|
|
61
coding/coding_tests/value_opt_string_test.cpp
Normal file
61
coding/coding_tests/value_opt_string_test.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include "../../testing/testing.hpp"
|
||||
|
||||
#include "../value_opt_string.hpp"
|
||||
|
||||
#include "../reader.hpp"
|
||||
#include "../writer.hpp"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
template <class T>
|
||||
void TestStringCodingT(T const * arr, size_t count, size_t maxSize)
|
||||
{
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
StringNumericOptimal s;
|
||||
s.Set(arr[i]);
|
||||
|
||||
vector<char> buffer;
|
||||
MemWriter<vector<char> > w(buffer);
|
||||
|
||||
s.Write(w);
|
||||
|
||||
size_t const sz = buffer.size();
|
||||
TEST_GREATER(sz, 0, ());
|
||||
TEST_LESS_OR_EQUAL(sz, maxSize, ());
|
||||
|
||||
MemReader r(&buffer[0], sz);
|
||||
ReaderSource<MemReader> src(r);
|
||||
s.Read(src);
|
||||
|
||||
TEST_EQUAL(utils::to_string(arr[i]), s.Get(), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(StringNumericOptimal_IntCoding1)
|
||||
{
|
||||
int arr[] = { 0, 1, 2, 666, 0x0FFFFFFF, 0x7FFFFFFF-1, 0x7FFFFFFF };
|
||||
TestStringCodingT(arr, ARRAY_SIZE(arr), 5); // should be coded as VarUint
|
||||
}
|
||||
|
||||
UNIT_TEST(StringNumericOptimal_IntCoding2)
|
||||
{
|
||||
int arr[] = { -1, -2, -666666, 0xFFFFFFFE, 0xFFFFFFFF };
|
||||
TestStringCodingT(arr, ARRAY_SIZE(arr), 12); // should be coded as String
|
||||
}
|
||||
|
||||
UNIT_TEST(StringNumericOptimal_StringCoding)
|
||||
{
|
||||
char const * arr[] = { "xxx", "yyy", "a", "0xFFFFFF", "123456UL" };
|
||||
TestStringCodingT(arr, ARRAY_SIZE(arr), 12); // should be coded as String
|
||||
}
|
||||
|
||||
UNIT_TEST(StringNumericOptimal_LargeStringCoding)
|
||||
{
|
||||
string s;
|
||||
std::fill_n(back_inserter(s), 10000, 'x');
|
||||
|
||||
TestStringCodingT(&s, 1, 10006);
|
||||
}
|
|
@ -12,15 +12,15 @@
|
|||
|
||||
#include "../base/start_mem_debug.hpp"
|
||||
|
||||
typedef basic_string<uint8_t> byte_string;
|
||||
|
||||
inline byte_string StringToByteString(string const & str)
|
||||
{
|
||||
byte_string result;
|
||||
result.resize(str.size());
|
||||
memcpy(&result[0], &str[0], str.size());
|
||||
return result;
|
||||
}
|
||||
//typedef basic_string<uint8_t> byte_string;
|
||||
//
|
||||
//inline byte_string StringToByteString(string const & str)
|
||||
//{
|
||||
// byte_string result;
|
||||
// result.resize(str.size());
|
||||
// memcpy(&result[0], &str[0], str.size());
|
||||
// return result;
|
||||
//}
|
||||
|
||||
inline string ToUtf8(wstring const & wstr)
|
||||
{
|
||||
|
|
64
coding/value_opt_string.hpp
Normal file
64
coding/value_opt_string.hpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
|
||||
#include "varint.hpp"
|
||||
|
||||
#include "../base/string_utils.hpp"
|
||||
#include "../base/assert.hpp"
|
||||
|
||||
#include "../std/string.hpp"
|
||||
|
||||
|
||||
class StringNumericOptimal
|
||||
{
|
||||
string m_s;
|
||||
|
||||
static const uint8_t numeric_bit = 1;
|
||||
|
||||
public:
|
||||
inline void Set(string const & s)
|
||||
{
|
||||
CHECK ( !s.empty(), () );
|
||||
m_s = s;
|
||||
}
|
||||
inline void Set(char const * p)
|
||||
{
|
||||
m_s = p;
|
||||
CHECK ( !m_s.empty(), () );
|
||||
}
|
||||
template <class T> void Set(T const & s)
|
||||
{
|
||||
m_s = utils::to_string(s);
|
||||
CHECK ( !m_s.empty(), () );
|
||||
}
|
||||
|
||||
inline string Get() const { return m_s; }
|
||||
|
||||
template <class TSink> void Write(TSink & sink)
|
||||
{
|
||||
int n;
|
||||
if (utils::to_int(m_s, n) && n >= 0)
|
||||
WriteVarUint(sink, static_cast<uint32_t>((n << 1) | numeric_bit));
|
||||
else
|
||||
{
|
||||
size_t const sz = m_s.size();
|
||||
ASSERT_GREATER ( sz, 0, () );
|
||||
|
||||
WriteVarUint(sink, static_cast<uint32_t>((sz-1) << 1));
|
||||
sink.Write(m_s.c_str(), sz);
|
||||
}
|
||||
}
|
||||
|
||||
template <class TSource> void Read(TSource & src)
|
||||
{
|
||||
uint32_t sz = ReadVarUint<uint32_t>(src);
|
||||
|
||||
if ((sz & numeric_bit) != 0)
|
||||
m_s = utils::to_string(sz >> 1);
|
||||
else
|
||||
{
|
||||
sz = (sz >> 1) + 1;
|
||||
m_s.resize(sz);
|
||||
src.Read(&m_s[0], sz);
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Add table
Reference in a new issue