nlib
MpReader.h
[詳解]
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_MSGPACK_MPREADER_H_
4 #define INCLUDE_NN_NLIB_MSGPACK_MPREADER_H_
5 
6 #include <map>
7 #include <string>
8 #include <utility>
9 #include <vector>
10 
11 #include "nn/nlib/InputStream.h"
13 #include "nn/nlib/Nlist.h"
14 
15 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS)
16 #undef NLIB_VIS_PUBLIC
17 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
18 #endif
19 
20 NLIB_NAMESPACE_BEGIN
21 namespace msgpack {
22 
23 class MpReader;
24 template <class T>
25 bool MpRead(MpReader* obj, T* v);
26 
28  size_t maxArraySize;
29  size_t maxMapSize;
30  size_t maxRawSize;
31 
32  public:
33  NLIB_CEXPR MpReaderSettings(size_t max_array_size_, size_t max_map_size_,
34  size_t max_raw_size_) NLIB_NOEXCEPT
35  : maxArraySize(max_array_size_),
36  maxMapSize(max_map_size_),
37  maxRawSize(max_raw_size_) {}
38  NLIB_CEXPR MpReaderSettings() NLIB_NOEXCEPT : maxArraySize(1024 * 64),
39  maxMapSize(1024),
40  maxRawSize(1024 * 512) {}
41 };
42 
44  public:
47  NLIB_VIS_PUBLIC bool Init(InputStream* istr,
48  const MpReaderSettings& settings) NLIB_NOEXCEPT NLIB_NONNULL;
49  bool Init(InputStream* istr) NLIB_NOEXCEPT NLIB_NONNULL {
50  return this->Init(istr, MpReaderSettings());
51  }
52  bool Close() NLIB_NOEXCEPT {
53  m_Istr = NULL;
54  return true;
55  }
56 
57  public:
58  static NLIB_VIS_PUBLIC bool Read(MpObject* obj, const void* p, size_t n,
59  const MpReaderSettings& settings) NLIB_NOEXCEPT NLIB_NONNULL;
60  static bool Read(MpObject* obj, const void* p, size_t n) NLIB_NOEXCEPT NLIB_NONNULL {
61  return Read(obj, p, n, MpReaderSettings());
62  }
63  void SetError(errno_t e) NLIB_NOEXCEPT {
64  if (m_ErrorValue == 0) m_ErrorValue = e;
65  }
66  errno_t GetErrorValue() const NLIB_NOEXCEPT { return m_ErrorValue; }
67  NLIB_VIS_PUBLIC bool GetNextValue() NLIB_NOEXCEPT;
68  NLIB_VIS_PUBLIC bool GetNextArrayNum(size_t* num) NLIB_NOEXCEPT;
69  NLIB_VIS_PUBLIC bool GetNextMapNum(size_t* num) NLIB_NOEXCEPT;
70  NLIB_VIS_PUBLIC bool GetNextRawNum(size_t* num) NLIB_NOEXCEPT;
71  NLIB_VIS_PUBLIC bool GetNextRawBody(void* p, size_t num) NLIB_NOEXCEPT;
72 
73  template <class T>
74  errno_t Convert(T* v) {
75  return this->Convert_(v);
76  }
77 
78  template <class T>
79  bool Read(T v) {
80  // T cannot be T* though v is only pointer type
81  // because of conflict against array types.
82  return Read_(v);
83  }
84  template <size_t n>
85  bool Read(char (&v)[n]) NLIB_NOEXCEPT {
86  return this->Read(&v[0], n); // n is OK
87  }
88  template <class T, size_t n>
89  bool Read(T (&v)[n]) {
90  return this->Read(&v[0], n);
91  }
92 
93  NLIB_VIS_PUBLIC bool Read(char* v, size_t n) NLIB_NOEXCEPT NLIB_NONNULL;
94  NLIB_VIS_PUBLIC bool Read(void* v, size_t n) NLIB_NOEXCEPT NLIB_NONNULL;
95  template <class T>
96  bool Read(T* v, size_t n) NLIB_NONNULL;
97  bool Read(MpObject* obj) NLIB_NOEXCEPT NLIB_NONNULL {
98  return this->Read_(&obj);
99  }
100 
101  NLIB_VIS_PUBLIC bool SkipMpObject() NLIB_NOEXCEPT;
102  NLIB_VIS_PUBLIC bool CheckString(const char* key, size_t keylen) NLIB_NOEXCEPT NLIB_NONNULL;
103  bool CheckString(const char* key) NLIB_NOEXCEPT NLIB_NONNULL {
104  return CheckString(key, nlib_strlen(key));
105  }
106  NLIB_SAFE_BOOL(MpReader, GetErrorValue() == 0);
107 
108  private:
109  NLIB_VIS_HIDDEN bool GetU32(uint32_t* pv) NLIB_NOEXCEPT;
110  NLIB_VIS_HIDDEN bool GetU64(uint64_t* pv) NLIB_NOEXCEPT;
111 
112  NLIB_VIS_PUBLIC errno_t Convert_(int8_t* v) NLIB_NOEXCEPT;
113  NLIB_VIS_PUBLIC errno_t Convert_(int16_t* v) NLIB_NOEXCEPT;
114  NLIB_VIS_PUBLIC errno_t Convert_(int32_t* v) NLIB_NOEXCEPT;
115  NLIB_VIS_PUBLIC errno_t Convert_(int64_t* v) NLIB_NOEXCEPT;
116  NLIB_VIS_PUBLIC errno_t Convert_(uint8_t* v) NLIB_NOEXCEPT;
117  NLIB_VIS_PUBLIC errno_t Convert_(uint16_t* v) NLIB_NOEXCEPT;
118  NLIB_VIS_PUBLIC errno_t Convert_(uint32_t* v) NLIB_NOEXCEPT;
119  NLIB_VIS_PUBLIC errno_t Convert_(uint64_t* v) NLIB_NOEXCEPT;
120  NLIB_VIS_PUBLIC errno_t Convert_(float* v) NLIB_NOEXCEPT;
121  NLIB_VIS_PUBLIC errno_t Convert_(double* v) NLIB_NOEXCEPT;
122  NLIB_VIS_PUBLIC errno_t Convert_(bool* v) NLIB_NOEXCEPT;
124  template <class T>
125  errno_t Convert_(T* v);
126 
127 #define NLIB_EXEC_READ return GetNextValue() ? (void)this->Convert(v), true : false
128  NLIB_VIS_PUBLIC bool Read_(int8_t* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
129  NLIB_VIS_PUBLIC bool Read_(int16_t* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
130  NLIB_VIS_PUBLIC bool Read_(int32_t* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
131  NLIB_VIS_PUBLIC bool Read_(int64_t* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
132  NLIB_VIS_PUBLIC bool Read_(uint8_t* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
133  NLIB_VIS_PUBLIC bool Read_(uint16_t* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
134  NLIB_VIS_PUBLIC bool Read_(uint32_t* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
135  NLIB_VIS_PUBLIC bool Read_(uint64_t* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
136  NLIB_VIS_PUBLIC bool Read_(float* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
137  NLIB_VIS_PUBLIC bool Read_(double* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
138  NLIB_VIS_PUBLIC bool Read_(bool* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
139  NLIB_VIS_PUBLIC bool Read_(nil* v) NLIB_NOEXCEPT { NLIB_EXEC_READ; }
140  NLIB_VIS_PUBLIC bool Read_(std::string* v);
141  NLIB_VIS_PUBLIC bool Read_(MpObject** o) NLIB_NOEXCEPT;
142  template <class T>
143  bool Read_(T* v);
144 #undef NLIB_EXEC_READ
145 
146  NLIB_VIS_HIDDEN bool ReadMap(MpObject* obj, uint32_t n) NLIB_NOEXCEPT;
147  NLIB_VIS_HIDDEN bool ReadArray(MpObject* obj, uint32_t n) NLIB_NOEXCEPT;
148  NLIB_VIS_HIDDEN bool ReadRaw(MpObject* obj, uint32_t n) NLIB_NOEXCEPT;
149 
150  private:
151  struct ValueObj {
152  enum Category {
153  CAT_NIL = 0,
154  CAT_FALSE,
155  CAT_TRUE,
156  CAT_UINT,
157  CAT_INT,
158  CAT_FLOAT,
159  CAT_UINT64,
160  CAT_INT64,
161  CAT_DOUBLE
162  };
163  Category category;
164  union {
165  uint32_t u;
166  int32_t i;
167  float f;
168  uint64_t u64;
169  int64_t i64;
170  double d;
171  } value;
172  ValueObj() NLIB_NOEXCEPT : category(CAT_NIL) {}
173  };
174  size_t m_MaxArraySize;
175  size_t m_MaxMapSize;
176  size_t m_MaxRawSize;
177  InputStream* m_Istr;
178  errno_t m_ErrorValue;
179  ValueObj m_Obj;
181 };
182 
183 template <class T>
184 bool MpReader::Read(T* v, size_t n) {
185  size_t num;
186  if (!this->GetNextArrayNum(&num)) return false;
187  if (n < num) {
188  SetError(E2BIG);
189  return false;
190  }
191  size_t i;
192  for (i = 0; i < num; ++i) {
193  if (!this->Read(&v[i])) return false;
194  }
195  // The case of n > num is not error.
196  for (; i < n; ++i) {
197  v[i] = T();
198  }
199  return true;
200 }
201 
202 template <class T1, class T2>
203 inline bool MpRead(MpReader* r, std::pair<T1, T2>* v) {
204  size_t num;
205  if (!r->GetNextArrayNum(&num)) return false;
206  if (num != 2) {
207  r->SetError(E2BIG); // E2BIG even if num is 1
208  return false;
209  }
210  if (!r->Read(&v->first)) return false;
211  if (!r->Read(&v->second)) return false;
212  return true;
213 }
214 
215 template <class T, class Alloc>
216 bool MpRead(MpReader* r, std::vector<T, Alloc>* v) {
217  size_t num;
218  if (!r->GetNextArrayNum(&num)) return false;
219  v->resize(num);
220  for (size_t i = 0; i < num; ++i) {
221  if (!r->Read(&(*v)[i])) return false;
222  }
223  return true;
224 }
225 
226 template <class T, class Alloc>
228  size_t num;
229  if (!r->GetNextArrayNum(&num)) return false;
230  v->clear();
231  if (!v->reserve(num)) return false;
232  for (size_t i = 0; i < num; ++i) {
233  T* item = v->push_back();
234  if (!r->Read(item)) return false;
235  }
236  return true;
237 }
238 
239 template <class K, class V, class Pr, class Alloc>
240 bool MpRead(MpReader* r, std::map<K, V, Pr, Alloc>* m) {
241  size_t num;
242  if (!r->GetNextMapNum(&num)) return false;
243  K key;
244  V value;
245  for (size_t i = 0; i < num; ++i) {
246  if (!r->Read(&key)) return false;
247  if (!r->Read(&value)) return false;
248  (*m)[key] = value;
249  }
250  return true;
251 }
252 
253 template <class T>
254 bool MpReader::Read_(T* v) {
256 }
257 
258 #define NLIB_MPREADER_READ_(tp, coerce) \
259  \
260 template<> inline bool MpReader::Read_<tp>(tp * v) { \
261  coerce vv; \
262  if (!Read_(&vv)) return false; \
263  *v = static_cast<tp>(vv); \
264  return true; \
265  \
266 }
267 
268 NLIB_MPREADER_READ_(char, int8_t)
269 NLIB_MPREADER_READ_(unsigned char, uint8_t)
270 NLIB_MPREADER_READ_(int, int32_t)
271 NLIB_MPREADER_READ_(unsigned int, uint32_t)
272 NLIB_MPREADER_READ_(short, int16_t) // NOLINT
273 NLIB_MPREADER_READ_(unsigned short, uint16_t) // NOLINT
274 NLIB_MPREADER_READ_(long, nlib_long_compatible_t) // NOLINT
275 NLIB_MPREADER_READ_(unsigned long, nlib_ulong_compatible_t) // NOLINT
276 NLIB_MPREADER_READ_(long long, int64_t) // NOLINT
277 NLIB_MPREADER_READ_(unsigned long long, uint64_t) // NOLINT
278 
279 #undef NLIB_MPREADER_READ_
280 
281 #define NLIB_MPREADER_CONVERT_(tp, coerce) \
282  \
283 template<> inline errno_t MpReader::Convert_<tp>(tp * v) { \
284  return this->Convert_(reinterpret_cast<coerce*>(v)); \
285  \
286 }
287 
288 NLIB_MPREADER_CONVERT_(char, int8_t)
289 NLIB_MPREADER_CONVERT_(unsigned char, uint8_t)
290 NLIB_MPREADER_CONVERT_(int, int32_t)
291 NLIB_MPREADER_CONVERT_(unsigned int, uint32_t)
292 NLIB_MPREADER_CONVERT_(short, int16_t) // NOLINT
293 NLIB_MPREADER_CONVERT_(unsigned short, uint16_t) // NOLINT
294 NLIB_MPREADER_CONVERT_(long, nlib_long_compatible_t) // NOLINT
295 NLIB_MPREADER_CONVERT_(unsigned long, nlib_ulong_compatible_t) // NOLINT
296 NLIB_MPREADER_CONVERT_(long long, int64_t) // NOLINT
297 NLIB_MPREADER_CONVERT_(unsigned long long, uint64_t) // NOLINT
298 
299 #undef NLIB_MPREADER_CONVERT_
300 
301 } // namespace msgpack
302 NLIB_NAMESPACE_END
303 
304 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS)
305 #undef NLIB_VIS_PUBLIC
306 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
307 #endif
308 
309 #endif // INCLUDE_NN_NLIB_MSGPACK_MPREADER_H_
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
Definition: Platform.h:2151
bool Read(char(&v)[n]) noexcept
Read(T (&vec)[n]) を御覧ください。
Definition: MpReader.h:85
bool Read(T(&v)[n])
配列又は文字列を読み込みます。
Definition: MpReader.h:89
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
#define NLIB_NONNULL
全ての引数にNULLを指定することができないことを示します。
Definition: Platform_unix.h:66
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
Definition: Config.h:126
#define NLIB_SAFE_BOOL(class_name, exp)
クラス内に安全なoperator bool()を定義します。 可能であればC++11のexplicit boolを利用します。 ...
Definition: Config.h:141
入力ストリームの基底クラスを定義しています。
MessagePack形式のデータをストリームから読み込みます。
Definition: MpReader.h:43
errno_t GetErrorValue() const noexcept
発生したエラーを取得します。
Definition: MpReader.h:66
#define NLIB_VIS_HIDDEN
関数やクラス等のシンボルをライブラリの外部に公開しません。
Definition: Platform_unix.h:50
static bool Read(MpObject *obj, const void *p, size_t n, const MpReaderSettings &settings) noexcept
MpReaderオブジェクトを構築して、p からMpObjectを設定します。
uint32_t nlib_ulong_compatible_t
unsigned longと互換性のある整数型がtypedefされています。
Definition: Platform.h:425
void SetError(errno_t e) noexcept
エラーを設定します。
Definition: MpReader.h:63
bool Close() noexcept
MpReaderをクローズします。
Definition: MpReader.h:52
MessagePack又はJSONを読み込むことで作成されるオブジェクトです。
Definition: MpObject.h:83
size_t maxMapSize
連想配列の最大サイズを指定します。デフォルトは1024です。
Definition: MpReader.h:29
size_t maxArraySize
配列の最大サイズを指定します。デフォルトは65536です。
Definition: MpReader.h:28
pointer push_back()
末尾に要素を追加してデフォルトコンストラクタで初期化します。
Definition: Nlist.h:377
bool GetNextArrayNum(size_t *num) noexcept
配列のサイズデータを読み込みます。
bool GetNextMapNum(size_t *num) noexcept
連想配列のサイズデータを読み込みます。
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
std::vectorに似ていますが、コピーできないオブジェクトを格納可能なクラスが定義されています。 ...
static bool Read(MpObject *obj, const void *p, size_t n) noexcept
Read(MpObject* obj, const void* p, size_t n, const MpReaderSettings& settings)をsettings をデフォルト...
Definition: MpReader.h:60
bool Init(InputStream *istr) noexcept
オブジェクトを初期化します。
Definition: MpReader.h:49
void clear() noexcept
コンテナをクリアします。
Definition: Nlist.h:415
bool MpRead(MpReader *r, std::map< K, V, Pr, Alloc > *m)
データをmapに読み込みます。
Definition: MpReader.h:240
MessagePack, JSON及びCSVを読み込むと作成されるオブジェクトです。
入力ストリームの基底クラスです。このクラスを実体化することはできません。
Definition: InputStream.h:15
MpReaderの設定パラメータ群を格納する構造体です。
Definition: MpReader.h:27
bool Read(MpObject *obj) noexcept
Read(T v) を御覧ください。
Definition: MpReader.h:97
bool reserve(size_type n) noexcept
n 個の要素のためのメモリをアロケート済みにします。
Definition: Nlist.h:661
std::vectorに似た、コピーコンストラクタを持たないオブジェクトを格納可能なコンテナ類似クラスです。 ...
Definition: Nlist.h:19
constexpr MpReaderSettings(size_t max_array_size_, size_t max_map_size_, size_t max_raw_size_) noexcept
各データメンバを設定します。
Definition: MpReader.h:33
size_t nlib_strlen(const char *s)
内部でstrlen()を呼び出します。独自の実装が動作する場合もあります。
nlib_i64_t i64
nlib_i64_tがtypedefされています。
Definition: SimdInt.h:69
constexpr MpReaderSettings() noexcept
デフォルトコンストラクタです。各データメンバにデフォルト値を設定します。
Definition: MpReader.h:38
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:51
bool Read(T v)
ストリームからデータを読み込み、vに設定します。
Definition: MpReader.h:79
bool Read(BinaryReader *r, T *x)
この関数テンプレートを特殊化することで、ユーザー定義クラスに読み込むことができます。 ...
Definition: BinaryReader.h:158
size_t maxRawSize
バイト列の最大サイズを指定します。デフォルトは512KBytesです。
Definition: MpReader.h:30
int32_t nlib_long_compatible_t
longと互換性のある整数型がtypedefされています。
Definition: Platform.h:424
MessagePackのnil, 及びJSONのnullに対応するクラスです。
Definition: MpObject.h:44
bool ReadArray(BinaryReader *r, T *x, size_t n)
この関数テンプレートを特殊化することで、ユーザー定義クラスに読み込むことができます。 ...
Definition: BinaryReader.h:161
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:24