All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
BinaryParsing.h
1 // Copyright eeGeo Ltd (2012-2014), All Rights Reserved
2 
3 #pragma once
4 
5 #include "Types.h"
6 #include "VectorMath.h"
7 #include "Bounds.h"
8 #include <streambuf>
9 #include <cstdio>
10 #include <istream>
11 #include <string>
12 #include <vector>
13 
14 namespace Eegeo
15 {
16  namespace Resources
17  {
18  namespace BinaryParsing
19  {
20  class membuf : public std::basic_streambuf<char>, protected Eegeo::NonCopyable
21  {
22  public:
23  membuf(char* p, size_t n) {
24  setg(p, p, p + n);
25  }
26 
27  char* getCurrent() const
28  {
29  return gptr();
30  }
31 
32  protected:
33  virtual pos_type seekoff( off_type off, std::ios_base::seekdir dir,
34  std::ios_base::openmode which = std::ios_base::in | std::ios_base::out )
35  {
36  //Eegeo_ASSERT(which == std::ios_base::in);
37 
38  if (dir == std::ios::cur)
39  {
40  setg(eback(), gptr() + off, egptr());
41  }
42  else if (dir == std::ios::beg)
43  {
44  setg(eback(), eback() + off, egptr());
45  }
46  else if (dir == std::ios::end)
47  {
48  setg(eback(), egptr() - off, egptr());
49  }
50 
51  if (gptr() < eback())
52  return -1;
53  if (gptr() > egptr())
54  return -1;
55  return gptr() - eback();
56  }
57 
58  virtual pos_type seekpos( pos_type off,
59  std::ios_base::openmode which = std::ios_base::in | std::ios_base::out )
60  {
61  return seekoff(off, std::ios::beg, which);
62  };
63 
64  };
65 
66  bool StreamIsAligned(std::istream& stream, int alignment, bool alignedReads);
67 
68  void AlignStream(std::istream& reader, int alignment, bool alignedReads);
69 
70  namespace
71  {
72  template <class T>
73  T ParseT(std::istream& reader, bool alignedReads)
74  {
75  AlignStream(reader, sizeof(T), alignedReads);
76  T result;
77  reader.read((char*)&result, sizeof(T));
78  return result;
79  }
80 
81  template <>
82  inline Eegeo::v2 ParseT<Eegeo::v2>(std::istream& reader, bool alignedReads)
83  {
84  AlignStream(reader, sizeof(float), alignedReads);
85  Eegeo::v2 result;
86  reader.read((char*)&result, sizeof(Eegeo::v2));
87  return result;
88  }
89 
90  template <>
91  inline Eegeo::v3 ParseT<Eegeo::v3>(std::istream& reader, bool alignedReads)
92  {
93  AlignStream(reader, sizeof(float), alignedReads);
94  Eegeo::v3 result;
95  reader.read((char*)&result, sizeof(Eegeo::v3));
96  return result;
97  }
98 
99  template <>
100  inline Eegeo::v4 ParseT<Eegeo::v4>(std::istream& reader, bool alignedReads)
101  {
102  AlignStream(reader, sizeof(float), alignedReads);
103  Eegeo::v4 result;
104  reader.read((char*)&result, sizeof(Eegeo::v4));
105  return result;
106  }
107 
108  template <>
109  inline Eegeo::m44 ParseT<Eegeo::m44>(std::istream& reader, bool alignedReads)
110  {
111  AlignStream(reader, sizeof(float), alignedReads);
112  Eegeo::m44 result;
113  reader.read((char*)&result, sizeof(Eegeo::m44));
114  return result;
115  }
116 
117  template <>
118  inline Eegeo::Geometry::DoubleBounds3D ParseT<Eegeo::Geometry::DoubleBounds3D>(std::istream& reader, bool alignedReads)
119  {
120  AlignStream(reader, sizeof(double), alignedReads);
122  reader.read((char*)&result, sizeof(Eegeo::Geometry::DoubleBounds3D));
123  return result;
124  }
125  }
126 
128  {
129  public:
130  BinaryParser(const bool alignedReads);
131 
132  template <class T>
133  T Parse(std::istream& reader, size_t *parseSize) const
134  {
135  AlignStream(reader, sizeof(T));
136  T result;
137  reader.read((char*)&result, sizeof(T));
138 
139  *parseSize += sizeof(T);
140 
141  return result;
142  }
143 
144  template <class T>
145  T Parse(std::istream& reader) const
146  {
147  return ParseT<T>(reader, m_alignedReads);
148  }
149 
150  template <class T, size_t N>
151  void Parse(std::istream& reader, T (&result)[N]) const
152  {
153  AlignStream(reader, sizeof(T));
154  reader.read((char*)&result, sizeof(T) * N);
155  }
156 
157  template <class T>
158  void ParseShortString(std::istream& reader, std::string& outputString) const
159  {
160  size_t length = Parse<T>(reader);
161 
162  AlignStream(reader, sizeof(char));
163  outputString.resize(length);
164  reader.read((char*)&outputString[0], length * sizeof(char));
165  }
166 
167  std::string ParseFourCC(std::istream& reader) const;
168 
169  u32 Read7BitEncodedInt(std::istream& reader) const;
170  std::string ParseString(std::istream& reader) const;
171  std::vector<std::string> ParseStringArray(std::istream& reader) const;
172 
173  bool StreamIsAligned(std::istream& stream, int alignment) const
174  {
175  return BinaryParsing::StreamIsAligned(stream, alignment, m_alignedReads);
176  }
177 
178  void AlignStream(std::istream& stream, int alignment) const
179  {
180  BinaryParsing::AlignStream(stream, alignment, m_alignedReads);
181  }
182 
183  private:
184  bool m_alignedReads;
185  };
186  }
187  }
188 }