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

feature_meta.hpp « indexer - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8d1fb5dce400410337367d06b5a9ca280ed4cdb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#pragma once

#include "../coding/reader.hpp"
#include "../coding/multilang_utf8_string.hpp"

#include "../std/map.hpp"
#include "../std/string.hpp"
#include "../std/limits.hpp"
#include "../std/algorithm.hpp"
#include "../std/vector.hpp"

namespace feature
{
  class FeatureMetadata
  {
    typedef map<uint8_t, string> MetadataT;
    MetadataT m_metadata;

  public:
    enum EMetadataType {
      FMD_CUISINE = 1,
      FMD_OPEN_HOURS = 2,
      FMD_PHONE_NUMBER = 3,
      FMD_FAX_NUMBER = 4,
      FMD_STARS = 5,
      FMD_OPERATOR = 6,
      FMD_URL = 7,
      FMD_WEBSITE = 8,
      FMD_INTERNET = 9,
      FMD_ELE = 10,
      FMD_TURN_LANES = 11,
      FMD_TURN_LANES_FORWARD = 12,
      FMD_TURN_LANES_BACKWARD = 13,
      FMD_EMAIL = 14
    };

    bool Add(EMetadataType type, string const & s)
    {
      if (m_metadata[type].empty())
      {
        m_metadata[type] = s;
      }
      else
      {
        m_metadata[type] = m_metadata[type] + ", " + s;
      }
      return true;
    }

    string Get(EMetadataType type) const
    {
      auto it = m_metadata.find(type);
      return (it == m_metadata.end()) ? string() : it->second;
    }

    vector<EMetadataType> GetPresentTypes() const
    {
      vector<EMetadataType> types;
      for (auto item: m_metadata)
        types.push_back(static_cast<EMetadataType>(item.first));

      return types;
    }

    void Drop(EMetadataType type)
    {
      m_metadata.erase(type);
    }

    inline bool Empty() const { return m_metadata.empty(); }
    inline size_t Size() const { return m_metadata.size(); }

    template <class ArchiveT> void SerializeToMWM(ArchiveT & ar) const
    {
      for (auto const & e: m_metadata)
      {
        uint8_t last_key_mark = (&e == &(*m_metadata.crbegin())) << 7; /// set high bit (0x80) if it last element
        uint8_t elem[2] = {static_cast<uint8_t>(e.first | last_key_mark), static_cast<uint8_t>(min(e.second.size(), (size_t)numeric_limits<uint8_t>::max()))};
        ar.Write(elem, sizeof(elem));
        ar.Write(e.second.data(), elem[1]);
      }
    }
    template <class ArchiveT> void DeserializeFromMWM(ArchiveT & ar)
    {
      uint8_t header[2] = {0};
      char buffer[uint8_t(-1)] = {0};
      do
      {
        ar.Read(header, sizeof(header));
        ar.Read(buffer, header[1]);
        m_metadata[static_cast<uint8_t>(header[0] & 0x7F)].assign(buffer, header[1]);
      } while (!(header[0] & 0x80));
    }

    template <class ArchiveT> void Serialize(ArchiveT & ar) const
    {
      uint8_t const metadata_size = m_metadata.size();
      WriteToSink(ar, metadata_size);
      if (metadata_size)
      {
        for(auto & it: m_metadata)
        {
          WriteToSink(ar, static_cast<uint8_t>(it.first));
          utils::WriteString(ar, it.second);
        }
      }
    }

    template <class ArchiveT> void Deserialize(ArchiveT & ar)
    {
      uint8_t const metadata_size = ReadPrimitiveFromSource<uint8_t>(ar);
      for (size_t i=0; i < metadata_size; ++i)
      {
        uint8_t const key = ReadPrimitiveFromSource<uint8_t>(ar);
        string value;
        utils::ReadString(ar, value);
        m_metadata.insert(make_pair(key, value));
      }

    }
  };
}