nlib
MpWriter.h
[詳解]
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_MSGPACK_MPWRITER_H_
4 #define INCLUDE_NN_NLIB_MSGPACK_MPWRITER_H_
5 
6 #include <map>
7 #include <string>
8 #include <utility>
9 #include <vector>
10 
12 #include "nn/nlib/OutputStream.h"
13 #include "nn/nlib/BinaryWriter.h"
14 #include "nn/nlib/Cstring.h"
15 #include "nn/nlib/Nlist.h"
16 
17 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS)
18 #undef NLIB_VIS_PUBLIC
19 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
20 #endif
21 
22 NLIB_NAMESPACE_BEGIN
23 namespace msgpack {
24 
25 class MpWriter;
26 
27 template <class T>
28 bool MpWrite(MpWriter* obj, const T& v);
29 
31  public:
32  MpWriter() NLIB_NOEXCEPT : m_ErrorValue(0) {}
33  ~MpWriter() NLIB_NOEXCEPT { this->Close(); }
34  bool Init(OutputStream* stream) NLIB_NOEXCEPT NLIB_NONNULL;
36  if (!m_Writer.Flush()) {
37  this->SetError(EIO);
38  return false;
39  }
40  return this->GetErrorValue() == 0;
41  }
43  // MpWriter does not own m_Ostr, and do not close m_Ostr.
44  if (!m_Writer.Close()) {
45  this->SetError(EIO);
46  }
47  return this->GetErrorValue() == 0;
48  }
50  if (m_ErrorValue == 0) m_ErrorValue = e;
51  }
52  errno_t GetErrorValue() const NLIB_NOEXCEPT { return m_ErrorValue; }
53 
54  public:
55  bool Write(const char* str) NLIB_NOEXCEPT NLIB_NONNULL {
56  return this->Write(&str[0], nlib_strlen(str));
57  }
58  template <uint32_t n>
59  bool Write(const char (&str)[n]) NLIB_NOEXCEPT {
60  return this->Write(&str[0], nlib_strlen(str));
61  }
62  template <class T, size_t n>
63  bool Write(const T (&vec)[n]);
64  template <class T>
65  bool Write(const T& tp);
66 
67  bool Write(const void* p, size_t n) NLIB_NOEXCEPT NLIB_NONNULL;
68  bool WriteArrayCount(uint32_t n) NLIB_NOEXCEPT;
69  bool WriteMapCount(uint32_t n) NLIB_NOEXCEPT;
70  bool WriteRawCount(uint32_t n) NLIB_NOEXCEPT;
71  bool WriteRawBody(const void* p, uint32_t n) NLIB_NOEXCEPT NLIB_NONNULL;
72  bool Write(const MpObject& obj) NLIB_NOEXCEPT;
73  OutputStream* GetStream() NLIB_NOEXCEPT { return m_Writer.GetStream(); }
74  NLIB_SAFE_BOOL(MpWriter, GetErrorValue() == 0);
75 
76  private: // See: http://wiki.msgpack.org/display/MSGPACK/Format+specification
77  bool WriteU8(uint8_t v) NLIB_NOEXCEPT;
78  bool WriteU16(uint16_t v) NLIB_NOEXCEPT;
79  bool WriteU32(uint32_t v) NLIB_NOEXCEPT;
80  bool WriteU64(uint64_t v) NLIB_NOEXCEPT;
81  bool WriteI8(int8_t v) NLIB_NOEXCEPT;
82  bool WriteI16(int16_t v) NLIB_NOEXCEPT;
83  bool WriteI32(int32_t v) NLIB_NOEXCEPT;
84  bool WriteI64(int64_t v) NLIB_NOEXCEPT;
85  bool Write_(uint8_t v) NLIB_NOEXCEPT { return this->WriteU8(v); }
86  bool Write_(uint16_t v) NLIB_NOEXCEPT { return this->WriteU16(v); }
87  bool Write_(uint32_t v) NLIB_NOEXCEPT { return this->WriteU32(v); }
88  bool Write_(uint64_t v) NLIB_NOEXCEPT { return this->WriteU64(v); }
89  bool Write_(int8_t v) NLIB_NOEXCEPT { return this->WriteI8(v); }
90  bool Write_(int16_t v) NLIB_NOEXCEPT { return this->WriteI16(v); }
91  bool Write_(int32_t v) NLIB_NOEXCEPT { return this->WriteI32(v); }
92  bool Write_(int64_t v) NLIB_NOEXCEPT { return this->WriteI64(v); }
93  bool Write_(float v) NLIB_NOEXCEPT;
94  bool Write_(double v) NLIB_NOEXCEPT;
95  bool Write_(bool v) NLIB_NOEXCEPT {
96  return m_Writer.Write<uint8_t>(v ? 0xC3 : 0xC2); // true : false
97  }
98  bool Write_(nil v) NLIB_NOEXCEPT {
99  NLIB_UNUSED(v);
100  return m_Writer.Write<uint8_t>(0xC0); // nil
101  }
102  bool Write_(const std::string& str) NLIB_NOEXCEPT { return this->Write(&str[0], str.size()); }
103  template <class T>
104  bool Write_(const T& v);
105 
106  private:
107  BinaryWriter m_Writer;
108  errno_t m_ErrorValue;
110 };
111 
112 #define NLIB_MPWRITER_CHK_NSTREAM \
113  if (!m_Ostr) { \
114  SetError(ENOENT); \
115  return false; \
116  }
117 #define NLIB_MPWRITER_SET_ERROR \
118  SetError(EIO); \
119  return false
120 
121 template <class T, size_t n>
122 bool MpWriter::Write(const T (&vec)[n]) {
123  if (!this->WriteArrayCount(static_cast<uint32_t>(n))) return false;
124  for (size_t i = 0; i < n; ++i) {
125  if (!this->Write(vec[i])) {
126  NLIB_MPWRITER_SET_ERROR;
127  }
128  }
129  return true;
130 }
131 
132 template <class T>
133 inline bool MpWriter::Write(const T& tp) {
134  if (this->Write_(tp)) {
135  return true;
136  }
137  NLIB_MPWRITER_SET_ERROR;
138 }
139 
140 #undef NLIB_MPWRITER_SET_ERROR
141 #undef NLIB_MPWRITER_CHK_NSTREAM
142 
143 #define NLIB_MPWRITE(tp, coerce) \
144 template<> inline bool MpWrite(MpWriter* obj, const tp& v) { \
145  return obj->Write(static_cast<coerce>(v)); \
146 }
147 
148 NLIB_MPWRITE(char, int32_t)
149 NLIB_MPWRITE(unsigned char, uint32_t)
150 NLIB_MPWRITE(int, int32_t)
151 NLIB_MPWRITE(unsigned int, uint32_t)
152 NLIB_MPWRITE(short, int32_t) // NOLINT
153 NLIB_MPWRITE(unsigned short, uint32_t) // NOLINT
154 NLIB_MPWRITE(long long, int64_t) // NOLINT
155 NLIB_MPWRITE(unsigned long long, uint64_t) // NOLINT
156 NLIB_MPWRITE(long, nlib_long_compatible_t) // NOLINT
157 NLIB_MPWRITE(unsigned long, nlib_ulong_compatible_t) // NOLINT
158 
159 #undef NLIB_MPWRITE
160 
161 template <class T1, class T2>
162 bool MpWrite(MpWriter* w, const std::pair<T1, T2>& v) {
163  return w->WriteArrayCount(2) && w->Write(v.first) && w->Write(v.second);
164 }
165 
166 inline bool MpWrite(MpWriter* w, const char* str) {
167  uint32_t n = static_cast<uint32_t>(StrLen(str));
168  return w->WriteRawCount(n) && w->WriteRawBody(str, n);
169 }
170 
171 template <class T, class Alloc>
172 bool MpWrite(MpWriter* w, const std::vector<T, Alloc>& vec) {
173  size_t n = vec.size();
174  if (!w->WriteArrayCount(static_cast<uint32_t>(n))) return false;
175  typename std::vector<T, Alloc>::const_iterator it = vec.begin();
176  typename std::vector<T, Alloc>::const_iterator it_end = vec.end();
177  for (; it != it_end; ++it) {
178  if (!w->Write(*it)) return false;
179  }
180  return true;
181 }
182 
183 template <class T, class Alloc>
184 bool MpWrite(MpWriter* w, const Nlist<T, Alloc>& vec) {
185  size_t n = vec.size();
186  if (!w->WriteArrayCount(static_cast<uint32_t>(n))) return false;
187  typename Nlist<T, Alloc>::const_iterator it = vec.begin();
188  typename Nlist<T, Alloc>::const_iterator it_end = vec.end();
189  for (; it != it_end; ++it) {
190  if (!w->Write(*it)) return false;
191  }
192  return true;
193 }
194 
195 template <class K, class V, class Pr, class Alloc>
196 bool MpWrite(MpWriter* w, const std::map<K, V, Pr, Alloc>& m) {
197  size_t n = m.size();
198  if (!w->WriteMapCount(static_cast<uint32_t>(n))) return false;
199  typename std::map<K, V, Pr, Alloc>::const_iterator it = m.begin();
200  typename std::map<K, V, Pr, Alloc>::const_iterator end = m.end();
201  for (; it != end; ++it) {
202  if (!w->Write(it->first)) return false;
203  if (!w->Write(it->second)) return false;
204  }
205  return true;
206 }
207 
208 template <class T>
209 bool MpWriter::Write_(const T& v) {
210  // This function must be at the end of this file.
212 }
213 
214 } // namespace msgpack
215 NLIB_NAMESPACE_END
216 
217 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS)
218 #undef NLIB_VIS_PUBLIC
219 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
220 #endif
221 
222 #endif // INCLUDE_NN_NLIB_MSGPACK_MPWRITER_H_
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
Definition: Platform.h:2151
bool Write(const char(&str)[n]) noexcept
Write(const T (&vec)[n]) を御覧ください。
Definition: MpWriter.h:59
#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
~MpWriter() noexcept
デストラクタです。
Definition: MpWriter.h:33
OutputStream * GetStream() noexcept
Init()で設定したベースストリームを取得します。
Definition: MpWriter.h:73
MessagePack形式のデータをストリームに書き込みます。
Definition: MpWriter.h:30
iterator begin() noexcept
コンテナの先頭を指す反復子を返します。
Definition: Nlist.h:441
uint32_t nlib_ulong_compatible_t
unsigned longと互換性のある整数型がtypedefされています。
Definition: Platform.h:425
bool WriteMapCount(uint32_t n) noexcept
連想配列のヘッダ情報を書き込みます。
BaseType::const_iterator const_iterator
読み取り専用フォワードイテレータ
Definition: Nlist.h:358
MessagePack又はJSONを読み込むことで作成されるオブジェクトです。
Definition: MpObject.h:83
bool Close() noexcept
MpWriterをクローズします。
Definition: MpWriter.h:42
bool Write(BinaryWriter *w, T x)
この関数テンプレートを特殊化することで、ユーザー定義クラスを書きこむことができます。 ...
Definition: BinaryWriter.h:121
bool WriteArrayCount(uint32_t n) noexcept
配列のヘッダ情報を書き込みます。
std::vectorに似ていますが、コピーできないオブジェクトを格納可能なクラスが定義されています。 ...
bool WriteRawCount(uint32_t n) noexcept
バイト列データのヘッダ情報を書き込みます。
size_type size() const noexcept
格納されている要素の個数を返します。
Definition: Nlist.h:365
MpWriter() noexcept
デフォルトコンストラクタです。
Definition: MpWriter.h:32
MessagePack, JSON及びCSVを読み込むと作成されるオブジェクトです。
bool WriteRawBody(const void *p, uint32_t n) noexcept
バイト列データの本体を書き込みます。
ストリームにバイナリファイルを書き込むクラスを定義しています。
bool Write(const char *str) noexcept
文字列を書き込みます。
Definition: MpWriter.h:55
void SetError(errno_t e) noexcept
エラーを設定します。
Definition: MpWriter.h:49
std::vectorに似た、コピーコンストラクタを持たないオブジェクトを格納可能なコンテナ類似クラスです。 ...
Definition: Nlist.h:19
size_t nlib_strlen(const char *s)
内部でstrlen()を呼び出します。独自の実装が動作する場合もあります。
strlen, strcpy等を安全に使えるようにラップしています。
bool Flush() noexcept
内部ストリームへの書き込みをフラッシュします。
Definition: MpWriter.h:35
bool MpWrite(MpWriter *w, const std::map< K, V, Pr, Alloc > &m)
m をMpWriter経由で書き込みます。
Definition: MpWriter.h:196
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:51
size_t StrLen(const char *str) noexcept
nlib_strlen()をラップします。
Definition: Cstring.h:17
int32_t nlib_long_compatible_t
longと互換性のある整数型がtypedefされています。
Definition: Platform.h:424
出力ストリームの基底クラスを定義しています。
出力ストリームの基底クラスです。このクラスを実体化することはできません。
Definition: OutputStream.h:17
iterator end() noexcept
コンテナの末尾を指す反復子を返します。
Definition: Nlist.h:454
errno_t GetErrorValue() const noexcept
エラー値を取得します。
Definition: MpWriter.h:52
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:24