Add string that optimized for integer positive values serialization.

This commit is contained in:
vng 2011-05-06 19:51:46 +03:00 committed by Alex Zolotarev
parent 0e8efdd557
commit 76ddd0f420
5 changed files with 137 additions and 10 deletions

View file

@ -76,3 +76,4 @@ HEADERS += \
bit_shift.hpp \
base64.hpp \
sha2.hpp \
value_opt_string.hpp \

View file

@ -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 \

View 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);
}

View file

@ -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)
{

View 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);
}
}
};