Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArsentiy Milchakov <milcars@mapswithme.com>2017-08-16 16:10:37 +0300
committerYuri Gorshenin <mipt.vi002@gmail.com>2017-08-16 16:20:50 +0300
commitb3ab518fd70f72420f4278d7053ecaf880001817 (patch)
treee5f656564c51ce6c4ee102cf3db488d6f2822c6f /local_ads
parent948bcf950d8091b1db1960a814992d0062f10f6a (diff)
[local_ads] campaign ser/des fixes + tests
Diffstat (limited to 'local_ads')
-rw-r--r--local_ads/campaign_serialization.cpp140
-rw-r--r--local_ads/local_ads_tests/campaign_serialization_test.cpp25
2 files changed, 85 insertions, 80 deletions
diff --git a/local_ads/campaign_serialization.cpp b/local_ads/campaign_serialization.cpp
index 8dcce2e803..1d583f3657 100644
--- a/local_ads/campaign_serialization.cpp
+++ b/local_ads/campaign_serialization.cpp
@@ -1,8 +1,12 @@
#include "local_ads/campaign_serialization.hpp"
-#include "coding/varint.hpp"
#include "coding/byte_stream.hpp"
+#include "coding/reader.hpp"
+#include "coding/varint.hpp"
+#include "coding/write_to_sink.hpp"
+#include "base/exception.hpp"
+#include "base/logging.hpp"
#include "base/stl_add.hpp"
#include <climits>
@@ -14,6 +18,8 @@ namespace
{
using namespace local_ads;
+DECLARE_EXCEPTION(UnknownVersion, RootException);
+
auto const kHalfByteShift = CHAR_BIT / 2;
auto const kHalfByteMaxValue = 15;
auto const kLowerMask = 0x0F;
@@ -22,44 +28,25 @@ auto const kMinZoomLevel = 10;
auto const kMaxZoomLevel = 17;
auto const kMaxPriority = 7;
-template<typename T>
-constexpr bool IsEnumOrIntegral()
+template <typename Integral, typename Source,
+ typename std::enable_if<std::is_integral<Integral>::value, void *>::type = nullptr>
+std::vector<Integral> ReadVarUintArray(Source & s, size_t chunksNumber)
{
- return std::is_integral<T>::value || std::is_enum<T>::value;
-}
-
-template<typename ByteStream, typename T,
- typename std::enable_if<IsEnumOrIntegral<T>(), void>::type * = nullptr>
-void Write(ByteStream & s, T t)
-{
- s.Write(&t, sizeof(T));
-}
+ std::vector<Integral> result;
+ for (size_t i = 0; i < chunksNumber; ++i)
+ result.emplace_back(static_cast<Integral>(ReadVarUint<uint64_t>(s)));
-template<typename T, typename ByteStream,
- typename std::enable_if<IsEnumOrIntegral<T>(), void>::type * = nullptr>
-T Read(ByteStream & s)
-{
- T t;
- s.Read(static_cast<void*>(&t), sizeof(t));
- return t;
+ return result;
}
-template<typename Integral,
- typename ByteStream,
- typename std::enable_if<std::is_integral<Integral>::value, void*>::type = nullptr>
-std::vector<Integral> ReadData(ByteStream & s, size_t chunksNumber)
+template <typename Integral, typename Source>
+std::vector<Integral> ReadArray(Source & s, size_t chunksNumber)
{
std::vector<Integral> result;
- result.reserve(chunksNumber);
- auto const streamBegin = s.PtrUC();
- auto const afterLastReadByte = ReadVarUint64Array(
- streamBegin,
- chunksNumber,
- MakeBackInsertFunctor(result)
- );
-
- ASSERT_EQUAL(result.size(), chunksNumber, ());
- s.Advance(static_cast<decltype(streamBegin)>(afterLastReadByte) - streamBegin);
+ for (size_t i = 0; i < chunksNumber; ++i)
+ {
+ result.emplace_back(ReadPrimitiveFromSource<Integral>(s));
+ }
return result;
}
@@ -68,31 +55,28 @@ std::vector<uint8_t> SerializeV1(std::vector<Campaign> const & campaigns)
{
std::vector<uint8_t> buff;
PushBackByteSink<decltype(buff)> dst(buff);
- Write(dst, Version::V1);
- Write(dst, campaigns.size());
+ WriteToSink(dst, Version::V1);
+ WriteToSink(dst, campaigns.size());
for (auto const & c : campaigns)
WriteVarUint(dst, c.m_featureId);
for (auto const & c : campaigns)
WriteVarUint(dst, c.m_iconId);
for (auto const & c : campaigns)
- Write(dst, c.m_daysBeforeExpired);
+ WriteVarUint(dst, c.m_daysBeforeExpired);
return buff;
}
std::vector<Campaign> DeserializeV1(std::vector<uint8_t> const & bytes)
{
- ArrayByteSource src(bytes.data());
- CHECK_EQUAL(Read<Version>(src), Version::V1, ());
- auto const chunksNumber = Read<uint64_t>(src);
+ ReaderSource<MemReaderWithExceptions> src({bytes.data(), bytes.size()});
- auto const featureIds = ReadData<uint32_t>(src, chunksNumber);
- auto const icons = ReadData<uint16_t>(src, chunksNumber);
- auto const expirations = ReadData<uint8_t>(src, chunksNumber);
+ CHECK_EQUAL(ReadPrimitiveFromSource<Version>(src), Version::V1, ());
+ auto const chunksNumber = ReadPrimitiveFromSource<uint64_t>(src);
- CHECK_EQUAL(featureIds.size(), chunksNumber, ());
- CHECK_EQUAL(icons.size(), chunksNumber, ());
- CHECK_EQUAL(expirations.size(), chunksNumber, ());
+ auto const featureIds = ReadVarUintArray<uint32_t>(src, chunksNumber);
+ auto const icons = ReadVarUintArray<uint16_t>(src, chunksNumber);
+ auto const expirations = ReadVarUintArray<uint8_t>(src, chunksNumber);
std::vector<Campaign> campaigns;
campaigns.reserve(chunksNumber);
@@ -135,35 +119,32 @@ std::vector<uint8_t> SerializeV2(std::vector<Campaign> const & campaigns)
{
std::vector<uint8_t> buff;
PushBackByteSink<decltype(buff)> dst(buff);
- Write(dst, Version::V2);
- Write(dst, campaigns.size());
+ WriteToSink(dst, Version::V2);
+ WriteToSink(dst, campaigns.size());
for (auto const & c : campaigns)
WriteVarUint(dst, c.m_featureId);
for (auto const & c : campaigns)
WriteVarUint(dst, c.m_iconId);
for (auto const & c : campaigns)
- Write(dst, c.m_daysBeforeExpired);
+ WriteVarUint(dst, c.m_daysBeforeExpired);
for (auto const & c : campaigns)
- Write(dst, PackZoomAndPriority(c.m_minZoomLevel, c.m_priority));
+ WriteToSink(dst, PackZoomAndPriority(c.m_minZoomLevel, c.m_priority));
return buff;
}
std::vector<Campaign> DeserializeV2(std::vector<uint8_t> const & bytes)
{
- ArrayByteSource src(bytes.data());
- CHECK_EQUAL(Read<Version>(src), Version::V2, ());
- auto const chunksNumber = Read<uint64_t>(src);
+ ReaderSource<MemReaderWithExceptions> src({bytes.data(), bytes.size()});
+
+ CHECK_EQUAL(ReadPrimitiveFromSource<Version>(src), Version::V2, ());
+ auto const chunksNumber = ReadPrimitiveFromSource<uint64_t>(src);
- auto const featureIds = ReadData<uint32_t>(src, chunksNumber);
- auto const icons = ReadData<uint16_t>(src, chunksNumber);
- auto const expirations = ReadData<uint8_t>(src, chunksNumber);
- auto const zoomAndPriority = ReadData<uint8_t>(src, chunksNumber);
+ auto const featureIds = ReadVarUintArray<uint32_t>(src, chunksNumber);
+ auto const icons = ReadVarUintArray<uint16_t>(src, chunksNumber);
+ auto const expirations = ReadVarUintArray<uint8_t>(src, chunksNumber);
- CHECK_EQUAL(featureIds.size(), chunksNumber, ());
- CHECK_EQUAL(icons.size(), chunksNumber, ());
- CHECK_EQUAL(expirations.size(), chunksNumber, ());
- CHECK_EQUAL(zoomAndPriority.size(), chunksNumber, ());
+ auto const zoomAndPriority = ReadArray<uint8_t>(src, chunksNumber);
std::vector<Campaign> campaigns;
campaigns.reserve(chunksNumber);
@@ -187,11 +168,18 @@ namespace local_ads
{
std::vector<uint8_t> Serialize(std::vector<Campaign> const & campaigns, Version const version)
{
- switch (version)
+ try
{
- case Version::V1: return SerializeV1(campaigns);
- case Version::V2: return SerializeV2(campaigns);
- default: ASSERT(false, ("Unknown version"));
+ switch (version)
+ {
+ case Version::V1: return SerializeV1(campaigns);
+ case Version::V2: return SerializeV2(campaigns);
+ default: MYTHROW(UnknownVersion, (version));
+ }
+ }
+ catch (RootException const & e)
+ {
+ LOG(LERROR, ("Cannot to serialize campaigns", e.what(), e.Msg()));
}
return {};
@@ -204,14 +192,26 @@ std::vector<uint8_t> Serialize(std::vector<Campaign> const & campaigns)
std::vector<Campaign> Deserialize(std::vector<uint8_t> const & bytes)
{
- ArrayByteSource src(bytes.data());
- auto const version = Read<Version>(src);
+ try
+ {
+ ReaderSource<MemReaderWithExceptions> src({bytes.data(), bytes.size()});
- switch (version)
+ auto const version = ReadPrimitiveFromSource<Version>(src);
+
+ switch (version)
+ {
+ case Version::V1: return DeserializeV1(bytes);
+ case Version::V2: return DeserializeV2(bytes);
+ default: MYTHROW(UnknownVersion, (version));
+ }
+ }
+ catch (RootException const & e)
{
- case Version::V1: return DeserializeV1(bytes);
- case Version::V2: return DeserializeV2(bytes);
- default: ASSERT(false, ("Unknown version"));
+ LOG(LERROR, ("Cannot to deserialize received data", e.what(), e.Msg()));
+ }
+ catch (std::bad_alloc const & e)
+ {
+ LOG(LERROR, ("Cannot to allocate memory for local ads campaigns", e.what()));
}
return {};
diff --git a/local_ads/local_ads_tests/campaign_serialization_test.cpp b/local_ads/local_ads_tests/campaign_serialization_test.cpp
index 4cec8f9ab0..a111539555 100644
--- a/local_ads/local_ads_tests/campaign_serialization_test.cpp
+++ b/local_ads/local_ads_tests/campaign_serialization_test.cpp
@@ -2,6 +2,7 @@
#include "local_ads/campaign_serialization.hpp"
+#include <limits>
#include <random>
#include <vector>
@@ -9,6 +10,9 @@ using namespace local_ads;
namespace
{
+template <typename T>
+using Limits = typename std::numeric_limits<T>;
+
bool TestSerialization(std::vector<Campaign> const & cs, Version const v)
{
auto const bytes = Serialize(cs, v);
@@ -19,9 +23,9 @@ std::vector<Campaign> GenerateCampaignsV1(size_t number)
{
std::random_device rd;
std::mt19937 gen(rd());
- std::uniform_int_distribution<> featureIds(1, 600000);
- std::uniform_int_distribution<> icons(1, 4096);
- std::uniform_int_distribution<> expirationDays(1, 30);
+ std::uniform_int_distribution<> featureIds(1, Limits<uint32_t>::max());
+ std::uniform_int_distribution<> icons(1, Limits<uint16_t>::max());
+ std::uniform_int_distribution<> expirationDays(1, Limits<uint8_t>::max());
std::vector<Campaign> cs;
while (number--)
@@ -38,9 +42,9 @@ std::vector<Campaign> GenerateCampaignsV2(size_t number)
{
int kSeed = 42;
std::mt19937 gen(kSeed);
- std::uniform_int_distribution<> featureIds(1, 600000);
- std::uniform_int_distribution<> icons(1, 4096);
- std::uniform_int_distribution<> expirationDays(1, 30);
+ std::uniform_int_distribution<> featureIds(1, Limits<uint32_t>::max());
+ std::uniform_int_distribution<> icons(1, Limits<uint16_t>::max());
+ std::uniform_int_distribution<> expirationDays(1, Limits<uint8_t>::max());
std::uniform_int_distribution<> zoomLevels(10, 17);
std::uniform_int_distribution<> priorities(0, 7);
@@ -61,14 +65,15 @@ std::vector<Campaign> GenerateCampaignsV2(size_t number)
UNIT_TEST(Serialization_Smoke)
{
TEST(TestSerialization({
- {10, 10, 10},
- {1000, 100, 20},
+ {0, 0, 0},
+ {Limits<uint32_t>::max(), Limits<uint16_t>::max(), Limits<uint8_t>::max()},
{120003, 456, 15}
}, Version::V1), ());
TEST(TestSerialization({
- {10, 10, 10, 10, 0},
- {1000, 100, 20, 17, 7},
+ {0, 0, 0, 10, 0},
+ {Limits<uint32_t>::max(), Limits<uint16_t>::max(), Limits<uint8_t>::max()},
+ {1000, 100, 255, 17, 7},
{120003, 456, 15, 13, 6}
}, Version::V2), ());