nlib
MpWriter.h
Go to the documentation of this file.
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
Defines noexcept geared to the environment, or the equivalent.
Definition: Platform.h:2151
bool Write(const char(&str)[n]) noexcept
See Write(const T (&vec)[n]).
Definition: MpWriter.h:59
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
#define NLIB_NONNULL
Indicates that you cannot specify NULL for all arguments.
Definition: Platform_unix.h:66
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Definition: Config.h:126
#define NLIB_SAFE_BOOL(class_name, exp)
Defines a safe operator bool function in the class. Uses the C++11 explicit bool if it is available f...
Definition: Config.h:141
~MpWriter() noexcept
Destructor.
Definition: MpWriter.h:33
OutputStream * GetStream() noexcept
Gets the base stream specified in Init.
Definition: MpWriter.h:73
Writes the MessagePack formatted data to the stream.
Definition: MpWriter.h:30
iterator begin() noexcept
Returns the iterator pointing to the beginning of the container.
Definition: Nlist.h:441
uint32_t nlib_ulong_compatible_t
Defines an integer type that is compatible with unsigned long using typedef.
Definition: Platform.h:425
bool WriteMapCount(uint32_t n) noexcept
Writes associative array header information.
BaseType::const_iterator const_iterator
Read-only forward iterator.
Definition: Nlist.h:358
Object created when MessagePack or JSON is read.
Definition: MpObject.h:83
bool Close() noexcept
Closes MpWriter.
Definition: MpWriter.h:42
bool Write(BinaryWriter *w, T x)
You can write user-defined class objects by specializing this function template.
Definition: BinaryWriter.h:121
bool WriteArrayCount(uint32_t n) noexcept
Writes array header information.
Defines the class that resembles std::vector but can store objects that cannot be copied...
bool WriteRawCount(uint32_t n) noexcept
Writes byte array data header information.
size_type size() const noexcept
Returns the number of stored elements.
Definition: Nlist.h:365
MpWriter() noexcept
Instantiates the object with default parameters (default constructor).
Definition: MpWriter.h:32
Object created when MessagePack, JSON, or CSV is read.
bool WriteRawBody(const void *p, uint32_t n) noexcept
Writes byte array data body.
Defines the class for writing binary files to streams.
bool Write(const char *str) noexcept
Writes a text string.
Definition: MpWriter.h:55
void SetError(errno_t e) noexcept
Sets an error.
Definition: MpWriter.h:49
A container-like class similar to std::vector that can store objects that do not have copy constructo...
Definition: Nlist.h:19
size_t nlib_strlen(const char *s)
Internally calls strlen(). In some cases, it may operate as an independent implementation.
Wraps functions like strlen and strcpy so they can be safely used.
bool Flush() noexcept
Flushes the write to the stream.
Definition: MpWriter.h:35
bool MpWrite(MpWriter *w, const std::map< K, V, Pr, Alloc > &m)
Writes m via MpWriter.
Definition: MpWriter.h:196
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:51
size_t StrLen(const char *str) noexcept
Wraps the nlib_strlen function.
Definition: Cstring.h:17
int32_t nlib_long_compatible_t
Defines an integer type that is compatible with long using typedef.
Definition: Platform.h:424
Defines the base class for output streams.
The base class for output streams. This class cannot be instantiated.
Definition: OutputStream.h:17
iterator end() noexcept
Returns the iterator pointing to the end of the container.
Definition: Nlist.h:454
errno_t GetErrorValue() const noexcept
Gets the error value.
Definition: MpWriter.h:52
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24