| 195 | } |
| 196 | |
| 197 | bool Editor::Save(FeaturesContainer const & features) const |
| 198 | { |
| 199 | if (features.empty()) |
| 200 | return m_storage->Reset(); |
| 201 | |
| 202 | LOG(LINFO, ("Saving OSM edits to XML...")); |
| 203 | |
| 204 | xml_document doc; |
| 205 | xml_node root = doc.append_child(kXmlRootNode); |
| 206 | // Use format_version for possible future format changes. |
| 207 | root.append_attribute("format_version") = 1; |
| 208 | for (auto const & mwm : features) |
| 209 | { |
| 210 | if (!mwm.first.IsAlive()) |
| 211 | continue; |
| 212 | |
| 213 | xml_node mwmNode = root.append_child(kXmlMwmNode); |
| 214 | mwmNode.append_attribute("name") = mwm.first.GetInfo()->GetCountryName().c_str(); |
| 215 | mwmNode.append_attribute("version") = static_cast<long long>(mwm.first.GetInfo()->GetVersion()); |
| 216 | xml_node const deleted = mwmNode.append_child(kDeleteSection); |
| 217 | xml_node const modified = mwmNode.append_child(kModifySection); |
| 218 | xml_node const created = mwmNode.append_child(kCreateSection); |
| 219 | xml_node const obsolete = mwmNode.append_child(kObsoleteSection); |
| 220 | for (auto & index : mwm.second) |
| 221 | { |
| 222 | FeatureTypeInfo const & fti = index.second; |
| 223 | // TODO: Do we really need to serialize deleted features in full details? Looks like mwm ID |
| 224 | // and meta fields are enough. |
| 225 | XMLFeature xf = editor::ToXML(fti.m_object, true /* type serializing helps during migration */); |
| 226 | xf.SetEditJournal(fti.m_object.GetJournal()); |
| 227 | xf.SetMWMFeatureIndex(index.first); |
| 228 | if (!fti.m_street.empty()) |
| 229 | xf.SetTagValue(kAddrStreetTag, fti.m_street); |
| 230 | ASSERT_NOT_EQUAL(0, fti.m_modificationTimestamp, ()); |
| 231 | xf.SetModificationTime(fti.m_modificationTimestamp); |
| 232 | if (fti.m_uploadAttemptTimestamp != base::INVALID_TIME_STAMP) |
| 233 | { |
| 234 | xf.SetUploadTime(fti.m_uploadAttemptTimestamp); |
| 235 | ASSERT(!fti.m_uploadStatus.empty(), ("Upload status updates with upload timestamp.")); |
| 236 | xf.SetUploadStatus(fti.m_uploadStatus); |
| 237 | if (!fti.m_uploadError.empty()) |
| 238 | xf.SetUploadError(fti.m_uploadError); |
| 239 | } |
| 240 | LOG(LDEBUG, ("Saved XMLFeature:\n", editor::DebugPrint(xf))); |
| 241 | switch (fti.m_status) |
| 242 | { |
| 243 | case FeatureStatus::Deleted: VERIFY(xf.AttachToParentNode(deleted), ()); break; |
| 244 | case FeatureStatus::Modified: VERIFY(xf.AttachToParentNode(modified), ()); break; |
| 245 | case FeatureStatus::Created: VERIFY(xf.AttachToParentNode(created), ()); break; |
| 246 | case FeatureStatus::Obsolete: VERIFY(xf.AttachToParentNode(obsolete), ()); break; |
| 247 | case FeatureStatus::Untouched: CHECK(false, ("Not edited features shouldn't be here.")); |
| 248 | } |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | return m_storage->Save(doc); |
| 253 | } |
| 254 |
nothing calls this directly
no test coverage detected