16 #ifndef INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ 17 #define INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ 24 #include "nn/nlib/Swap.h" 28 #ifdef NLIB_CXX11_STDLIB_ARRAY 32 #ifdef NLIB_CXX11_STDLIB_UNORDERED 33 #include <unordered_map> 36 #ifdef NLIB_CXX11_STDLIB_TUPLE 40 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS) 41 #undef NLIB_VIS_PUBLIC 42 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT 121 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj :
nullptr;
125 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj :
nullptr;
128 NLIB_ASSERT(this->IsArray());
129 NLIB_ASSERT(n < size_);
130 return (*via_.ary)[n];
136 return GetMapItem(&str[0]);
140 return GetMapItem(&str[0]);
142 template<
class STDSTRING>
144 return GetMapItem(&str[0], str.size());
146 template<
class STDSTRING>
148 return GetMapItem(&str[0], str.size());
152 template<
class STDSTRING>
166 #ifdef __cpp_rvalue_references 168 nlib_memcpy(
this,
sizeof(*
this), &rhs,
sizeof(rhs));
172 nlib_memcpy(
this,
sizeof(*
this), &rhs,
sizeof(rhs));
178 nlib_memcpy(
this,
sizeof(*
this), &rhs,
sizeof(rhs));
182 nlib_memcpy(
this,
sizeof(*
this), &rhs,
sizeof(rhs));
188 swap(type_, rhs.type_);
189 swap(raw14size_, rhs.raw14size_);
190 swap(raw14data_, rhs.raw14data_);
192 swap(size_, rhs.size_);
193 swap(via_.u64, rhs.via_.u64);
199 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Construct(
this, x);
206 MpObjectKv** obj) NLIB_NOEXCEPT NLIB_NONNULL {
208 errno_t e = this->GetMapItem(str, n, &kv);
209 if (e != 0)
return e;
216 if (type_ == kString)
return via_.str;
218 return reinterpret_cast<nlib_utf8_t*
>(&raw14data_);
224 template<
class STDSTRING>
226 return RemoveMapItem(str.c_str(), kv);
230 return const_cast<MpObject*
>(
this)->GetString();
233 if (type_ == kBinary) {
243 const void*
GetBinary(uint32_t* n)
const NLIB_NOEXCEPT {
244 return const_cast<MpObject*
>(
this)->GetBinary(n);
246 void*
GetExt(int8_t* tp, uint32_t* n) NLIB_NOEXCEPT {
249 *tp =
static_cast<int8_t
>(raw14data_);
255 const void*
GetExt(int8_t* tp, uint32_t* n)
const NLIB_NOEXCEPT {
256 return const_cast<MpObject*
>(
this)->GetExt(tp, n);
260 #ifdef NLIB_CXX11_STDLIB_TUPLE 261 std::tuple<errno_t, const nlib_byte_t*, uint32_t>
262 GetBinary()
const NLIB_NOEXCEPT {
263 if (type_ == kBinary) {
264 return std::make_tuple(0, static_cast<const nlib_byte_t*>(via_.binary), size_);
266 return std::make_tuple(
267 0, reinterpret_cast<const nlib_byte_t*>(&raw14data_), raw14size_);
269 return std::make_tuple(EACCES,
nullptr, 0);
271 std::tuple<errno_t, int8_t, const nlib_byte_t*, uint32_t>
272 GetExt()
const NLIB_NOEXCEPT {
274 return std::make_tuple(EACCES, static_cast<int8_t>(0),
nullptr, 0);
275 return std::make_tuple(0, static_cast<int8_t>(raw14data_),
276 static_cast<const nlib_byte_t*>(via_.binary), size_);
280 #ifdef __cpp_rvalue_references 281 std::pair<errno_t, MpObject>
282 RemoveArrayItem(
size_t n) NLIB_NOEXCEPT {
283 std::pair<errno_t, MpObject> rval;
284 rval.first = RemoveArrayItem(n, &rval.second);
287 std::pair<errno_t, MpObjectKv>
290 std::pair<errno_t, MpObjectKv*>
291 GetMapItem(
const nlib_utf8_t* str,
size_t n) NLIB_NOEXCEPT {
293 return std::make_pair(GetMapItem(str, n, &kv), kv);
295 std::pair<errno_t, const MpObjectKv*>
296 GetMapItem(
const nlib_utf8_t* str,
size_t n)
const NLIB_NOEXCEPT {
298 return std::make_pair(GetMapItem(str, n, &kv), kv);
302 std::pair<errno_t, nlib_time> GetTimestamp()
const NLIB_NOEXCEPT;
309 uint32_t n =
static_cast<uint32_t
>(
nlib_strlen(str));
310 return InitString(str, n);
320 template <u
int32_t n>
322 template <
class T, u
int32_t n>
324 #ifdef NLIB_CXX11_STDLIB_ARRAY 325 template <
class T,
size_t n>
330 return MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>
::Box(
this, v);
337 template <
class T,
size_t n>
339 return this->
Unbox(&a[0], n);
341 #ifdef NLIB_CXX11_STDLIB_ARRAY 342 template <
class T,
size_t n>
344 return this->
Unbox(reinterpret_cast<T*>(&*a.begin()), n);
349 return this->
Unbox(&str[0], n);
360 return MyBox<typename RemovePtr<T>::type,
361 typename IsIntegral<typename RemovePtr<T>::type>::type,
362 typename IsSigned<typename RemovePtr<T>::type>::type>
::Unbox(
this, v);
370 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Assign(
this, x);
389 kStringInline = 0x80 | kString,
390 kBinaryInline = 0x80 | kBinary,
391 kBooleanFalse = 0x00 | kBoolean,
392 kBooleanTrue = 0x80 | kBoolean,
405 STRING_INLINE = kStringInline,
406 BINARY_INLINE = kBinaryInline,
407 RAW_INLINE = 0x80 | RAW,
408 BOOLEAN_FALSE = kBooleanFalse,
409 BOOLEAN_TRUE = kBooleanTrue
415 if (type_ == kStringInline || type_ == kBinaryInline)
420 bool IsNil() const NLIB_NOEXCEPT {
return GetType() == kNil; }
421 bool IsBoolean() const NLIB_NOEXCEPT {
return GetType() == kBoolean; }
424 return tp == kUint64 || tp == kInt64;
426 bool IsFloat() const NLIB_NOEXCEPT {
return GetType() == kFloat; }
427 bool IsDouble() const NLIB_NOEXCEPT {
return GetType() == kDouble; }
428 bool IsString() const NLIB_NOEXCEPT {
return GetType() == kString; }
429 bool IsBinary() const NLIB_NOEXCEPT {
return GetType() == kBinary; }
430 bool IsExt() const NLIB_NOEXCEPT {
return GetType() == kExt; }
431 bool IsArray() const NLIB_NOEXCEPT {
return GetType() == kArray; }
432 bool IsMap() const NLIB_NOEXCEPT {
return GetType() == kMap; }
436 template <
class T,
class IS_INTEGRAL,
class IS_SIGNED>
440 if (!v)
return EINVAL;
443 static void Assign(
MpObject* This,
const T& x);
444 static void Construct(
MpObject* This,
const T& x);
446 void ReleaseIfNeeded() NLIB_NOEXCEPT {
447 if (type_ >= kString && type_ <= kExt) ReleaseIfNeeded_();
469 #ifdef __cpp_rvalue_references 470 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS 475 : first(std::move(rhs.first)), second(std::move(rhs.second)) {}
477 first = std::move(rhs.first);
478 second = std::move(rhs.second);
496 #ifdef __cpp_rvalue_references 497 inline std::pair<errno_t, MpObjectKv>
498 MpObject::RemoveMapItem(
size_t n) NLIB_NOEXCEPT {
499 std::pair<errno_t, MpObjectKv> rval;
500 rval.first = RemoveMapItem(n, &rval.second);
506 struct MpObject::MyBox<nil, FalseType, FalseType> {
509 This->ReleaseIfNeeded();
513 static void Assign(
MpObject* This, nil x) NLIB_NOEXCEPT { This->
Box(x); }
514 static void Construct(
MpObject* This, nil) NLIB_NOEXCEPT { This->type_ = kNil; }
518 struct MpObject::MyBox<bool, TrueType, FalseType> {
520 This->ReleaseIfNeeded();
521 This->type_ = v ?
static_cast<uint8_t
>(kBooleanTrue) : static_cast<uint8_t>(kBooleanFalse);
525 if (This->type_ == kBooleanFalse) {
528 }
else if (
NLIB_LIKELY(This->type_ == kBooleanTrue)) {
535 static void Assign(
MpObject* This,
bool x) NLIB_NOEXCEPT { This->
Box(x); }
536 static void Construct(
MpObject* This,
bool x) NLIB_NOEXCEPT {
537 This->type_ = x ?
static_cast<uint8_t
>(kBooleanTrue) : static_cast<uint8_t>(kBooleanFalse);
542 struct MpObject::MyBox<T, TrueType, TrueType> {
544 This->ReleaseIfNeeded();
545 This->type_ = kInt64;
551 if (This->type_ == kInt64) {
552 *v =
static_cast<T
>(This->via_.i64);
555 *v =
static_cast<T
>(This->via_.u64);
561 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
562 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
563 This->type_ = kInt64;
569 struct MpObject::MyBox<T, TrueType, FalseType> {
571 This->ReleaseIfNeeded();
572 This->type_ = kUint64;
578 if (This->type_ == kInt64) {
579 *v =
static_cast<T
>(This->via_.i64);
582 *v =
static_cast<T
>(This->via_.u64);
588 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
589 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
590 This->type_ = kUint64;
595 template <
class TR1_WORKAROUND>
596 struct MpObject::MyBox<float, FalseType, TR1_WORKAROUND> {
598 This->ReleaseIfNeeded();
599 This->type_ = kFloat;
605 switch (This->type_) {
610 *v =
static_cast<float>(This->via_.f64);
618 static void Assign(
MpObject* This,
float x) NLIB_NOEXCEPT { This->
Box(x); }
619 static void Construct(
MpObject* This,
float x) NLIB_NOEXCEPT {
620 This->type_ = kFloat;
625 template <
class TR1_WORKAROUND>
626 struct MpObject::MyBox<double, FalseType, TR1_WORKAROUND> {
628 This->ReleaseIfNeeded();
629 This->type_ = kDouble;
635 switch (This->type_) {
648 static void Assign(
MpObject* This,
double x) NLIB_NOEXCEPT { This->
Box(x); }
649 static void Construct(
MpObject* This,
double x) NLIB_NOEXCEPT {
650 This->type_ = kDouble;
655 template <
class STDSTRING>
656 struct MpObject::MyBox<STDSTRING, FalseType, FalseType> {
658 uint32_t n =
static_cast<uint32_t
>(str.size());
663 static_cast<const void*>(&str[0]),
673 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
678 template <
class T,
class ALLOC>
679 struct MpObject::MyBox<std::vector<T, ALLOC>, FalseType, FalseType> {
681 uint32_t n =
static_cast<uint32_t
>(vec.size());
686 for (uint32_t i = 0; i < n; ++i) {
687 e = (*tmp.via_.ary)[i].
Box(vec[i]);
696 NLIB_TRY { vec->resize(This->size_); }
697 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
698 for (uint32_t i = 0; i < This->size_; ++i) {
706 template <
class T,
class ALLOC>
707 struct MpObject::MyBox<Nlist<T, ALLOC>, FalseType, FalseType> {
709 size_t n = vec.
size();
714 for (
size_t i = 0; i < n; ++it, ++i) {
715 e = (*tmp.via_.ary)[i].
Box(*it);
726 for (uint32_t i = 0; i < This->size_; ++i) {
735 template <
class T1,
class T2>
736 struct MpObject::MyBox<std::pair<T1, T2>, FalseType, FalseType> {
741 e = (*tmp.via_.ary)[0].
Box(p.first);
743 e = (*tmp.via_.ary)[1].
Box(p.second);
753 e = (*This->via_.ary)[0].
Unbox(&p->first);
755 e = (*This->via_.ary)[1].
Unbox(&p->second);
761 #if defined(NLIB_CXX11_STDLIB_TUPLE) && defined(__cpp_variadic_templates) 762 template <
class ...Args>
763 struct MpObject::MyBox<std::tuple<Args...>, FalseType, FalseType > {
765 template<
size_t N,
class HEAD>
767 return (*tmp->via_.ary)[N].Box(head);
769 template<
size_t N,
class HEAD,
class ...TAIL>
770 static errno_t BoxHelper(
MpObject* tmp,
const HEAD& head, TAIL&... tail) {
771 ErrnoT e = (*tmp->via_.ary)[N].
Box(head);
773 return BoxHelper<N + 1, TAIL...>(tmp, tail...);
775 template<
size_t N,
class HEAD>
777 return (*This->via_.ary)[N].Unbox(&head);
779 template<
size_t N,
class HEAD,
class ...TAIL>
780 static errno_t UnboxHelper(
const MpObject* This, HEAD& head, TAIL&... tail) {
783 return UnboxHelper<N + 1, TAIL...>(This, tail...);
785 template<
int ...>
struct seq {};
786 template<
int N,
int ...S>
struct gens : gens<N - 1, N - 1, S...> {};
788 struct gens<0, S...> {
789 typedef seq<S...> type;
793 return BoxHelper<0>(tmp, std::get<S>(p)...);
797 return UnboxHelper<0>(This, std::get<S>(p)...);
802 size_t count = std::tuple_size<std::tuple<Args...> >::value;
806 typedef typename gens<
sizeof...(Args)>::type MySeq;
807 e =
Box(&tmp, MySeq(), p);
815 if (
NLIB_UNLIKELY(This->size_ != std::tuple_size<std::tuple<Args...> >::value))
817 typedef typename gens<
sizeof...(Args)>::type MySeq;
818 return Unbox(This, MySeq(), *p);
823 template <
class K,
class V,
class Pr,
class Alloc>
824 struct MpObject::MyBox<std::map<K, V, Pr, Alloc>, FalseType, FalseType> {
826 typedef typename std::map<K, V, Pr, Alloc> maptype;
827 uint32_t n =
static_cast<uint32_t
>(m.size());
832 typename maptype::const_iterator it;
833 typename maptype::const_iterator it_end = m.end();
835 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
849 for (uint32_t i = 0; i < This->size_; ++i) {
858 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
865 #ifdef NLIB_CXX11_STDLIB_UNORDERED 866 template <
class K,
class V,
class Hash,
class Pr,
class Alloc>
867 struct MpObject::MyBox<std::unordered_map<K, V, Hash, Pr, Alloc>, FalseType, FalseType > {
868 static errno_t Box(
MpObject* This,
const std::unordered_map<K, V, Hash, Pr, Alloc>& m) {
869 typedef typename std::unordered_map<K, V, Hash, Pr, Alloc> maptype;
870 uint32_t n =
static_cast<uint32_t
>(m.size());
875 typename maptype::const_iterator it;
876 typename maptype::const_iterator it_end = m.end();
878 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
892 for (uint32_t i = 0; i < This->size_; ++i) {
901 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
911 return lhs.first == rhs.first && lhs.second == rhs.second;
914 return !(lhs == rhs);
917 return !(lhs == rhs);
920 template <u
int32_t n>
923 ErrnoT e = this->InitString(nn);
925 nlib_memcpy(this->GetString(), nn, static_cast<const void*>(&str[0]), nn);
929 template <
class T, u
int32_t n>
934 for (uint32_t i = 0; i < n; ++i) {
935 e = (*tmp.via_.ary)[i].
Box(vec[i]);
942 #ifdef NLIB_CXX11_STDLIB_ARRAY 943 template <
class T,
size_t n>
948 for (uint32_t i = 0; i < n; ++i) {
949 e = (*tmp.via_.ary)[i].
Box(vec[i]);
959 NLIB_EINVAL_IFNULL(a);
963 for (uint32_t i = 0; i < size_; ++i) {
973 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObject)
974 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObjectKv)
979 MpObject* p = this->GetArrayItem(n);
986 template<
class STDSTRING>
987 inline MpObject* MpObject::SwapMapItem(
const STDSTRING& key,
MpObject* obj) NLIB_NOEXCEPT {
988 MpObject* p = this->GetMapItem(key);
998 MpObject* p = this->GetMapItem(key);
1006 MpObject* p = this->GetMapItem(key);
1016 swap(first, rhs.first);
1017 swap(second, rhs.second);
1022 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS) 1023 #undef NLIB_VIS_PUBLIC 1024 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT 1027 #endif // INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ nlib_utf8_t * GetString() noexcept
Gets a string from an object.
errno_t Unbox(T v) const
Unboxes the object.
bool IsString() const noexcept
Determines whether the stored value is a string.
bool IsMap() const noexcept
Determines whether the stored value is an associative array.
MpObject & operator[](size_t n)
For an array, returns a reference to an element of the array.
MpObjectKv() noexcept
Instantiates the object with default parameters (default constructor).
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Represents an unsigned integer type. The internal representation is uint64_t.
Represents an integer type. The internal representation is int64_t.
MpObject() noexcept
Instantiates the object with default parameters (default constructor). Set to the nil type...
~MpObject() noexcept
Destructor.
const void * GetExt(int8_t *tp, uint32_t *n) const noexcept
Gets an extended data type from an object.
Represents an array. The internal representation is an array of MpObject.
iterator begin() noexcept
Returns the iterator pointing to the beginning of the container.
const MpObject * GetArrayItem(size_t n) const noexcept
The same as GetArrayItem(size_t n).
const void * GetBinary(uint32_t *n) const noexcept
Gets binary from an object.
const nlib_utf8_t * GetString() const noexcept
Gets a string from an object.
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are equal.
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are not equal.
errno_t Box(const T &v)
Boxes the object.
BaseType::const_iterator const_iterator
Read-only forward iterator.
Object created when MessagePack or JSON is read.
Represents a floating point type. The internal representation is float.
pointer push_back()
Adds an element to the end and initializes it with the default constructor.
MpObjectKv & assign(MpObjectKv &rhs, move_tag) noexcept
Corresponds to a move assignment operator.
MpObject(MpObject &rhs, move_tag) noexcept
Corresponds to a move constructor.
MpObject(MpObject &&rhs) noexcept
Instantiates the object (move constructor). This function is useful when using C++11.
MpObject & operator=(const T &x)
The value is passed into MpObject.
MpObject second
Object used as a value.
Defines the class that resembles std::vector but can store objects that cannot be copied...
ObjectType
Data type of the object stored in MpObject.
An empty structure indicating that an argument to a function needs to be moved.
bool IsExt() const noexcept
Determines whether the stored value is extended data.
MpObject & operator=(MpObject &&rhs) noexcept
Move assignment operator. This function is useful when using C++11.
errno_t InitArray(uint32_t n) noexcept
Initializes as an object with an n element array.
void clear() noexcept
Clears the container.
Represents a floating point type. The internal representation is double.
errno_t Unbox(const MpObject *obj, T *v)
This function template can be specialized to define unboxing the user type.
bool IsNil() const noexcept
Determines whether the stored value is nil.
void swap(MpObject &rhs) noexcept
Swaps the content of the object.
#define NLIB_CATCH(x)
Defines catch(x) if exceptions are enabled. If not, defines if (true).
errno_t InitString(uint32_t n) noexcept
Initializes the object as a string.
Class that wraps errno_t. This class improves visual representations in the Visual Studio debugger...
errno_t Box(const nlib_utf8_t *str) noexcept
Boxes the string.
#define NLIB_TRY
Defines try if exceptions are enabled. If not, defines if (true).
ObjectType GetType() const noexcept
Returns the object type.
bool IsArray() const noexcept
Determines whether the stored value is an array.
MpObject(const T &x)
The constructor for boxing a T-type object.
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
errno_t InitString(const nlib_utf8_t *str) noexcept
Initializes the object as a string.
errno_t Unbox(nlib_utf8_t(&str)[n]) const noexcept
See Unbox(T (&a)[n]).
const MpObject * GetMapItem(const STDSTRING &str) const noexcept
The same as GetMapItem(const STDSTRING& str).
A file that contains the configuration information for each development environment.
~MpObjectKv() noexcept
Destructor.
Represents a boolean type. The internal representation is a bool.
bool reserve(size_type n) noexcept
Allocates memory for n number of elements.
uint32_t GetSize() const noexcept
Returns the size of the array, associative array, string, or binary.
A container-like class similar to std::vector that can store objects that do not have copy constructo...
errno_t RemoveMapItem(const STDSTRING &str, MpObjectKv *kv) noexcept
Specifies a key and deletes the corresponding key and object in the associative array.
MpObject & assign(MpObject &rhs, move_tag) noexcept
Assigns the object by using swap for a move.
size_type size() const noexcept
Returns the number of stored elements.
Respresents a byte array (string).
static bool IsJsonPointer(const nlib_utf8_t *str) noexcept
This function is equivalent to IsJsonPointer(str, str + nlib_strlen(str)).
bool IsBoolean() const noexcept
Determines whether the stored value is a boolean.
void * GetBinary(uint32_t *n) noexcept
Gets binary from an object.
Wraps functions like strlen and strcpy so they can be safely used.
void * GetExt(int8_t *tp, uint32_t *n) noexcept
Gets an extended data type from an object.
bool IsFloat() const noexcept
Determines whether the stored value is a single precision float.
MpObject first
Object used as a key.
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
MpObject * GetMapItem(const STDSTRING &str) noexcept
Specifies a string and gets the object in the associative array.
errno_t InitMap(uint32_t n) noexcept
Initializes the object as an n element associative array.
MpObject * GetArrayItem(size_t n) noexcept
Specifies an index and gets the object in the array.
bool IsDouble() const noexcept
Determines whether the stored value is a double.
A pair consisting of an MpObject-type key and value. Used to store an associative array...
errno_t GetMapItem(const nlib_utf8_t *str, size_t n, MpObjectKv **obj) noexcept
Obtains the pair of a key and value from the associative array by specifying a non-null terminated st...
Class that corresponds to nil in MessagePack and null in JSON.
bool IsInteger() const noexcept
Determines whether the stored value is an integer.
bool IsBinary() const noexcept
Determines whether the stored value is binary.
Represents an associative array. The internal representation is an array of MpObject pairs...
MpObjectKv(MpObjectKv &rhs, move_tag) noexcept
Corresponds to a move constructor.
errno_t Unbox(T(&a)[n]) const
Unboxes the object value.
errno_t Box(MpObject *obj, const T &v)
This function template can be specialized to define boxing the user type.