All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
SerializableUrlHash.h
1 // Copyright eeGeo Ltd (2012-2014), All Rights Reserved
2 
3 #pragma once
4 
5 #include "Types.h"
6 #include "tr1.h"
7 #include "IFileIO.h"
8 #include <string>
9 #include <iostream>
10 #include <vector>
11 
12 namespace Eegeo
13 {
14  namespace Helpers
15  {
17  {
18  public:
19  typedef Eegeo::unordered_set<std::string>::type TContainer;
20 
21  private:
22  IFileIO& m_fileIO;
23  TContainer m_members;
24  const unsigned int Sentinel;
25 
26  public:
27 
29  :m_fileIO(fileIO)
30  ,Sentinel(0x3605C077)
31  {}
32 
33  TContainer::const_iterator First() const { return m_members.begin(); }
34  TContainer::const_iterator End() const { return m_members.end(); }
35 
36  bool Contains(const std::string& item) {
37  return m_members.find(item) != m_members.end();
38  }
39 
40  void Add(const std::string& item) {
41  m_members.insert(item);
42  }
43 
44  void Remove(const std::string& item) {
45  TContainer::iterator it = m_members.find(item);
46  Eegeo_ASSERT(it != m_members.end());
47  m_members.erase(it);
48  }
49 
50  void FromFile(const std::string& file)
51  {
52  std::fstream stream;
53  size_t size;
54 
55  m_members.clear();
56 
57  //Check file mode (binary vs text) on windows
58  if(m_fileIO.OpenFile(stream, size, file))
59  {
60  int sentinelContainer = 0;
61  stream.read((char*)&sentinelContainer, sizeof(unsigned int));
62 
63  if(sentinelContainer != Sentinel)
64  {
65  //file is corrupted - bail
66  stream.close();
67  m_members.clear();
68  return;
69  }
70 
71  unsigned char labelSize = 0;
72  for(size_t index = sizeof(unsigned int); index < size - sizeof(unsigned int);) //room for sentinels
73  {
74  //string label length
75  stream.read((char*)&labelSize, sizeof(unsigned char));
76 
77  //read the buffer into a temp vector
78  std::vector<char> readBuffer(labelSize);
79  stream.read((char*)&readBuffer[0], sizeof(char)*labelSize);
80 
81  //copy the buffer into a string and add to members
82  std::string member;
83  member.assign(&readBuffer[0], labelSize);
84 
85  m_members.insert(member);
86 
87  index += (sizeof(char) + (sizeof(char) * labelSize));
88  }
89 
90  sentinelContainer = 0;
91  stream.read((char*)&sentinelContainer, sizeof(unsigned int));
92 
93  if(sentinelContainer != Sentinel)
94  {
95  //file is corrupted - bail
96  stream.close();
97  m_members.clear();
98  return;
99  }
100 
101  stream.close();
102  }
103  }
104 
105  void ToFile(std::string file)
106  {
107  size_t size = 0;
108 
109  size += 4; //start sentinel bytes
110 
111  //calculate the size
112  for(TContainer::const_iterator member = m_members.begin(); member != m_members.end(); ++ member)
113  {
114  Eegeo_ASSERT(member->size() <= std::numeric_limits<unsigned char>::max()); //url should be <= 256 chars
115  size += sizeof(char); //url length
116  size += sizeof(char) * member->size(); //url chars
117  }
118 
119  size += 4; //end sentinel bytes
120 
121  //make a buffer of correct size and copy data into it
122  std::vector<Byte> buffer;
123  buffer.resize(size);
124  int writeHead = 0;
125 
126  *(unsigned int*)(&buffer[writeHead]) = Sentinel;
127  writeHead += 4;
128 
129  for(TContainer::const_iterator member = m_members.begin(); member != m_members.end(); ++ member)
130  {
131  unsigned char stringLength = (unsigned char)member->size();
132 
133  buffer[writeHead] = stringLength;
134  writeHead += sizeof(unsigned char);
135 
136  memcpy(&buffer[writeHead], member->c_str(), stringLength);
137  writeHead += sizeof(char) * stringLength;
138  }
139 
140  *(unsigned int*)(&buffer[writeHead]) = Sentinel;
141  writeHead += 4;
142 
143  Eegeo_ASSERT(writeHead == size);
144 
145  if(!m_fileIO.WriteFile(&buffer[0], size, file))
146  {
147  Eegeo_ASSERT(false, "CACHE MANIFEST UPDATE FAILED");
148  }
149  }
150  };
151  }
152 }