diff --git a/editor/editor_tests/xml_feature_test.cpp b/editor/editor_tests/xml_feature_test.cpp index 6f76e4e2f7..b1e6451283 100644 --- a/editor/editor_tests/xml_feature_test.cpp +++ b/editor/editor_tests/xml_feature_test.cpp @@ -60,6 +60,7 @@ UNIT_TEST(XMLFeature_Setters) feature.SetTagValue("opening_hours", "Mo-Fr 08:15-17:30"); feature.SetType("amenity|atm"); + feature.SetHeader(0xaf); stringstream sstr; feature.Save(sstr); @@ -87,6 +88,7 @@ UNIT_TEST(XMLFeature_Setters) + 0xaf )"; @@ -118,6 +120,7 @@ UNIT_TEST(XMLFeatureFromXml) + 0xaf )"; @@ -144,4 +147,5 @@ UNIT_TEST(XMLFeatureFromXml) TEST_EQUAL(my::TimestampToString(feature.GetModificationTime()), "2015-11-27T21:13:32Z", ()); TEST_EQUAL(feature.GetType(), "amenity|atm", ()); + TEST_EQUAL(feature.GetHeader(), 0xaf, ()); } diff --git a/editor/xml_feature.cpp b/editor/xml_feature.cpp index 1b830f0bb5..c319595721 100644 --- a/editor/xml_feature.cpp +++ b/editor/xml_feature.cpp @@ -50,6 +50,10 @@ void ValidateNode(pugi::xml_node const & node) throw; } + // TODO(mgsergio): try parse header. + if (!node.child("mapswithme:header")) + MYTHROW(editor::XMLFeatureNoHeaderError, ("Node has no mapswithme:header child")); + if (!node.attribute("timestamp")) MYTHROW(editor::XMLFeatureNoTimestampError, ("Node has no timestamp attribute")); } @@ -201,8 +205,26 @@ pair SplitMapsmeType(string const & type) ASSERT(parts.size() == 2, ("Too many parts in type: " + type)); return make_pair(parts[0], parts[1]); } + +bool ReadHexByte(string const & str, uint8_t & byte) +{ + stringstream sstr(str); + uint32_t result; + sstr >> std::hex >> result; + byte = static_cast(result); + return !sstr.fail(); +} + +bool WriteHexByte(uint8_t const byte, string & str) +{ + stringstream sstr; + sstr << std::hex << std::showbase << std::showbase << static_cast(byte); + str = sstr.str(); + return !sstr.fail(); +} } // namespace + namespace editor { XMLFeature::XMLFeature() @@ -255,6 +277,23 @@ void XMLFeature::SetType(string const & type) SetTagValue(p.first, p.second); } +uint8_t XMLFeature::GetHeader() const +{ + auto const node = GetRootNode().select_node("mapswithme:header"); + uint8_t result; + ReadHexByte(node.node().text().get(), result); + return result; +} + +void XMLFeature::SetHeader(uint8_t const header) +{ + auto node = GetRootNode().child("mapswithme:header"); + node = node ? node : GetRootNode().append_child("mapswithme:header"); + string hex; + WriteHexByte(header, hex); + node.text() = hex.data(); +} + m2::PointD XMLFeature::GetCenter() const { return PointFromLatLon(GetRootNode()); diff --git a/editor/xml_feature.hpp b/editor/xml_feature.hpp index 58fc76ef6e..d5b4369ea4 100644 --- a/editor/xml_feature.hpp +++ b/editor/xml_feature.hpp @@ -18,6 +18,7 @@ DECLARE_EXCEPTION(XMLFeatureError, RootException); DECLARE_EXCEPTION(XMLFeatureNoNodeError, XMLFeatureError); DECLARE_EXCEPTION(XMLFeatureNoLatLonError, XMLFeatureError); DECLARE_EXCEPTION(XMLFeatureNoTimestampError, XMLFeatureError); +DECLARE_EXCEPTION(XMLFeatureNoHeaderError, XMLFeatureError); class XMLFeature { @@ -35,9 +36,18 @@ public: string GetType() const; void SetType(string const & type); + uint8_t GetHeader() const; + void SetHeader(uint8_t const header); + string GetName(string const & lang) const; string GetName(uint8_t const langCode = StringUtf8Multilang::DEFAULT_CODE) const; + template + void ForEachName(TFunc && func) const + { + //TODO(mgsergio): implement me :) + } + void SetName(string const & name); void SetName(string const & lang, string const & name); void SetName(uint8_t const langCode, string const & name);