object.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. #include <msgpack.hpp>
  2. #include <gtest/gtest.h>
  3. enum enum_test {
  4. elem
  5. };
  6. MSGPACK_ADD_ENUM(enum_test);
  7. struct outer_enum {
  8. enum enum_test {
  9. elem
  10. };
  11. };
  12. MSGPACK_ADD_ENUM(outer_enum::enum_test);
  13. #if !defined(MSGPACK_USE_CPP03)
  14. enum class enum_class_test {
  15. elem
  16. };
  17. MSGPACK_ADD_ENUM(enum_class_test);
  18. struct outer_enum_class {
  19. enum class enum_class_test {
  20. elem
  21. };
  22. };
  23. MSGPACK_ADD_ENUM(outer_enum_class::enum_class_test);
  24. #endif // !defined(MSGPACK_USE_CPP03)
  25. struct myclass {
  26. myclass() : num(0), str("default") { }
  27. myclass(int num, const std::string& str) :
  28. num(num), str(str) { }
  29. ~myclass() { }
  30. int num;
  31. std::string str;
  32. std::vector<double> vec;
  33. std::map<std::string, std::vector<char> > map;
  34. MSGPACK_DEFINE(num, str, vec, map);
  35. bool operator==(const myclass& o) const
  36. {
  37. return num == o.num && str == o.str && vec == o.vec && map == o.map;
  38. }
  39. };
  40. std::ostream& operator<<(std::ostream& o, const myclass& m)
  41. {
  42. return o << "myclass("<<m.num<<",\""<<m.str<<"\")";
  43. }
  44. TEST(object, convert)
  45. {
  46. myclass m1(1, "custom");
  47. msgpack::sbuffer sbuf;
  48. msgpack::pack(sbuf, m1);
  49. msgpack::object_handle oh =
  50. msgpack::unpack(sbuf.data(), sbuf.size());
  51. myclass m2;
  52. oh.get().convert(m2);
  53. EXPECT_EQ(m1, m2);
  54. }
  55. TEST(object, as)
  56. {
  57. myclass m1(1, "custom");
  58. msgpack::sbuffer sbuf;
  59. msgpack::pack(sbuf, m1);
  60. msgpack::object_handle oh =
  61. msgpack::unpack(sbuf.data(), sbuf.size());
  62. EXPECT_EQ(m1, oh.get().as<myclass>());
  63. }
  64. TEST(object, cross_zone_copy)
  65. {
  66. myclass m1(1, "custom");
  67. m1.vec.push_back(1.0);
  68. m1.vec.push_back(0.1);
  69. std::vector<char> vc;
  70. vc.push_back('t');
  71. vc.push_back('w');
  72. vc.push_back('o');
  73. m1.map["one"] = vc;
  74. msgpack::zone z1;
  75. msgpack::object::with_zone obj1(z1);
  76. {
  77. msgpack::zone z2;
  78. msgpack::object::with_zone obj2(z2);
  79. obj2 << m1;
  80. obj1 << obj2;
  81. EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.f64, 1.0);
  82. #if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT)
  83. EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.dec, 1.0);
  84. #endif // MSGPACK_USE_LEGACY_NAME_AS_FLOAT
  85. EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr[0], 'o');
  86. EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr[0], 't');
  87. EXPECT_NE(
  88. obj1.via.array.ptr[2].via.array.ptr,
  89. obj2.via.array.ptr[2].via.array.ptr);
  90. EXPECT_NE(
  91. obj1.via.array.ptr[3].via.map.ptr,
  92. obj2.via.array.ptr[3].via.map.ptr);
  93. EXPECT_NE(
  94. obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr,
  95. obj2.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr);
  96. EXPECT_NE(
  97. obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr,
  98. obj2.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr);
  99. }
  100. EXPECT_EQ(m1, obj1.as<myclass>());
  101. }
  102. TEST(object, cross_zone_copy_construct)
  103. {
  104. myclass m1(1, "custom");
  105. m1.vec.push_back(1.0);
  106. m1.vec.push_back(0.1);
  107. std::vector<char> vc;
  108. vc.push_back('t');
  109. vc.push_back('w');
  110. vc.push_back('o');
  111. m1.map["one"] = vc;
  112. msgpack::zone z1;
  113. msgpack::zone z2;
  114. msgpack::object::with_zone obj2(z2);
  115. obj2 << m1;
  116. msgpack::object obj1(obj2, z1);
  117. EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.f64, 1.0);
  118. #if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT)
  119. EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.dec, 1.0);
  120. #endif // MSGPACK_USE_LEGACY_NAME_AS_FLOAT
  121. EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr[0], 'o');
  122. EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr[0], 't');
  123. EXPECT_NE(
  124. obj1.via.array.ptr[2].via.array.ptr,
  125. obj2.via.array.ptr[2].via.array.ptr);
  126. EXPECT_NE(
  127. obj1.via.array.ptr[3].via.map.ptr,
  128. obj2.via.array.ptr[3].via.map.ptr);
  129. EXPECT_NE(
  130. obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr,
  131. obj2.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr);
  132. EXPECT_NE(
  133. obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr,
  134. obj2.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr);
  135. EXPECT_EQ(m1, obj1.as<myclass>());
  136. }
  137. TEST(object, cross_zone_copy_ext)
  138. {
  139. msgpack::zone z1;
  140. msgpack::zone z2;
  141. msgpack::object::with_zone obj1(z1);
  142. obj1.type = msgpack::type::EXT;
  143. char* ptr = static_cast<char*>(obj1.zone.allocate_align(2, MSGPACK_ZONE_ALIGNOF(char)));
  144. ptr[0] = 1;
  145. ptr[1] = 2;
  146. obj1.via.ext.ptr = ptr;
  147. obj1.via.ext.size = 1;
  148. msgpack::object::with_zone obj2(z2);
  149. obj2 << obj1;
  150. EXPECT_EQ(obj2.via.ext.size, 1u);
  151. EXPECT_EQ(obj2.via.ext.ptr[0], 1);
  152. EXPECT_EQ(obj2.via.ext.ptr[1], 2);
  153. EXPECT_NE(
  154. obj1.via.ext.ptr,
  155. obj2.via.ext.ptr);
  156. }
  157. TEST(object, cross_zone_copy_construct_ext)
  158. {
  159. msgpack::zone z1;
  160. msgpack::zone z2;
  161. msgpack::object::with_zone obj1(z1);
  162. obj1.type = msgpack::type::EXT;
  163. char* ptr = static_cast<char*>(obj1.zone.allocate_align(2, MSGPACK_ZONE_ALIGNOF(char)));
  164. ptr[0] = 1;
  165. ptr[1] = 2;
  166. obj1.via.ext.ptr = ptr;
  167. obj1.via.ext.size = 1;
  168. msgpack::object obj2(obj1, z2);
  169. EXPECT_EQ(obj2.via.ext.size, 1u);
  170. EXPECT_EQ(obj2.via.ext.ptr[0], 1);
  171. EXPECT_EQ(obj2.via.ext.ptr[1], 2);
  172. EXPECT_NE(
  173. obj1.via.ext.ptr,
  174. obj2.via.ext.ptr);
  175. }
  176. TEST(object, print)
  177. {
  178. msgpack::object obj;
  179. std::cout << obj << std::endl;
  180. }
  181. TEST(object, is_nil)
  182. {
  183. msgpack::object obj;
  184. EXPECT_TRUE(obj.is_nil());
  185. }
  186. TEST(object, type_error)
  187. {
  188. msgpack::object obj(1);
  189. EXPECT_THROW(obj.as<std::string>(), msgpack::type_error);
  190. EXPECT_THROW(obj.as<std::vector<int> >(), msgpack::type_error);
  191. EXPECT_EQ(1, obj.as<int>());
  192. EXPECT_EQ(1, obj.as<short>());
  193. EXPECT_EQ(1u, obj.as<unsigned int>());
  194. EXPECT_EQ(1u, obj.as<unsigned long>());
  195. }
  196. TEST(object, equal_primitive)
  197. {
  198. msgpack::object obj_nil;
  199. EXPECT_EQ(obj_nil, msgpack::object());
  200. msgpack::object obj_int(1);
  201. EXPECT_EQ(obj_int, msgpack::object(1));
  202. EXPECT_EQ(obj_int, 1);
  203. msgpack::object obj_float(1.2);
  204. EXPECT_EQ(obj_float, msgpack::object(1.2));
  205. EXPECT_EQ(obj_float, 1.2);
  206. msgpack::object obj_bool(true);
  207. EXPECT_EQ(obj_bool, msgpack::object(true));
  208. EXPECT_EQ(obj_bool, true);
  209. }
  210. TEST(object, construct_primitive)
  211. {
  212. msgpack::object obj_nil;
  213. EXPECT_EQ(msgpack::type::NIL, obj_nil.type);
  214. msgpack::object obj_uint(1);
  215. EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type);
  216. EXPECT_EQ(1u, obj_uint.via.u64);
  217. msgpack::object obj_int(-1);
  218. EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type);
  219. EXPECT_EQ(-1, obj_int.via.i64);
  220. msgpack::object obj_float(1.2F);
  221. EXPECT_EQ(msgpack::type::FLOAT32, obj_float.type);
  222. EXPECT_EQ(1.2F, obj_float.via.f64);
  223. msgpack::object obj_double(1.2);
  224. EXPECT_EQ(msgpack::type::FLOAT64, obj_double.type);
  225. EXPECT_EQ(msgpack::type::FLOAT, obj_double.type);
  226. EXPECT_EQ(1.2, obj_double.via.f64);
  227. #if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT)
  228. EXPECT_EQ(msgpack::type::DOUBLE, obj_double.type);
  229. EXPECT_EQ(1.2, obj_double.via.dec);
  230. #endif // MSGPACK_USE_LEGACY_NAME_AS_FLOAT
  231. msgpack::object obj_bool(true);
  232. EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type);
  233. EXPECT_EQ(true, obj_bool.via.boolean);
  234. }
  235. TEST(object, construct_enum)
  236. {
  237. msgpack::object obj(elem);
  238. EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
  239. EXPECT_EQ(static_cast<uint64_t>(elem), obj.via.u64);
  240. }
  241. #if !defined(MSGPACK_USE_CPP03)
  242. TEST(object, construct_enum_newstyle)
  243. {
  244. msgpack::object obj(enum_test::elem);
  245. EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
  246. EXPECT_EQ(elem, obj.via.u64);
  247. }
  248. #endif // !defined(MSGPACK_USE_CPP03)
  249. TEST(object, construct_enum_outer)
  250. {
  251. msgpack::object obj(outer_enum::elem);
  252. EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
  253. EXPECT_EQ(static_cast<uint64_t>(elem), obj.via.u64);
  254. }
  255. #if !defined(MSGPACK_USE_CPP03)
  256. TEST(object, construct_enum_outer_newstyle)
  257. {
  258. msgpack::object obj(outer_enum::enum_test::elem);
  259. EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
  260. EXPECT_EQ(elem, obj.via.u64);
  261. }
  262. TEST(object, construct_class_enum)
  263. {
  264. msgpack::object obj(enum_class_test::elem);
  265. EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
  266. EXPECT_EQ(elem, obj.via.u64);
  267. }
  268. TEST(object, construct_class_enum_outer)
  269. {
  270. msgpack::object obj(outer_enum_class::enum_class_test::elem);
  271. EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
  272. EXPECT_EQ(elem, obj.via.u64);
  273. }
  274. #endif // !defined(MSGPACK_USE_CPP03)
  275. TEST(object, clone_int)
  276. {
  277. int v = 0;
  278. msgpack::object obj(v);
  279. std::size_t sz1 = msgpack::aligned_zone_size(obj);
  280. msgpack::object_handle h = msgpack::clone(obj);
  281. EXPECT_EQ(h.get(), obj);
  282. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  283. h = msgpack::clone(obj);
  284. EXPECT_EQ(h.get(), obj);
  285. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  286. }
  287. TEST(object, clone_str)
  288. {
  289. msgpack::zone z;
  290. std::string v = "123456789";
  291. msgpack::object obj(v, z);
  292. std::size_t sz1 = msgpack::aligned_zone_size(obj);
  293. msgpack::object_handle h = msgpack::clone(obj);
  294. EXPECT_EQ(h.get(), obj);
  295. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  296. h = msgpack::clone(obj);
  297. EXPECT_EQ(h.get(), obj);
  298. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  299. }
  300. TEST(object, clone_bin)
  301. {
  302. msgpack::zone z;
  303. std::vector<char> v;
  304. v.push_back('A');
  305. v.push_back('B');
  306. v.push_back('C');
  307. msgpack::object obj(v, z);
  308. std::size_t sz1 = msgpack::aligned_zone_size(obj);
  309. msgpack::object_handle h = msgpack::clone(obj);
  310. EXPECT_EQ(h.get(), obj);
  311. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  312. h = msgpack::clone(obj);
  313. EXPECT_EQ(h.get(), obj);
  314. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  315. }
  316. TEST(object, clone_array)
  317. {
  318. msgpack::zone z;
  319. std::vector<int> v;
  320. v.push_back(1);
  321. v.push_back(2);
  322. v.push_back(3);
  323. msgpack::object obj(v, z);
  324. std::size_t sz1 = msgpack::aligned_zone_size(obj);
  325. msgpack::object_handle h = msgpack::clone(obj);
  326. EXPECT_EQ(h.get(), obj);
  327. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  328. h = msgpack::clone(obj);
  329. EXPECT_EQ(h.get(), obj);
  330. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  331. }
  332. TEST(object, clone_map)
  333. {
  334. msgpack::zone z;
  335. std::map<int, std::string> v;
  336. v.insert(std::map<int, std::string>::value_type(1, "ABC"));
  337. v.insert(std::map<int, std::string>::value_type(2, "DEF"));
  338. v.insert(std::map<int, std::string>::value_type(3, "GHI"));
  339. msgpack::object obj(v, z);
  340. std::size_t sz1 = msgpack::aligned_zone_size(obj);
  341. msgpack::object_handle h = msgpack::clone(obj);
  342. EXPECT_EQ(h.get(), obj);
  343. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  344. h = msgpack::clone(obj);
  345. EXPECT_EQ(h.get(), obj);
  346. EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get()));
  347. }
  348. TEST(object, pack_float)
  349. {
  350. msgpack::object obj(1.2F);
  351. std::stringstream ss1;
  352. msgpack::pack(ss1, obj);
  353. std::stringstream ss2;
  354. msgpack::pack(ss2, 1.2F);
  355. EXPECT_EQ(static_cast<size_t>(5), ss1.str().size());
  356. EXPECT_EQ(ss1.str(), ss2.str());
  357. }
  358. TEST(object, pack_double)
  359. {
  360. msgpack::object obj(1.2);
  361. std::stringstream ss1;
  362. msgpack::pack(ss1, obj);
  363. std::stringstream ss2;
  364. msgpack::pack(ss2, 1.2);
  365. EXPECT_EQ(static_cast<size_t>(9), ss1.str().size());
  366. EXPECT_EQ(ss1.str(), ss2.str());
  367. }
  368. TEST(object, handle_operators)
  369. {
  370. int i = 1;
  371. msgpack::object obj(i);
  372. msgpack::object_handle oh = msgpack::clone(obj);
  373. EXPECT_EQ(oh.get(), *oh);
  374. EXPECT_EQ(oh->as<int>(), oh.get().as<int>());
  375. }