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:
Diffstat (limited to 'local_ads/campaign_serialization.cpp')
-rw-r--r--local_ads/campaign_serialization.cpp110
1 files changed, 79 insertions, 31 deletions
diff --git a/local_ads/campaign_serialization.cpp b/local_ads/campaign_serialization.cpp
index 4b64e1a87d..7c20bf7042 100644
--- a/local_ads/campaign_serialization.cpp
+++ b/local_ads/campaign_serialization.cpp
@@ -13,8 +13,9 @@ namespace
{
using namespace local_ads;
-auto const kHalfByteShift = 0x4;
-auto const kLowerMask = 0xF;
+auto const kHalfByteShift = CHAR_BIT / 2;
+auto const kHalfByteMaxValue = 15;
+auto const kLowerMask = 0x0F;
auto const kUpperMask = 0xF0;
auto const kMinZoomLevel = 10;
auto const kMaxZoomLevel = 17;
@@ -61,10 +62,27 @@ std::vector<Integral> ReadData(ByteStream & s, size_t chunksNumber)
return result;
}
+
+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());
+ 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);
+
+ return buff;
+}
+
std::vector<Campaign> DeserializeV1(std::vector<uint8_t> const & bytes)
{
ArrayByteSource src(bytes.data());
- CHECK_EQUAL(Read<Version>(src), Version::v1, ());
+ CHECK_EQUAL(Read<Version>(src), Version::V1, ());
auto const chunksNumber = Read<uint64_t>(src);
auto const featureIds = ReadData<uint32_t>(src, chunksNumber);
@@ -88,10 +106,52 @@ uint8_t ZoomIndex(uint8_t zoomValue) { return zoomValue - kMinZoomLevel; }
uint8_t ZoomValue(uint8_t zoomIndex) { return zoomIndex + kMinZoomLevel; }
+uint8_t PackZoomAndPriority(uint8_t minZoomLevel, uint8_t priority)
+{
+ ASSERT_GREATER_OR_EQUAL(minZoomLevel, kMinZoomLevel, ("Unsupported zoom level"));
+ ASSERT_LESS_OR_EQUAL(minZoomLevel, kMaxZoomLevel, ("Unsupported zoom level"));
+ ASSERT_LESS_OR_EQUAL(priority, kMaxPriority, ("Unsupported priority value"));
+
+ auto const zoomIndex = ZoomIndex(minZoomLevel);
+ ASSERT_LESS_OR_EQUAL(zoomIndex, kHalfByteMaxValue, ());
+ ASSERT_LESS_OR_EQUAL(priority, kHalfByteMaxValue, ());
+
+ // Pack zoom and priority into single byte.
+ return (zoomIndex & kLowerMask) | ((priority << kHalfByteShift) & kUpperMask);
+}
+
+uint8_t UnpackZoom(uint8_t src)
+{
+ return ZoomValue(src & kLowerMask);
+}
+
+uint8_t UnpackPriority(uint8_t src)
+{
+ return (src >> kHalfByteShift) & kLowerMask;
+}
+
+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());
+ 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);
+ for (auto const & c : campaigns)
+ Write(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, ());
+ CHECK_EQUAL(Read<Version>(src), Version::V2, ());
auto const chunksNumber = Read<uint64_t>(src);
auto const featureIds = ReadData<uint32_t>(src, chunksNumber);
@@ -109,8 +169,8 @@ std::vector<Campaign> DeserializeV2(std::vector<uint8_t> const & bytes)
for (size_t i = 0; i < chunksNumber; ++i)
{
campaigns.emplace_back(featureIds[i], icons[i], expirations[i],
- ZoomValue(zoomAndPriority[i] & kLowerMask),
- (zoomAndPriority[i] >> kHalfByteShift) & kLowerMask);
+ UnpackZoom(zoomAndPriority[i]),
+ UnpackPriority(zoomAndPriority[i]));
ASSERT_GREATER_OR_EQUAL(campaigns.back().m_minZoomLevel, kMinZoomLevel,
("Unsupported zoom level"));
@@ -126,32 +186,19 @@ namespace local_ads
{
std::vector<uint8_t> Serialize(std::vector<Campaign> const & campaigns, Version const version)
{
- std::vector<uint8_t> buff;
- PushBackByteSink<decltype(buff)> dst(buff);
- Write(dst, version);
- Write(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);
- for (auto const & c : campaigns)
+ switch (version)
{
- ASSERT_GREATER_OR_EQUAL(c.m_minZoomLevel, kMinZoomLevel, ("Unsupported zoom level"));
- ASSERT_LESS_OR_EQUAL(c.m_minZoomLevel, kMaxZoomLevel, ("Unsupported zoom level"));
- ASSERT_LESS_OR_EQUAL(c.m_priority, kMaxPriority, ("Unsupported priority value"));
-
- Write(dst, static_cast<uint8_t>((ZoomIndex(c.m_minZoomLevel) & kLowerMask) |
- ((c.m_priority << kHalfByteShift) & kUpperMask)));
+ case Version::V1: return SerializeV1(campaigns);
+ case Version::V2: return SerializeV2(campaigns);
+ default: ASSERT(false, ("Unknown version"));
}
- return buff;
+ return {};
}
std::vector<uint8_t> Serialize(std::vector<Campaign> const & campaigns)
{
- return Serialize(campaigns, Version::latest);
+ return Serialize(campaigns, Version::Latest);
}
std::vector<Campaign> Deserialize(std::vector<uint8_t> const & bytes)
@@ -161,9 +208,9 @@ std::vector<Campaign> Deserialize(std::vector<uint8_t> const & bytes)
switch (version)
{
- case Version::v1: return DeserializeV1(bytes);
- case Version::v2: return DeserializeV2(bytes);
- default: ASSERT(false, ("Unknown version type"));
+ case Version::V1: return DeserializeV1(bytes);
+ case Version::V2: return DeserializeV2(bytes);
+ default: ASSERT(false, ("Unknown version"));
}
return {};
@@ -175,9 +222,10 @@ std::string DebugPrint(local_ads::Version version)
switch (version)
{
- case Version::unknown: return "Unknown";
- case Version::v1: return "Version 1";
- case Version::v2: return "Version 2";
+ case Version::Unknown: return "Unknown";
+ case Version::V1: return "Version 1";
+ case Version::V2: return "Version 2";
+ default: ASSERT(false, ("Unknown version"));
}
}
} // namespace local_ads