summaryrefslogtreecommitdiff
path: root/cpp/msgpack/object.hpp
diff options
context:
space:
mode:
authorfrsyuki <frsyuki@users.sourceforge.jp>2010-02-06 20:09:41 +0900
committerfrsyuki <frsyuki@users.sourceforge.jp>2010-02-06 20:09:41 +0900
commitcd10fbc1fe39308045f0b7bf9cce5f8153f25f1d (patch)
tree44e4a1e075deebc3339cdd44e1f550a3ea914e88 /cpp/msgpack/object.hpp
parentca0b085d156260b6d916139495a6d306a1e7f886 (diff)
downloadmsgpack-python-cd10fbc1fe39308045f0b7bf9cce5f8153f25f1d.tar.gz
removed symbolic links
Diffstat (limited to 'cpp/msgpack/object.hpp')
-rw-r--r--cpp/msgpack/object.hpp329
1 files changed, 329 insertions, 0 deletions
diff --git a/cpp/msgpack/object.hpp b/cpp/msgpack/object.hpp
new file mode 100644
index 0000000..ed2e290
--- /dev/null
+++ b/cpp/msgpack/object.hpp
@@ -0,0 +1,329 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#ifndef MSGPACK_OBJECT_HPP__
+#define MSGPACK_OBJECT_HPP__
+
+#include "msgpack/object.h"
+#include "msgpack/pack.hpp"
+#include <string.h>
+#include <stdexcept>
+#include <typeinfo>
+#include <limits>
+#include <ostream>
+
+namespace msgpack {
+
+
+class type_error : public std::bad_cast { };
+
+
+namespace type {
+ enum object_type {
+ NIL = 0x01,
+ BOOLEAN = 0x02,
+ POSITIVE_INTEGER = 0x03,
+ NEGATIVE_INTEGER = 0x04,
+ DOUBLE = 0x05,
+ RAW = 0x06,
+ ARRAY = 0x07,
+ MAP = 0x08,
+ };
+}
+
+
+struct object;
+struct object_kv;
+
+struct object_array {
+ uint32_t size;
+ object* ptr;
+};
+
+struct object_map {
+ uint32_t size;
+ object_kv* ptr;
+};
+
+struct object_raw {
+ uint32_t size;
+ const char* ptr;
+};
+
+struct object {
+ union union_type {
+ bool boolean;
+ uint64_t u64;
+ int64_t i64;
+ double dec;
+ object_array array;
+ object_map map;
+ object_raw raw;
+ object_raw ref; // obsolete
+ };
+
+ type::object_type type;
+ union_type via;
+
+ bool is_nil() const { return type == type::NIL; }
+
+ template <typename T>
+ T as() const;
+
+ template <typename T>
+ void convert(T* v) const;
+
+ object();
+ object(msgpack_object obj);
+ operator msgpack_object();
+
+private:
+ struct implicit_type;
+
+public:
+ implicit_type convert() const;
+};
+
+struct object_kv {
+ object key;
+ object val;
+};
+
+bool operator==(const object x, const object y);
+bool operator!=(const object x, const object y);
+
+std::ostream& operator<< (std::ostream& s, const object o);
+
+
+template <typename Stream, typename T>
+packer<Stream>& operator<< (packer<Stream>& o, const T& v);
+
+template <typename T>
+T& operator>> (object o, T& v);
+
+
+struct object::implicit_type {
+ implicit_type(object o) : obj(o) { }
+ ~implicit_type() { }
+
+ template <typename T>
+ operator T() { return obj.as<T>(); }
+
+private:
+ object obj;
+};
+
+
+// obsolete
+template <typename Type>
+class define : public Type {
+public:
+ typedef Type msgpack_type;
+ typedef define<Type> define_type;
+
+ define() {}
+ define(const msgpack_type& v) : msgpack_type(v) {}
+
+ template <typename Packer>
+ void msgpack_pack(Packer& o) const
+ {
+ o << static_cast<const msgpack_type&>(*this);
+ }
+
+ void msgpack_unpack(object o)
+ {
+ o >> static_cast<msgpack_type&>(*this);
+ }
+};
+
+
+template <typename Stream>
+template <typename T>
+inline packer<Stream>& packer<Stream>::pack(const T& v)
+{
+ *this << v;
+ return *this;
+}
+
+inline object& operator>> (object o, object& v)
+{
+ v = o;
+ return v;
+}
+
+template <typename T>
+inline T& operator>> (object o, T& v)
+{
+ v.msgpack_unpack(o.convert());
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const T& v)
+{
+ v.msgpack_pack(o);
+ return o;
+}
+
+
+inline bool operator!=(const object x, const object y)
+{ return !(x == y); }
+
+
+inline object::object() { }
+
+inline object::object(msgpack_object obj)
+{
+ // FIXME beter way?
+ ::memcpy(this, &obj, sizeof(obj));
+}
+
+inline object::operator msgpack_object()
+{
+ // FIXME beter way?
+ msgpack_object obj;
+ ::memcpy(&obj, this, sizeof(obj));
+ return obj;
+}
+
+
+inline object::implicit_type object::convert() const
+{
+ return implicit_type(*this);
+}
+
+template <typename T>
+inline void object::convert(T* v) const
+{
+ *this >> *v;
+}
+
+template <typename T>
+inline T object::as() const
+{
+ T v;
+ convert(&v);
+ return v;
+}
+
+
+// obsolete
+template <typename T>
+inline void convert(T& v, object o)
+{
+ o.convert(&v);
+}
+
+// obsolete
+template <typename Stream, typename T>
+inline void pack(packer<Stream>& o, const T& v)
+{
+ o.pack(v);
+}
+
+// obsolete
+template <typename Stream, typename T>
+inline void pack_copy(packer<Stream>& o, T v)
+{
+ pack(o, v);
+}
+
+
+template <typename Stream>
+packer<Stream>& operator<< (packer<Stream>& o, const object& v)
+{
+ switch(v.type) {
+ case type::NIL:
+ o.pack_nil();
+ return o;
+
+ case type::BOOLEAN:
+ if(v.via.boolean) {
+ o.pack_true();
+ } else {
+ o.pack_false();
+ }
+ return o;
+
+ case type::POSITIVE_INTEGER:
+ if(v.via.u64 <= (uint64_t)std::numeric_limits<uint16_t>::max()) {
+ if(v.via.u64 <= (uint16_t)std::numeric_limits<uint8_t>::max()) {
+ o.pack_uint8(v.via.u64);
+ } else {
+ o.pack_uint16(v.via.u64);
+ }
+ } else {
+ if(v.via.u64 <= (uint64_t)std::numeric_limits<uint32_t>::max()) {
+ o.pack_uint32(v.via.u64);
+ } else {
+ o.pack_uint64(v.via.u64);
+ }
+ }
+ return o;
+
+ case type::NEGATIVE_INTEGER:
+ if(v.via.i64 >= (int64_t)std::numeric_limits<int16_t>::min()) {
+ if(v.via.i64 >= (int64_t)std::numeric_limits<int8_t>::min()) {
+ o.pack_int8(v.via.i64);
+ } else {
+ o.pack_int16(v.via.i64);
+ }
+ } else {
+ if(v.via.i64 >= (int64_t)std::numeric_limits<int32_t>::min()) {
+ o.pack_int64(v.via.i64);
+ } else {
+ o.pack_int64(v.via.i64);
+ }
+ }
+ return o;
+
+ case type::RAW:
+ o.pack_raw(v.via.raw.size);
+ o.pack_raw_body(v.via.raw.ptr, v.via.raw.size);
+ return o;
+
+ case type::ARRAY:
+ o.pack_array(v.via.array.size);
+ for(object* p(v.via.array.ptr),
+ * const pend(v.via.array.ptr + v.via.array.size);
+ p < pend; ++p) {
+ o << *p;
+ }
+ return o;
+
+ case type::MAP:
+ o.pack_map(v.via.map.size);
+ for(object_kv* p(v.via.map.ptr),
+ * const pend(v.via.map.ptr + v.via.map.size);
+ p < pend; ++p) {
+ o << p->key;
+ o << p->val;
+ }
+ return o;
+
+ default:
+ throw type_error();
+ }
+}
+
+
+} // namespace msgpack
+
+#include "msgpack/type.hpp"
+
+#endif /* msgpack/object.hpp */
+