mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-10-21 15:51:44 +02:00
Compare commits
575 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
076bd07f39 | ||
![]() |
00e897503b | ||
![]() |
2f3c47f385 | ||
![]() |
2b28211701 | ||
![]() |
46c794fc2e | ||
![]() |
0408738b48 | ||
![]() |
eb8a338a0e | ||
![]() |
23480bfe8a | ||
![]() |
3384dbc92d | ||
![]() |
8446549ed8 | ||
![]() |
6a9f3ae71d | ||
![]() |
c58ce1a975 | ||
![]() |
c6d9bbd7b0 | ||
![]() |
65ddd1a455 | ||
![]() |
58c0fe0f91 | ||
![]() |
b96b62f2ac | ||
![]() |
43fc0a52a6 | ||
![]() |
4f3d9a1ded | ||
![]() |
b50ff920f0 | ||
![]() |
983ae0c5a2 | ||
![]() |
9d4db84987 | ||
![]() |
dfaa281476 | ||
![]() |
c1c25c455c | ||
![]() |
e65197f386 | ||
![]() |
ecbb8f8711 | ||
![]() |
03aa736199 | ||
![]() |
821b1f0384 | ||
![]() |
233ad3aaff | ||
![]() |
9c4812f4d4 | ||
![]() |
337cc9fa78 | ||
![]() |
dfe29a0329 | ||
![]() |
85e90aa81e | ||
![]() |
86d30fe571 | ||
![]() |
173302267f | ||
![]() |
8e3ea8d26c | ||
![]() |
cb065563c2 | ||
![]() |
27b89b237b | ||
![]() |
21f0d0bfc4 | ||
![]() |
d5e583b09e | ||
![]() |
15fb9bbcb2 | ||
![]() |
a03418ab12 | ||
![]() |
035513844d | ||
![]() |
193906b8ce | ||
![]() |
d354f2e8c2 | ||
![]() |
24a8ee436f | ||
![]() |
6e5f9404b7 | ||
![]() |
64fe90aabb | ||
![]() |
7e31d487e0 | ||
![]() |
ee16e2eb30 | ||
![]() |
003fb3392f | ||
![]() |
0e82278cd5 | ||
![]() |
5b544248bc | ||
![]() |
d4d7495c0a | ||
![]() |
8325cce44c | ||
![]() |
ee0debc5b3 | ||
![]() |
8f1bd12a17 | ||
![]() |
fccf1016e4 | ||
![]() |
1b010a082b | ||
![]() |
324f215316 | ||
![]() |
ace4f1e7f0 | ||
![]() |
5c5f16f148 | ||
![]() |
f50855d5c0 | ||
![]() |
86917b0ba7 | ||
![]() |
7201fcbe0f | ||
![]() |
83f1735fbb | ||
![]() |
80fd8e70f0 | ||
![]() |
698c1c2b7a | ||
![]() |
5d3287f5aa | ||
![]() |
6990fe6f51 | ||
![]() |
0b81068368 | ||
![]() |
5b1851ae22 | ||
![]() |
0d5708a01d | ||
![]() |
67ab510b5d | ||
![]() |
d1264a1289 | ||
![]() |
3b973021a1 | ||
![]() |
182624895f | ||
![]() |
548de3739c | ||
![]() |
718a3efd64 | ||
![]() |
76b8c3250b | ||
![]() |
dafaa8bd8c | ||
![]() |
9c9b2c25ea | ||
![]() |
e89cd81022 | ||
![]() |
5debbd2be8 | ||
![]() |
fe26df5355 | ||
![]() |
85778494e4 | ||
![]() |
a94ce3c715 | ||
![]() |
a440ff1117 | ||
![]() |
8195137bc5 | ||
![]() |
3e2bd25e4e | ||
![]() |
ffd0c2f624 | ||
![]() |
23333c98d7 | ||
![]() |
5a12ab98c4 | ||
![]() |
0b327a63fc | ||
![]() |
15b28a245c | ||
![]() |
6ef5684797 | ||
![]() |
d439b1495b | ||
![]() |
9e096a3f0e | ||
![]() |
0acf6ec150 | ||
![]() |
4b36340474 | ||
![]() |
910e642a8b | ||
![]() |
9f571146fb | ||
![]() |
339725f73d | ||
![]() |
aff964c58b | ||
![]() |
0c07e745f8 | ||
![]() |
419d2e9564 | ||
![]() |
f936a307c6 | ||
![]() |
4e4678edfa | ||
![]() |
cb7a4b3116 | ||
![]() |
5ca4c42a74 | ||
![]() |
1238a7ca07 | ||
![]() |
a9db60a73d | ||
![]() |
bd32ac19d4 | ||
![]() |
eaf9944e43 | ||
![]() |
703fdbc01d | ||
![]() |
2daa08b0e7 | ||
![]() |
05d9d22d9e | ||
![]() |
8b7894f9bd | ||
![]() |
a71439607f | ||
![]() |
aca0d7f969 | ||
![]() |
310a8e4342 | ||
![]() |
24fbe1ef5b | ||
![]() |
33d8faa35d | ||
![]() |
44be714f65 | ||
![]() |
0df3da6b10 | ||
![]() |
79197b6ec7 | ||
![]() |
353b6b51cb | ||
![]() |
bd9a2c0d3a | ||
![]() |
53b0ee6536 | ||
![]() |
78daac0f1b | ||
![]() |
b970b9b9a8 | ||
![]() |
0339db57f1 | ||
![]() |
461b147897 | ||
![]() |
a3cd13b399 | ||
![]() |
eb5d326a1e | ||
![]() |
cce6eb94e2 | ||
![]() |
8311c72c69 | ||
![]() |
9a059285d9 | ||
![]() |
469ac7891d | ||
![]() |
16264a5693 | ||
![]() |
6eedb50f56 | ||
![]() |
5f07215662 | ||
![]() |
d3a02fb2ca | ||
![]() |
2c823f1aaa | ||
![]() |
706293aadc | ||
![]() |
dfdceb4258 | ||
![]() |
0014b7fdb9 | ||
![]() |
3b28f1f8af | ||
![]() |
c689d476ca | ||
![]() |
cc534fd21f | ||
![]() |
124efcf247 | ||
![]() |
dd452b05e3 | ||
![]() |
b5617f7df9 | ||
![]() |
b73ca1ba3a | ||
![]() |
39ad071c4f | ||
![]() |
fa0b576a45 | ||
![]() |
c2c7591987 | ||
![]() |
3e939e3775 | ||
![]() |
f6384e10bc | ||
![]() |
c283842563 | ||
![]() |
1135976225 | ||
![]() |
76679d33df | ||
![]() |
e9d44b90bc | ||
![]() |
8a7a391166 | ||
![]() |
d6c5a9eece | ||
![]() |
56ad6915d0 | ||
![]() |
466c260782 | ||
![]() |
d8e2d1725a | ||
![]() |
33b43d03ac | ||
![]() |
517509db6e | ||
![]() |
95f01a5976 | ||
![]() |
d08d3bf56d | ||
![]() |
587fd669e8 | ||
![]() |
e3553b87fe | ||
![]() |
a078d2360c | ||
![]() |
2d3abf8e6e | ||
![]() |
cacae0fb7d | ||
![]() |
d7fc215c16 | ||
![]() |
bb69aa18f2 | ||
![]() |
e4f515166a | ||
![]() |
f325acb0ea | ||
![]() |
d1b6e65dd8 | ||
![]() |
4688252bd4 | ||
![]() |
b1df5d3ad7 | ||
![]() |
09bad2938e | ||
![]() |
bad69fd397 | ||
![]() |
b4ae6bf82c | ||
![]() |
eac0f83864 | ||
![]() |
3f16f080ac | ||
![]() |
5de2b974fb | ||
![]() |
6a9cb51828 | ||
![]() |
f1c294ca50 | ||
![]() |
c320e44a23 | ||
![]() |
ea36ef3107 | ||
![]() |
fedc37d079 | ||
![]() |
86ccfcc03c | ||
![]() |
bc8d8ab65a | ||
![]() |
a7a23d3bc8 | ||
![]() |
82d33944e6 | ||
![]() |
8a629ad6fb | ||
![]() |
e1711ffcf2 | ||
![]() |
063d51c662 | ||
![]() |
d8e3575a46 | ||
![]() |
6fa609be3f | ||
![]() |
70982e204c | ||
![]() |
2af7df5865 | ||
![]() |
59610e81de | ||
![]() |
cdfac703ef | ||
![]() |
ad5ebd007e | ||
![]() |
1bd347d997 | ||
![]() |
147056073d | ||
![]() |
1b3231e617 | ||
![]() |
7ac4ad3e38 | ||
![]() |
0a345cb12b | ||
![]() |
19ff0dd17f | ||
![]() |
e3bf8a404b | ||
![]() |
dbb28d9a8f | ||
![]() |
19fd4e755c | ||
![]() |
77698cd924 | ||
![]() |
945d279f28 | ||
![]() |
645d296841 | ||
![]() |
57446de875 | ||
![]() |
3473800ab6 | ||
![]() |
7e5c5153a8 | ||
![]() |
1b8979f285 | ||
![]() |
2aac51dd20 | ||
![]() |
69e32d264c | ||
![]() |
71ae75a5bf | ||
![]() |
86043fd87e | ||
![]() |
d8aaef4f04 | ||
![]() |
7fc34b6369 | ||
![]() |
92b346efa7 | ||
![]() |
c790735b9f | ||
![]() |
64711e615e | ||
![]() |
2065affd45 | ||
![]() |
4067c56b5d | ||
![]() |
65515638aa | ||
![]() |
371ba3ffe3 | ||
![]() |
5395b62f2f | ||
![]() |
3e164eab26 | ||
![]() |
ad85533975 | ||
![]() |
d6c2a97931 | ||
![]() |
17def94ba4 | ||
![]() |
cf254ea240 | ||
![]() |
2d05110239 | ||
![]() |
0017f4fce8 | ||
![]() |
02f3dd947a | ||
![]() |
ef0874feba | ||
![]() |
14aa1420f0 | ||
![]() |
c506cd97e0 | ||
![]() |
3761aacb1d | ||
![]() |
233f13aac5 | ||
![]() |
0ced3ec2d2 | ||
![]() |
5b786f65a4 | ||
![]() |
770542c8c7 | ||
![]() |
4f1207a38c | ||
![]() |
2b65f81e23 | ||
![]() |
c10eb2c17b | ||
![]() |
3f5ac54bf5 | ||
![]() |
790f9409b1 | ||
![]() |
a3d831b723 | ||
![]() |
b9483deea3 | ||
![]() |
c211d2ac45 | ||
![]() |
119a03dd5f | ||
![]() |
f3fbb7e1f6 | ||
![]() |
2be98e8467 | ||
![]() |
91b1806e9d | ||
![]() |
8548b3645a | ||
![]() |
4bbfb3f9a3 | ||
![]() |
98eec72522 | ||
![]() |
562d50df4d | ||
![]() |
f3ee5ab372 | ||
![]() |
aa2a3e5b07 | ||
![]() |
8467307239 | ||
![]() |
90da951a6f | ||
![]() |
59f81b331c | ||
![]() |
77a7d3d26a | ||
![]() |
4321b80999 | ||
![]() |
4b93b06323 | ||
![]() |
96fb2e4b7c | ||
![]() |
3dc1048dfb | ||
![]() |
28f4bd5a67 | ||
![]() |
b01c270889 | ||
![]() |
7c92f8a90b | ||
![]() |
a4a04872a3 | ||
![]() |
f2d13cd647 | ||
![]() |
9346908485 | ||
![]() |
b3a7ba14f7 | ||
![]() |
524ef9553c | ||
![]() |
a85f6e72fe | ||
![]() |
1ae6a41336 | ||
![]() |
3ec55791c6 | ||
![]() |
a3accd28ea | ||
![]() |
fc5bc84207 | ||
![]() |
d8b4051d6d | ||
![]() |
804a1cc22d | ||
![]() |
cdd60e5f9c | ||
![]() |
7c76f07384 | ||
![]() |
a3b1ef9527 | ||
![]() |
0bd4150a80 | ||
![]() |
7f7f5253f2 | ||
![]() |
2a0a847634 | ||
![]() |
92ddb37ed3 | ||
![]() |
01f944e6bd | ||
![]() |
732c8d7350 | ||
![]() |
21678aeef5 | ||
![]() |
cda1ca35a4 | ||
![]() |
923580d2cd | ||
![]() |
190af1d32b | ||
![]() |
bffe0443f9 | ||
![]() |
29e99e229b | ||
![]() |
2736b88dd5 | ||
![]() |
e739c60e9f | ||
![]() |
1c0afbc5c5 | ||
![]() |
ee1ba5c0f2 | ||
![]() |
02342ba540 | ||
![]() |
12a130e9bc | ||
![]() |
dfb97e7961 | ||
![]() |
54e03a62bd | ||
![]() |
ec9659ff25 | ||
![]() |
0a41b253f3 | ||
![]() |
002b86198c | ||
![]() |
7161a235f1 | ||
![]() |
391034a785 | ||
![]() |
446a7fbd67 | ||
![]() |
2ccb09434f | ||
![]() |
7974060a40 | ||
![]() |
e8abcc1765 | ||
![]() |
1be1927a1f | ||
![]() |
894ff71664 | ||
![]() |
93bed9c5df | ||
![]() |
34c008adce | ||
![]() |
22ddd91b1f | ||
![]() |
e121f34407 | ||
![]() |
df8a3e870a | ||
![]() |
13b6708a09 | ||
![]() |
6aa196cf55 | ||
![]() |
142493076a | ||
![]() |
3d905a7a4f | ||
![]() |
0a8a6ed168 | ||
![]() |
68b6fa46e6 | ||
![]() |
80f7c54e4d | ||
![]() |
c0e2041006 | ||
![]() |
f6d2cd7704 | ||
![]() |
6d9a629b15 | ||
![]() |
ead8edc7cd | ||
![]() |
664eefdddb | ||
![]() |
220d76c974 | ||
![]() |
d973192b5e | ||
![]() |
978bb5059f | ||
![]() |
f59178bc33 | ||
![]() |
53899cc492 | ||
![]() |
6379d0fe0f | ||
![]() |
a1c4d8696a | ||
![]() |
7f42ed86f2 | ||
![]() |
6bb8b4c994 | ||
![]() |
afefbe4e56 | ||
![]() |
5cd37e5505 | ||
![]() |
d6a825981d | ||
![]() |
a1c01c6722 | ||
![]() |
8d182f1d79 | ||
![]() |
29707bd2ea | ||
![]() |
c2bf2a8174 | ||
![]() |
b402849557 | ||
![]() |
cb85dcfcb8 | ||
![]() |
49379140c7 | ||
![]() |
63f6c86b46 | ||
![]() |
1865898cd4 | ||
![]() |
8935ecfdb8 | ||
![]() |
4902bed409 | ||
![]() |
e6f6aba207 | ||
![]() |
bab622de25 | ||
![]() |
a86c1624a7 | ||
![]() |
c707392a5a | ||
![]() |
1f07721ec4 | ||
![]() |
4767e45035 | ||
![]() |
f2a64ed685 | ||
![]() |
2c9966a0a3 | ||
![]() |
953aa95c64 | ||
![]() |
446266776e | ||
![]() |
845af014dc | ||
![]() |
7c8f8703a1 | ||
![]() |
a0c18e4380 | ||
![]() |
e8d8099563 | ||
![]() |
2c9d90d463 | ||
![]() |
130d2064d5 | ||
![]() |
a10eb2a0d7 | ||
![]() |
b71cc5d7ee | ||
![]() |
8512f9eda1 | ||
![]() |
80058083b8 | ||
![]() |
d5a17a3c25 | ||
![]() |
eab7c87781 | ||
![]() |
d2962d8676 | ||
![]() |
5e602fb575 | ||
![]() |
599964ea5f | ||
![]() |
562de7926b | ||
![]() |
8eaed95e02 | ||
![]() |
3cffd46008 | ||
![]() |
e239bfda8a | ||
![]() |
bd887b660d | ||
![]() |
7c1e0ea95d | ||
![]() |
afbddbfcda | ||
![]() |
9eeb702ca5 | ||
![]() |
4cb6d6995f | ||
![]() |
fe7e7a8d07 | ||
![]() |
f8ee79ab72 | ||
![]() |
a11165830b | ||
![]() |
11cde61eab | ||
![]() |
cd862409cc | ||
![]() |
7644555d6b | ||
![]() |
07e68aa694 | ||
![]() |
0ae206b1bb | ||
![]() |
5bdac96375 | ||
![]() |
f0e044ecd8 | ||
![]() |
f32234291e | ||
![]() |
83acd6529f | ||
![]() |
6a60cb4dc0 | ||
![]() |
1de03fbe18 | ||
![]() |
0e0a2aa981 | ||
![]() |
af73b9d11b | ||
![]() |
859969241a | ||
![]() |
6852a8ca9d | ||
![]() |
c694f1a4a9 | ||
![]() |
d36543b204 | ||
![]() |
6981234736 | ||
![]() |
10bf3ee9de | ||
![]() |
9953218de1 | ||
![]() |
50c74103aa | ||
![]() |
c5e15123fd | ||
![]() |
4adcdb5ba8 | ||
![]() |
60b36ffaa3 | ||
![]() |
d86104ed5d | ||
![]() |
0f02ef20a9 | ||
![]() |
0768cf17b6 | ||
![]() |
197205853f | ||
![]() |
bebcc24ab8 | ||
![]() |
987248ccbb | ||
![]() |
56ece4db0f | ||
![]() |
c7f8b94ccd | ||
![]() |
95b820305a | ||
![]() |
599b200ca5 | ||
![]() |
a9566b31be | ||
![]() |
f30837d726 | ||
![]() |
1242ffa4c6 | ||
![]() |
37c0347c47 | ||
![]() |
65befb84a0 | ||
![]() |
a41f7ce3bd | ||
![]() |
81ced6bf2a | ||
![]() |
fa8033f998 | ||
![]() |
19e3178d0c | ||
![]() |
1e6262f24f | ||
![]() |
beb2284440 | ||
![]() |
0c4f0de13d | ||
![]() |
0cd31a4b96 | ||
![]() |
ef0a86e7cc | ||
![]() |
b79c1345b9 | ||
![]() |
5bb8b6f16c | ||
![]() |
f6f675d1e1 | ||
![]() |
9f684e7670 | ||
![]() |
a998706452 | ||
![]() |
5e19bc6f84 | ||
![]() |
169f287970 | ||
![]() |
c56926428c | ||
![]() |
43eab5c4e5 | ||
![]() |
c6424c2ce7 | ||
![]() |
dfe19d308c | ||
![]() |
b75db110dc | ||
![]() |
9e50ba6ec6 | ||
![]() |
aca2ba13c2 | ||
![]() |
c5afe7a573 | ||
![]() |
8b90968cb1 | ||
![]() |
9281dba896 | ||
![]() |
c7555f1c3c | ||
![]() |
e781831032 | ||
![]() |
8025895168 | ||
![]() |
799935e44c | ||
![]() |
209d8d058c | ||
![]() |
0368a70dd7 | ||
![]() |
c3603426de | ||
![]() |
80db9971b5 | ||
![]() |
e3e771708e | ||
![]() |
b9bca2a19f | ||
![]() |
ffae70a99a | ||
![]() |
10ec1e48b0 | ||
![]() |
84123f5445 | ||
![]() |
25531d8393 | ||
![]() |
adfadc542a | ||
![]() |
7682e1cb57 | ||
![]() |
1fe4109a42 | ||
![]() |
b97baf4d47 | ||
![]() |
f91728561f | ||
![]() |
2b75d54ce1 | ||
![]() |
cdc09a7d30 | ||
![]() |
4cc6c3e535 | ||
![]() |
8f43e033a4 | ||
![]() |
918dbd1926 | ||
![]() |
8fc86ce7fa | ||
![]() |
bf0cb40586 | ||
![]() |
a62aefe74b | ||
![]() |
138d232149 | ||
![]() |
8fa64e3ab2 | ||
![]() |
8d0d2bd3fc | ||
![]() |
2146f5f623 | ||
![]() |
623df23570 | ||
![]() |
4a15d8b6d2 | ||
![]() |
af83a62474 | ||
![]() |
a0705a6c67 | ||
![]() |
712b8eec3d | ||
![]() |
558e9c21ed | ||
![]() |
23a7137e6a | ||
![]() |
71a1cb0184 | ||
![]() |
09b47cc536 | ||
![]() |
b5c78de2dd | ||
![]() |
a1bd14e516 | ||
![]() |
9684c8664f | ||
![]() |
3c75361e5a | ||
![]() |
c44c9ab74d | ||
![]() |
8cc9c871b7 | ||
![]() |
31d211cded | ||
![]() |
c42cba1d54 | ||
![]() |
c87f7cb9ac | ||
![]() |
421bee3871 | ||
![]() |
2c7573a032 | ||
![]() |
fe2a0f5089 | ||
![]() |
59ba8dec4e | ||
![]() |
ff0e1bbbc0 | ||
![]() |
18c712cd99 | ||
![]() |
8de1f764fd | ||
![]() |
a91c1ec6d9 | ||
![]() |
c8e351b31e | ||
![]() |
b4c98584db | ||
![]() |
1d17836b7d | ||
![]() |
193a739749 | ||
![]() |
48da2b8353 | ||
![]() |
40dc9de6c9 | ||
![]() |
d7469e4694 | ||
![]() |
fdfabc9f88 | ||
![]() |
5658ca5b90 | ||
![]() |
8b79e6d3c7 | ||
![]() |
8c67087a15 | ||
![]() |
057f73a73e | ||
![]() |
d3bb37d113 | ||
![]() |
6c91b862c9 | ||
![]() |
cba47b635a | ||
![]() |
cd83388f8b | ||
![]() |
02ae247536 | ||
![]() |
1621a68191 | ||
![]() |
2aef495d62 | ||
![]() |
227c168b65 | ||
![]() |
dcbcf5842f | ||
![]() |
8a3ac6d9bd | ||
![]() |
6cabad19d5 | ||
![]() |
dad7a03d19 | ||
![]() |
7b152640d9 | ||
![]() |
78fddff34e | ||
![]() |
78f542f6c0 | ||
![]() |
f8a016edb5 | ||
![]() |
9ac69337e8 | ||
![]() |
ca0c844f32 | ||
![]() |
e629e8784f | ||
![]() |
e944c1ee93 | ||
![]() |
02c882bda3 | ||
![]() |
2c29377abf | ||
![]() |
21992f1b9e | ||
![]() |
8a3f090684 | ||
![]() |
a4258505a9 | ||
![]() |
ba4a971bfa | ||
![]() |
6abc120279 | ||
![]() |
64c36b7a8f | ||
![]() |
64b9f0762c | ||
![]() |
e799082e5c | ||
![]() |
eab66a022e | ||
![]() |
485915c27a | ||
![]() |
45fb482ab4 | ||
![]() |
33a7d56042 | ||
![]() |
8f7f23a0e5 |
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
*.o
|
||||
*.so
|
||||
ruby/Makefile
|
||||
*.5
|
||||
*.8
|
||||
*.6
|
||||
_obj
|
||||
_test
|
@@ -1,4 +1,26 @@
|
||||
|
||||
2011-04-24 version 0.5.6:
|
||||
|
||||
* #42 fixes double-free problem on msgpack_unpacker_release_zone
|
||||
|
||||
2011-02-24 version 0.5.5:
|
||||
|
||||
* eliminates dependency of winsock2.h header
|
||||
* fixes msgpack_vc.postbuild.bat file
|
||||
* fixes some implicit cast warnings
|
||||
|
||||
2010-08-29 version 0.5.4:
|
||||
|
||||
* includes msgpack_vc2008.vcproj file in source package
|
||||
* fixes type::fix_int types
|
||||
|
||||
2010-08-27 version 0.5.3:
|
||||
|
||||
* adds type::fix_{u,}int{8,16,32,64} types
|
||||
* adds msgpack_pack_fix_{u,}int{8,16,32,64} functions
|
||||
* adds packer<Stream>::pack_fix_{u,}int{8,16,32,64} functions
|
||||
* fixes include paths
|
||||
|
||||
2010-07-14 version 0.5.2:
|
||||
|
||||
* type::raw::str(), operator==, operator!=, operator< and operator> are now const
|
||||
|
@@ -6,7 +6,9 @@ DOC_FILES = \
|
||||
NOTICE \
|
||||
msgpack_vc8.vcproj \
|
||||
msgpack_vc8.sln \
|
||||
msgpack_vc8.postbuild.bat
|
||||
msgpack_vc2008.vcproj \
|
||||
msgpack_vc2008.sln \
|
||||
msgpack_vc.postbuild.bat
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(DOC_FILES)
|
||||
|
@@ -13,9 +13,10 @@ On UNIX-like platform, run ./configure && make && sudo make install:
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
On Windows, open msgpack_vc8.vcproj file and build it using batch build. DLLs are built on lib folder, and the headers are built on include folder.
|
||||
On Windows, open msgpack_vc8.vcproj or msgpack_vc2008 file and build it using batch build. DLLs are built on lib folder,
|
||||
and the headers are built on include folder.
|
||||
|
||||
To use the library in your program, include msgpack.hpp header and link msgpack and msgpackc library.
|
||||
To use the library in your program, include msgpack.hpp header and link "msgpack" library.
|
||||
|
||||
|
||||
## Example
|
||||
@@ -34,15 +35,9 @@ To use the library in your program, include msgpack.hpp header and link msgpack
|
||||
msgpack::pack(&buffer, target);
|
||||
|
||||
// Deserialize the serialized data.
|
||||
msgpack::zone mempool; // this manages the life of deserialized object
|
||||
msgpack::object obj;
|
||||
msgpack::unpack_return ret =
|
||||
msgpack::unpack(buffer.data, buffer.size, NULL, &mempool, &obj);
|
||||
|
||||
if(ret != msgapck::UNPACK_SUCCESS) {
|
||||
// error check
|
||||
exit(1);
|
||||
}
|
||||
msgpack::unpacked msg; // includes memory pool and deserialized object
|
||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
|
||||
msgpack::object obj = msg.get();
|
||||
|
||||
// Print the deserialized object to stdout.
|
||||
std::cout << obj << std::endl; // ["Hello," "World!"]
|
||||
@@ -55,24 +50,24 @@ To use the library in your program, include msgpack.hpp header and link msgpack
|
||||
obj.as<int>(); // type is mismatched, msgpack::type_error is thrown
|
||||
}
|
||||
|
||||
API document and other example codes are available at the [wiki.](http://msgpack.sourceforge.net/start)
|
||||
API documents and other example codes are available at the [wiki.](http://redmine.msgpack.org/projects/msgpack/wiki)
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright (C) 2008-2010 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.
|
||||
Copyright (C) 2008-2010 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.
|
||||
|
||||
See also NOTICE file.
|
||||
|
||||
|
@@ -38,7 +38,8 @@ test -f ChangeLog || touch ChangeLog
|
||||
test -f NEWS || touch NEWS
|
||||
test -f README || cp -f README.md README
|
||||
|
||||
if ! ./preprocess; then
|
||||
./preprocess
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
AC_INIT(src/object.cpp)
|
||||
AC_CONFIG_AUX_DIR(ac)
|
||||
AM_INIT_AUTOMAKE(msgpack, 0.5.2)
|
||||
AM_INIT_AUTOMAKE(msgpack, 0.5.6)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
@@ -55,7 +55,7 @@ if test "$msgpack_cv_atomic_ops" != "yes"; then
|
||||
Note that gcc < 4.1 is not supported.
|
||||
|
||||
If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to
|
||||
add CFLAGS="--march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows:
|
||||
add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows:
|
||||
|
||||
$ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686"
|
||||
])
|
||||
|
@@ -24,12 +24,13 @@ copy src\msgpack\pack.hpp include\msgpack\
|
||||
copy src\msgpack\unpack.hpp include\msgpack\
|
||||
copy src\msgpack\object.hpp include\msgpack\
|
||||
copy src\msgpack\zone.hpp include\msgpack\
|
||||
copy src\msgpack\type.hpp include\msgpack\type\
|
||||
copy src\msgpack\type.hpp include\msgpack\
|
||||
copy src\msgpack\type\bool.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\deque.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\fixint.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\float.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\int.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\list.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\deque.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\map.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\nil.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\pair.hpp include\msgpack\type\
|
||||
@@ -39,6 +40,6 @@ copy src\msgpack\type\string.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\vector.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\tuple.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\define.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\tr1\unordered_map.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\tr1\unordered_set.hpp include\msgpack\type\
|
||||
copy src\msgpack\type\tr1\unordered_map.hpp include\msgpack\type\tr1\
|
||||
copy src\msgpack\type\tr1\unordered_set.hpp include\msgpack\type\tr1\
|
||||
|
@@ -28,7 +28,7 @@
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Gathering header files"
|
||||
CommandLine="msgpack_vc8.postbuild.bat"
|
||||
CommandLine="msgpack_vc.postbuild.bat"
|
||||
Outputs="include"
|
||||
/>
|
||||
<Tool
|
||||
@@ -96,7 +96,7 @@
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Gathering header files"
|
||||
CommandLine="msgpack_vc8.postbuild.bat"
|
||||
CommandLine="msgpack_vc.postbuild.bat"
|
||||
Outputs="include"
|
||||
/>
|
||||
<Tool
|
||||
|
@@ -12,7 +12,7 @@ preprocess() {
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$1" == "clean" ];then
|
||||
if [ "$1" = "clean" ];then
|
||||
rm -f src/msgpack/type/tuple.hpp
|
||||
rm -f src/msgpack/type/define.hpp
|
||||
rm -f src/msgpack/zone.hpp
|
||||
@@ -29,3 +29,6 @@ cp -f ../msgpack/unpack_template.h src/msgpack/
|
||||
cp -f ../test/cases.mpac test/
|
||||
cp -f ../test/cases_compact.mpac test/
|
||||
|
||||
sed -e 's/8\.00/9.00/' < msgpack_vc8.vcproj > msgpack_vc2008.vcproj
|
||||
sed -e 's/9\.00/10.00/' -e 's/msgpack_vc8/msgpack_vc2008/' < msgpack_vc8.sln > msgpack_vc2008.sln
|
||||
|
||||
|
@@ -58,10 +58,11 @@ nobase_include_HEADERS += \
|
||||
msgpack/zone.hpp \
|
||||
msgpack/type.hpp \
|
||||
msgpack/type/bool.hpp \
|
||||
msgpack/type/deque.hpp \
|
||||
msgpack/type/float.hpp \
|
||||
msgpack/type/fixint.hpp \
|
||||
msgpack/type/int.hpp \
|
||||
msgpack/type/list.hpp \
|
||||
msgpack/type/deque.hpp \
|
||||
msgpack/type/map.hpp \
|
||||
msgpack/type/nil.hpp \
|
||||
msgpack/type/pair.hpp \
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_OBJECT_H__
|
||||
#define MSGPACK_OBJECT_H__
|
||||
|
||||
#include "msgpack/zone.h"
|
||||
#include "zone.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -18,9 +18,9 @@
|
||||
#ifndef MSGPACK_OBJECT_HPP__
|
||||
#define MSGPACK_OBJECT_HPP__
|
||||
|
||||
#include "msgpack/object.h"
|
||||
#include "msgpack/pack.hpp"
|
||||
#include "msgpack/zone.hpp"
|
||||
#include "object.h"
|
||||
#include "pack.hpp"
|
||||
#include "zone.hpp"
|
||||
#include <string.h>
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
|
@@ -18,8 +18,8 @@
|
||||
#ifndef MSGPACK_PACK_H__
|
||||
#define MSGPACK_PACK_H__
|
||||
|
||||
#include "msgpack/pack_define.h"
|
||||
#include "msgpack/object.h"
|
||||
#include "pack_define.h"
|
||||
#include "object.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -70,6 +70,15 @@ static int msgpack_pack_int16(msgpack_packer* pk, int16_t d);
|
||||
static int msgpack_pack_int32(msgpack_packer* pk, int32_t d);
|
||||
static int msgpack_pack_int64(msgpack_packer* pk, int64_t d);
|
||||
|
||||
static int msgpack_pack_fix_uint8(msgpack_packer* pk, uint8_t d);
|
||||
static int msgpack_pack_fix_uint16(msgpack_packer* pk, uint16_t d);
|
||||
static int msgpack_pack_fix_uint32(msgpack_packer* pk, uint32_t d);
|
||||
static int msgpack_pack_fix_uint64(msgpack_packer* pk, uint64_t d);
|
||||
static int msgpack_pack_fix_int8(msgpack_packer* pk, int8_t d);
|
||||
static int msgpack_pack_fix_int16(msgpack_packer* pk, int16_t d);
|
||||
static int msgpack_pack_fix_int32(msgpack_packer* pk, int32_t d);
|
||||
static int msgpack_pack_fix_int64(msgpack_packer* pk, int64_t d);
|
||||
|
||||
static int msgpack_pack_float(msgpack_packer* pk, float d);
|
||||
static int msgpack_pack_double(msgpack_packer* pk, double d);
|
||||
|
||||
@@ -96,12 +105,15 @@ int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);
|
||||
#define msgpack_pack_inline_func_cint(name) \
|
||||
inline int msgpack_pack ## name
|
||||
|
||||
#define msgpack_pack_inline_func_fixint(name) \
|
||||
inline int msgpack_pack_fix ## name
|
||||
|
||||
#define msgpack_pack_user msgpack_packer*
|
||||
|
||||
#define msgpack_pack_append_buffer(user, buf, len) \
|
||||
return (*(user)->callback)((user)->data, (const char*)buf, len)
|
||||
|
||||
#include "msgpack/pack_template.h"
|
||||
#include "pack_template.h"
|
||||
|
||||
inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback)
|
||||
{
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_PACK_HPP__
|
||||
#define MSGPACK_PACK_HPP__
|
||||
|
||||
#include "msgpack/pack_define.h"
|
||||
#include "pack_define.h"
|
||||
#include <stdexcept>
|
||||
#include <limits.h>
|
||||
|
||||
@@ -45,6 +45,15 @@ public:
|
||||
packer<Stream>& pack_int32(int32_t d);
|
||||
packer<Stream>& pack_int64(int64_t d);
|
||||
|
||||
packer<Stream>& pack_fix_uint8(uint8_t d);
|
||||
packer<Stream>& pack_fix_uint16(uint16_t d);
|
||||
packer<Stream>& pack_fix_uint32(uint32_t d);
|
||||
packer<Stream>& pack_fix_uint64(uint64_t d);
|
||||
packer<Stream>& pack_fix_int8(int8_t d);
|
||||
packer<Stream>& pack_fix_int16(int16_t d);
|
||||
packer<Stream>& pack_fix_int32(int32_t d);
|
||||
packer<Stream>& pack_fix_int64(int64_t d);
|
||||
|
||||
packer<Stream>& pack_short(short d);
|
||||
packer<Stream>& pack_int(int d);
|
||||
packer<Stream>& pack_long(long d);
|
||||
@@ -78,6 +87,15 @@ private:
|
||||
static void _pack_int32(Stream& x, int32_t d);
|
||||
static void _pack_int64(Stream& x, int64_t d);
|
||||
|
||||
static void _pack_fix_uint8(Stream& x, uint8_t d);
|
||||
static void _pack_fix_uint16(Stream& x, uint16_t d);
|
||||
static void _pack_fix_uint32(Stream& x, uint32_t d);
|
||||
static void _pack_fix_uint64(Stream& x, uint64_t d);
|
||||
static void _pack_fix_int8(Stream& x, int8_t d);
|
||||
static void _pack_fix_int16(Stream& x, int16_t d);
|
||||
static void _pack_fix_int32(Stream& x, int32_t d);
|
||||
static void _pack_fix_int64(Stream& x, int64_t d);
|
||||
|
||||
static void _pack_short(Stream& x, short d);
|
||||
static void _pack_int(Stream& x, int d);
|
||||
static void _pack_long(Stream& x, long d);
|
||||
@@ -133,11 +151,15 @@ inline void pack(Stream& s, const T& v)
|
||||
template <typename Stream> \
|
||||
inline void packer<Stream>::_pack ## name
|
||||
|
||||
#define msgpack_pack_inline_func_fixint(name) \
|
||||
template <typename Stream> \
|
||||
inline void packer<Stream>::_pack_fix ## name
|
||||
|
||||
#define msgpack_pack_user Stream&
|
||||
|
||||
#define msgpack_pack_append_buffer append_buffer
|
||||
|
||||
#include "msgpack/pack_template.h"
|
||||
#include "pack_template.h"
|
||||
|
||||
|
||||
template <typename Stream>
|
||||
@@ -149,6 +171,7 @@ packer<Stream>::packer(Stream& s) : m_stream(s) { }
|
||||
template <typename Stream>
|
||||
packer<Stream>::~packer() { }
|
||||
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_uint8(uint8_t d)
|
||||
{ _pack_uint8(m_stream, d); return *this; }
|
||||
@@ -182,6 +205,39 @@ inline packer<Stream>& packer<Stream>::pack_int64(int64_t d)
|
||||
{ _pack_int64(m_stream, d); return *this;}
|
||||
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_fix_uint8(uint8_t d)
|
||||
{ _pack_fix_uint8(m_stream, d); return *this; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_fix_uint16(uint16_t d)
|
||||
{ _pack_fix_uint16(m_stream, d); return *this; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_fix_uint32(uint32_t d)
|
||||
{ _pack_fix_uint32(m_stream, d); return *this; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_fix_uint64(uint64_t d)
|
||||
{ _pack_fix_uint64(m_stream, d); return *this; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_fix_int8(int8_t d)
|
||||
{ _pack_fix_int8(m_stream, d); return *this; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_fix_int16(int16_t d)
|
||||
{ _pack_fix_int16(m_stream, d); return *this; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_fix_int32(int32_t d)
|
||||
{ _pack_fix_int32(m_stream, d); return *this; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_fix_int64(int64_t d)
|
||||
{ _pack_fix_int64(m_stream, d); return *this;}
|
||||
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& packer<Stream>::pack_short(short d)
|
||||
{ _pack_short(m_stream, d); return *this; }
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_SBUFFER_HPP__
|
||||
#define MSGPACK_SBUFFER_HPP__
|
||||
|
||||
#include "msgpack/sbuffer.h"
|
||||
#include "sbuffer.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace msgpack {
|
||||
@@ -28,9 +28,13 @@ class sbuffer : public msgpack_sbuffer {
|
||||
public:
|
||||
sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE)
|
||||
{
|
||||
base::data = (char*)::malloc(initsz);
|
||||
if(!base::data) {
|
||||
throw std::bad_alloc();
|
||||
if(initsz == 0) {
|
||||
base::data = NULL;
|
||||
} else {
|
||||
base::data = (char*)::malloc(initsz);
|
||||
if(!base::data) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
base::size = 0;
|
||||
@@ -80,7 +84,7 @@ public:
|
||||
private:
|
||||
void expand_buffer(size_t len)
|
||||
{
|
||||
size_t nsize = (base::alloc) ?
|
||||
size_t nsize = (base::alloc > 0) ?
|
||||
base::alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
|
||||
|
||||
while(nsize < base::size + len) { nsize *= 2; }
|
||||
|
@@ -1,15 +1,16 @@
|
||||
#include "msgpack/type/bool.hpp"
|
||||
#include "msgpack/type/float.hpp"
|
||||
#include "msgpack/type/int.hpp"
|
||||
#include "msgpack/type/list.hpp"
|
||||
#include "msgpack/type/deque.hpp"
|
||||
#include "msgpack/type/map.hpp"
|
||||
#include "msgpack/type/nil.hpp"
|
||||
#include "msgpack/type/pair.hpp"
|
||||
#include "msgpack/type/raw.hpp"
|
||||
#include "msgpack/type/set.hpp"
|
||||
#include "msgpack/type/string.hpp"
|
||||
#include "msgpack/type/vector.hpp"
|
||||
#include "msgpack/type/tuple.hpp"
|
||||
#include "msgpack/type/define.hpp"
|
||||
#include "type/bool.hpp"
|
||||
#include "type/deque.hpp"
|
||||
#include "type/fixint.hpp"
|
||||
#include "type/float.hpp"
|
||||
#include "type/int.hpp"
|
||||
#include "type/list.hpp"
|
||||
#include "type/map.hpp"
|
||||
#include "type/nil.hpp"
|
||||
#include "type/pair.hpp"
|
||||
#include "type/raw.hpp"
|
||||
#include "type/set.hpp"
|
||||
#include "type/string.hpp"
|
||||
#include "type/vector.hpp"
|
||||
#include "type/tuple.hpp"
|
||||
#include "type/define.hpp"
|
||||
|
||||
|
172
cpp/src/msgpack/type/fixint.hpp
Normal file
172
cpp/src/msgpack/type/fixint.hpp
Normal file
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// MessagePack for C++ static resolution routine
|
||||
//
|
||||
// Copyright (C) 2020 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_TYPE_FIXINT_HPP__
|
||||
#define MSGPACK_TYPE_FIXINT_HPP__
|
||||
|
||||
#include "msgpack/object.hpp"
|
||||
#include "msgpack/type/int.hpp"
|
||||
|
||||
namespace msgpack {
|
||||
|
||||
namespace type {
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct fix_int {
|
||||
fix_int() : value(0) { }
|
||||
fix_int(T value) : value(value) { }
|
||||
|
||||
operator T() const { return value; }
|
||||
|
||||
T get() const { return value; }
|
||||
|
||||
private:
|
||||
T value;
|
||||
};
|
||||
|
||||
|
||||
typedef fix_int<uint8_t> fix_uint8;
|
||||
typedef fix_int<uint16_t> fix_uint16;
|
||||
typedef fix_int<uint32_t> fix_uint32;
|
||||
typedef fix_int<uint64_t> fix_uint64;
|
||||
|
||||
typedef fix_int<int8_t> fix_int8;
|
||||
typedef fix_int<int16_t> fix_int16;
|
||||
typedef fix_int<int32_t> fix_int32;
|
||||
typedef fix_int<int64_t> fix_int64;
|
||||
|
||||
|
||||
} // namespace type
|
||||
|
||||
|
||||
inline type::fix_int8& operator>> (object o, type::fix_int8& v)
|
||||
{ v = type::detail::convert_integer<int8_t>(o); return v; }
|
||||
|
||||
inline type::fix_int16& operator>> (object o, type::fix_int16& v)
|
||||
{ v = type::detail::convert_integer<int16_t>(o); return v; }
|
||||
|
||||
inline type::fix_int32& operator>> (object o, type::fix_int32& v)
|
||||
{ v = type::detail::convert_integer<int32_t>(o); return v; }
|
||||
|
||||
inline type::fix_int64& operator>> (object o, type::fix_int64& v)
|
||||
{ v = type::detail::convert_integer<int64_t>(o); return v; }
|
||||
|
||||
|
||||
inline type::fix_uint8& operator>> (object o, type::fix_uint8& v)
|
||||
{ v = type::detail::convert_integer<uint8_t>(o); return v; }
|
||||
|
||||
inline type::fix_uint16& operator>> (object o, type::fix_uint16& v)
|
||||
{ v = type::detail::convert_integer<uint16_t>(o); return v; }
|
||||
|
||||
inline type::fix_uint32& operator>> (object o, type::fix_uint32& v)
|
||||
{ v = type::detail::convert_integer<uint32_t>(o); return v; }
|
||||
|
||||
inline type::fix_uint64& operator>> (object o, type::fix_uint64& v)
|
||||
{ v = type::detail::convert_integer<uint64_t>(o); return v; }
|
||||
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int8& v)
|
||||
{ o.pack_fix_int8(v); return o; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int16& v)
|
||||
{ o.pack_fix_int16(v); return o; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int32& v)
|
||||
{ o.pack_fix_int32(v); return o; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int64& v)
|
||||
{ o.pack_fix_int64(v); return o; }
|
||||
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint8& v)
|
||||
{ o.pack_fix_uint8(v); return o; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint16& v)
|
||||
{ o.pack_fix_uint16(v); return o; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint32& v)
|
||||
{ o.pack_fix_uint32(v); return o; }
|
||||
|
||||
template <typename Stream>
|
||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint64& v)
|
||||
{ o.pack_fix_uint64(v); return o; }
|
||||
|
||||
|
||||
inline void operator<< (object& o, type::fix_int8 v)
|
||||
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
||||
|
||||
inline void operator<< (object& o, type::fix_int16 v)
|
||||
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
||||
|
||||
inline void operator<< (object& o, type::fix_int32 v)
|
||||
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
||||
|
||||
inline void operator<< (object& o, type::fix_int64 v)
|
||||
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
||||
|
||||
|
||||
inline void operator<< (object& o, type::fix_uint8 v)
|
||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
||||
|
||||
inline void operator<< (object& o, type::fix_uint16 v)
|
||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
||||
|
||||
inline void operator<< (object& o, type::fix_uint32 v)
|
||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
||||
|
||||
inline void operator<< (object& o, type::fix_uint64 v)
|
||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
||||
|
||||
|
||||
inline void operator<< (object::with_zone& o, type::fix_int8 v)
|
||||
{ static_cast<object&>(o) << v; }
|
||||
|
||||
inline void operator<< (object::with_zone& o, type::fix_int16 v)
|
||||
{ static_cast<object&>(o) << v; }
|
||||
|
||||
inline void operator<< (object::with_zone& o, type::fix_int32 v)
|
||||
{ static_cast<object&>(o) << v; }
|
||||
|
||||
inline void operator<< (object::with_zone& o, type::fix_int64 v)
|
||||
{ static_cast<object&>(o) << v; }
|
||||
|
||||
|
||||
inline void operator<< (object::with_zone& o, type::fix_uint8 v)
|
||||
{ static_cast<object&>(o) << v; }
|
||||
|
||||
inline void operator<< (object::with_zone& o, type::fix_uint16 v)
|
||||
{ static_cast<object&>(o) << v; }
|
||||
|
||||
inline void operator<< (object::with_zone& o, type::fix_uint32 v)
|
||||
{ static_cast<object&>(o) << v; }
|
||||
|
||||
inline void operator<< (object::with_zone& o, type::fix_uint64 v)
|
||||
{ static_cast<object&>(o) << v; }
|
||||
|
||||
|
||||
} // namespace msgpack
|
||||
|
||||
#endif /* msgpack/type/fixint.hpp */
|
||||
|
@@ -30,7 +30,7 @@ namespace msgpack {
|
||||
inline float& operator>> (object o, float& v)
|
||||
{
|
||||
if(o.type != type::DOUBLE) { throw type_error(); }
|
||||
v = o.via.dec;
|
||||
v = (float)o.via.dec;
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const double& v)
|
||||
inline void operator<< (object& o, float v)
|
||||
{
|
||||
o.type = type::DOUBLE;
|
||||
o.via.dec = v;
|
||||
o.via.dec = (double)v;
|
||||
}
|
||||
|
||||
inline void operator<< (object& o, double v)
|
||||
|
@@ -35,11 +35,11 @@ namespace detail {
|
||||
if(o.type == type::POSITIVE_INTEGER) {
|
||||
if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
|
||||
{ throw type_error(); }
|
||||
return o.via.u64;
|
||||
return (T)o.via.u64;
|
||||
} else if(o.type == type::NEGATIVE_INTEGER) {
|
||||
if(o.via.i64 < (int64_t)std::numeric_limits<T>::min())
|
||||
{ throw type_error(); }
|
||||
return o.via.i64;
|
||||
return (T)o.via.i64;
|
||||
}
|
||||
throw type_error();
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace detail {
|
||||
if(o.type == type::POSITIVE_INTEGER) {
|
||||
if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
|
||||
{ throw type_error(); }
|
||||
return o.via.u64;
|
||||
return (T)o.via.u64;
|
||||
}
|
||||
throw type_error();
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ inline void operator<< (object::with_zone& o, const std::string& v)
|
||||
o.type = type::RAW;
|
||||
char* ptr = (char*)o.zone->malloc(v.size());
|
||||
o.via.raw.ptr = ptr;
|
||||
o.via.raw.size = v.size();
|
||||
o.via.raw.size = (uint32_t)v.size();
|
||||
memcpy(ptr, v.data(), v.size());
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ inline void operator<< (object& o, const std::string& v)
|
||||
{
|
||||
o.type = type::RAW;
|
||||
o.via.raw.ptr = v.data();
|
||||
o.via.raw.size = v.size();
|
||||
o.via.raw.size = (uint32_t)v.size();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -18,8 +18,8 @@
|
||||
#ifndef MSGPACK_UNPACKER_H__
|
||||
#define MSGPACK_UNPACKER_H__
|
||||
|
||||
#include "msgpack/zone.h"
|
||||
#include "msgpack/object.h"
|
||||
#include "zone.h"
|
||||
#include "object.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -18,9 +18,9 @@
|
||||
#ifndef MSGPACK_UNPACK_HPP__
|
||||
#define MSGPACK_UNPACK_HPP__
|
||||
|
||||
#include "msgpack/unpack.h"
|
||||
#include "msgpack/object.hpp"
|
||||
#include "msgpack/zone.hpp"
|
||||
#include "unpack.h"
|
||||
#include "object.hpp"
|
||||
#include "zone.hpp"
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -258,17 +258,7 @@ inline object unpacker::data()
|
||||
|
||||
inline zone* unpacker::release_zone()
|
||||
{
|
||||
if(!msgpack_unpacker_flush_zone(this)) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
zone* r = new zone();
|
||||
|
||||
msgpack_zone old = *base::z;
|
||||
*base::z = *r;
|
||||
*static_cast<msgpack_zone*>(r) = old;
|
||||
|
||||
return r;
|
||||
return static_cast<msgpack::zone*>(msgpack_unpacker_release_zone(static_cast<msgpack_unpacker*>(this)));
|
||||
}
|
||||
|
||||
inline void unpacker::reset_zone()
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_VREFBUFFER_H__
|
||||
#define MSGPACK_VREFBUFFER_H__
|
||||
|
||||
#include "msgpack/zone.h"
|
||||
#include "zone.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_VREFBUFFER_HPP__
|
||||
#define MSGPACK_VREFBUFFER_HPP__
|
||||
|
||||
#include "msgpack/vrefbuffer.h"
|
||||
#include "vrefbuffer.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace msgpack {
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_ZBUFFER_H__
|
||||
#define MSGPACK_ZBUFFER_H__
|
||||
|
||||
#include "msgpack/sysdep.h"
|
||||
#include "sysdep.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_ZBUFFER_HPP__
|
||||
#define MSGPACK_ZBUFFER_HPP__
|
||||
|
||||
#include "msgpack/zbuffer.h"
|
||||
#include "zbuffer.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace msgpack {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MessagePack for C memory pool implementation
|
||||
*
|
||||
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
||||
* Copyright (C) 2008-2010 FURUHASHI Sadayuki
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_ZONE_H__
|
||||
#define MSGPACK_ZONE_H__
|
||||
|
||||
#include "msgpack/sysdep.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -73,6 +73,8 @@ static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size
|
||||
static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
|
||||
void (*func)(void* data), void* data);
|
||||
|
||||
static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b);
|
||||
|
||||
bool msgpack_zone_is_empty(msgpack_zone* zone);
|
||||
|
||||
void msgpack_zone_clear(msgpack_zone* zone);
|
||||
@@ -129,6 +131,13 @@ bool msgpack_zone_push_finalizer(msgpack_zone* zone,
|
||||
return true;
|
||||
}
|
||||
|
||||
void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b)
|
||||
{
|
||||
msgpack_zone tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// MessagePack for C++ memory pool
|
||||
//
|
||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
||||
// Copyright (C) 2008-2010 FURUHASHI Sadayuki
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef MSGPACK_ZONE_HPP__
|
||||
#define MSGPACK_ZONE_HPP__
|
||||
|
||||
#include "msgpack/zone.h"
|
||||
#include "zone.h"
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
void swap(zone& o);
|
||||
|
||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||
T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>);
|
||||
@@ -111,6 +113,11 @@ inline void zone::clear()
|
||||
msgpack_zone_clear(this);
|
||||
}
|
||||
|
||||
inline void zone::swap(zone& o)
|
||||
{
|
||||
msgpack_zone_swap(this, &o);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void zone::object_destructor(void* obj)
|
||||
{
|
||||
|
@@ -164,7 +164,7 @@ void msgpack_object_print(FILE* out, msgpack_object o)
|
||||
|
||||
default:
|
||||
// FIXME
|
||||
fprintf(out, "#<UNKNOWN %hu %"PRIu64">", o.type, o.via.u64);
|
||||
fprintf(out, "#<UNKNOWN %i %"PRIu64">", o.type, o.via.u64);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,10 @@
|
||||
#include "msgpack/unpack_define.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _msgpack_atomic_counter_header
|
||||
#include _msgpack_atomic_counter_header
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
msgpack_zone* z;
|
||||
@@ -333,6 +337,7 @@ msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac)
|
||||
|
||||
msgpack_zone* old = mpac->z;
|
||||
mpac->z = r;
|
||||
CTX_CAST(mpac->ctx)->user.z = mpac->z;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
|
||||
AM_CPPFLAGS = -I../src
|
||||
AM_C_CPPFLAGS = -I../src
|
||||
AM_LDFLAGS = ../src/libmsgpack.la -lgtest_main
|
||||
AM_LDFLAGS = ../src/libmsgpack.la -lgtest_main -pthread
|
||||
|
||||
check_PROGRAMS = \
|
||||
zone \
|
||||
@@ -13,6 +13,8 @@ check_PROGRAMS = \
|
||||
convert \
|
||||
buffer \
|
||||
cases \
|
||||
fixint \
|
||||
fixint_c \
|
||||
version \
|
||||
msgpackc_test \
|
||||
msgpack_test
|
||||
@@ -38,6 +40,10 @@ buffer_LDADD = -lz
|
||||
|
||||
cases_SOURCES = cases.cc
|
||||
|
||||
fixint_SOURCES = fixint.cc
|
||||
|
||||
fixint_c_SOURCES = fixint_c.cc
|
||||
|
||||
version_SOURCES = version.cc
|
||||
|
||||
msgpackc_test_SOURCES = msgpackc_test.cpp
|
||||
|
@@ -32,5 +32,7 @@ TEST(cases, format)
|
||||
EXPECT_TRUE( pac_compact.next(&result_compact) );
|
||||
EXPECT_EQ(result_compact.get(), result.get());
|
||||
}
|
||||
|
||||
EXPECT_FALSE( pac_compact.next(&result) );
|
||||
}
|
||||
|
||||
|
55
cpp/test/fixint.cc
Normal file
55
cpp/test/fixint.cc
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <msgpack.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
template <typename T>
|
||||
void check_size(size_t size) {
|
||||
T v(0);
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, v);
|
||||
EXPECT_EQ(size, sbuf.size());
|
||||
}
|
||||
|
||||
TEST(fixint, size)
|
||||
{
|
||||
check_size<msgpack::type::fix_int8>(2);
|
||||
check_size<msgpack::type::fix_int16>(3);
|
||||
check_size<msgpack::type::fix_int32>(5);
|
||||
check_size<msgpack::type::fix_int64>(9);
|
||||
|
||||
check_size<msgpack::type::fix_uint8>(2);
|
||||
check_size<msgpack::type::fix_uint16>(3);
|
||||
check_size<msgpack::type::fix_uint32>(5);
|
||||
check_size<msgpack::type::fix_uint64>(9);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void check_convert() {
|
||||
T v1(-11);
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, v1);
|
||||
|
||||
msgpack::unpacked msg;
|
||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
|
||||
|
||||
T v2;
|
||||
msg.get().convert(&v2);
|
||||
|
||||
EXPECT_EQ(v1.get(), v2.get());
|
||||
|
||||
EXPECT_EQ(msg.get(), msgpack::object(T(v1.get())));
|
||||
}
|
||||
|
||||
TEST(fixint, convert)
|
||||
{
|
||||
check_convert<msgpack::type::fix_int8>();
|
||||
check_convert<msgpack::type::fix_int16>();
|
||||
check_convert<msgpack::type::fix_int32>();
|
||||
check_convert<msgpack::type::fix_int64>();
|
||||
|
||||
check_convert<msgpack::type::fix_uint8>();
|
||||
check_convert<msgpack::type::fix_uint16>();
|
||||
check_convert<msgpack::type::fix_uint32>();
|
||||
check_convert<msgpack::type::fix_uint64>();
|
||||
}
|
||||
|
32
cpp/test/fixint_c.cc
Normal file
32
cpp/test/fixint_c.cc
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <msgpack.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(fixint, size)
|
||||
{
|
||||
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
|
||||
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
|
||||
|
||||
size_t sum = 0;
|
||||
|
||||
EXPECT_EQ(0, msgpack_pack_fix_int8(pk, 0));
|
||||
EXPECT_EQ(sum+=2, sbuf->size);
|
||||
EXPECT_EQ(0, msgpack_pack_fix_int16(pk, 0));
|
||||
EXPECT_EQ(sum+=3, sbuf->size);
|
||||
EXPECT_EQ(0, msgpack_pack_fix_int32(pk, 0));
|
||||
EXPECT_EQ(sum+=5, sbuf->size);
|
||||
EXPECT_EQ(0, msgpack_pack_fix_int64(pk, 0));
|
||||
EXPECT_EQ(sum+=9, sbuf->size);
|
||||
|
||||
EXPECT_EQ(0, msgpack_pack_fix_uint8(pk, 0));
|
||||
EXPECT_EQ(sum+=2, sbuf->size);
|
||||
EXPECT_EQ(0, msgpack_pack_fix_uint16(pk, 0));
|
||||
EXPECT_EQ(sum+=3, sbuf->size);
|
||||
EXPECT_EQ(0, msgpack_pack_fix_uint32(pk, 0));
|
||||
EXPECT_EQ(sum+=5, sbuf->size);
|
||||
EXPECT_EQ(0, msgpack_pack_fix_uint64(pk, 0));
|
||||
EXPECT_EQ(sum+=9, sbuf->size);
|
||||
|
||||
msgpack_sbuffer_free(sbuf);
|
||||
msgpack_packer_free(pk);
|
||||
}
|
||||
|
@@ -7,9 +7,21 @@ TEST(streaming, basic)
|
||||
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
|
||||
|
||||
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
|
||||
|
||||
// 1, 2, 3, "raw", ["data"], {0.3: 0.4}
|
||||
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
|
||||
EXPECT_EQ(0, msgpack_pack_int(pk, 2));
|
||||
EXPECT_EQ(0, msgpack_pack_int(pk, 3));
|
||||
EXPECT_EQ(0, msgpack_pack_raw(pk, 3));
|
||||
EXPECT_EQ(0, msgpack_pack_raw_body(pk, "raw", 3));
|
||||
EXPECT_EQ(0, msgpack_pack_array(pk, 1));
|
||||
EXPECT_EQ(0, msgpack_pack_raw(pk, 4));
|
||||
EXPECT_EQ(0, msgpack_pack_raw_body(pk, "data", 4));
|
||||
EXPECT_EQ(0, msgpack_pack_map(pk, 1));
|
||||
EXPECT_EQ(0, msgpack_pack_float(pk, 0.4));
|
||||
EXPECT_EQ(0, msgpack_pack_double(pk, 0.8));
|
||||
int max_count = 6;
|
||||
|
||||
msgpack_packer_free(pk);
|
||||
|
||||
const char* input = buffer->data;
|
||||
@@ -22,36 +34,65 @@ TEST(streaming, basic)
|
||||
msgpack_unpacked_init(&result);
|
||||
|
||||
int count = 0;
|
||||
while(count < 3) {
|
||||
while(count < max_count) {
|
||||
bool unpacked = false;
|
||||
|
||||
msgpack_unpacker_reserve_buffer(&pac, 32*1024);
|
||||
|
||||
/* read buffer into msgpack_unapcker_buffer(&pac) upto
|
||||
* msgpack_unpacker_buffer_capacity(&pac) bytes. */
|
||||
size_t len = 1;
|
||||
memcpy(msgpack_unpacker_buffer(&pac), input, len);
|
||||
input += len;
|
||||
while(!unpacked) {
|
||||
/* read buffer into msgpack_unapcker_buffer(&pac) upto
|
||||
* msgpack_unpacker_buffer_capacity(&pac) bytes. */
|
||||
memcpy(msgpack_unpacker_buffer(&pac), input, 1);
|
||||
input += 1;
|
||||
|
||||
msgpack_unpacker_buffer_consumed(&pac, len);
|
||||
EXPECT_TRUE(input <= eof);
|
||||
|
||||
while(msgpack_unpacker_next(&pac, &result)) {
|
||||
msgpack_object obj = result.data;
|
||||
switch(count++) {
|
||||
case 0:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type);
|
||||
EXPECT_EQ(1, result.data.via.u64);
|
||||
break;
|
||||
case 1:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type);
|
||||
EXPECT_EQ(2, result.data.via.u64);
|
||||
break;
|
||||
case 2:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type);
|
||||
EXPECT_EQ(3, result.data.via.u64);
|
||||
return;
|
||||
msgpack_unpacker_buffer_consumed(&pac, 1);
|
||||
|
||||
while(msgpack_unpacker_next(&pac, &result)) {
|
||||
unpacked = 1;
|
||||
msgpack_object obj = result.data;
|
||||
msgpack_object e;
|
||||
switch(count++) {
|
||||
case 0:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
|
||||
EXPECT_EQ(1, obj.via.u64);
|
||||
break;
|
||||
case 1:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
|
||||
EXPECT_EQ(2, obj.via.u64);
|
||||
break;
|
||||
case 2:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
|
||||
EXPECT_EQ(3, obj.via.u64);
|
||||
break;
|
||||
case 3:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_RAW, obj.type);
|
||||
EXPECT_EQ(std::string("raw",3), std::string(obj.via.raw.ptr, obj.via.raw.size));
|
||||
break;
|
||||
case 4:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
|
||||
EXPECT_EQ(1, obj.via.array.size);
|
||||
e = obj.via.array.ptr[0];
|
||||
EXPECT_EQ(MSGPACK_OBJECT_RAW, e.type);
|
||||
EXPECT_EQ(std::string("data",4), std::string(e.via.raw.ptr, e.via.raw.size));
|
||||
break;
|
||||
case 5:
|
||||
EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type);
|
||||
EXPECT_EQ(1, obj.via.map.size);
|
||||
e = obj.via.map.ptr[0].key;
|
||||
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type);
|
||||
ASSERT_FLOAT_EQ(0.4, (float)e.via.dec);
|
||||
e = obj.via.map.ptr[0].val;
|
||||
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type);
|
||||
ASSERT_DOUBLE_EQ(0.8, e.via.dec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_TRUE(input < eof);
|
||||
}
|
||||
|
||||
msgpack_unpacker_destroy(&pac);
|
||||
msgpack_unpacked_destroy(&result);
|
||||
}
|
||||
|
||||
|
1
erlang/.gitignore
vendored
1
erlang/.gitignore
vendored
@@ -2,3 +2,4 @@ MANIFEST
|
||||
*.beam
|
||||
.omakedb*
|
||||
*.omc
|
||||
*~
|
@@ -22,7 +22,7 @@
|
||||
# Phony targets are scoped, so you probably want to declare them first.
|
||||
#
|
||||
|
||||
.PHONY: all clean test #install
|
||||
.PHONY: all clean test edoc dialyzer #install
|
||||
|
||||
########################################################################
|
||||
# Subdirectories.
|
||||
@@ -33,10 +33,19 @@
|
||||
.DEFAULT: msgpack.beam
|
||||
|
||||
msgpack.beam: msgpack.erl
|
||||
erlc $<
|
||||
erlc -Wall +debug_info $<
|
||||
|
||||
msgpack.html: msgpack.erl
|
||||
erl -noshell -run edoc_run file $<
|
||||
|
||||
test: msgpack.beam
|
||||
erl -noshell -s msgpack test -s init stop
|
||||
|
||||
edoc: msgpack.erl
|
||||
erl -noshell -eval 'ok=edoc:files(["msgpack.erl"], [{dir, "edoc"}]).' -s init stop
|
||||
|
||||
dialyzer: msgpack.erl
|
||||
dialyzer --src $<
|
||||
|
||||
clean:
|
||||
-rm *.beam
|
||||
-rm -f *.beam *.html
|
||||
|
4
erlang/edoc/.gitignore
vendored
Normal file
4
erlang/edoc/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.html
|
||||
*.css
|
||||
*.png
|
||||
edoc-info
|
@@ -15,89 +15,121 @@
|
||||
%% See the License for the specific language governing permissions and
|
||||
%% limitations under the License.
|
||||
|
||||
|
||||
%% @doc <a href="http://msgpack.org/">MessagePack</a> codec for Erlang.
|
||||
%%
|
||||
%% APIs are almost compatible with <a href="http://redmine.msgpack.org/projects/msgpack/wiki/QuickStartC">C API</a>
|
||||
%% except for buffering functions (both copying and zero-copying), which are unavailable.
|
||||
%%
|
||||
%% <table border="1">
|
||||
%% <caption>Equivalence between Erlang and <a href="http://msgpack.sourceforge.jp/spec">Msgpack type</a> :</caption>
|
||||
%% <tr><th> erlang </th><th> msgpack </th></tr>
|
||||
%% <tr><td> integer() </td><td> pos_fixnum/neg_fixnum/uint8/uint16/uint32/uint64/int8/int16/int32/int64 </td></tr>
|
||||
%% <tr><td> float() </td><td> float/double </td></tr>
|
||||
%% <tr><td> nil </td><td> nil </td></tr>
|
||||
%% <tr><td> boolean() </td><td> boolean </td></tr>
|
||||
%% <tr><td> binary() </td><td> fix_raw/raw16/raw32 </td></tr>
|
||||
%% <tr><td> list() </td><td> fix_array/array16/array32 </td></tr>
|
||||
%% <tr><td> {proplist()} </td><td> fix_map/map16/map32 </td></tr>
|
||||
%% </table>
|
||||
%% @end
|
||||
|
||||
-module(msgpack).
|
||||
-author('kuenishi+msgpack@gmail.com').
|
||||
|
||||
%% tuples, atoms are not supported. lists, integers, double, and so on.
|
||||
%% see http://msgpack.sourceforge.jp/spec for
|
||||
%% supported formats. APIs are almost compatible
|
||||
%% for C API (http://msgpack.sourceforge.jp/c:doc)
|
||||
%% except buffering functions (both copying and zero-copying).
|
||||
-export([pack/1, unpack/1, unpack_all/1]).
|
||||
-export([pack_map/1]).
|
||||
|
||||
% compile:
|
||||
% erl> c(msgpack).
|
||||
% erl> S = <some term>.
|
||||
% erl> {S, <<>>} = msgpack:unpack( msgpack:pack(S) ).
|
||||
-type reason() :: enomem | badarg | no_code_matches.
|
||||
% @type msgpack_term() = [msgpack_term()]
|
||||
% | {[{msgpack_term(),msgpack_term()}]}
|
||||
% | integer() | float() | binary().
|
||||
% Erlang representation of msgpack data.
|
||||
-type msgpack_term() :: [msgpack_term()]
|
||||
| {[{msgpack_term(),msgpack_term()}]}
|
||||
| integer() | float() | binary().
|
||||
|
||||
% ===== external APIs ===== %
|
||||
-spec pack(Term::msgpack_term()) -> binary().
|
||||
pack(I) when is_integer(I) andalso I < 0 ->
|
||||
pack_int_(I);
|
||||
pack(I) when is_integer(I) ->
|
||||
pack_uint_(I);
|
||||
pack(F) when is_float(F) ->
|
||||
pack_double(F);
|
||||
pack(nil) ->
|
||||
<< 16#C0:8 >>;
|
||||
pack(true) ->
|
||||
<< 16#C3:8 >>;
|
||||
pack(false) ->
|
||||
<< 16#C2:8 >>;
|
||||
pack(Bin) when is_binary(Bin) ->
|
||||
pack_raw(Bin);
|
||||
pack(List) when is_list(List) ->
|
||||
pack_array(List);
|
||||
pack({Map}) when is_list(Map) ->
|
||||
pack_map(Map);
|
||||
pack(Map) when is_tuple(Map), element(1,Map)=:=dict ->
|
||||
pack_map(dict:to_list(Map));
|
||||
pack(_Other) ->
|
||||
{error, undefined}.
|
||||
|
||||
% unpacking.
|
||||
% if failed in decoding and not end, get more data
|
||||
% and feed more Bin into this function.
|
||||
% TODO: error case for imcomplete format when short for any type formats.
|
||||
-spec unpack( Bin::binary() )-> {msgpack_term(), binary()} |
|
||||
{more, non_neg_integer()} | {more, undefined} |
|
||||
{error, reason()}.
|
||||
unpack(Bin) when not is_binary(Bin)->
|
||||
{error, badarg};
|
||||
unpack(Bin) when bit_size(Bin) >= 8 ->
|
||||
unpack_(Bin);
|
||||
unpack(<<>>)->
|
||||
{more, 1};
|
||||
unpack(_) ->
|
||||
{more, undefined}.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% external APIs
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
-spec unpack_all( binary() ) -> [msgpack_term()].
|
||||
% @doc Encode an erlang term into an msgpack binary.
|
||||
% Returns {error, {badarg, term()}} if the input is illegal.
|
||||
% @spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}
|
||||
-spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}.
|
||||
pack(Term)->
|
||||
try
|
||||
pack_(Term)
|
||||
catch
|
||||
throw:Exception ->
|
||||
{error, Exception}
|
||||
end.
|
||||
|
||||
% @doc Decode an msgpack binary into an erlang term.
|
||||
% It only decodes the first msgpack packet contained in the binary; the rest is returned as is.
|
||||
% Returns {error, {badarg, term()}} if the input is corrupted.
|
||||
% Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again).
|
||||
% @spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}
|
||||
-spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}.
|
||||
unpack(Bin) when is_binary(Bin) ->
|
||||
try
|
||||
unpack_(Bin)
|
||||
catch
|
||||
throw:Exception ->
|
||||
{error, Exception}
|
||||
end;
|
||||
unpack(Other) ->
|
||||
{error, {badarg, Other}}.
|
||||
|
||||
% @doc Decode an msgpack binary into an erlang terms.
|
||||
% It only decodes ALL msgpack packets contained in the binary. No packets should not remain.
|
||||
% Returns {error, {badarg, term()}} if the input is corrupted.
|
||||
% Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again).
|
||||
% @spec unpack_all(binary()) -> [msgpack_term()] | {error, incomplete} | {error, {badarg, term()}}
|
||||
-spec unpack_all(binary()) -> [msgpack_term()] | {error, incomplete} | {error, {badarg, term()}}.
|
||||
unpack_all(Data)->
|
||||
case unpack(Data) of
|
||||
{ Term, Binary } when bit_size(Binary) =:= 0 ->
|
||||
try
|
||||
unpack_all_(Data)
|
||||
catch
|
||||
throw:Exception ->
|
||||
{error, Exception}
|
||||
end.
|
||||
unpack_all_(Data)->
|
||||
case unpack_(Data) of
|
||||
{ Term, <<>> } ->
|
||||
[Term];
|
||||
{ Term, Binary } when is_binary(Binary) ->
|
||||
[Term|unpack_all(Binary)]
|
||||
[Term|unpack_all_(Binary)]
|
||||
end.
|
||||
|
||||
-spec pack_map(M::[{msgpack_term(),msgpack_term()}])-> binary().
|
||||
pack_map(M)->
|
||||
case length(M) of
|
||||
Len when Len < 16 ->
|
||||
<< 2#1000:4, Len:4/integer-unit:1, (pack_map_(M, <<>>))/binary >>;
|
||||
Len when Len < 16#10000 -> % 65536
|
||||
<< 16#DE:8, Len:16/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>;
|
||||
Len ->
|
||||
<< 16#DF:8, Len:32/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>
|
||||
end.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% internal APIs
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% ===== internal APIs ===== %
|
||||
% pack them all
|
||||
-spec pack_(msgpack_term()) -> binary() | no_return().
|
||||
pack_(I) when is_integer(I) andalso I < 0 ->
|
||||
pack_int_(I);
|
||||
pack_(I) when is_integer(I) ->
|
||||
pack_uint_(I);
|
||||
pack_(F) when is_float(F) ->
|
||||
pack_double(F);
|
||||
pack_(nil) ->
|
||||
<< 16#C0:8 >>;
|
||||
pack_(true) ->
|
||||
<< 16#C3:8 >>;
|
||||
pack_(false) ->
|
||||
<< 16#C2:8 >>;
|
||||
pack_(Bin) when is_binary(Bin) ->
|
||||
pack_raw(Bin);
|
||||
pack_(List) when is_list(List) ->
|
||||
pack_array(List);
|
||||
pack_({Map}) when is_list(Map) ->
|
||||
pack_map(Map);
|
||||
pack_(Other) ->
|
||||
throw({badarg, Other}).
|
||||
|
||||
|
||||
-spec pack_uint_(non_neg_integer()) -> binary().
|
||||
% positive fixnum
|
||||
pack_uint_(N) when N < 128 ->
|
||||
<< 2#0:1, N:7 >>;
|
||||
@@ -114,8 +146,9 @@ pack_uint_(N) when N < 16#FFFFFFFF->
|
||||
pack_uint_(N) ->
|
||||
<< 16#CF:8, N:64/big-unsigned-integer-unit:1 >>.
|
||||
|
||||
-spec pack_int_(integer()) -> binary().
|
||||
% negative fixnum
|
||||
pack_int_(N) when is_integer(N) , N >= -32->
|
||||
pack_int_(N) when N >= -32->
|
||||
<< 2#111:3, N:5 >>;
|
||||
% int 8
|
||||
pack_int_(N) when N > -128 ->
|
||||
@@ -130,14 +163,18 @@ pack_int_(N) when N > -16#FFFFFFFF ->
|
||||
pack_int_(N) ->
|
||||
<< 16#D3:8, N:64/big-signed-integer-unit:1 >>.
|
||||
|
||||
|
||||
-spec pack_double(float()) -> binary().
|
||||
% float : erlang's float is always IEEE 754 64bit format.
|
||||
%pack_float(F) when is_float(F)->
|
||||
% pack_float(F) when is_float(F)->
|
||||
% << 16#CA:8, F:32/big-float-unit:1 >>.
|
||||
% pack_double(F).
|
||||
% double
|
||||
pack_double(F) ->
|
||||
<< 16#CB:8, F:64/big-float-unit:1 >>.
|
||||
|
||||
|
||||
-spec pack_raw(binary()) -> binary().
|
||||
% raw bytes
|
||||
pack_raw(Bin) ->
|
||||
case byte_size(Bin) of
|
||||
@@ -149,53 +186,59 @@ pack_raw(Bin) ->
|
||||
<< 16#DB:8, Len:32/big-unsigned-integer-unit:1, Bin/binary >>
|
||||
end.
|
||||
|
||||
% list / tuple
|
||||
|
||||
-spec pack_array([msgpack_term()]) -> binary() | no_return().
|
||||
% list
|
||||
pack_array(L) ->
|
||||
case length(L) of
|
||||
Len when Len < 16 ->
|
||||
<< 2#1001:4, Len:4/integer-unit:1, (pack_array_(L, <<>>))/binary >>;
|
||||
Len when Len < 16#10000 -> % 65536
|
||||
<< 16#DC:8, Len:16/big-unsigned-integer-unit:1,(pack_array_(L, <<>>))/binary >>;
|
||||
<< 16#DC:8, Len:16/big-unsigned-integer-unit:1, (pack_array_(L, <<>>))/binary >>;
|
||||
Len ->
|
||||
<< 16#DD:8, Len:32/big-unsigned-integer-unit:1,(pack_array_(L, <<>>))/binary >>
|
||||
<< 16#DD:8, Len:32/big-unsigned-integer-unit:1, (pack_array_(L, <<>>))/binary >>
|
||||
end.
|
||||
|
||||
pack_array_([], Acc) -> Acc;
|
||||
pack_array_([Head|Tail], Acc) ->
|
||||
pack_array_(Tail, <<Acc/binary, (pack(Head))/binary>>).
|
||||
pack_array_(Tail, <<Acc/binary, (pack_(Head))/binary>>).
|
||||
|
||||
% FIXME! this should be without lists:reverse/1
|
||||
unpack_array_(<<>>, 0, RetList) -> {lists:reverse(RetList), <<>>};
|
||||
unpack_array_(Remain, 0, RetList) when is_binary(Remain)-> {lists:reverse(RetList), Remain};
|
||||
unpack_array_(<<>>, RestLen, _RetList) when RestLen > 0 -> {more, undefined};
|
||||
unpack_array_(Bin, RestLen, RetList) when is_binary(Bin)->
|
||||
case unpack(Bin) of
|
||||
{more, _} -> {more, undefined};
|
||||
{Term, Rest}-> unpack_array_(Rest, RestLen-1, [Term|RetList])
|
||||
% Users SHOULD NOT send too long list: this uses lists:reverse/1
|
||||
-spec unpack_array_(binary(), non_neg_integer(), [msgpack_term()]) -> {[msgpack_term()], binary()} | no_return().
|
||||
unpack_array_(Bin, 0, Acc) -> {lists:reverse(Acc), Bin};
|
||||
unpack_array_(Bin, Len, Acc) ->
|
||||
{Term, Rest} = unpack_(Bin),
|
||||
unpack_array_(Rest, Len-1, [Term|Acc]).
|
||||
|
||||
|
||||
-spec pack_map(M::[{msgpack_term(),msgpack_term()}]) -> binary() | no_return().
|
||||
pack_map(M)->
|
||||
case length(M) of
|
||||
Len when Len < 16 ->
|
||||
<< 2#1000:4, Len:4/integer-unit:1, (pack_map_(M, <<>>))/binary >>;
|
||||
Len when Len < 16#10000 -> % 65536
|
||||
<< 16#DE:8, Len:16/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>;
|
||||
Len ->
|
||||
<< 16#DF:8, Len:32/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>
|
||||
end.
|
||||
|
||||
pack_map_([], Acc) -> Acc;
|
||||
pack_map_([{Key,Value}|Tail], Acc) ->
|
||||
pack_map_(Tail, << Acc/binary, (pack(Key))/binary, (pack(Value))/binary>>).
|
||||
pack_map_(Tail, << Acc/binary, (pack_(Key))/binary, (pack_(Value))/binary>>).
|
||||
|
||||
% FIXME! this should be without lists:reverse/1
|
||||
-spec unpack_map_(binary(), non_neg_integer(), [{term(), msgpack_term()}])->
|
||||
{more, non_neg_integer()} | { any(), binary()}.
|
||||
unpack_map_(Bin, 0, Acc) -> {{lists:reverse(Acc)}, Bin};
|
||||
% Users SHOULD NOT send too long list: this uses lists:reverse/1
|
||||
-spec unpack_map_(binary(), non_neg_integer(), [{msgpack_term(), msgpack_term()}]) ->
|
||||
{{[{msgpack_term(), msgpack_term()}]}, binary()} | no_return().
|
||||
unpack_map_(Bin, 0, Acc) -> {{lists:reverse(Acc)}, Bin};
|
||||
unpack_map_(Bin, Len, Acc) ->
|
||||
case unpack(Bin) of
|
||||
{more, _} -> {more, undefined};
|
||||
{Key, Rest} ->
|
||||
case unpack(Rest) of
|
||||
{more, _} -> {more, undefined};
|
||||
{Value, Rest2} ->
|
||||
unpack_map_(Rest2,Len-1,[{Key,Value}|Acc])
|
||||
end
|
||||
end.
|
||||
{Key, Rest} = unpack_(Bin),
|
||||
{Value, Rest2} = unpack_(Rest),
|
||||
unpack_map_(Rest2, Len-1, [{Key,Value}|Acc]).
|
||||
|
||||
-spec unpack_(Payload::binary()) ->
|
||||
{more, pos_integer()} | {msgpack_term(), binary()} | {error, reason()}.
|
||||
unpack_(Binary)->
|
||||
case Binary of
|
||||
% unpack them all
|
||||
-spec unpack_(Bin::binary()) -> {msgpack_term(), binary()} | no_return().
|
||||
unpack_(Bin) ->
|
||||
case Bin of
|
||||
% ATOMS
|
||||
<<16#C0, Rest/binary>> -> {nil, Rest};
|
||||
<<16#C2, Rest/binary>> -> {false, Rest};
|
||||
@@ -229,48 +272,46 @@ unpack_(Binary)->
|
||||
<<2#101:3, L:5, V:L/binary, Rest/binary>> -> {V, Rest}; % raw bytes
|
||||
<<2#1001:4, L:4, Rest/binary>> -> unpack_array_(Rest, L, []); % array
|
||||
<<2#1000:4, L:4, Rest/binary>> -> unpack_map_(Rest, L, []); % map
|
||||
|
||||
% Incomplete / invalid data
|
||||
<<16#CA, Rest/binary>> -> {more, 4-byte_size(Rest)};
|
||||
<<16#CB, Rest/binary>> -> {more, 8-byte_size(Rest)};
|
||||
<<16#CC>> -> {more, 1};
|
||||
<<16#CD, Rest/binary>> -> {more, 2-byte_size(Rest)};
|
||||
<<16#CE, Rest/binary>> -> {more, 4-byte_size(Rest)};
|
||||
<<16#CF, Rest/binary>> -> {more, 8-byte_size(Rest)};
|
||||
<<16#D0>> -> {more, 1};
|
||||
<<16#D1, Rest/binary>> -> {more, 2-byte_size(Rest)};
|
||||
<<16#D2, Rest/binary>> -> {more, 4-byte_size(Rest)};
|
||||
<<16#D3, Rest/binary>> -> {more, 8-byte_size(Rest)};
|
||||
<<16#DA, Rest/binary>> -> {more, 16-byte_size(Rest)};
|
||||
<<16#DB, Rest/binary>> -> {more, 32-byte_size(Rest)};
|
||||
<<16#DC, Rest/binary>> -> {more, 2-byte_size(Rest)};
|
||||
<<16#DD, Rest/binary>> -> {more, 4-byte_size(Rest)};
|
||||
<<16#DE, Rest/binary>> -> {more, 2-byte_size(Rest)};
|
||||
<<16#DF, Rest/binary>> -> {more, 4-byte_size(Rest)};
|
||||
<<2#101:3, L:5, Rest/binary>> -> {more, L-byte_size(Rest)};
|
||||
|
||||
<<>> -> {more, 1};
|
||||
<<2#101:3, _/binary>> -> {more, undefined};
|
||||
<<F:8, Rest/binary>> when F==16#C1;
|
||||
F==16#C7; F==16#C8; F==16#C9; F==16#D5;
|
||||
F==16#D6; F==16#D7; F==16#D8; F==16#D9->
|
||||
{error, {badarg, <<F, Rest/binary>>}};
|
||||
Other ->
|
||||
{error, {badarg, Other}}
|
||||
% Invalid data
|
||||
<<F, R/binary>> when F==16#C1;
|
||||
F==16#C4; F==16#C5; F==16#C6; F==16#C7; F==16#C8; F==16#C9;
|
||||
F==16#D4; F==16#D5; F==16#D6; F==16#D7; F==16#D8; F==16#D9 ->
|
||||
throw({badarg, <<F, R/binary>>});
|
||||
% Incomplete data (we've covered every complete/invalid case; anything left is incomplete)
|
||||
_ ->
|
||||
throw(incomplete)
|
||||
end.
|
||||
|
||||
|
||||
% ===== test codes ===== %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% unit tests
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-ifdef(EUNIT).
|
||||
|
||||
compare_all([], [])-> ok;
|
||||
compare_all([], R)-> {toomuchrhs, R};
|
||||
compare_all(L, [])-> {toomuchlhs, L};
|
||||
compare_all([], R)-> {toomuchrhs, R};
|
||||
compare_all(L, [])-> {toomuchlhs, L};
|
||||
compare_all([LH|LTL], [RH|RTL]) ->
|
||||
LH=RH,
|
||||
?assertEqual(LH, RH),
|
||||
compare_all(LTL, RTL).
|
||||
|
||||
port_receive(Port) ->
|
||||
port_receive(Port, <<>>).
|
||||
port_receive(Port, Acc) ->
|
||||
receive
|
||||
{Port, {data, Data}} -> port_receive(Port, <<Acc/binary, Data/binary>>);
|
||||
{Port, eof} -> Acc
|
||||
after 1000 -> Acc
|
||||
end.
|
||||
|
||||
test_([]) -> 0;
|
||||
test_([Term|Rest])->
|
||||
Pack = msgpack:pack(Term),
|
||||
?assertEqual({Term, <<>>}, msgpack:unpack( Pack )),
|
||||
1+test_(Rest).
|
||||
|
||||
test_data()->
|
||||
[true, false, nil,
|
||||
0, 1, 2, 123, 512, 1230, 678908, 16#FFFFFFFFFF,
|
||||
@@ -291,24 +332,18 @@ basic_test()->
|
||||
|
||||
port_test()->
|
||||
Tests = test_data(),
|
||||
{[Tests],<<>>} = msgpack:unpack(msgpack:pack([Tests])),
|
||||
Port = open_port({spawn, "ruby ../test/crosslang.rb"}, [binary]),
|
||||
true = port_command(Port, msgpack:pack(Tests) ),
|
||||
receive
|
||||
{Port, {data, Data}}-> {Tests, <<>>}=msgpack:unpack(Data)
|
||||
after 1024-> ?assert(false) end,
|
||||
?assertEqual({[Tests],<<>>}, msgpack:unpack(msgpack:pack([Tests]))),
|
||||
|
||||
Port = open_port({spawn, "ruby ../test/crosslang.rb"}, [binary, eof]),
|
||||
true = port_command(Port, msgpack:pack(Tests)),
|
||||
?assertEqual({Tests, <<>>}, msgpack:unpack(port_receive(Port))),
|
||||
port_close(Port).
|
||||
|
||||
test_p(Len,Term,OrigBin,Len) ->
|
||||
{Term, <<>>}=msgpack:unpack(OrigBin);
|
||||
test_p(I,_,OrigBin,Len) when I < Len->
|
||||
<<Bin:I/binary, _/binary>> = OrigBin,
|
||||
case msgpack:unpack(Bin) of
|
||||
{more, N} when not is_integer(N) ->
|
||||
?assertEqual(undefined, N);
|
||||
{more, N} ->
|
||||
?assert( N < Len )
|
||||
end.
|
||||
?assertEqual({error,incomplete}, msgpack:unpack(Bin)).
|
||||
|
||||
partial_test()-> % error handling test.
|
||||
Term = lists:seq(0, 45),
|
||||
@@ -318,10 +353,7 @@ partial_test()-> % error handling test.
|
||||
|
||||
long_test()->
|
||||
Longer = lists:seq(0, 655),
|
||||
% Longest = lists:seq(0,12345),
|
||||
{Longer, <<>>} = msgpack:unpack(msgpack:pack(Longer)),
|
||||
% {Longest, <<>>} = msgpack:unpack(msgpack:pack(Longest)).
|
||||
ok.
|
||||
{Longer, <<>>} = msgpack:unpack(msgpack:pack(Longer)).
|
||||
|
||||
map_test()->
|
||||
Ints = lists:seq(0, 65),
|
||||
@@ -331,6 +363,7 @@ map_test()->
|
||||
ok.
|
||||
|
||||
unknown_test()->
|
||||
Port = open_port({spawn, "ruby testcase_generator.rb"}, [binary, eof]),
|
||||
Tests = [0, 1, 2, 123, 512, 1230, 678908,
|
||||
-1, -23, -512, -1230, -567898,
|
||||
<<"hogehoge">>, <<"243546rf7g68h798j">>,
|
||||
@@ -338,25 +371,25 @@ unknown_test()->
|
||||
-234.4355, 1.0e-34, 1.0e64,
|
||||
[23, 234, 0.23],
|
||||
[0,42,<<"sum">>, [1,2]], [1,42, nil, [3]],
|
||||
{[{1,2},{<<"hoge">>,nil}]},
|
||||
{[{1,2},{<<"hoge">>,nil}]}, % map
|
||||
-234, -50000,
|
||||
42
|
||||
],
|
||||
Port = open_port({spawn, "ruby testcase_generator.rb"}, [binary]),
|
||||
receive
|
||||
{Port, {data, Data}}->
|
||||
compare_all(Tests, msgpack:unpack_all(Data))
|
||||
after 1024-> ?assert(false) end,
|
||||
?assertEqual(ok, compare_all(Tests, msgpack:unpack_all(port_receive(Port)))),
|
||||
port_close(Port).
|
||||
|
||||
test_([]) -> 0;
|
||||
test_([Before|Rest])->
|
||||
Pack = msgpack:pack(Before),
|
||||
{After, <<>>} = msgpack:unpack( Pack ),
|
||||
?assertEqual(Before, After),
|
||||
1+test_(Rest).
|
||||
|
||||
other_test()->
|
||||
{more,1}=msgpack:unpack(<<>>).
|
||||
?assertEqual({error,incomplete},msgpack:unpack(<<>>)).
|
||||
|
||||
benchmark_test()->
|
||||
Data=[test_data() || _ <- lists:seq(0, 10000)],
|
||||
S=?debugTime(" serialize", msgpack:pack(Data)),
|
||||
{Data,<<>>}=?debugTime("deserialize", msgpack:unpack(S)),
|
||||
?debugFmt("for ~p KB test data.", [byte_size(S) div 1024]).
|
||||
|
||||
error_test()->
|
||||
?assertEqual({error,{badarg, atom}}, msgpack:pack(atom)),
|
||||
Term = {"hoge", "hage", atom},
|
||||
?assertEqual({error,{badarg, Term}}, msgpack:pack(Term)).
|
||||
|
||||
-endif.
|
||||
|
11
go/Makefile
Normal file
11
go/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
include $(GOROOT)/src/Make.inc
|
||||
|
||||
TARG=msgpack
|
||||
|
||||
GOFILES=pack.go unpack.go
|
||||
|
||||
include $(GOROOT)/src/Make.pkg
|
||||
|
||||
%: install %.go
|
||||
$(GC) $*.go
|
||||
$(LD) -o $@ $*.$O
|
218
go/msgpack_test.go
Normal file
218
go/msgpack_test.go
Normal file
@@ -0,0 +1,218 @@
|
||||
package msgpack_test
|
||||
|
||||
import (
|
||||
. "msgpack"
|
||||
"testing"
|
||||
"bytes"
|
||||
"reflect"
|
||||
"math"
|
||||
);
|
||||
|
||||
func equal(lhs reflect.Value, rhs reflect.Value) bool {
|
||||
{
|
||||
_rhs, ok := rhs.(*reflect.InterfaceValue)
|
||||
if ok { return equal(lhs, _rhs.Elem()) }
|
||||
}
|
||||
switch _lhs := lhs.(type) {
|
||||
case *reflect.InterfaceValue:
|
||||
return equal(_lhs.Elem(), rhs)
|
||||
case *reflect.BoolValue:
|
||||
_rhs, ok := rhs.(*reflect.BoolValue)
|
||||
return ok && _lhs.Get() == _rhs.Get()
|
||||
case *reflect.UintValue:
|
||||
_rhs, ok := rhs.(*reflect.UintValue)
|
||||
return ok && _lhs.Get() == _rhs.Get()
|
||||
case *reflect.IntValue:
|
||||
_rhs, ok := rhs.(*reflect.IntValue)
|
||||
return ok && _lhs.Get() == _rhs.Get()
|
||||
case *reflect.FloatValue:
|
||||
_rhs, ok := rhs.(*reflect.FloatValue)
|
||||
return ok && _lhs.Get() == _rhs.Get()
|
||||
case reflect.ArrayOrSliceValue:
|
||||
_rhs := rhs.(reflect.ArrayOrSliceValue)
|
||||
if _lhs.Len() != _rhs.Len() { return false; }
|
||||
for i := 0; i < _lhs.Len(); i++ {
|
||||
if !equal(_lhs.Elem(i), _rhs.Elem(i)) { return false; }
|
||||
}
|
||||
return true;
|
||||
case *reflect.MapValue:
|
||||
_rhs := rhs.(*reflect.MapValue)
|
||||
if _lhs.Len() != _rhs.Len() { return false; }
|
||||
for _, k := range _lhs.Keys() {
|
||||
lv, rv := _lhs.Elem(k), _rhs.Elem(k)
|
||||
if lv == nil || rv == nil || !equal(lv, rv) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
func TestPackUint8(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []uint8 { 0, 1, 2, 125, 126, 127, 128, 253, 254, 255 } {
|
||||
_, err := PackUint8(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackUint16(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []uint16 { 0, 1, 2, 125, 126, 127, 128, 253, 254, 255, 256, 65533, 65534, 65535 } {
|
||||
_, err := PackUint16(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff, 0xcd, 0x01, 0x00, 0xcd, 0xff, 0xfd, 0xcd, 0xff, 0xfe, 0xcd, 0xff, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackUint32(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []uint32 { 0, 1, 2, 125, 126, 127, 128, 253, 254, 255, 256, 65533, 65534, 65535, 65536, 4294967293, 4294967294, 4294967295 } {
|
||||
_, err := PackUint32(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff, 0xcd, 0x01, 0x00, 0xcd, 0xff, 0xfd, 0xcd, 0xff, 0xfe, 0xcd, 0xff, 0xff, 0xce, 0x00, 0x01, 0x00, 0x00, 0xce, 0xff, 0xff, 0xff, 0xfd, 0xce, 0xff, 0xff, 0xff, 0xfe, 0xce, 0xff, 0xff, 0xff, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackUint64(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []uint64 { 0, 1, 2, 125, 126, 127, 128, 253, 254, 255, 256, 65533, 65534, 65535, 65536, 4294967293, 4294967294, 4294967295, 4294967296, 18446744073709551613, 18446744073709551614, 18446744073709551615 } {
|
||||
_, err := PackUint64(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff, 0xcd, 0x01, 0x00, 0xcd, 0xff, 0xfd, 0xcd, 0xff, 0xfe, 0xcd, 0xff, 0xff, 0xce, 0x00, 0x01, 0x00, 0x00, 0xce, 0xff, 0xff, 0xff, 0xfd, 0xce, 0xff, 0xff, 0xff, 0xfe, 0xce, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackInt8(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []int8 { -128, -127, -34, -33, -32, -31, 0, 1, 126, 127 } {
|
||||
_, err := PackInt8(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0xd0, 0x80, 0xd0, 0x81, 0xd0, 0xde, 0xd0, 0xdf, 0xe0, 0xe1, 0x00, 0x01, 0x7e, 0x7f }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackInt16(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []int16 { -32768, -32767, -131, -130, -129, -128, -127, -34, -33, -32, -31, 0, 1, 126, 127, 128, 129, 130, 32765, 32766, 32767 } {
|
||||
_, err := PackInt16(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0xd1, 0x80, 0x00, 0xd1, 0x80, 0x01, 0xd1, 0xff, 0x7d, 0xd1, 0xff, 0x7e, 0xd1, 0xff, 0x7f, 0xd0, 0x80, 0xd0, 0x81, 0xd0, 0xde, 0xd0, 0xdf, 0xe0, 0xe1, 0x00, 0x01, 0x7e, 0x7f, 0xd1, 0x00, 0x80, 0xd1, 0x00, 0x81, 0xd1, 0x00, 0x82, 0xd1, 0x7f, 0xfd, 0xd1, 0x7f, 0xfe, 0xd1, 0x7f, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackInt32(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []int32 { -2147483648, -2147483647, -2147483646, -32771, -32770, -32769, -32768, -32767, -131, -130, -129, -128, -127, -34, -33, -32, -31, 0, 1, 126, 127, 128, 129, 130, 32765, 32766, 32767, 32768, 32769, 32770, 2147483645, 2147483646, 2147483647 } {
|
||||
_, err := PackInt32(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0xd2, 0x80, 0x00, 0x00, 0x00, 0xd2, 0x80, 0x00, 0x00, 0x01, 0xd2, 0x80, 0x00, 0x00, 0x02, 0xd2, 0xff, 0xff, 0x7f, 0xfd, 0xd2, 0xff, 0xff, 0x7f, 0xfe, 0xd2, 0xff, 0xff, 0x7f, 0xff, 0xd1, 0x80, 0x00, 0xd1, 0x80, 0x01, 0xd1, 0xff, 0x7d, 0xd1, 0xff, 0x7e, 0xd1, 0xff, 0x7f, 0xd0, 0x80, 0xd0, 0x81, 0xd0, 0xde, 0xd0, 0xdf, 0xe0, 0xe1, 0x00, 0x01, 0x7e, 0x7f, 0xd1, 0x00, 0x80, 0xd1, 0x00, 0x81, 0xd1, 0x00, 0x82, 0xd1, 0x7f, 0xfd, 0xd1, 0x7f, 0xfe, 0xd1, 0x7f, 0xff, 0xd2, 0x00, 0x00, 0x80, 0x00, 0xd2, 0x00, 0x00, 0x80, 0x01, 0xd2, 0x00, 0x00, 0x80, 0x02, 0xd2, 0x7f, 0xff, 0xff, 0xfd, 0xd2, 0x7f, 0xff, 0xff, 0xfe, 0xd2, 0x7f, 0xff, 0xff, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackInt64(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []int64 { -9223372036854775808, -9223372036854775807, -9223372036854775806, -2147483651, -2147483650, -2147483649, -2147483648, -2147483647, -2147483646, -32771, -32770, -32769, -32768, -32767, -131, -130, -129, -128, -127, -34, -33, -32, -31, 0, 1, 126, 127, 128, 129, 130, 32765, 32766, 32767, 32768, 32769, 32770, 2147483645, 2147483646, 2147483647, 2147483648, 2147483649, 2147483650, 4294967296, 4294967297, 4294967298 } {
|
||||
_, err := PackInt64(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xfd, 0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xfe, 0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xd2, 0x80, 0x00, 0x00, 0x00, 0xd2, 0x80, 0x00, 0x00, 0x01, 0xd2, 0x80, 0x00, 0x00, 0x02, 0xd2, 0xff, 0xff, 0x7f, 0xfd, 0xd2, 0xff, 0xff, 0x7f, 0xfe, 0xd2, 0xff, 0xff, 0x7f, 0xff, 0xd1, 0x80, 0x00, 0xd1, 0x80, 0x01, 0xd1, 0xff, 0x7d, 0xd1, 0xff, 0x7e, 0xd1, 0xff, 0x7f, 0xd0, 0x80, 0xd0, 0x81, 0xd0, 0xde, 0xd0, 0xdf, 0xe0, 0xe1, 0x00, 0x01, 0x7e, 0x7f, 0xd1, 0x00, 0x80, 0xd1, 0x00, 0x81, 0xd1, 0x00, 0x82, 0xd1, 0x7f, 0xfd, 0xd1, 0x7f, 0xfe, 0xd1, 0x7f, 0xff, 0xd2, 0x00, 0x00, 0x80, 0x00, 0xd2, 0x00, 0x00, 0x80, 0x01, 0xd2, 0x00, 0x00, 0x80, 0x02, 0xd2, 0x7f, 0xff, 0xff, 0xfd, 0xd2, 0x7f, 0xff, 0xff, 0xfe, 0xd2, 0x7f, 0xff, 0xff, 0xff, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x02, 0xd3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackNil(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
nbyteswrite, err := PackNil(b)
|
||||
if nbyteswrite != 1 { t.Error("nbyteswrite != 1") }
|
||||
if err != nil { t.Error("err != nil") }
|
||||
if bytes.Compare(b.Bytes(), []byte { 0xc0 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackBool(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range []bool { false, true } {
|
||||
nbyteswrite, err := PackBool(b, i)
|
||||
if nbyteswrite != 1 { t.Error("nbyteswrite != 1") }
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0xc2, 0xc3 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackInt32Array(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
_, err := PackInt32Array(b, []int32 {})
|
||||
if err != nil { t.Error("err != nil") }
|
||||
_, err = PackInt32Array(b, []int32 { 0 })
|
||||
if err != nil { t.Error("err != nil") }
|
||||
_, err = PackInt32Array(b, []int32 { 0, 1 })
|
||||
if err != nil { t.Error("err != nil") }
|
||||
_, err = PackInt32Array(b, []int32 { 0, 1, 2 })
|
||||
if err != nil { t.Error("err != nil") }
|
||||
if bytes.Compare(b.Bytes(), []byte { 0x90, 0x91, 0x00, 0x92, 0x00, 0x01, 0x93, 0x00, 0x01, 0x02 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackArray(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
_, err := PackArray(b, reflect.NewValue([]int32 {}).(reflect.ArrayOrSliceValue))
|
||||
if err != nil { t.Error("err != nil") }
|
||||
_, err = PackArray(b, reflect.NewValue([]int32 { 0 }).(reflect.ArrayOrSliceValue))
|
||||
if err != nil { t.Error("err != nil") }
|
||||
_, err = PackArray(b, reflect.NewValue([]int32 { 0, 1 }).(reflect.ArrayOrSliceValue))
|
||||
if err != nil { t.Error("err != nil") }
|
||||
_, err = PackArray(b, reflect.NewValue([]int32 { 0, 1, 2 }).(reflect.ArrayOrSliceValue))
|
||||
if err != nil { t.Error("err != nil") }
|
||||
if bytes.Compare(b.Bytes(), []byte { 0x90, 0x91, 0x00, 0x92, 0x00, 0x01, 0x93, 0x00, 0x01, 0x02 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPackMap(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
_, err := PackMap(b, reflect.NewValue(map[int] int { 0: 1, 2: 3, 4: 5 }).(*reflect.MapValue))
|
||||
if err != nil { t.Error("err != nil") }
|
||||
if bytes.Compare(b.Bytes(), []byte { 0x83, 0x00, 0x01, 0x04, 0x05, 0x02, 0x03 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
||||
}
|
||||
|
||||
func TestPack(t *testing.T) {
|
||||
b := &bytes.Buffer{}
|
||||
for _, i := range [](interface{}) { nil, false, true, 0, 1, 2, 3, 127, -32, -1, -33, 128 } {
|
||||
_, err := Pack(b, i)
|
||||
if err != nil { t.Error("err != nil") }
|
||||
}
|
||||
if bytes.Compare(b.Bytes(), []byte { 0xc0, 0xc2, 0xc3, 0x00, 0x01, 0x02, 0x03, 0x7f, 0xf0, 0xff, 0xd0, 0xef, 0xd1, 0x00, 0x80 }) == 0 { t.Error("wrong output") }
|
||||
}
|
||||
|
||||
func TestUnpackArray(t *testing.T) {
|
||||
b := bytes.NewBuffer([]byte { 0x90, 0x91, 0x00, 0x92, 0x00, 0x01, 0x93, 0xd1, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xdc, 0x00, 0x02, 0x00, 0x01, 0xdd, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03 })
|
||||
for _, v := range [](interface{}) { [](interface{}) {}, [](interface{}) { int8(0) }, [](interface{}) { int8(0), int8(1) }, [](interface{}) { int16(0), int32(1), int64(2) }, [](interface{}){ int8(0), int8(1) }, [](interface{}) { int8(0), int8(1), int8(2), int8(3) } } {
|
||||
retval, _, e := Unpack(b)
|
||||
if e != nil { t.Error("err != nil") }
|
||||
if !equal(reflect.NewValue(retval.Interface()), reflect.NewValue(v)) { t.Errorf("%s != %s", retval.Interface(), v) }
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnpackInt(t *testing.T) {
|
||||
b := bytes.NewBuffer([]byte { 0xff, 0xe0, 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xd0, 0x01, 0xd0, 0x80, 0xd0, 0xff, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff, 0xd1, 0x00, 0x00, 0xd1, 0x7f, 0xff, 0xd1, 0xff, 0xff, 0xcd, 0x80, 0x00, 0xcd, 0xff, 0xff, 0xd2, 0x7f, 0xff, 0xff, 0xff, 0xce, 0x7f, 0xff, 0xff, 0xff, 0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff })
|
||||
for _, v := range [](interface{}) {
|
||||
int8(-1), int8(-32), int8(0), int8(1), int8(2), int8(125), int8(126), int8(127), int8(1), int8(-128), int8(-1), uint8(128), uint8(253), uint8(254), uint8(255), int16(0), int16(32767), int16(-1), uint16(32768), uint16(65535), int32(2147483647), uint32(2147483647), int64(9223372036854775807), uint64(18446744073709551615) } {
|
||||
retval, _, e := Unpack(b)
|
||||
if e != nil { t.Error("err != nil") }
|
||||
if retval.Interface() != v { t.Errorf("%u != %u", retval.Interface(), v) }
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnpackFloat(t *testing.T) {
|
||||
b := bytes.NewBuffer([]byte { 0xca, 0x3d, 0xcc, 0xcc, 0xcd, 0xca, 0x3e, 0x4c, 0xcc, 0xcd, 0xca, 0xbd, 0xcc, 0xcc, 0xcd, 0xca, 0xbe, 0x4c, 0xcc, 0xcd, 0xca, 0x7f, 0x80, 0x00, 0x00, 0xca, 0xff, 0x80, 0x00, 0x00, 0xca, 0xff, 0xc0, 0x00, 0x0, 0xcb, 0x3f, 0xb9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0x3f, 0xc9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0xbf, 0xb9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0xbf, 0xc9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0xcb, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
|
||||
for _, v := range [](interface{}) { float32(.1), float32(.2), float32(-.1), float32(-.2), float32(math.Inf(1)), float32(math.Inf(-1)), float32(math.NaN()), float64(.1), float64(.2), float64(-.1), float64(-.2) } {
|
||||
retval, _, e := Unpack(b)
|
||||
if e != nil { t.Error("err != nil") }
|
||||
isnan := false
|
||||
if _v, ok := v.(float64); ok {
|
||||
isnan = math.IsNaN(_v)
|
||||
} else if _v, ok := v.(float32); ok {
|
||||
isnan = math.IsNaN(float64(_v))
|
||||
}
|
||||
if isnan {
|
||||
if retval.Interface() == v { t.Errorf("[NaN] %u == %u", retval.Interface(), v) }
|
||||
} else {
|
||||
if retval.Interface() != v { t.Errorf("%u != %u", retval.Interface(), v) }
|
||||
}
|
||||
}
|
||||
}
|
591
go/pack.go
Normal file
591
go/pack.go
Normal file
@@ -0,0 +1,591 @@
|
||||
package msgpack
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"unsafe"
|
||||
"reflect"
|
||||
);
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackUint8(writer io.Writer, value uint8) (n int, err os.Error) {
|
||||
if value < 128 {
|
||||
return writer.Write([]byte { byte(value) })
|
||||
}
|
||||
return writer.Write([]byte { 0xcc, byte(value) })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackUint16(writer io.Writer, value uint16) (n int, err os.Error) {
|
||||
if value < 128 {
|
||||
return writer.Write([]byte { byte(value) })
|
||||
} else if value < 256 {
|
||||
return writer.Write([]byte { 0xcc, byte(value) })
|
||||
}
|
||||
return writer.Write([]byte { 0xcd, byte(value >> 8), byte(value) })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackUint32(writer io.Writer, value uint32) (n int, err os.Error) {
|
||||
if value < 128 {
|
||||
return writer.Write([]byte { byte(value) })
|
||||
} else if value < 256 {
|
||||
return writer.Write([]byte { 0xcc, byte(value) })
|
||||
} else if value < 65536 {
|
||||
return writer.Write([]byte { 0xcd, byte(value >> 8), byte(value) })
|
||||
}
|
||||
return writer.Write([]byte { 0xce, byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value) })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackUint64(writer io.Writer, value uint64) (n int, err os.Error) {
|
||||
if value < 128 {
|
||||
return writer.Write([]byte { byte(value) })
|
||||
} else if value < 256 {
|
||||
return writer.Write([]byte { 0xcc, byte(value) })
|
||||
} else if value < 65536 {
|
||||
return writer.Write([]byte { 0xcd, byte(value >> 8), byte(value) })
|
||||
} else if value < 4294967296 {
|
||||
return writer.Write([]byte { 0xce, byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value) })
|
||||
}
|
||||
return writer.Write([]byte { 0xcf, byte(value >> 56), byte(value >> 48), byte(value >> 40), byte(value >> 32), byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value) })
|
||||
}
|
||||
|
||||
func PackUint(writer io.Writer, value uint) (n int, err os.Error) {
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
switch unsafe.Sizeof(value) {
|
||||
case 4:
|
||||
return PackUint32(writer, *(*uint32)(unsafe.Pointer(&value)))
|
||||
case 8:
|
||||
return PackUint64(writer, *(*uint64)(unsafe.Pointer(&value)))
|
||||
}
|
||||
return 0, os.ENOENT // never get here
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt8(writer io.Writer, value int8) (n int, err os.Error) {
|
||||
if value < -32 {
|
||||
return writer.Write([]byte { 0xd0, byte(value) })
|
||||
}
|
||||
return writer.Write([]byte { byte(value) })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt16(writer io.Writer, value int16) (n int, err os.Error) {
|
||||
if value < -128 || value >= 128 {
|
||||
return writer.Write([]byte { 0xd1, byte(uint16(value) >> 8), byte(value) })
|
||||
} else if value < -32 {
|
||||
return writer.Write([]byte { 0xd0, byte(value) })
|
||||
}
|
||||
return writer.Write([]byte { byte(value) })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt32(writer io.Writer, value int32) (n int, err os.Error) {
|
||||
if value < -32768 || value >= 32768 {
|
||||
return writer.Write([]byte { 0xd2, byte(uint32(value) >> 24), byte(uint32(value) >> 16), byte(uint32(value) >> 8), byte(value) })
|
||||
} else if value < -128 {
|
||||
return writer.Write([]byte { 0xd1, byte(uint32(value) >> 8), byte(value) })
|
||||
} else if value < -32 {
|
||||
return writer.Write([]byte { 0xd0, byte(value) })
|
||||
} else if value >= 128 {
|
||||
return writer.Write([]byte { 0xd1, byte(uint32(value) >> 8), byte(value) })
|
||||
}
|
||||
return writer.Write([]byte { byte(value) })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt64(writer io.Writer, value int64) (n int, err os.Error) {
|
||||
if value < -2147483648 || value >= 2147483648 {
|
||||
return writer.Write([]byte { 0xd3, byte(uint64(value) >> 56), byte(uint64(value) >> 48), byte(uint64(value) >> 40), byte(uint64(value) >> 32), byte(uint64(value) >> 24), byte(uint64(value) >> 16), byte(uint64(value) >> 8), byte(value) })
|
||||
} else if value < -32768 || value >= 32768 {
|
||||
return writer.Write([]byte { 0xd2, byte(uint64(value) >> 24), byte(uint64(value) >> 16), byte(uint64(value) >> 8), byte(value) })
|
||||
} else if value < -128 || value >= 128 {
|
||||
return writer.Write([]byte { 0xd1, byte(uint64(value) >> 8), byte(value) })
|
||||
} else if value < -32 {
|
||||
return writer.Write([]byte { 0xd0, byte(value) })
|
||||
}
|
||||
return writer.Write([]byte { byte(value) })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt(writer io.Writer, value int) (n int, err os.Error) {
|
||||
switch unsafe.Sizeof(value) {
|
||||
case 4:
|
||||
return PackInt32(writer, *(*int32)(unsafe.Pointer(&value)))
|
||||
case 8:
|
||||
return PackInt64(writer, *(*int64)(unsafe.Pointer(&value)))
|
||||
}
|
||||
return 0, os.ENOENT // never get here
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackNil(writer io.Writer) (n int, err os.Error) {
|
||||
return writer.Write([]byte{ 0xc0 })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackBool(writer io.Writer, value bool) (n int, err os.Error) {
|
||||
var code byte;
|
||||
if value {
|
||||
code = 0xc3
|
||||
} else {
|
||||
code = 0xc2
|
||||
}
|
||||
return writer.Write([]byte{ code })
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackFloat32(writer io.Writer, value float32) (n int, err os.Error) {
|
||||
return PackUint32(writer, *(*uint32)(unsafe.Pointer(&value)))
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackFloat64(writer io.Writer, value float64) (n int, err os.Error) {
|
||||
return PackUint64(writer, *(*uint64)(unsafe.Pointer(&value)))
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackBytes(writer io.Writer, value []byte) (n int, err os.Error) {
|
||||
if len(value) < 32 {
|
||||
n1, err := writer.Write([]byte { 0xa0 | uint8(len(value)) })
|
||||
if err != nil { return n1, err }
|
||||
n2, err := writer.Write(value)
|
||||
return n1 + n2, err
|
||||
} else if len(value) < 65536 {
|
||||
n1, err := writer.Write([]byte { 0xda, byte(len(value) >> 16), byte(len(value)) })
|
||||
if err != nil { return n1, err }
|
||||
n2, err := writer.Write(value)
|
||||
return n1 + n2, err
|
||||
}
|
||||
n1, err := writer.Write([]byte { 0xdb, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n1, err }
|
||||
n2, err := writer.Write(value)
|
||||
return n1 + n2, err
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackUint16Array(writer io.Writer, value []uint16) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint16(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint16(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint16(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackUint32Array(writer io.Writer, value []uint32) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackUint64Array(writer io.Writer, value []uint64) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackUint64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackUintArray(writer io.Writer, value []uint) (n int, err os.Error) {
|
||||
switch unsafe.Sizeof(0) {
|
||||
case 4:
|
||||
return PackUint32Array(writer, *(*[]uint32)(unsafe.Pointer(&value)))
|
||||
case 8:
|
||||
return PackUint64Array(writer, *(*[]uint64)(unsafe.Pointer(&value)))
|
||||
}
|
||||
return 0, os.ENOENT // never get here
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt8Array(writer io.Writer, value []int8) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt8(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt8(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt8(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt16Array(writer io.Writer, value []int16) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt16(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt16(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt16(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt32Array(writer io.Writer, value []int32) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackInt64Array(writer io.Writer, value []int64) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackInt64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackIntArray(writer io.Writer, value []int) (n int, err os.Error) {
|
||||
switch unsafe.Sizeof(0) {
|
||||
case 4:
|
||||
return PackInt32Array(writer, *(*[]int32)(unsafe.Pointer(&value)))
|
||||
case 8:
|
||||
return PackInt64Array(writer, *(*[]int64)(unsafe.Pointer(&value)))
|
||||
}
|
||||
return 0, os.ENOENT // never get here
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackFloat32Array(writer io.Writer, value []float32) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackFloat32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackFloat32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackFloat32(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackFloat64Array(writer io.Writer, value []float64) (n int, err os.Error) {
|
||||
if len(value) < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackFloat64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if len(value) < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackFloat64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
||||
if err != nil { return n, err }
|
||||
for _, i := range value {
|
||||
_n, err := PackFloat64(writer, i)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackArray(writer io.Writer, value reflect.ArrayOrSliceValue) (n int, err os.Error) {
|
||||
{
|
||||
elemType, ok := value.Type().(reflect.ArrayOrSliceType).Elem().(*reflect.UintType)
|
||||
if ok && elemType.Kind() == reflect.Uint8 {
|
||||
return PackBytes(writer, value.Interface().([]byte))
|
||||
}
|
||||
}
|
||||
|
||||
l := value.Len()
|
||||
if l < 16 {
|
||||
n, err := writer.Write([]byte { 0x90 | byte(l) })
|
||||
if err != nil { return n, err }
|
||||
for i := 0; i < l; i++ {
|
||||
_n, err := PackValue(writer, value.Elem(i))
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if l < 65536 {
|
||||
n, err := writer.Write([]byte { 0xdc, byte(l >> 8), byte(l) })
|
||||
if err != nil { return n, err }
|
||||
for i := 0; i < l; i++ {
|
||||
_n, err := PackValue(writer, value.Elem(i))
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdd, byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l) })
|
||||
if err != nil { return n, err }
|
||||
for i := 0; i < l; i++ {
|
||||
_n, err := PackValue(writer, value.Elem(i))
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackMap(writer io.Writer, value *reflect.MapValue) (n int, err os.Error) {
|
||||
keys := value.Keys()
|
||||
if value.Len() < 16 {
|
||||
n, err := writer.Write([]byte { 0x80 | byte(len(keys)) })
|
||||
if err != nil { return n, err }
|
||||
for _, k := range keys {
|
||||
_n, err := PackValue(writer, k)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
_n, err = PackValue(writer, value.Elem(k))
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else if value.Len() < 65536 {
|
||||
n, err := writer.Write([]byte { 0xde, byte(len(keys) >> 8), byte(len(keys)) })
|
||||
if err != nil { return n, err }
|
||||
for _, k := range keys {
|
||||
_n, err := PackValue(writer, k)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
_n, err = PackValue(writer, value.Elem(k))
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
} else {
|
||||
n, err := writer.Write([]byte { 0xdf, byte(len(keys) >> 24), byte(len(keys) >> 16), byte(len(keys) >> 8), byte(len(keys)) })
|
||||
if err != nil { return n, err }
|
||||
for _, k := range keys {
|
||||
_n, err := PackValue(writer, k)
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
_n, err = PackValue(writer, value.Elem(k))
|
||||
if err != nil { return n, err }
|
||||
n += _n
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func PackValue(writer io.Writer, value reflect.Value) (n int, err os.Error) {
|
||||
if value == nil || value.Type() == nil { return PackNil(writer) }
|
||||
switch _value := value.(type) {
|
||||
case *reflect.BoolValue: return PackBool(writer, _value.Get())
|
||||
case *reflect.UintValue: return PackUint64(writer, _value.Get())
|
||||
case *reflect.IntValue: return PackInt64(writer, _value.Get())
|
||||
case *reflect.FloatValue: return PackFloat64(writer, _value.Get())
|
||||
case *reflect.ArrayValue: return PackArray(writer, _value)
|
||||
case *reflect.SliceValue: return PackArray(writer, _value)
|
||||
case *reflect.MapValue: return PackMap(writer, _value)
|
||||
case *reflect.InterfaceValue:
|
||||
__value := reflect.NewValue(_value.Interface())
|
||||
_, ok := __value.(*reflect.InterfaceValue)
|
||||
if !ok {
|
||||
return PackValue(writer, __value)
|
||||
}
|
||||
}
|
||||
panic("unsupported type: " + value.Type().String())
|
||||
}
|
||||
|
||||
// Packs a given value and writes it into the specified writer.
|
||||
func Pack(writer io.Writer, value interface{}) (n int, err os.Error) {
|
||||
if value == nil { return PackNil(writer) }
|
||||
switch _value := value.(type) {
|
||||
case bool: return PackBool(writer, _value)
|
||||
case uint8: return PackUint8(writer, _value)
|
||||
case uint16: return PackUint16(writer, _value)
|
||||
case uint32: return PackUint32(writer, _value)
|
||||
case uint64: return PackUint64(writer, _value)
|
||||
case uint: return PackUint(writer, _value)
|
||||
case int8: return PackInt8(writer, _value)
|
||||
case int16: return PackInt16(writer, _value)
|
||||
case int32: return PackInt32(writer, _value)
|
||||
case int64: return PackInt64(writer, _value)
|
||||
case int: return PackInt(writer, _value)
|
||||
case float32: return PackFloat32(writer, _value)
|
||||
case float64: return PackFloat64(writer, _value)
|
||||
case []byte: return PackBytes(writer, _value)
|
||||
case []uint16: return PackUint16Array(writer, _value)
|
||||
case []uint32: return PackUint32Array(writer, _value)
|
||||
case []uint64: return PackUint64Array(writer, _value)
|
||||
case []uint: return PackUintArray(writer, _value)
|
||||
case []int8: return PackInt8Array(writer, _value)
|
||||
case []int16: return PackInt16Array(writer, _value)
|
||||
case []int32: return PackInt32Array(writer, _value)
|
||||
case []int64: return PackInt64Array(writer, _value)
|
||||
case []int: return PackIntArray(writer, _value)
|
||||
case []float32: return PackFloat32Array(writer, _value)
|
||||
case []float64: return PackFloat64Array(writer, _value)
|
||||
default:
|
||||
return PackValue(writer, reflect.NewValue(value))
|
||||
}
|
||||
return 0, nil // never get here
|
||||
}
|
288
go/unpack.go
Normal file
288
go/unpack.go
Normal file
@@ -0,0 +1,288 @@
|
||||
package msgpack
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"unsafe"
|
||||
"strconv"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func readByte(reader io.Reader) (v uint8, err os.Error) {
|
||||
data := [1]byte{}
|
||||
_, e := reader.Read(data[0:])
|
||||
if e != nil { return 0, e }
|
||||
return data[0], nil
|
||||
}
|
||||
|
||||
func readUint16(reader io.Reader) (v uint16, n int, err os.Error) {
|
||||
data := [2]byte{}
|
||||
n, e := reader.Read(data[0:])
|
||||
if e != nil { return 0, n, e }
|
||||
return (uint16(data[0]) << 8) | uint16(data[1]), n, nil
|
||||
}
|
||||
|
||||
func readUint32(reader io.Reader) (v uint32, n int, err os.Error) {
|
||||
data := [4]byte{}
|
||||
n, e := reader.Read(data[0:])
|
||||
if e != nil { return 0, n, e }
|
||||
return (uint32(data[0]) << 24) | (uint32(data[1]) << 16) | (uint32(data[2]) << 8) | uint32(data[3]), n, nil
|
||||
}
|
||||
|
||||
func readUint64(reader io.Reader) (v uint64, n int, err os.Error) {
|
||||
data := [8]byte{}
|
||||
n, e := reader.Read(data[0:])
|
||||
if e != nil { return 0, n, e }
|
||||
return (uint64(data[0]) << 56) | (uint64(data[1]) << 48) | (uint64(data[2]) << 40) | (uint64(data[3]) << 32) | (uint64(data[4]) << 24) | (uint64(data[5]) << 16) | (uint64(data[6]) << 8) | uint64(data[7]), n, nil
|
||||
}
|
||||
|
||||
func readInt16(reader io.Reader) (v int16, n int, err os.Error) {
|
||||
data := [2]byte{}
|
||||
n, e := reader.Read(data[0:])
|
||||
if e != nil { return 0, n, e }
|
||||
return (int16(data[0]) << 8) | int16(data[1]), n, nil
|
||||
}
|
||||
|
||||
func readInt32(reader io.Reader) (v int32, n int, err os.Error) {
|
||||
data := [4]byte{}
|
||||
n, e := reader.Read(data[0:])
|
||||
if e != nil { return 0, n, e }
|
||||
return (int32(data[0]) << 24) | (int32(data[1]) << 16) | (int32(data[2]) << 8) | int32(data[3]), n, nil
|
||||
}
|
||||
|
||||
func readInt64(reader io.Reader) (v int64, n int, err os.Error) {
|
||||
data := [8]byte{}
|
||||
n, e := reader.Read(data[0:])
|
||||
if e != nil { return 0, n, e }
|
||||
return (int64(data[0]) << 56) | (int64(data[1]) << 48) | (int64(data[2]) << 40) | (int64(data[3]) << 32) | (int64(data[4]) << 24) | (int64(data[5]) << 16) | (int64(data[6]) << 8) | int64(data[7]), n, nil
|
||||
}
|
||||
|
||||
func unpackArray(reader io.Reader, nelems uint) (v reflect.Value, n int, err os.Error) {
|
||||
retval := make([]interface{}, nelems)
|
||||
nbytesread := 0
|
||||
var i uint
|
||||
for i = 0; i < nelems; i++ {
|
||||
v, n, e := Unpack(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval[i] = v.Interface()
|
||||
}
|
||||
return reflect.NewValue(retval), nbytesread, nil
|
||||
}
|
||||
|
||||
func unpackArrayReflected(reader io.Reader, nelems uint) (v reflect.Value, n int, err os.Error) {
|
||||
retval := make([]reflect.Value, nelems)
|
||||
nbytesread := 0
|
||||
var i uint
|
||||
for i = 0; i < nelems; i++ {
|
||||
v, n, e := UnpackReflected(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval[i] = v
|
||||
}
|
||||
return reflect.NewValue(retval), nbytesread, nil
|
||||
}
|
||||
|
||||
func unpackMap(reader io.Reader, nelems uint) (v reflect.Value, n int, err os.Error) {
|
||||
retval := make(map [interface{}] interface{})
|
||||
nbytesread := 0
|
||||
var i uint
|
||||
for i = 0; i < nelems; i++ {
|
||||
k, n, e := Unpack(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
v, n, e := Unpack(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval[k.Interface()] = v.Interface()
|
||||
}
|
||||
return reflect.NewValue(retval), nbytesread, nil
|
||||
}
|
||||
|
||||
func unpackMapReflected(reader io.Reader, nelems uint) (v reflect.Value, n int, err os.Error) {
|
||||
retval := make(map [reflect.Value] reflect.Value)
|
||||
nbytesread := 0
|
||||
var i uint
|
||||
for i = 0; i < nelems; i++ {
|
||||
k, n, e := UnpackReflected(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
v, n, e := UnpackReflected(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval[k] = v
|
||||
}
|
||||
return reflect.NewValue(retval), nbytesread, nil
|
||||
}
|
||||
|
||||
func unpack(reader io.Reader, reflected bool) (v reflect.Value, n int, err os.Error) {
|
||||
var retval reflect.Value
|
||||
var nbytesread int = 0
|
||||
|
||||
c, e := readByte(reader)
|
||||
if e != nil { return nil, 0, e }
|
||||
nbytesread += 1
|
||||
if c < 0x80 || c >= 0xe0 {
|
||||
retval = reflect.NewValue(int8(c))
|
||||
} else if c >= 0x80 && c <= 0x8f {
|
||||
if reflected {
|
||||
retval, n, e = unpackMapReflected(reader, uint(c & 0xf))
|
||||
} else {
|
||||
retval, n, e = unpackMap(reader, uint(c & 0xf))
|
||||
}
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
nbytesread += n
|
||||
} else if c >= 0x90 && c <= 0x9f {
|
||||
if reflected {
|
||||
retval, n, e = unpackArrayReflected(reader, uint(c & 0xf))
|
||||
} else {
|
||||
retval, n, e = unpackArray(reader, uint(c & 0xf))
|
||||
}
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
nbytesread += n
|
||||
} else if c >= 0xa0 && c <= 0xbf {
|
||||
data := make([]byte, c & 0xf);
|
||||
n, e := reader.Read(data)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
} else {
|
||||
switch c {
|
||||
case 0xc0: retval = reflect.NewValue(nil)
|
||||
case 0xc2: retval = reflect.NewValue(false)
|
||||
case 0xc3: retval = reflect.NewValue(true)
|
||||
case 0xca:
|
||||
data, n, e := readUint32(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(*(*float32)(unsafe.Pointer(&data)))
|
||||
case 0xcb:
|
||||
data, n, e := readUint64(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(*(*float64)(unsafe.Pointer(&data)))
|
||||
case 0xcc:
|
||||
data, e := readByte(reader)
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(uint8(data))
|
||||
nbytesread += 1
|
||||
case 0xcd:
|
||||
data, n, e := readUint16(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
case 0xce:
|
||||
data, n, e := readUint32(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
case 0xcf:
|
||||
data, n, e := readUint64(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
case 0xd0:
|
||||
data, e := readByte(reader)
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(int8(data))
|
||||
nbytesread += 1
|
||||
case 0xd1:
|
||||
data, n, e := readInt16(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
case 0xd2:
|
||||
data, n, e := readInt32(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
case 0xd3:
|
||||
data, n, e := readInt64(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
case 0xda:
|
||||
nbytestoread, n, e := readUint16(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
data := make([]byte, nbytestoread)
|
||||
n, e = reader.Read(data)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
case 0xdb:
|
||||
nbytestoread, n, e := readUint32(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
data := make([]byte, nbytestoread)
|
||||
n, e = reader.Read(data)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
retval = reflect.NewValue(data)
|
||||
case 0xdc:
|
||||
nelemstoread, n, e := readUint16(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
if reflected {
|
||||
retval, n, e = unpackArrayReflected(reader, uint(nelemstoread))
|
||||
} else {
|
||||
retval, n, e = unpackArray(reader, uint(nelemstoread))
|
||||
}
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
case 0xdd:
|
||||
nelemstoread, n, e := readUint32(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
if reflected {
|
||||
retval, n, e = unpackArrayReflected(reader, uint(nelemstoread))
|
||||
} else {
|
||||
retval, n, e = unpackArray(reader, uint(nelemstoread))
|
||||
}
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
case 0xde:
|
||||
nelemstoread, n, e := readUint16(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
if reflected {
|
||||
retval, n, e = unpackMapReflected(reader, uint(nelemstoread))
|
||||
} else {
|
||||
retval, n, e = unpackMap(reader, uint(nelemstoread))
|
||||
}
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
case 0xdf:
|
||||
nelemstoread, n, e := readUint32(reader)
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
if reflected {
|
||||
retval, n, e = unpackMapReflected(reader, uint(nelemstoread))
|
||||
} else {
|
||||
retval, n, e = unpackMap(reader, uint(nelemstoread))
|
||||
}
|
||||
nbytesread += n
|
||||
if e != nil { return nil, nbytesread, e }
|
||||
default:
|
||||
panic("unsupported code: " + strconv.Itoa(int(c)))
|
||||
}
|
||||
}
|
||||
return retval, nbytesread, nil
|
||||
}
|
||||
|
||||
// Reads a value from the reader, unpack and returns it.
|
||||
func Unpack(reader io.Reader) (v reflect.Value, n int, err os.Error) {
|
||||
return unpack(reader, false)
|
||||
}
|
||||
|
||||
// Reads unpack a value from the reader, unpack and returns it. When the
|
||||
// value is an array or map, leaves the elements wrapped by corresponding
|
||||
// wrapper objects defined in reflect package.
|
||||
func UnpackReflected(reader io.Reader) (v reflect.Value, n int, err os.Error) {
|
||||
return unpack(reader, true)
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009, Hideyuki Tanaka
|
||||
Copyright (c) 2009-2010, Hideyuki Tanaka
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@@ -1,137 +0,0 @@
|
||||
#include <msgpack.h>
|
||||
|
||||
void msgpack_sbuffer_init_wrap(msgpack_sbuffer* sbuf)
|
||||
{
|
||||
msgpack_sbuffer_init(sbuf);
|
||||
}
|
||||
|
||||
void msgpack_sbuffer_destroy_wrap(msgpack_sbuffer* sbuf)
|
||||
{
|
||||
msgpack_sbuffer_destroy(sbuf);
|
||||
}
|
||||
|
||||
int msgpack_sbuffer_write_wrap(void* data, const char* buf, unsigned int len)
|
||||
{
|
||||
return msgpack_sbuffer_write(data, buf, len);
|
||||
}
|
||||
|
||||
msgpack_packer* msgpack_packer_new_wrap(void *data, msgpack_packer_write callback)
|
||||
{
|
||||
return msgpack_packer_new(data, callback);
|
||||
}
|
||||
|
||||
void msgpack_packer_free_wrap(msgpack_packer* pk)
|
||||
{
|
||||
msgpack_packer_free(pk);
|
||||
}
|
||||
|
||||
int msgpack_pack_uint8_wrap(msgpack_packer* pk, uint8_t d)
|
||||
{
|
||||
return msgpack_pack_uint8(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_uint16_wrap(msgpack_packer* pk, uint16_t d)
|
||||
{
|
||||
return msgpack_pack_uint16(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_uint32_wrap(msgpack_packer* pk, uint32_t d)
|
||||
{
|
||||
return msgpack_pack_uint32(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_uint64_wrap(msgpack_packer* pk, uint64_t d)
|
||||
{
|
||||
return msgpack_pack_uint64(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_int8_wrap(msgpack_packer* pk, int8_t d)
|
||||
{
|
||||
return msgpack_pack_int8(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_int16_wrap(msgpack_packer* pk, int16_t d)
|
||||
{
|
||||
return msgpack_pack_int16(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_int32_wrap(msgpack_packer* pk, int32_t d)
|
||||
{
|
||||
return msgpack_pack_int32(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_int64_wrap(msgpack_packer* pk, int64_t d)
|
||||
{
|
||||
return msgpack_pack_int64(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_double_wrap(msgpack_packer* pk, double d)
|
||||
{
|
||||
return msgpack_pack_double(pk, d);
|
||||
}
|
||||
|
||||
int msgpack_pack_nil_wrap(msgpack_packer* pk)
|
||||
{
|
||||
return msgpack_pack_nil(pk);
|
||||
}
|
||||
|
||||
int msgpack_pack_true_wrap(msgpack_packer* pk)
|
||||
{
|
||||
return msgpack_pack_true(pk);
|
||||
}
|
||||
|
||||
int msgpack_pack_false_wrap(msgpack_packer* pk)
|
||||
{
|
||||
return msgpack_pack_false(pk);
|
||||
}
|
||||
|
||||
int msgpack_pack_array_wrap(msgpack_packer* pk, unsigned int n)
|
||||
{
|
||||
return msgpack_pack_array(pk, n);
|
||||
}
|
||||
|
||||
int msgpack_pack_map_wrap(msgpack_packer* pk, unsigned int n)
|
||||
{
|
||||
return msgpack_pack_map(pk, n);
|
||||
}
|
||||
|
||||
int msgpack_pack_raw_wrap(msgpack_packer* pk, size_t l)
|
||||
{
|
||||
return msgpack_pack_raw(pk, l);
|
||||
}
|
||||
|
||||
int msgpack_pack_raw_body_wrap(msgpack_packer* pk, const void *b, size_t l)
|
||||
{
|
||||
return msgpack_pack_raw_body(pk, b, l);
|
||||
}
|
||||
|
||||
bool msgpack_unpacker_reserve_buffer_wrap(msgpack_unpacker *mpac, size_t size)
|
||||
{
|
||||
return msgpack_unpacker_reserve_buffer(mpac, size);
|
||||
}
|
||||
|
||||
char *msgpack_unpacker_buffer_wrap(msgpack_unpacker *mpac)
|
||||
{
|
||||
return msgpack_unpacker_buffer(mpac);
|
||||
}
|
||||
|
||||
size_t msgpack_unpacker_buffer_capacity_wrap(const msgpack_unpacker *mpac)
|
||||
{
|
||||
return msgpack_unpacker_buffer_capacity(mpac);
|
||||
}
|
||||
|
||||
void msgpack_unpacker_buffer_consumed_wrap(msgpack_unpacker *mpac, size_t size)
|
||||
{
|
||||
msgpack_unpacker_buffer_consumed(mpac, size);
|
||||
}
|
||||
|
||||
void msgpack_unpacker_data_wrap(msgpack_unpacker *mpac, msgpack_object *obj)
|
||||
{
|
||||
*obj=msgpack_unpacker_data(mpac);
|
||||
}
|
||||
|
||||
size_t msgpack_unpacker_message_size_wrap(const msgpack_unpacker *mpac)
|
||||
{
|
||||
return msgpack_unpacker_message_size(mpac);
|
||||
}
|
||||
|
@@ -1,32 +1,50 @@
|
||||
Name: msgpack
|
||||
Version: 0.2.2
|
||||
License: BSD3
|
||||
License-File: LICENSE
|
||||
Author: Hideyuki Tanaka
|
||||
Maintainer: Hideyuki Tanaka <tanaka.hideyuki@gmail.com>
|
||||
Category: Data
|
||||
Synopsis: A Haskell binding to MessagePack
|
||||
Name: msgpack
|
||||
Version: 0.6.1.1
|
||||
Synopsis: A Haskell implementation of MessagePack
|
||||
Description:
|
||||
A Haskell binding to MessagePack <http://msgpack.sourceforge.jp/>
|
||||
Homepage: http://github.com/tanakh/hsmsgpack
|
||||
Stability: Experimental
|
||||
Tested-with: GHC==6.10.4
|
||||
Cabal-Version: >=1.2
|
||||
Build-Type: Simple
|
||||
A Haskell implementation of MessagePack <http://msgpack.org/>
|
||||
|
||||
library
|
||||
build-depends: base>=4 && <5, mtl, bytestring
|
||||
ghc-options: -O2 -Wall
|
||||
hs-source-dirs: src
|
||||
extra-libraries: msgpackc
|
||||
License: BSD3
|
||||
License-File: LICENSE
|
||||
Copyright: Copyright (c) 2009-2011, Hideyuki Tanaka
|
||||
Category: Data
|
||||
Author: Hideyuki Tanaka
|
||||
Maintainer: Hideyuki Tanaka <tanaka.hideyuki@gmail.com>
|
||||
Homepage: http://github.com/msgpack/msgpack
|
||||
Stability: Experimental
|
||||
Cabal-Version: >= 1.6
|
||||
Build-Type: Simple
|
||||
|
||||
Extra-source-files:
|
||||
test/Test.hs
|
||||
test/UserData.hs
|
||||
|
||||
Library
|
||||
Build-depends: base >=4 && <5,
|
||||
transformers >= 0.2 && < 0.3,
|
||||
bytestring >= 0.9 && < 0.10,
|
||||
text >= 0.11 && < 0.12,
|
||||
vector >= 0.7 && < 0.8,
|
||||
attoparsec >= 0.8 && < 0.9,
|
||||
binary >= 0.5.0 && < 0.5.1,
|
||||
data-binary-ieee754 >= 0.4 && < 0.5,
|
||||
deepseq >= 1.1 && <1.2,
|
||||
template-haskell >= 2.4 && < 2.6
|
||||
|
||||
Ghc-options: -Wall
|
||||
Hs-source-dirs: src
|
||||
|
||||
Exposed-modules:
|
||||
Data.MessagePack
|
||||
Data.MessagePack.Base
|
||||
Data.MessagePack.Class
|
||||
Data.MessagePack.Feed
|
||||
Data.MessagePack.Monad
|
||||
Data.MessagePack.Stream
|
||||
Data.MessagePack.Assoc
|
||||
Data.MessagePack.Pack
|
||||
Data.MessagePack.Unpack
|
||||
Data.MessagePack.Object
|
||||
Data.MessagePack.Derive
|
||||
|
||||
C-Sources:
|
||||
cbits/msgpack.c
|
||||
Other-modules:
|
||||
Data.MessagePack.Internal.Utf8
|
||||
|
||||
Source-repository head
|
||||
Type: git
|
||||
Location: git://github.com/msgpack/msgpack.git
|
||||
|
@@ -1,7 +1,7 @@
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009-2010
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
@@ -13,51 +13,15 @@
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack(
|
||||
module Data.MessagePack.Base,
|
||||
module Data.MessagePack.Class,
|
||||
module Data.MessagePack.Feed,
|
||||
module Data.MessagePack.Monad,
|
||||
module Data.MessagePack.Stream,
|
||||
|
||||
-- * Pack and Unpack
|
||||
packb,
|
||||
unpackb,
|
||||
|
||||
-- * Pure version of Pack and Unpack
|
||||
packb',
|
||||
unpackb',
|
||||
module Data.MessagePack.Assoc,
|
||||
module Data.MessagePack.Pack,
|
||||
module Data.MessagePack.Unpack,
|
||||
module Data.MessagePack.Object,
|
||||
module Data.MessagePack.Derive,
|
||||
) where
|
||||
|
||||
import Data.ByteString (ByteString)
|
||||
import System.IO.Unsafe
|
||||
|
||||
import Data.MessagePack.Base
|
||||
import Data.MessagePack.Class
|
||||
import Data.MessagePack.Feed
|
||||
import Data.MessagePack.Monad
|
||||
import Data.MessagePack.Stream
|
||||
|
||||
-- | Pack Haskell data to MessagePack string.
|
||||
packb :: OBJECT a => a -> IO ByteString
|
||||
packb dat = do
|
||||
sb <- newSimpleBuffer
|
||||
pc <- newPacker sb
|
||||
pack pc dat
|
||||
simpleBufferData sb
|
||||
|
||||
-- | Unpack MessagePack string to Haskell data.
|
||||
unpackb :: OBJECT a => ByteString -> IO (Result a)
|
||||
unpackb bs = do
|
||||
withZone $ \z -> do
|
||||
r <- unpackObject z bs
|
||||
return $ case r of
|
||||
Left err -> Left (show err)
|
||||
Right (_, dat) -> fromObject dat
|
||||
|
||||
-- | Pure version of 'packb'.
|
||||
packb' :: OBJECT a => a -> ByteString
|
||||
packb' dat = unsafePerformIO $ packb dat
|
||||
|
||||
-- | Pure version of 'unpackb'.
|
||||
unpackb' :: OBJECT a => ByteString -> Result a
|
||||
unpackb' bs = unsafePerformIO $ unpackb bs
|
||||
import Data.MessagePack.Assoc
|
||||
import Data.MessagePack.Pack
|
||||
import Data.MessagePack.Unpack
|
||||
import Data.MessagePack.Object
|
||||
import Data.MessagePack.Derive
|
||||
|
28
haskell/src/Data/MessagePack/Assoc.hs
Normal file
28
haskell/src/Data/MessagePack/Assoc.hs
Normal file
@@ -0,0 +1,28 @@
|
||||
{-# Language DeriveDataTypeable #-}
|
||||
{-# Language GeneralizedNewtypeDeriving #-}
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Assoc
|
||||
-- Copyright : (c) Daiki Handa, 2010
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- MessagePack map labeling type
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Assoc (
|
||||
Assoc(..)
|
||||
) where
|
||||
|
||||
import Control.DeepSeq
|
||||
import Data.Typeable
|
||||
|
||||
-- not defined for general Functor for performance reason.
|
||||
-- (ie. you would want to write custom instances for each type using specialized mapM-like functions)
|
||||
newtype Assoc a=Assoc{unAssoc :: a} deriving(Show,Eq,Ord,Typeable,NFData)
|
||||
|
@@ -1,584 +0,0 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE ForeignFunctionInterface #-}
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Base
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- Low Level Interface to MessagePack C API
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Base(
|
||||
-- * Simple Buffer
|
||||
SimpleBuffer,
|
||||
newSimpleBuffer,
|
||||
simpleBufferData,
|
||||
|
||||
-- * Serializer
|
||||
Packer,
|
||||
newPacker,
|
||||
|
||||
packU8,
|
||||
packU16,
|
||||
packU32,
|
||||
packU64,
|
||||
packS8,
|
||||
packS16,
|
||||
packS32,
|
||||
packS64,
|
||||
|
||||
packTrue,
|
||||
packFalse,
|
||||
|
||||
packInt,
|
||||
packDouble,
|
||||
packNil,
|
||||
packBool,
|
||||
|
||||
packArray,
|
||||
packMap,
|
||||
packRAW,
|
||||
packRAWBody,
|
||||
packRAW',
|
||||
|
||||
-- * Stream Deserializer
|
||||
Unpacker,
|
||||
defaultInitialBufferSize,
|
||||
newUnpacker,
|
||||
unpackerReserveBuffer,
|
||||
unpackerBuffer,
|
||||
unpackerBufferCapacity,
|
||||
unpackerBufferConsumed,
|
||||
unpackerFeed,
|
||||
unpackerExecute,
|
||||
unpackerData,
|
||||
unpackerReleaseZone,
|
||||
unpackerResetZone,
|
||||
unpackerReset,
|
||||
unpackerMessageSize,
|
||||
|
||||
-- * MessagePack Object
|
||||
Object(..),
|
||||
packObject,
|
||||
|
||||
UnpackReturn(..),
|
||||
unpackObject,
|
||||
|
||||
-- * Memory Zone
|
||||
Zone,
|
||||
newZone,
|
||||
freeZone,
|
||||
withZone,
|
||||
) where
|
||||
|
||||
import Control.Exception
|
||||
import Control.Monad
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString as BS hiding (pack, unpack)
|
||||
import Data.Int
|
||||
import Data.Word
|
||||
import Foreign.C
|
||||
import Foreign.Concurrent
|
||||
import Foreign.ForeignPtr hiding (newForeignPtr)
|
||||
import Foreign.Marshal.Alloc
|
||||
import Foreign.Marshal.Array
|
||||
import Foreign.Ptr
|
||||
import Foreign.Storable
|
||||
|
||||
#include <msgpack.h>
|
||||
|
||||
type SimpleBuffer = ForeignPtr ()
|
||||
|
||||
type WriteCallback = Ptr () -> CString -> CUInt -> IO CInt
|
||||
|
||||
-- | Create a new Simple Buffer. It will be deleted automatically.
|
||||
newSimpleBuffer :: IO SimpleBuffer
|
||||
newSimpleBuffer = do
|
||||
ptr <- mallocBytes (#size msgpack_sbuffer)
|
||||
fptr <- newForeignPtr ptr $ do
|
||||
msgpack_sbuffer_destroy ptr
|
||||
free ptr
|
||||
withForeignPtr fptr $ \p ->
|
||||
msgpack_sbuffer_init p
|
||||
return fptr
|
||||
|
||||
-- | Get data of Simple Buffer.
|
||||
simpleBufferData :: SimpleBuffer -> IO ByteString
|
||||
simpleBufferData sb =
|
||||
withForeignPtr sb $ \ptr -> do
|
||||
size <- (#peek msgpack_sbuffer, size) ptr
|
||||
dat <- (#peek msgpack_sbuffer, data) ptr
|
||||
BS.packCStringLen (dat, fromIntegral (size :: CSize))
|
||||
|
||||
foreign import ccall "msgpack_sbuffer_init_wrap" msgpack_sbuffer_init ::
|
||||
Ptr () -> IO ()
|
||||
|
||||
foreign import ccall "msgpack_sbuffer_destroy_wrap" msgpack_sbuffer_destroy ::
|
||||
Ptr () -> IO ()
|
||||
|
||||
foreign import ccall "msgpack_sbuffer_write_wrap" msgpack_sbuffer_write ::
|
||||
WriteCallback
|
||||
|
||||
type Packer = ForeignPtr ()
|
||||
|
||||
-- | Create new Packer. It will be deleted automatically.
|
||||
newPacker :: SimpleBuffer -> IO Packer
|
||||
newPacker sbuf = do
|
||||
cb <- wrap_callback msgpack_sbuffer_write
|
||||
ptr <- withForeignPtr sbuf $ \ptr ->
|
||||
msgpack_packer_new ptr cb
|
||||
fptr <- newForeignPtr ptr $ do
|
||||
msgpack_packer_free ptr
|
||||
return fptr
|
||||
|
||||
foreign import ccall "msgpack_packer_new_wrap" msgpack_packer_new ::
|
||||
Ptr () -> FunPtr WriteCallback -> IO (Ptr ())
|
||||
|
||||
foreign import ccall "msgpack_packer_free_wrap" msgpack_packer_free ::
|
||||
Ptr () -> IO ()
|
||||
|
||||
foreign import ccall "wrapper" wrap_callback ::
|
||||
WriteCallback -> IO (FunPtr WriteCallback)
|
||||
|
||||
packU8 :: Packer -> Word8 -> IO Int
|
||||
packU8 pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_uint8 ptr n
|
||||
|
||||
foreign import ccall "msgpack_pack_uint8_wrap" msgpack_pack_uint8 ::
|
||||
Ptr () -> Word8 -> IO CInt
|
||||
|
||||
packU16 :: Packer -> Word16 -> IO Int
|
||||
packU16 pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_uint16 ptr n
|
||||
|
||||
foreign import ccall "msgpack_pack_uint16_wrap" msgpack_pack_uint16 ::
|
||||
Ptr () -> Word16 -> IO CInt
|
||||
|
||||
packU32 :: Packer -> Word32 -> IO Int
|
||||
packU32 pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_uint32 ptr n
|
||||
|
||||
foreign import ccall "msgpack_pack_uint32_wrap" msgpack_pack_uint32 ::
|
||||
Ptr () -> Word32 -> IO CInt
|
||||
|
||||
packU64 :: Packer -> Word64 -> IO Int
|
||||
packU64 pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_uint64 ptr n
|
||||
|
||||
foreign import ccall "msgpack_pack_uint64_wrap" msgpack_pack_uint64 ::
|
||||
Ptr () -> Word64 -> IO CInt
|
||||
|
||||
packS8 :: Packer -> Int8 -> IO Int
|
||||
packS8 pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_int8 ptr n
|
||||
|
||||
foreign import ccall "msgpack_pack_int8_wrap" msgpack_pack_int8 ::
|
||||
Ptr () -> Int8 -> IO CInt
|
||||
|
||||
packS16 :: Packer -> Int16 -> IO Int
|
||||
packS16 pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_int16 ptr n
|
||||
|
||||
foreign import ccall "msgpack_pack_int16_wrap" msgpack_pack_int16 ::
|
||||
Ptr () -> Int16 -> IO CInt
|
||||
|
||||
packS32 :: Packer -> Int32 -> IO Int
|
||||
packS32 pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_int32 ptr n
|
||||
|
||||
foreign import ccall "msgpack_pack_int32_wrap" msgpack_pack_int32 ::
|
||||
Ptr () -> Int32 -> IO CInt
|
||||
|
||||
packS64 :: Packer -> Int64 -> IO Int
|
||||
packS64 pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_int64 ptr n
|
||||
|
||||
foreign import ccall "msgpack_pack_int64_wrap" msgpack_pack_int64 ::
|
||||
Ptr () -> Int64 -> IO CInt
|
||||
|
||||
-- | Pack an integral data.
|
||||
packInt :: Integral a => Packer -> a -> IO Int
|
||||
packInt pc n = packS64 pc $ fromIntegral n
|
||||
|
||||
-- | Pack a double data.
|
||||
packDouble :: Packer -> Double -> IO Int
|
||||
packDouble pc d =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_double ptr (realToFrac d)
|
||||
|
||||
foreign import ccall "msgpack_pack_double_wrap" msgpack_pack_double ::
|
||||
Ptr () -> CDouble -> IO CInt
|
||||
|
||||
-- | Pack a nil.
|
||||
packNil :: Packer -> IO Int
|
||||
packNil pc =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_nil ptr
|
||||
|
||||
foreign import ccall "msgpack_pack_nil_wrap" msgpack_pack_nil ::
|
||||
Ptr () -> IO CInt
|
||||
|
||||
packTrue :: Packer -> IO Int
|
||||
packTrue pc =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_true ptr
|
||||
|
||||
foreign import ccall "msgpack_pack_true_wrap" msgpack_pack_true ::
|
||||
Ptr () -> IO CInt
|
||||
|
||||
packFalse :: Packer -> IO Int
|
||||
packFalse pc =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_false ptr
|
||||
|
||||
foreign import ccall "msgpack_pack_false_wrap" msgpack_pack_false ::
|
||||
Ptr () -> IO CInt
|
||||
|
||||
-- | Pack a bool data.
|
||||
packBool :: Packer -> Bool -> IO Int
|
||||
packBool pc True = packTrue pc
|
||||
packBool pc False = packFalse pc
|
||||
|
||||
-- | 'packArray' @p n@ starts packing an array.
|
||||
-- Next @n@ data will consist this array.
|
||||
packArray :: Packer -> Int -> IO Int
|
||||
packArray pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_array ptr (fromIntegral n)
|
||||
|
||||
foreign import ccall "msgpack_pack_array_wrap" msgpack_pack_array ::
|
||||
Ptr () -> CUInt -> IO CInt
|
||||
|
||||
-- | 'packMap' @p n@ starts packing a map.
|
||||
-- Next @n@ pairs of data (2*n data) will consist this map.
|
||||
packMap :: Packer -> Int -> IO Int
|
||||
packMap pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_map ptr (fromIntegral n)
|
||||
|
||||
foreign import ccall "msgpack_pack_map_wrap" msgpack_pack_map ::
|
||||
Ptr () -> CUInt -> IO CInt
|
||||
|
||||
-- | 'packRAW' @p n@ starts packing a byte sequence.
|
||||
-- Next total @n@ bytes of 'packRAWBody' call will consist this sequence.
|
||||
packRAW :: Packer -> Int -> IO Int
|
||||
packRAW pc n =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
msgpack_pack_raw ptr (fromIntegral n)
|
||||
|
||||
foreign import ccall "msgpack_pack_raw_wrap" msgpack_pack_raw ::
|
||||
Ptr () -> CSize -> IO CInt
|
||||
|
||||
-- | Pack a byte sequence.
|
||||
packRAWBody :: Packer -> ByteString -> IO Int
|
||||
packRAWBody pc bs =
|
||||
liftM fromIntegral $ withForeignPtr pc $ \ptr ->
|
||||
BS.useAsCStringLen bs $ \(str, len) ->
|
||||
msgpack_pack_raw_body ptr (castPtr str) (fromIntegral len)
|
||||
|
||||
foreign import ccall "msgpack_pack_raw_body_wrap" msgpack_pack_raw_body ::
|
||||
Ptr () -> Ptr () -> CSize -> IO CInt
|
||||
|
||||
-- | Pack a single byte stream. It calls 'packRAW' and 'packRAWBody'.
|
||||
packRAW' :: Packer -> ByteString -> IO Int
|
||||
packRAW' pc bs = do
|
||||
_ <- packRAW pc (BS.length bs)
|
||||
packRAWBody pc bs
|
||||
|
||||
type Unpacker = ForeignPtr ()
|
||||
|
||||
defaultInitialBufferSize :: Int
|
||||
defaultInitialBufferSize = 32 * 1024 -- #const MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE
|
||||
|
||||
-- | 'newUnpacker' @initialBufferSize@ creates a new Unpacker. It will be deleted automatically.
|
||||
newUnpacker :: Int -> IO Unpacker
|
||||
newUnpacker initialBufferSize = do
|
||||
ptr <- msgpack_unpacker_new (fromIntegral initialBufferSize)
|
||||
fptr <- newForeignPtr ptr $ do
|
||||
msgpack_unpacker_free ptr
|
||||
return fptr
|
||||
|
||||
foreign import ccall "msgpack_unpacker_new" msgpack_unpacker_new ::
|
||||
CSize -> IO (Ptr ())
|
||||
|
||||
foreign import ccall "msgpack_unpacker_free" msgpack_unpacker_free ::
|
||||
Ptr() -> IO ()
|
||||
|
||||
-- | 'unpackerReserveBuffer' @up size@ reserves at least @size@ bytes of buffer.
|
||||
unpackerReserveBuffer :: Unpacker -> Int -> IO Bool
|
||||
unpackerReserveBuffer up size =
|
||||
withForeignPtr up $ \ptr ->
|
||||
liftM (/=0) $ msgpack_unpacker_reserve_buffer ptr (fromIntegral size)
|
||||
|
||||
foreign import ccall "msgpack_unpacker_reserve_buffer_wrap" msgpack_unpacker_reserve_buffer ::
|
||||
Ptr () -> CSize -> IO CChar
|
||||
|
||||
-- | Get a pointer of unpacker buffer.
|
||||
unpackerBuffer :: Unpacker -> IO (Ptr CChar)
|
||||
unpackerBuffer up =
|
||||
withForeignPtr up $ \ptr ->
|
||||
msgpack_unpacker_buffer ptr
|
||||
|
||||
foreign import ccall "msgpack_unpacker_buffer_wrap" msgpack_unpacker_buffer ::
|
||||
Ptr () -> IO (Ptr CChar)
|
||||
|
||||
-- | Get size of allocated buffer.
|
||||
unpackerBufferCapacity :: Unpacker -> IO Int
|
||||
unpackerBufferCapacity up =
|
||||
withForeignPtr up $ \ptr ->
|
||||
liftM fromIntegral $ msgpack_unpacker_buffer_capacity ptr
|
||||
|
||||
foreign import ccall "msgpack_unpacker_buffer_capacity_wrap" msgpack_unpacker_buffer_capacity ::
|
||||
Ptr () -> IO CSize
|
||||
|
||||
-- | 'unpackerBufferConsumed' @up size@ notices that writed @size@ bytes to buffer.
|
||||
unpackerBufferConsumed :: Unpacker -> Int -> IO ()
|
||||
unpackerBufferConsumed up size =
|
||||
withForeignPtr up $ \ptr ->
|
||||
msgpack_unpacker_buffer_consumed ptr (fromIntegral size)
|
||||
|
||||
foreign import ccall "msgpack_unpacker_buffer_consumed_wrap" msgpack_unpacker_buffer_consumed ::
|
||||
Ptr () -> CSize -> IO ()
|
||||
|
||||
-- | Write byte sequence to Unpacker. It is utility funciton, calls 'unpackerReserveBuffer', 'unpackerBuffer' and 'unpackerBufferConsumed'.
|
||||
unpackerFeed :: Unpacker -> ByteString -> IO ()
|
||||
unpackerFeed up bs =
|
||||
BS.useAsCStringLen bs $ \(str, len) -> do
|
||||
True <- unpackerReserveBuffer up len
|
||||
ptr <- unpackerBuffer up
|
||||
copyArray ptr str len
|
||||
unpackerBufferConsumed up len
|
||||
|
||||
-- | Execute deserializing. It returns 0 when buffer contains not enough bytes, returns 1 when succeeded, returns negative value when it failed.
|
||||
unpackerExecute :: Unpacker -> IO Int
|
||||
unpackerExecute up =
|
||||
withForeignPtr up $ \ptr ->
|
||||
liftM fromIntegral $ msgpack_unpacker_execute ptr
|
||||
|
||||
foreign import ccall "msgpack_unpacker_execute" msgpack_unpacker_execute ::
|
||||
Ptr () -> IO CInt
|
||||
|
||||
-- | Returns a deserialized object when 'unpackerExecute' returned 1.
|
||||
unpackerData :: Unpacker -> IO Object
|
||||
unpackerData up =
|
||||
withForeignPtr up $ \ptr ->
|
||||
allocaBytes (#size msgpack_object) $ \pobj -> do
|
||||
msgpack_unpacker_data ptr pobj
|
||||
peekObject pobj
|
||||
|
||||
foreign import ccall "msgpack_unpacker_data_wrap" msgpack_unpacker_data ::
|
||||
Ptr () -> Ptr () -> IO ()
|
||||
|
||||
-- | Release memory zone. The returned zone must be freed by calling 'freeZone'.
|
||||
unpackerReleaseZone :: Unpacker -> IO Zone
|
||||
unpackerReleaseZone up =
|
||||
withForeignPtr up $ \ptr ->
|
||||
msgpack_unpacker_release_zone ptr
|
||||
|
||||
foreign import ccall "msgpack_unpacker_release_zone" msgpack_unpacker_release_zone ::
|
||||
Ptr () -> IO (Ptr ())
|
||||
|
||||
-- | Free memory zone used by Unapcker.
|
||||
unpackerResetZone :: Unpacker -> IO ()
|
||||
unpackerResetZone up =
|
||||
withForeignPtr up $ \ptr ->
|
||||
msgpack_unpacker_reset_zone ptr
|
||||
|
||||
foreign import ccall "msgpack_unpacker_reset_zone" msgpack_unpacker_reset_zone ::
|
||||
Ptr () -> IO ()
|
||||
|
||||
-- | Reset Unpacker state except memory zone.
|
||||
unpackerReset :: Unpacker -> IO ()
|
||||
unpackerReset up =
|
||||
withForeignPtr up $ \ptr ->
|
||||
msgpack_unpacker_reset ptr
|
||||
|
||||
foreign import ccall "msgpack_unpacker_reset" msgpack_unpacker_reset ::
|
||||
Ptr () -> IO ()
|
||||
|
||||
-- | Returns number of bytes of sequence of deserializing object.
|
||||
unpackerMessageSize :: Unpacker -> IO Int
|
||||
unpackerMessageSize up =
|
||||
withForeignPtr up $ \ptr ->
|
||||
liftM fromIntegral $ msgpack_unpacker_message_size ptr
|
||||
|
||||
foreign import ccall "msgpack_unpacker_message_size_wrap" msgpack_unpacker_message_size ::
|
||||
Ptr () -> IO CSize
|
||||
|
||||
type Zone = Ptr ()
|
||||
|
||||
-- | Create a new memory zone. It must be freed manually.
|
||||
newZone :: IO Zone
|
||||
newZone =
|
||||
msgpack_zone_new (#const MSGPACK_ZONE_CHUNK_SIZE)
|
||||
|
||||
-- | Free a memory zone.
|
||||
freeZone :: Zone -> IO ()
|
||||
freeZone z =
|
||||
msgpack_zone_free z
|
||||
|
||||
-- | Create a memory zone, then execute argument, then free memory zone.
|
||||
withZone :: (Zone -> IO a) -> IO a
|
||||
withZone z =
|
||||
bracket newZone freeZone z
|
||||
|
||||
foreign import ccall "msgpack_zone_new" msgpack_zone_new ::
|
||||
CSize -> IO Zone
|
||||
|
||||
foreign import ccall "msgpack_zone_free" msgpack_zone_free ::
|
||||
Zone -> IO ()
|
||||
|
||||
-- | Object Representation of MessagePack data.
|
||||
data Object =
|
||||
ObjectNil
|
||||
| ObjectBool Bool
|
||||
| ObjectInteger Int
|
||||
| ObjectDouble Double
|
||||
| ObjectRAW ByteString
|
||||
| ObjectArray [Object]
|
||||
| ObjectMap [(Object, Object)]
|
||||
deriving (Show)
|
||||
|
||||
peekObject :: Ptr a -> IO Object
|
||||
peekObject ptr = do
|
||||
typ <- (#peek msgpack_object, type) ptr
|
||||
case (typ :: CInt) of
|
||||
(#const MSGPACK_OBJECT_NIL) ->
|
||||
return ObjectNil
|
||||
(#const MSGPACK_OBJECT_BOOLEAN) ->
|
||||
peekObjectBool ptr
|
||||
(#const MSGPACK_OBJECT_POSITIVE_INTEGER) ->
|
||||
peekObjectPositiveInteger ptr
|
||||
(#const MSGPACK_OBJECT_NEGATIVE_INTEGER) ->
|
||||
peekObjectNegativeInteger ptr
|
||||
(#const MSGPACK_OBJECT_DOUBLE) ->
|
||||
peekObjectDouble ptr
|
||||
(#const MSGPACK_OBJECT_RAW) ->
|
||||
peekObjectRAW ptr
|
||||
(#const MSGPACK_OBJECT_ARRAY) ->
|
||||
peekObjectArray ptr
|
||||
(#const MSGPACK_OBJECT_MAP) ->
|
||||
peekObjectMap ptr
|
||||
_ ->
|
||||
fail $ "peekObject: unknown object type (" ++ show typ ++ ")"
|
||||
|
||||
peekObjectBool :: Ptr a -> IO Object
|
||||
peekObjectBool ptr = do
|
||||
b <- (#peek msgpack_object, via.boolean) ptr
|
||||
return $ ObjectBool $ (b :: CUChar) /= 0
|
||||
|
||||
peekObjectPositiveInteger :: Ptr a -> IO Object
|
||||
peekObjectPositiveInteger ptr = do
|
||||
n <- (#peek msgpack_object, via.u64) ptr
|
||||
return $ ObjectInteger $ fromIntegral (n :: Word64)
|
||||
|
||||
peekObjectNegativeInteger :: Ptr a -> IO Object
|
||||
peekObjectNegativeInteger ptr = do
|
||||
n <- (#peek msgpack_object, via.i64) ptr
|
||||
return $ ObjectInteger $ fromIntegral (n :: Int64)
|
||||
|
||||
peekObjectDouble :: Ptr a -> IO Object
|
||||
peekObjectDouble ptr = do
|
||||
d <- (#peek msgpack_object, via.dec) ptr
|
||||
return $ ObjectDouble $ realToFrac (d :: CDouble)
|
||||
|
||||
peekObjectRAW :: Ptr a -> IO Object
|
||||
peekObjectRAW ptr = do
|
||||
size <- (#peek msgpack_object, via.raw.size) ptr
|
||||
p <- (#peek msgpack_object, via.raw.ptr) ptr
|
||||
bs <- BS.packCStringLen (p, fromIntegral (size :: Word32))
|
||||
return $ ObjectRAW bs
|
||||
|
||||
peekObjectArray :: Ptr a -> IO Object
|
||||
peekObjectArray ptr = do
|
||||
csize <- (#peek msgpack_object, via.array.size) ptr
|
||||
let size = fromIntegral (csize :: Word32)
|
||||
p <- (#peek msgpack_object, via.array.ptr) ptr
|
||||
objs <- mapM (\i -> peekObject $ p `plusPtr`
|
||||
((#size msgpack_object) * i))
|
||||
[0..size-1]
|
||||
return $ ObjectArray objs
|
||||
|
||||
peekObjectMap :: Ptr a -> IO Object
|
||||
peekObjectMap ptr = do
|
||||
csize <- (#peek msgpack_object, via.map.size) ptr
|
||||
let size = fromIntegral (csize :: Word32)
|
||||
p <- (#peek msgpack_object, via.map.ptr) ptr
|
||||
dat <- mapM (\i -> peekObjectKV $ p `plusPtr`
|
||||
((#size msgpack_object_kv) * i))
|
||||
[0..size-1]
|
||||
return $ ObjectMap dat
|
||||
|
||||
peekObjectKV :: Ptr a -> IO (Object, Object)
|
||||
peekObjectKV ptr = do
|
||||
k <- peekObject $ ptr `plusPtr` (#offset msgpack_object_kv, key)
|
||||
v <- peekObject $ ptr `plusPtr` (#offset msgpack_object_kv, val)
|
||||
return (k, v)
|
||||
|
||||
-- | Pack a Object.
|
||||
packObject :: Packer -> Object -> IO ()
|
||||
packObject pc ObjectNil = packNil pc >> return ()
|
||||
|
||||
packObject pc (ObjectBool b) = packBool pc b >> return ()
|
||||
|
||||
packObject pc (ObjectInteger n) = packInt pc n >> return ()
|
||||
|
||||
packObject pc (ObjectDouble d) = packDouble pc d >> return ()
|
||||
|
||||
packObject pc (ObjectRAW bs) = packRAW' pc bs >> return ()
|
||||
|
||||
packObject pc (ObjectArray ls) = do
|
||||
_ <- packArray pc (length ls)
|
||||
mapM_ (packObject pc) ls
|
||||
|
||||
packObject pc (ObjectMap ls) = do
|
||||
_ <- packMap pc (length ls)
|
||||
mapM_ (\(a, b) -> packObject pc a >> packObject pc b) ls
|
||||
|
||||
data UnpackReturn =
|
||||
UnpackContinue -- ^ not enough bytes to unpack object
|
||||
| UnpackParseError -- ^ got invalid bytes
|
||||
| UnpackError -- ^ other error
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | Unpack a single MessagePack object from byte sequence.
|
||||
unpackObject :: Zone -> ByteString -> IO (Either UnpackReturn (Int, Object))
|
||||
unpackObject z dat =
|
||||
allocaBytes (#size msgpack_object) $ \ptr ->
|
||||
BS.useAsCStringLen dat $ \(str, len) ->
|
||||
alloca $ \poff -> do
|
||||
poke poff 0
|
||||
ret <- msgpack_unpack str (fromIntegral len) poff z ptr
|
||||
case ret of
|
||||
(#const MSGPACK_UNPACK_SUCCESS) -> do
|
||||
off <- peek poff
|
||||
obj <- peekObject ptr
|
||||
return $ Right (fromIntegral off, obj)
|
||||
(#const MSGPACK_UNPACK_EXTRA_BYTES) -> do
|
||||
off <- peek poff
|
||||
obj <- peekObject ptr
|
||||
return $ Right (fromIntegral off, obj)
|
||||
(#const MSGPACK_UNPACK_CONTINUE) ->
|
||||
return $ Left UnpackContinue
|
||||
(#const MSGPACK_UNPACK_PARSE_ERROR) ->
|
||||
return $ Left UnpackParseError
|
||||
_ ->
|
||||
return $ Left UnpackError
|
||||
|
||||
foreign import ccall "msgpack_unpack" msgpack_unpack ::
|
||||
Ptr CChar -> CSize -> Ptr CSize -> Zone -> Ptr () -> IO CInt
|
@@ -1,101 +0,0 @@
|
||||
{-# LANGUAGE TypeSynonymInstances #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE OverlappingInstances #-}
|
||||
{-# LANGUAGE IncoherentInstances #-}
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Class
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- Serializing Haskell values to and from MessagePack Objects.
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Class(
|
||||
-- * Serialization to and from Object
|
||||
OBJECT(..),
|
||||
Result,
|
||||
pack,
|
||||
) where
|
||||
|
||||
import Control.Monad.Error
|
||||
import Data.ByteString.Char8 (ByteString)
|
||||
import qualified Data.ByteString.Char8 as C8
|
||||
|
||||
import Data.MessagePack.Base
|
||||
|
||||
-- | The class of types serializable to and from MessagePack object
|
||||
class OBJECT a where
|
||||
toObject :: a -> Object
|
||||
fromObject :: Object -> Result a
|
||||
|
||||
-- | A type for parser results
|
||||
type Result a = Either String a
|
||||
|
||||
instance OBJECT Object where
|
||||
toObject = id
|
||||
fromObject = Right
|
||||
|
||||
fromObjectError :: String
|
||||
fromObjectError = "fromObject: cannot cast"
|
||||
|
||||
instance OBJECT () where
|
||||
toObject = const ObjectNil
|
||||
fromObject ObjectNil = Right ()
|
||||
fromObject _ = Left fromObjectError
|
||||
|
||||
instance OBJECT Int where
|
||||
toObject = ObjectInteger
|
||||
fromObject (ObjectInteger n) = Right n
|
||||
fromObject _ = Left fromObjectError
|
||||
|
||||
instance OBJECT Bool where
|
||||
toObject = ObjectBool
|
||||
fromObject (ObjectBool b) = Right b
|
||||
fromObject _ = Left fromObjectError
|
||||
|
||||
instance OBJECT Double where
|
||||
toObject = ObjectDouble
|
||||
fromObject (ObjectDouble d) = Right d
|
||||
fromObject _ = Left fromObjectError
|
||||
|
||||
instance OBJECT ByteString where
|
||||
toObject = ObjectRAW
|
||||
fromObject (ObjectRAW bs) = Right bs
|
||||
fromObject _ = Left fromObjectError
|
||||
|
||||
instance OBJECT String where
|
||||
toObject = toObject . C8.pack
|
||||
fromObject obj = liftM C8.unpack $ fromObject obj
|
||||
|
||||
instance OBJECT a => OBJECT [a] where
|
||||
toObject = ObjectArray . map toObject
|
||||
fromObject (ObjectArray arr) =
|
||||
mapM fromObject arr
|
||||
fromObject _ =
|
||||
Left fromObjectError
|
||||
|
||||
instance (OBJECT a, OBJECT b) => OBJECT [(a, b)] where
|
||||
toObject =
|
||||
ObjectMap . map (\(a, b) -> (toObject a, toObject b))
|
||||
fromObject (ObjectMap mem) = do
|
||||
mapM (\(a, b) -> liftM2 (,) (fromObject a) (fromObject b)) mem
|
||||
fromObject _ =
|
||||
Left fromObjectError
|
||||
|
||||
instance OBJECT a => OBJECT (Maybe a) where
|
||||
toObject (Just a) = toObject a
|
||||
toObject Nothing = ObjectNil
|
||||
|
||||
fromObject ObjectNil = return Nothing
|
||||
fromObject obj = liftM Just $ fromObject obj
|
||||
|
||||
-- | Pack a serializable Haskell value.
|
||||
pack :: OBJECT a => Packer -> a -> IO ()
|
||||
pack pc = packObject pc . toObject
|
106
haskell/src/Data/MessagePack/Derive.hs
Normal file
106
haskell/src/Data/MessagePack/Derive.hs
Normal file
@@ -0,0 +1,106 @@
|
||||
{-# Language TemplateHaskell #-}
|
||||
|
||||
module Data.MessagePack.Derive (
|
||||
derivePack,
|
||||
deriveUnpack,
|
||||
deriveObject,
|
||||
) where
|
||||
|
||||
import Control.Applicative
|
||||
import Control.Monad
|
||||
import Language.Haskell.TH
|
||||
|
||||
import Data.MessagePack.Pack
|
||||
import Data.MessagePack.Unpack
|
||||
import Data.MessagePack.Object
|
||||
|
||||
deriveUnpack :: Name -> Q [Dec]
|
||||
deriveUnpack typName = do
|
||||
TyConI (DataD _ name _ cons _) <- reify typName
|
||||
|
||||
return
|
||||
[ InstanceD [] (AppT (ConT ''Unpackable) (ConT name))
|
||||
[ FunD 'get [Clause [] (NormalB $ ch $ map body cons) []]
|
||||
]]
|
||||
|
||||
where
|
||||
body (NormalC conName elms) =
|
||||
DoE $
|
||||
tupOrListP (map VarP names) (VarE 'get) ++
|
||||
[ NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ]
|
||||
where
|
||||
names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms
|
||||
|
||||
body (RecC conName elms) =
|
||||
body (NormalC conName $ map (\(_, b, c) -> (b, c)) elms)
|
||||
|
||||
ch = foldl1 (\e f -> AppE (AppE (VarE '(<|>)) e) f)
|
||||
|
||||
derivePack :: Name -> Q [Dec]
|
||||
derivePack typName = do
|
||||
TyConI (DataD _ name _ cons _) <- reify typName
|
||||
|
||||
return
|
||||
[ InstanceD [] (AppT (ConT ''Packable) (ConT name))
|
||||
[ FunD 'put (map body cons)
|
||||
]]
|
||||
|
||||
where
|
||||
body (NormalC conName elms) =
|
||||
Clause
|
||||
[ ConP conName $ map VarP names ]
|
||||
(NormalB $ AppE (VarE 'put) $ tupOrListE $ map VarE names) []
|
||||
where
|
||||
names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms
|
||||
|
||||
body (RecC conName elms) =
|
||||
body (NormalC conName $ map (\(_, b, c) -> (b, c)) elms)
|
||||
|
||||
deriveObject :: Name -> Q [Dec]
|
||||
deriveObject typName = do
|
||||
g <- derivePack typName
|
||||
p <- deriveUnpack typName
|
||||
|
||||
TyConI (DataD _ name _ cons _) <- reify typName
|
||||
let o = InstanceD [] (AppT (ConT ''OBJECT) (ConT name))
|
||||
[ FunD 'toObject (map toObjectBody cons),
|
||||
FunD 'tryFromObject [Clause [ VarP oname ]
|
||||
(NormalB $ ch $ map tryFromObjectBody cons) []]]
|
||||
|
||||
return $ g ++ p ++ [o]
|
||||
where
|
||||
toObjectBody (NormalC conName elms) =
|
||||
Clause
|
||||
[ ConP conName $ map VarP names ]
|
||||
(NormalB $ AppE (VarE 'toObject) $ tupOrListE $ map VarE names) []
|
||||
where
|
||||
names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms
|
||||
toObjectBody (RecC conName elms) =
|
||||
toObjectBody (NormalC conName $ map (\(_, b, c) -> (b, c)) elms)
|
||||
|
||||
tryFromObjectBody (NormalC conName elms) =
|
||||
DoE $
|
||||
tupOrListP (map VarP names) (AppE (VarE 'tryFromObject) (VarE oname)) ++
|
||||
[ NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ]
|
||||
where
|
||||
names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms
|
||||
tryFromObjectBody (RecC conName elms) =
|
||||
tryFromObjectBody (NormalC conName $ map (\(_, b, c) -> (b, c)) elms)
|
||||
|
||||
oname = mkName "o"
|
||||
ch = foldl1 (\e f -> AppE (AppE (VarE '(<|>)) e) f)
|
||||
|
||||
tupOrListP :: [Pat] -> Exp -> [Stmt]
|
||||
tupOrListP ls e
|
||||
| length ls == 0 =
|
||||
let lsname = mkName "ls" in
|
||||
[ BindS (VarP lsname) e
|
||||
, NoBindS $ AppE (VarE 'guard) $ AppE (VarE 'null) $ SigE (VarE lsname) (AppT ListT (ConT ''())) ]
|
||||
| length ls == 1 = [ BindS (ListP ls) e ]
|
||||
| otherwise = [ BindS (TupP ls) e ]
|
||||
|
||||
tupOrListE :: [Exp] -> Exp
|
||||
tupOrListE ls
|
||||
| length ls == 0 = SigE (ListE []) (AppT ListT (ConT ''()))
|
||||
| length ls == 1 = ListE ls
|
||||
| otherwise = TupE ls
|
@@ -1,62 +0,0 @@
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Feed
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- Feeders for Stream Deserializers
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Feed(
|
||||
-- * Feeder type
|
||||
Feeder,
|
||||
-- * Feeders
|
||||
feederFromHandle,
|
||||
feederFromFile,
|
||||
feederFromString,
|
||||
) where
|
||||
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString as BS
|
||||
import Data.IORef
|
||||
import System.IO
|
||||
|
||||
-- | Feeder returns Just ByteString when bytes remains, otherwise Nothing.
|
||||
type Feeder = IO (Maybe ByteString)
|
||||
|
||||
-- | Feeder from Handle
|
||||
feederFromHandle :: Handle -> IO Feeder
|
||||
feederFromHandle h = return $ do
|
||||
bs <- BS.hGetNonBlocking h bufSize
|
||||
if BS.length bs > 0
|
||||
then do return $ Just bs
|
||||
else do
|
||||
c <- BS.hGet h 1
|
||||
if BS.length c > 0
|
||||
then do return $ Just c
|
||||
else do
|
||||
hClose h
|
||||
return Nothing
|
||||
where
|
||||
bufSize = 4096
|
||||
|
||||
-- | Feeder from File
|
||||
feederFromFile :: FilePath -> IO Feeder
|
||||
feederFromFile path =
|
||||
openFile path ReadMode >>= feederFromHandle
|
||||
|
||||
-- | Feeder from ByteString
|
||||
feederFromString :: ByteString -> IO Feeder
|
||||
feederFromString bs = do
|
||||
r <- newIORef (Just bs)
|
||||
return $ f r
|
||||
where
|
||||
f r = do
|
||||
mb <- readIORef r
|
||||
writeIORef r Nothing
|
||||
return mb
|
28
haskell/src/Data/MessagePack/Internal/Utf8.hs
Normal file
28
haskell/src/Data/MessagePack/Internal/Utf8.hs
Normal file
@@ -0,0 +1,28 @@
|
||||
module Data.MessagePack.Internal.Utf8 (
|
||||
encodeUtf8,
|
||||
decodeUtf8,
|
||||
skipChar,
|
||||
toLBS,
|
||||
fromLBS,
|
||||
) where
|
||||
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Lazy as BL
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as T
|
||||
import qualified Data.Text.Encoding.Error as T
|
||||
|
||||
encodeUtf8 :: String -> B.ByteString
|
||||
encodeUtf8 = T.encodeUtf8 . T.pack
|
||||
|
||||
decodeUtf8 :: B.ByteString -> String
|
||||
decodeUtf8 = T.unpack . T.decodeUtf8With skipChar
|
||||
|
||||
skipChar :: T.OnDecodeError
|
||||
skipChar _ _ = Nothing
|
||||
|
||||
toLBS :: B.ByteString -> BL.ByteString
|
||||
toLBS bs = BL.fromChunks [bs]
|
||||
|
||||
fromLBS :: BL.ByteString -> B.ByteString
|
||||
fromLBS = B.concat . BL.toChunks
|
@@ -1,156 +0,0 @@
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Monad
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- Monadic Stream Serializers and Deserializers
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Monad(
|
||||
-- * Classes
|
||||
MonadPacker(..),
|
||||
MonadUnpacker(..),
|
||||
|
||||
-- * Packer and Unpacker type
|
||||
PackerT(..),
|
||||
UnpackerT(..),
|
||||
|
||||
-- * Packers
|
||||
packToString,
|
||||
packToHandle,
|
||||
packToFile,
|
||||
|
||||
-- * Unpackers
|
||||
unpackFrom,
|
||||
unpackFromString,
|
||||
unpackFromHandle,
|
||||
unpackFromFile,
|
||||
) where
|
||||
|
||||
import Control.Monad
|
||||
import Control.Monad.Trans
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString as BS
|
||||
import System.IO
|
||||
|
||||
import Data.MessagePack.Base hiding (Unpacker)
|
||||
import qualified Data.MessagePack.Base as Base
|
||||
import Data.MessagePack.Class
|
||||
import Data.MessagePack.Feed
|
||||
|
||||
class Monad m => MonadPacker m where
|
||||
-- | Serialize a object
|
||||
put :: OBJECT a => a -> m ()
|
||||
|
||||
class Monad m => MonadUnpacker m where
|
||||
-- | Deserialize a object
|
||||
get :: OBJECT a => m a
|
||||
|
||||
-- | Serializer Type
|
||||
newtype PackerT m r = PackerT { runPackerT :: Base.Packer -> m r }
|
||||
|
||||
instance Monad m => Monad (PackerT m) where
|
||||
a >>= b =
|
||||
PackerT $ \pc -> do
|
||||
r <- runPackerT a pc
|
||||
runPackerT (b r) pc
|
||||
|
||||
return r =
|
||||
PackerT $ \_ -> return r
|
||||
|
||||
instance MonadTrans PackerT where
|
||||
lift m = PackerT $ \_ -> m
|
||||
|
||||
instance MonadIO m => MonadIO (PackerT m) where
|
||||
liftIO = lift . liftIO
|
||||
|
||||
instance MonadIO m => MonadPacker (PackerT m) where
|
||||
put v = PackerT $ \pc -> liftIO $ do
|
||||
pack pc v
|
||||
|
||||
-- | Execute given serializer and returns byte sequence.
|
||||
packToString :: MonadIO m => PackerT m r -> m ByteString
|
||||
packToString m = do
|
||||
sb <- liftIO $ newSimpleBuffer
|
||||
pc <- liftIO $ newPacker sb
|
||||
_ <- runPackerT m pc
|
||||
liftIO $ simpleBufferData sb
|
||||
|
||||
-- | Execute given serializer and write byte sequence to Handle.
|
||||
packToHandle :: MonadIO m => Handle -> PackerT m r -> m ()
|
||||
packToHandle h m = do
|
||||
sb <- packToString m
|
||||
liftIO $ BS.hPut h sb
|
||||
liftIO $ hFlush h
|
||||
|
||||
-- | Execute given serializer and write byte sequence to file.
|
||||
packToFile :: MonadIO m => FilePath -> PackerT m r -> m ()
|
||||
packToFile p m = do
|
||||
sb <- packToString m
|
||||
liftIO $ BS.writeFile p sb
|
||||
|
||||
-- | Deserializer type
|
||||
newtype UnpackerT m r = UnpackerT { runUnpackerT :: Base.Unpacker -> Feeder -> m r }
|
||||
|
||||
instance Monad m => Monad (UnpackerT m) where
|
||||
a >>= b =
|
||||
UnpackerT $ \up feed -> do
|
||||
r <- runUnpackerT a up feed
|
||||
runUnpackerT (b r) up feed
|
||||
|
||||
return r =
|
||||
UnpackerT $ \_ _ -> return r
|
||||
|
||||
instance MonadTrans UnpackerT where
|
||||
lift m = UnpackerT $ \_ _ -> m
|
||||
|
||||
instance MonadIO m => MonadIO (UnpackerT m) where
|
||||
liftIO = lift . liftIO
|
||||
|
||||
instance MonadIO m => MonadUnpacker (UnpackerT m) where
|
||||
get = UnpackerT $ \up feed -> liftIO $ do
|
||||
executeOne up feed
|
||||
obj <- unpackerData up
|
||||
freeZone =<< unpackerReleaseZone up
|
||||
unpackerReset up
|
||||
let Right r = fromObject obj
|
||||
return r
|
||||
|
||||
where
|
||||
executeOne up feed = do
|
||||
resp <- unpackerExecute up
|
||||
guard $ resp>=0
|
||||
when (resp==0) $ do
|
||||
Just bs <- feed
|
||||
unpackerFeed up bs
|
||||
executeOne up feed
|
||||
|
||||
-- | Execute deserializer using given feeder.
|
||||
unpackFrom :: MonadIO m => Feeder -> UnpackerT m r -> m r
|
||||
unpackFrom f m = do
|
||||
up <- liftIO $ newUnpacker defaultInitialBufferSize
|
||||
runUnpackerT m up f
|
||||
|
||||
-- | Execute deserializer using given handle.
|
||||
unpackFromHandle :: MonadIO m => Handle -> UnpackerT m r -> m r
|
||||
unpackFromHandle h m =
|
||||
flip unpackFrom m =<< liftIO (feederFromHandle h)
|
||||
|
||||
-- | Execute deserializer using given file content.
|
||||
unpackFromFile :: MonadIO m => FilePath -> UnpackerT m r -> m r
|
||||
unpackFromFile p m = do
|
||||
h <- liftIO $ openFile p ReadMode
|
||||
r <- flip unpackFrom m =<< liftIO (feederFromHandle h)
|
||||
liftIO $ hClose h
|
||||
return r
|
||||
|
||||
-- | Execute deserializer from given byte sequence.
|
||||
unpackFromString :: MonadIO m => ByteString -> UnpackerT m r -> m r
|
||||
unpackFromString bs m = do
|
||||
flip unpackFrom m =<< liftIO (feederFromString bs)
|
334
haskell/src/Data/MessagePack/Object.hs
Normal file
334
haskell/src/Data/MessagePack/Object.hs
Normal file
@@ -0,0 +1,334 @@
|
||||
{-# Language TypeSynonymInstances #-}
|
||||
{-# Language FlexibleInstances #-}
|
||||
{-# Language IncoherentInstances #-}
|
||||
{-# Language DeriveDataTypeable #-}
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Object
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009-2010
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- MessagePack object definition
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Object(
|
||||
-- * MessagePack Object
|
||||
Object(..),
|
||||
|
||||
-- * Serialization to and from Object
|
||||
OBJECT(..),
|
||||
-- Result,
|
||||
) where
|
||||
|
||||
import Control.DeepSeq
|
||||
import Control.Exception
|
||||
import Control.Monad
|
||||
import Control.Monad.Trans.Error ()
|
||||
import qualified Data.Attoparsec as A
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Lazy as BL
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as T
|
||||
import qualified Data.Text.Lazy as TL
|
||||
import qualified Data.Text.Lazy.Encoding as TL
|
||||
import Data.Typeable
|
||||
|
||||
import Data.MessagePack.Assoc
|
||||
import Data.MessagePack.Pack
|
||||
import Data.MessagePack.Unpack
|
||||
import Data.MessagePack.Internal.Utf8
|
||||
|
||||
-- | Object Representation of MessagePack data.
|
||||
data Object
|
||||
= ObjectNil
|
||||
| ObjectBool Bool
|
||||
| ObjectInteger Int
|
||||
| ObjectFloat Float
|
||||
| ObjectDouble Double
|
||||
| ObjectRAW B.ByteString
|
||||
| ObjectArray [Object]
|
||||
| ObjectMap [(Object, Object)]
|
||||
deriving (Show, Eq, Ord, Typeable)
|
||||
|
||||
|
||||
instance NFData Object where
|
||||
rnf obj =
|
||||
case obj of
|
||||
ObjectNil -> ()
|
||||
ObjectBool b -> rnf b
|
||||
ObjectInteger n -> rnf n
|
||||
ObjectFloat f -> rnf f
|
||||
ObjectDouble d -> rnf d
|
||||
ObjectRAW bs -> bs `seq` ()
|
||||
ObjectArray a -> rnf a
|
||||
ObjectMap m -> rnf m
|
||||
|
||||
|
||||
instance Unpackable Object where
|
||||
get =
|
||||
A.choice
|
||||
[ liftM ObjectInteger get
|
||||
, liftM (\() -> ObjectNil) get
|
||||
, liftM ObjectBool get
|
||||
, liftM ObjectFloat get
|
||||
, liftM ObjectDouble get
|
||||
, liftM ObjectRAW get
|
||||
, liftM ObjectArray get
|
||||
, liftM (ObjectMap . unAssoc) get
|
||||
]
|
||||
|
||||
instance Packable Object where
|
||||
put obj =
|
||||
case obj of
|
||||
ObjectInteger n ->
|
||||
put n
|
||||
ObjectNil ->
|
||||
put ()
|
||||
ObjectBool b ->
|
||||
put b
|
||||
ObjectFloat f ->
|
||||
put f
|
||||
ObjectDouble d ->
|
||||
put d
|
||||
ObjectRAW raw ->
|
||||
put raw
|
||||
ObjectArray arr ->
|
||||
put arr
|
||||
ObjectMap m ->
|
||||
put $ Assoc m
|
||||
|
||||
-- | The class of types serializable to and from MessagePack object
|
||||
class (Unpackable a, Packable a) => OBJECT a where
|
||||
-- | Encode a value to MessagePack object
|
||||
toObject :: a -> Object
|
||||
toObject = unpack . pack
|
||||
|
||||
-- | Decode a value from MessagePack object
|
||||
fromObject :: Object -> a
|
||||
fromObject a =
|
||||
case tryFromObject a of
|
||||
Left err ->
|
||||
throw $ UnpackError err
|
||||
Right ret ->
|
||||
ret
|
||||
|
||||
-- | Decode a value from MessagePack object
|
||||
tryFromObject :: Object -> Either String a
|
||||
tryFromObject = tryUnpack . pack
|
||||
|
||||
instance OBJECT Object where
|
||||
toObject = id
|
||||
tryFromObject = Right
|
||||
|
||||
tryFromObjectError :: Either String a
|
||||
tryFromObjectError = Left "tryFromObject: cannot cast"
|
||||
|
||||
instance OBJECT () where
|
||||
toObject = const ObjectNil
|
||||
tryFromObject ObjectNil = Right ()
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT Int where
|
||||
toObject = ObjectInteger
|
||||
tryFromObject (ObjectInteger n) = Right n
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT Bool where
|
||||
toObject = ObjectBool
|
||||
tryFromObject (ObjectBool b) = Right b
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT Double where
|
||||
toObject = ObjectDouble
|
||||
tryFromObject (ObjectDouble d) = Right d
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT Float where
|
||||
toObject = ObjectFloat
|
||||
tryFromObject (ObjectFloat f) = Right f
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT String where
|
||||
toObject = toObject . encodeUtf8
|
||||
tryFromObject obj = liftM decodeUtf8 $ tryFromObject obj
|
||||
|
||||
instance OBJECT B.ByteString where
|
||||
toObject = ObjectRAW
|
||||
tryFromObject (ObjectRAW bs) = Right bs
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT BL.ByteString where
|
||||
toObject = ObjectRAW . fromLBS
|
||||
tryFromObject (ObjectRAW bs) = Right $ toLBS bs
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT T.Text where
|
||||
toObject = ObjectRAW . T.encodeUtf8
|
||||
tryFromObject (ObjectRAW bs) = Right $ T.decodeUtf8With skipChar bs
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT TL.Text where
|
||||
toObject = ObjectRAW . fromLBS . TL.encodeUtf8
|
||||
tryFromObject (ObjectRAW bs) = Right $ TL.decodeUtf8With skipChar $ toLBS bs
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT a => OBJECT [a] where
|
||||
toObject = ObjectArray . map toObject
|
||||
tryFromObject (ObjectArray arr) =
|
||||
mapM tryFromObject arr
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a1, OBJECT a2) => OBJECT (a1, a2) where
|
||||
toObject (a1, a2) = ObjectArray [toObject a1, toObject a2]
|
||||
tryFromObject (ObjectArray arr) =
|
||||
case arr of
|
||||
[o1, o2] -> do
|
||||
v1 <- tryFromObject o1
|
||||
v2 <- tryFromObject o2
|
||||
return (v1, v2)
|
||||
_ ->
|
||||
tryFromObjectError
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a1, OBJECT a2, OBJECT a3) => OBJECT (a1, a2, a3) where
|
||||
toObject (a1, a2, a3) = ObjectArray [toObject a1, toObject a2, toObject a3]
|
||||
tryFromObject (ObjectArray arr) =
|
||||
case arr of
|
||||
[o1, o2, o3] -> do
|
||||
v1 <- tryFromObject o1
|
||||
v2 <- tryFromObject o2
|
||||
v3 <- tryFromObject o3
|
||||
return (v1, v2, v3)
|
||||
_ ->
|
||||
tryFromObjectError
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4) => OBJECT (a1, a2, a3, a4) where
|
||||
toObject (a1, a2, a3, a4) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4]
|
||||
tryFromObject (ObjectArray arr) =
|
||||
case arr of
|
||||
[o1, o2, o3, o4] -> do
|
||||
v1 <- tryFromObject o1
|
||||
v2 <- tryFromObject o2
|
||||
v3 <- tryFromObject o3
|
||||
v4 <- tryFromObject o4
|
||||
return (v1, v2, v3, v4)
|
||||
_ ->
|
||||
tryFromObjectError
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5) => OBJECT (a1, a2, a3, a4, a5) where
|
||||
toObject (a1, a2, a3, a4, a5) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5]
|
||||
tryFromObject (ObjectArray arr) =
|
||||
case arr of
|
||||
[o1, o2, o3, o4, o5] -> do
|
||||
v1 <- tryFromObject o1
|
||||
v2 <- tryFromObject o2
|
||||
v3 <- tryFromObject o3
|
||||
v4 <- tryFromObject o4
|
||||
v5 <- tryFromObject o5
|
||||
return (v1, v2, v3, v4, v5)
|
||||
_ ->
|
||||
tryFromObjectError
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5, OBJECT a6) => OBJECT (a1, a2, a3, a4, a5, a6) where
|
||||
toObject (a1, a2, a3, a4, a5, a6) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5, toObject a6]
|
||||
tryFromObject (ObjectArray arr) =
|
||||
case arr of
|
||||
[o1, o2, o3, o4, o5, o6] -> do
|
||||
v1 <- tryFromObject o1
|
||||
v2 <- tryFromObject o2
|
||||
v3 <- tryFromObject o3
|
||||
v4 <- tryFromObject o4
|
||||
v5 <- tryFromObject o5
|
||||
v6 <- tryFromObject o6
|
||||
return (v1, v2, v3, v4, v5, v6)
|
||||
_ ->
|
||||
tryFromObjectError
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5, OBJECT a6, OBJECT a7) => OBJECT (a1, a2, a3, a4, a5, a6, a7) where
|
||||
toObject (a1, a2, a3, a4, a5, a6, a7) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5, toObject a6, toObject a7]
|
||||
tryFromObject (ObjectArray arr) =
|
||||
case arr of
|
||||
[o1, o2, o3, o4, o5, o6, o7] -> do
|
||||
v1 <- tryFromObject o1
|
||||
v2 <- tryFromObject o2
|
||||
v3 <- tryFromObject o3
|
||||
v4 <- tryFromObject o4
|
||||
v5 <- tryFromObject o5
|
||||
v6 <- tryFromObject o6
|
||||
v7 <- tryFromObject o7
|
||||
return (v1, v2, v3, v4, v5, v6, v7)
|
||||
_ ->
|
||||
tryFromObjectError
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5, OBJECT a6, OBJECT a7, OBJECT a8) => OBJECT (a1, a2, a3, a4, a5, a6, a7, a8) where
|
||||
toObject (a1, a2, a3, a4, a5, a6, a7, a8) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5, toObject a6, toObject a7, toObject a8]
|
||||
tryFromObject (ObjectArray arr) =
|
||||
case arr of
|
||||
[o1, o2, o3, o4, o5, o6, o7, o8] -> do
|
||||
v1 <- tryFromObject o1
|
||||
v2 <- tryFromObject o2
|
||||
v3 <- tryFromObject o3
|
||||
v4 <- tryFromObject o4
|
||||
v5 <- tryFromObject o5
|
||||
v6 <- tryFromObject o6
|
||||
v7 <- tryFromObject o7
|
||||
v8 <- tryFromObject o8
|
||||
return (v1, v2, v3, v4, v5, v6, v7, v8)
|
||||
_ ->
|
||||
tryFromObjectError
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5, OBJECT a6, OBJECT a7, OBJECT a8, OBJECT a9) => OBJECT (a1, a2, a3, a4, a5, a6, a7, a8, a9) where
|
||||
toObject (a1, a2, a3, a4, a5, a6, a7, a8, a9) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5, toObject a6, toObject a7, toObject a8, toObject a9]
|
||||
tryFromObject (ObjectArray arr) =
|
||||
case arr of
|
||||
[o1, o2, o3, o4, o5, o6, o7, o8, o9] -> do
|
||||
v1 <- tryFromObject o1
|
||||
v2 <- tryFromObject o2
|
||||
v3 <- tryFromObject o3
|
||||
v4 <- tryFromObject o4
|
||||
v5 <- tryFromObject o5
|
||||
v6 <- tryFromObject o6
|
||||
v7 <- tryFromObject o7
|
||||
v8 <- tryFromObject o8
|
||||
v9 <- tryFromObject o9
|
||||
return (v1, v2, v3, v4, v5, v6, v7, v8, v9)
|
||||
_ ->
|
||||
tryFromObjectError
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance (OBJECT a, OBJECT b) => OBJECT (Assoc [(a,b)]) where
|
||||
toObject =
|
||||
ObjectMap . map (\(a, b) -> (toObject a, toObject b)) . unAssoc
|
||||
tryFromObject (ObjectMap mem) = do
|
||||
liftM Assoc $ mapM (\(a, b) -> liftM2 (,) (tryFromObject a) (tryFromObject b)) mem
|
||||
tryFromObject _ =
|
||||
tryFromObjectError
|
||||
|
||||
instance OBJECT a => OBJECT (Maybe a) where
|
||||
toObject (Just a) = toObject a
|
||||
toObject Nothing = ObjectNil
|
||||
|
||||
tryFromObject ObjectNil = return Nothing
|
||||
tryFromObject obj = liftM Just $ tryFromObject obj
|
||||
|
204
haskell/src/Data/MessagePack/Pack.hs
Normal file
204
haskell/src/Data/MessagePack/Pack.hs
Normal file
@@ -0,0 +1,204 @@
|
||||
{-# Language FlexibleInstances #-}
|
||||
{-# Language IncoherentInstances #-}
|
||||
{-# Language TypeSynonymInstances #-}
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Pack
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009-2010
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- MessagePack Serializer using @Data.Binary.Pack@
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Pack (
|
||||
-- * Serializable class
|
||||
Packable(..),
|
||||
-- * Simple function to pack a Haskell value
|
||||
pack,
|
||||
) where
|
||||
|
||||
import Data.Binary.Put
|
||||
import Data.Binary.IEEE754
|
||||
import Data.Bits
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Lazy as BL
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as T
|
||||
import qualified Data.Text.Lazy as TL
|
||||
import qualified Data.Text.Lazy.Encoding as TL
|
||||
import qualified Data.Vector as V
|
||||
|
||||
import Data.MessagePack.Assoc
|
||||
import Data.MessagePack.Internal.Utf8
|
||||
|
||||
-- | Serializable class
|
||||
class Packable a where
|
||||
-- | Serialize a value
|
||||
put :: a -> Put
|
||||
|
||||
-- | Pack Haskell data to MessagePack string.
|
||||
pack :: Packable a => a -> BL.ByteString
|
||||
pack = runPut . put
|
||||
|
||||
instance Packable Int where
|
||||
put n =
|
||||
case n of
|
||||
_ | n >= 0 && n <= 127 ->
|
||||
putWord8 $ fromIntegral n
|
||||
_ | n >= -32 && n <= -1 ->
|
||||
putWord8 $ fromIntegral n
|
||||
_ | n >= 0 && n < 0x100 -> do
|
||||
putWord8 0xCC
|
||||
putWord8 $ fromIntegral n
|
||||
_ | n >= 0 && n < 0x10000 -> do
|
||||
putWord8 0xCD
|
||||
putWord16be $ fromIntegral n
|
||||
_ | n >= 0 && n < 0x100000000 -> do
|
||||
putWord8 0xCE
|
||||
putWord32be $ fromIntegral n
|
||||
_ | n >= 0 -> do
|
||||
putWord8 0xCF
|
||||
putWord64be $ fromIntegral n
|
||||
_ | n >= -0x80 -> do
|
||||
putWord8 0xD0
|
||||
putWord8 $ fromIntegral n
|
||||
_ | n >= -0x8000 -> do
|
||||
putWord8 0xD1
|
||||
putWord16be $ fromIntegral n
|
||||
_ | n >= -0x80000000 -> do
|
||||
putWord8 0xD2
|
||||
putWord32be $ fromIntegral n
|
||||
_ -> do
|
||||
putWord8 0xD3
|
||||
putWord64be $ fromIntegral n
|
||||
|
||||
instance Packable () where
|
||||
put _ =
|
||||
putWord8 0xC0
|
||||
|
||||
instance Packable Bool where
|
||||
put True = putWord8 0xC3
|
||||
put False = putWord8 0xC2
|
||||
|
||||
instance Packable Float where
|
||||
put f = do
|
||||
putWord8 0xCA
|
||||
putFloat32be f
|
||||
|
||||
instance Packable Double where
|
||||
put d = do
|
||||
putWord8 0xCB
|
||||
putFloat64be d
|
||||
|
||||
instance Packable String where
|
||||
put = putString encodeUtf8 B.length putByteString
|
||||
|
||||
instance Packable B.ByteString where
|
||||
put = putString id B.length putByteString
|
||||
|
||||
instance Packable BL.ByteString where
|
||||
put = putString id (fromIntegral . BL.length) putLazyByteString
|
||||
|
||||
instance Packable T.Text where
|
||||
put = putString T.encodeUtf8 B.length putByteString
|
||||
|
||||
instance Packable TL.Text where
|
||||
put = putString TL.encodeUtf8 (fromIntegral . BL.length) putLazyByteString
|
||||
|
||||
putString :: (s -> t) -> (t -> Int) -> (t -> Put) -> s -> Put
|
||||
putString cnv lf pf str = do
|
||||
let bs = cnv str
|
||||
case lf bs of
|
||||
len | len <= 31 -> do
|
||||
putWord8 $ 0xA0 .|. fromIntegral len
|
||||
len | len < 0x10000 -> do
|
||||
putWord8 0xDA
|
||||
putWord16be $ fromIntegral len
|
||||
len -> do
|
||||
putWord8 0xDB
|
||||
putWord32be $ fromIntegral len
|
||||
pf bs
|
||||
|
||||
instance Packable a => Packable [a] where
|
||||
put = putArray length (mapM_ put)
|
||||
|
||||
instance Packable a => Packable (V.Vector a) where
|
||||
put = putArray V.length (V.mapM_ put)
|
||||
|
||||
instance (Packable a1, Packable a2) => Packable (a1, a2) where
|
||||
put = putArray (const 2) f where
|
||||
f (a1, a2) = put a1 >> put a2
|
||||
|
||||
instance (Packable a1, Packable a2, Packable a3) => Packable (a1, a2, a3) where
|
||||
put = putArray (const 3) f where
|
||||
f (a1, a2, a3) = put a1 >> put a2 >> put a3
|
||||
|
||||
instance (Packable a1, Packable a2, Packable a3, Packable a4) => Packable (a1, a2, a3, a4) where
|
||||
put = putArray (const 4) f where
|
||||
f (a1, a2, a3, a4) = put a1 >> put a2 >> put a3 >> put a4
|
||||
|
||||
instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5) => Packable (a1, a2, a3, a4, a5) where
|
||||
put = putArray (const 5) f where
|
||||
f (a1, a2, a3, a4, a5) = put a1 >> put a2 >> put a3 >> put a4 >> put a5
|
||||
|
||||
instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5, Packable a6) => Packable (a1, a2, a3, a4, a5, a6) where
|
||||
put = putArray (const 6) f where
|
||||
f (a1, a2, a3, a4, a5, a6) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6
|
||||
|
||||
instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5, Packable a6, Packable a7) => Packable (a1, a2, a3, a4, a5, a6, a7) where
|
||||
put = putArray (const 7) f where
|
||||
f (a1, a2, a3, a4, a5, a6, a7) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7
|
||||
|
||||
instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5, Packable a6, Packable a7, Packable a8) => Packable (a1, a2, a3, a4, a5, a6, a7, a8) where
|
||||
put = putArray (const 8) f where
|
||||
f (a1, a2, a3, a4, a5, a6, a7, a8) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7 >> put a8
|
||||
|
||||
instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5, Packable a6, Packable a7, Packable a8, Packable a9) => Packable (a1, a2, a3, a4, a5, a6, a7, a8, a9) where
|
||||
put = putArray (const 9) f where
|
||||
f (a1, a2, a3, a4, a5, a6, a7, a8, a9) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7 >> put a8 >> put a9
|
||||
|
||||
putArray :: (a -> Int) -> (a -> Put) -> a -> Put
|
||||
putArray lf pf arr = do
|
||||
case lf arr of
|
||||
len | len <= 15 ->
|
||||
putWord8 $ 0x90 .|. fromIntegral len
|
||||
len | len < 0x10000 -> do
|
||||
putWord8 0xDC
|
||||
putWord16be $ fromIntegral len
|
||||
len -> do
|
||||
putWord8 0xDD
|
||||
putWord32be $ fromIntegral len
|
||||
pf arr
|
||||
|
||||
instance (Packable k, Packable v) => Packable (Assoc [(k,v)]) where
|
||||
put = putMap length (mapM_ putPair) . unAssoc
|
||||
|
||||
instance (Packable k, Packable v) => Packable (Assoc (V.Vector (k,v))) where
|
||||
put = putMap V.length (V.mapM_ putPair) . unAssoc
|
||||
|
||||
putPair :: (Packable a, Packable b) => (a, b) -> Put
|
||||
putPair (a, b) = put a >> put b
|
||||
|
||||
putMap :: (a -> Int) -> (a -> Put) -> a -> Put
|
||||
putMap lf pf m = do
|
||||
case lf m of
|
||||
len | len <= 15 ->
|
||||
putWord8 $ 0x80 .|. fromIntegral len
|
||||
len | len < 0x10000 -> do
|
||||
putWord8 0xDE
|
||||
putWord16be $ fromIntegral len
|
||||
len -> do
|
||||
putWord8 0xDF
|
||||
putWord32be $ fromIntegral len
|
||||
pf m
|
||||
|
||||
instance Packable a => Packable (Maybe a) where
|
||||
put Nothing = put ()
|
||||
put (Just a) = put a
|
||||
|
@@ -1,82 +0,0 @@
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Stream
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- Lazy Stream Serializers and Deserializers
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Stream(
|
||||
unpackObjects,
|
||||
unpackObjectsFromFile,
|
||||
unpackObjectsFromHandle,
|
||||
unpackObjectsFromString,
|
||||
) where
|
||||
|
||||
import Data.ByteString (ByteString)
|
||||
import System.IO
|
||||
import System.IO.Unsafe
|
||||
|
||||
import Data.MessagePack.Base
|
||||
import Data.MessagePack.Feed
|
||||
|
||||
-- | Unpack objects using given feeder.
|
||||
unpackObjects :: Feeder -> IO [Object]
|
||||
unpackObjects feeder = do
|
||||
up <- newUnpacker defaultInitialBufferSize
|
||||
f up
|
||||
where
|
||||
f up = unsafeInterleaveIO $ do
|
||||
mbo <- unpackOnce up
|
||||
case mbo of
|
||||
Just o -> do
|
||||
os <- f up
|
||||
return $ o:os
|
||||
Nothing ->
|
||||
return []
|
||||
|
||||
unpackOnce up = do
|
||||
resp <- unpackerExecute up
|
||||
case resp of
|
||||
0 -> do
|
||||
r <- feedOnce up
|
||||
if r
|
||||
then unpackOnce up
|
||||
else return Nothing
|
||||
1 -> do
|
||||
obj <- unpackerData up
|
||||
freeZone =<< unpackerReleaseZone up
|
||||
unpackerReset up
|
||||
return $ Just obj
|
||||
_ ->
|
||||
error $ "unpackerExecute fails: " ++ show resp
|
||||
|
||||
feedOnce up = do
|
||||
dat <- feeder
|
||||
case dat of
|
||||
Nothing ->
|
||||
return False
|
||||
Just bs -> do
|
||||
unpackerFeed up bs
|
||||
return True
|
||||
|
||||
-- | Unpack objects from file.
|
||||
unpackObjectsFromFile :: FilePath -> IO [Object]
|
||||
unpackObjectsFromFile fname =
|
||||
unpackObjects =<< feederFromFile fname
|
||||
|
||||
-- | Unpack objects from handle.
|
||||
unpackObjectsFromHandle :: Handle -> IO [Object]
|
||||
unpackObjectsFromHandle h =
|
||||
unpackObjects =<< feederFromHandle h
|
||||
|
||||
-- | Unpack oobjects from given byte sequence.
|
||||
unpackObjectsFromString :: ByteString -> IO [Object]
|
||||
unpackObjectsFromString bs =
|
||||
unpackObjects =<< feederFromString bs
|
323
haskell/src/Data/MessagePack/Unpack.hs
Normal file
323
haskell/src/Data/MessagePack/Unpack.hs
Normal file
@@ -0,0 +1,323 @@
|
||||
{-# Language FlexibleInstances #-}
|
||||
{-# Language IncoherentInstances #-}
|
||||
{-# Language TypeSynonymInstances #-}
|
||||
{-# Language DeriveDataTypeable #-}
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Unpack
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009-2010
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- MessagePack Deserializer using @Data.Attoparsec@
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Unpack(
|
||||
-- * MessagePack deserializer
|
||||
Unpackable(..),
|
||||
-- * Simple function to unpack a Haskell value
|
||||
unpack,
|
||||
tryUnpack,
|
||||
-- * Unpack exception
|
||||
UnpackError(..),
|
||||
-- * ByteString utils
|
||||
IsByteString(..),
|
||||
) where
|
||||
|
||||
import Control.Exception
|
||||
import Control.Monad
|
||||
import qualified Data.Attoparsec as A
|
||||
import Data.Binary.Get
|
||||
import Data.Binary.IEEE754
|
||||
import Data.Bits
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Lazy as BL
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as T
|
||||
import qualified Data.Text.Lazy as TL
|
||||
import qualified Data.Text.Lazy.Encoding as TL
|
||||
import Data.Int
|
||||
import Data.Typeable
|
||||
import qualified Data.Vector as V
|
||||
import Data.Word
|
||||
import Text.Printf
|
||||
|
||||
import Data.MessagePack.Assoc
|
||||
import Data.MessagePack.Internal.Utf8
|
||||
|
||||
-- | Deserializable class
|
||||
class Unpackable a where
|
||||
-- | Deserialize a value
|
||||
get :: A.Parser a
|
||||
|
||||
class IsByteString s where
|
||||
toBS :: s -> B.ByteString
|
||||
|
||||
instance IsByteString B.ByteString where
|
||||
toBS = id
|
||||
|
||||
instance IsByteString BL.ByteString where
|
||||
toBS = B.concat . BL.toChunks
|
||||
|
||||
-- | The exception of unpack
|
||||
data UnpackError =
|
||||
UnpackError String
|
||||
deriving (Show, Typeable)
|
||||
|
||||
instance Exception UnpackError
|
||||
|
||||
-- | Unpack MessagePack string to Haskell data.
|
||||
unpack :: (Unpackable a, IsByteString s) => s -> a
|
||||
unpack bs =
|
||||
case tryUnpack bs of
|
||||
Left err ->
|
||||
throw $ UnpackError err
|
||||
Right ret ->
|
||||
ret
|
||||
|
||||
-- | Unpack MessagePack string to Haskell data.
|
||||
tryUnpack :: (Unpackable a, IsByteString s) => s -> Either String a
|
||||
tryUnpack bs =
|
||||
case A.parse get (toBS bs) of
|
||||
A.Fail _ _ err ->
|
||||
Left err
|
||||
A.Partial _ ->
|
||||
Left "not enough input"
|
||||
A.Done _ ret ->
|
||||
Right ret
|
||||
|
||||
instance Unpackable Int where
|
||||
get = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
_ | c .&. 0x80 == 0x00 ->
|
||||
return $ fromIntegral c
|
||||
_ | c .&. 0xE0 == 0xE0 ->
|
||||
return $ fromIntegral (fromIntegral c :: Int8)
|
||||
0xCC ->
|
||||
return . fromIntegral =<< A.anyWord8
|
||||
0xCD ->
|
||||
return . fromIntegral =<< parseUint16
|
||||
0xCE ->
|
||||
return . fromIntegral =<< parseUint32
|
||||
0xCF ->
|
||||
return . fromIntegral =<< parseUint64
|
||||
0xD0 ->
|
||||
return . fromIntegral =<< parseInt8
|
||||
0xD1 ->
|
||||
return . fromIntegral =<< parseInt16
|
||||
0xD2 ->
|
||||
return . fromIntegral =<< parseInt32
|
||||
0xD3 ->
|
||||
return . fromIntegral =<< parseInt64
|
||||
_ ->
|
||||
fail $ printf "invlid integer tag: 0x%02X" c
|
||||
|
||||
instance Unpackable () where
|
||||
get = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
0xC0 ->
|
||||
return ()
|
||||
_ ->
|
||||
fail $ printf "invlid nil tag: 0x%02X" c
|
||||
|
||||
instance Unpackable Bool where
|
||||
get = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
0xC3 ->
|
||||
return True
|
||||
0xC2 ->
|
||||
return False
|
||||
_ ->
|
||||
fail $ printf "invlid bool tag: 0x%02X" c
|
||||
|
||||
instance Unpackable Float where
|
||||
get = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
0xCA ->
|
||||
return . runGet getFloat32be . toLBS =<< A.take 4
|
||||
_ ->
|
||||
fail $ printf "invlid float tag: 0x%02X" c
|
||||
|
||||
instance Unpackable Double where
|
||||
get = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
0xCB ->
|
||||
return . runGet getFloat64be . toLBS =<< A.take 8
|
||||
_ ->
|
||||
fail $ printf "invlid double tag: 0x%02X" c
|
||||
|
||||
instance Unpackable String where
|
||||
get = parseString (\n -> return . decodeUtf8 =<< A.take n)
|
||||
|
||||
instance Unpackable B.ByteString where
|
||||
get = parseString A.take
|
||||
|
||||
instance Unpackable BL.ByteString where
|
||||
get = parseString (\n -> return . toLBS =<< A.take n)
|
||||
|
||||
instance Unpackable T.Text where
|
||||
get = parseString (\n -> return . T.decodeUtf8With skipChar =<< A.take n)
|
||||
|
||||
instance Unpackable TL.Text where
|
||||
get = parseString (\n -> return . TL.decodeUtf8With skipChar . toLBS =<< A.take n)
|
||||
|
||||
parseString :: (Int -> A.Parser a) -> A.Parser a
|
||||
parseString aget = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
_ | c .&. 0xE0 == 0xA0 ->
|
||||
aget . fromIntegral $ c .&. 0x1F
|
||||
0xDA ->
|
||||
aget . fromIntegral =<< parseUint16
|
||||
0xDB ->
|
||||
aget . fromIntegral =<< parseUint32
|
||||
_ ->
|
||||
fail $ printf "invlid raw tag: 0x%02X" c
|
||||
|
||||
instance Unpackable a => Unpackable [a] where
|
||||
get = parseArray (flip replicateM get)
|
||||
|
||||
instance Unpackable a => Unpackable (V.Vector a) where
|
||||
get = parseArray (flip V.replicateM get)
|
||||
|
||||
instance (Unpackable a1, Unpackable a2) => Unpackable (a1, a2) where
|
||||
get = parseArray f where
|
||||
f 2 = get >>= \a1 -> get >>= \a2 -> return (a1, a2)
|
||||
f n = fail $ printf "wrong tupple size: expected 2 but got " n
|
||||
|
||||
instance (Unpackable a1, Unpackable a2, Unpackable a3) => Unpackable (a1, a2, a3) where
|
||||
get = parseArray f where
|
||||
f 3 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> return (a1, a2, a3)
|
||||
f n = fail $ printf "wrong tupple size: expected 3 but got " n
|
||||
|
||||
instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4) => Unpackable (a1, a2, a3, a4) where
|
||||
get = parseArray f where
|
||||
f 4 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> return (a1, a2, a3, a4)
|
||||
f n = fail $ printf "wrong tupple size: expected 4 but got " n
|
||||
|
||||
instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5) => Unpackable (a1, a2, a3, a4, a5) where
|
||||
get = parseArray f where
|
||||
f 5 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> return (a1, a2, a3, a4, a5)
|
||||
f n = fail $ printf "wrong tupple size: expected 5 but got " n
|
||||
|
||||
instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5, Unpackable a6) => Unpackable (a1, a2, a3, a4, a5, a6) where
|
||||
get = parseArray f where
|
||||
f 6 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> return (a1, a2, a3, a4, a5, a6)
|
||||
f n = fail $ printf "wrong tupple size: expected 6 but got " n
|
||||
|
||||
instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5, Unpackable a6, Unpackable a7) => Unpackable (a1, a2, a3, a4, a5, a6, a7) where
|
||||
get = parseArray f where
|
||||
f 7 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> return (a1, a2, a3, a4, a5, a6, a7)
|
||||
f n = fail $ printf "wrong tupple size: expected 7 but got " n
|
||||
|
||||
instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5, Unpackable a6, Unpackable a7, Unpackable a8) => Unpackable (a1, a2, a3, a4, a5, a6, a7, a8) where
|
||||
get = parseArray f where
|
||||
f 8 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> get >>= \a8 -> return (a1, a2, a3, a4, a5, a6, a7, a8)
|
||||
f n = fail $ printf "wrong tupple size: expected 8 but got " n
|
||||
|
||||
instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5, Unpackable a6, Unpackable a7, Unpackable a8, Unpackable a9) => Unpackable (a1, a2, a3, a4, a5, a6, a7, a8, a9) where
|
||||
get = parseArray f where
|
||||
f 9 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> get >>= \a8 -> get >>= \a9 -> return (a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
f n = fail $ printf "wrong tupple size: expected 9 but got " n
|
||||
|
||||
parseArray :: (Int -> A.Parser a) -> A.Parser a
|
||||
parseArray aget = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
_ | c .&. 0xF0 == 0x90 ->
|
||||
aget . fromIntegral $ c .&. 0x0F
|
||||
0xDC ->
|
||||
aget . fromIntegral =<< parseUint16
|
||||
0xDD ->
|
||||
aget . fromIntegral =<< parseUint32
|
||||
_ ->
|
||||
fail $ printf "invlid array tag: 0x%02X" c
|
||||
|
||||
instance (Unpackable k, Unpackable v) => Unpackable (Assoc [(k,v)]) where
|
||||
get = liftM Assoc $ parseMap (flip replicateM parsePair)
|
||||
|
||||
instance (Unpackable k, Unpackable v) => Unpackable (Assoc (V.Vector (k, v))) where
|
||||
get = liftM Assoc $ parseMap (flip V.replicateM parsePair)
|
||||
|
||||
parsePair :: (Unpackable k, Unpackable v) => A.Parser (k, v)
|
||||
parsePair = do
|
||||
a <- get
|
||||
b <- get
|
||||
return (a, b)
|
||||
|
||||
parseMap :: (Int -> A.Parser a) -> A.Parser a
|
||||
parseMap aget = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
_ | c .&. 0xF0 == 0x80 ->
|
||||
aget . fromIntegral $ c .&. 0x0F
|
||||
0xDE ->
|
||||
aget . fromIntegral =<< parseUint16
|
||||
0xDF ->
|
||||
aget . fromIntegral =<< parseUint32
|
||||
_ ->
|
||||
fail $ printf "invlid map tag: 0x%02X" c
|
||||
|
||||
instance Unpackable a => Unpackable (Maybe a) where
|
||||
get =
|
||||
A.choice
|
||||
[ liftM Just get
|
||||
, liftM (\() -> Nothing) get ]
|
||||
|
||||
parseUint16 :: A.Parser Word16
|
||||
parseUint16 = do
|
||||
b0 <- A.anyWord8
|
||||
b1 <- A.anyWord8
|
||||
return $ (fromIntegral b0 `shiftL` 8) .|. fromIntegral b1
|
||||
|
||||
parseUint32 :: A.Parser Word32
|
||||
parseUint32 = do
|
||||
b0 <- A.anyWord8
|
||||
b1 <- A.anyWord8
|
||||
b2 <- A.anyWord8
|
||||
b3 <- A.anyWord8
|
||||
return $ (fromIntegral b0 `shiftL` 24) .|.
|
||||
(fromIntegral b1 `shiftL` 16) .|.
|
||||
(fromIntegral b2 `shiftL` 8) .|.
|
||||
fromIntegral b3
|
||||
|
||||
parseUint64 :: A.Parser Word64
|
||||
parseUint64 = do
|
||||
b0 <- A.anyWord8
|
||||
b1 <- A.anyWord8
|
||||
b2 <- A.anyWord8
|
||||
b3 <- A.anyWord8
|
||||
b4 <- A.anyWord8
|
||||
b5 <- A.anyWord8
|
||||
b6 <- A.anyWord8
|
||||
b7 <- A.anyWord8
|
||||
return $ (fromIntegral b0 `shiftL` 56) .|.
|
||||
(fromIntegral b1 `shiftL` 48) .|.
|
||||
(fromIntegral b2 `shiftL` 40) .|.
|
||||
(fromIntegral b3 `shiftL` 32) .|.
|
||||
(fromIntegral b4 `shiftL` 24) .|.
|
||||
(fromIntegral b5 `shiftL` 16) .|.
|
||||
(fromIntegral b6 `shiftL` 8) .|.
|
||||
fromIntegral b7
|
||||
|
||||
parseInt8 :: A.Parser Int8
|
||||
parseInt8 = return . fromIntegral =<< A.anyWord8
|
||||
|
||||
parseInt16 :: A.Parser Int16
|
||||
parseInt16 = return . fromIntegral =<< parseUint16
|
||||
|
||||
parseInt32 :: A.Parser Int32
|
||||
parseInt32 = return . fromIntegral =<< parseUint32
|
||||
|
||||
parseInt64 :: A.Parser Int64
|
||||
parseInt64 = return . fromIntegral =<< parseUint64
|
@@ -1,16 +1,21 @@
|
||||
import Control.Monad.Trans
|
||||
{-# Language OverloadedStrings #-}
|
||||
|
||||
import Control.Monad.IO.Class
|
||||
import qualified Data.ByteString as B
|
||||
import Data.MessagePack
|
||||
|
||||
main = do
|
||||
sb <- packToString $ do
|
||||
sb <- return $ packToString $ do
|
||||
put [1,2,3::Int]
|
||||
put (3.14 :: Double)
|
||||
put "Hoge"
|
||||
put ("Hoge" :: B.ByteString)
|
||||
|
||||
print sb
|
||||
|
||||
unpackFromString sb $ do
|
||||
r <- unpackFromString sb $ do
|
||||
arr <- get
|
||||
dbl <- get
|
||||
str <- get
|
||||
liftIO $ print (arr :: [Int], dbl :: Double, str :: String)
|
||||
return (arr :: [Int], dbl :: Double, str :: B.ByteString)
|
||||
|
||||
print r
|
||||
|
@@ -1,14 +0,0 @@
|
||||
import Control.Applicative
|
||||
import qualified Data.ByteString as BS
|
||||
import Data.MessagePack
|
||||
|
||||
main = do
|
||||
sb <- newSimpleBuffer
|
||||
pc <- newPacker sb
|
||||
pack pc [1,2,3::Int]
|
||||
pack pc True
|
||||
pack pc "hoge"
|
||||
bs <- simpleBufferData sb
|
||||
|
||||
os <- unpackObjectsFromString bs
|
||||
mapM_ print os
|
@@ -1,36 +1,70 @@
|
||||
import Test.Framework
|
||||
import Test.Framework.Providers.QuickCheck2
|
||||
import Test.QuickCheck
|
||||
|
||||
import Control.Monad
|
||||
import qualified Data.ByteString.Char8 as B
|
||||
import qualified Data.ByteString.Lazy.Char8 as L
|
||||
import Data.MessagePack
|
||||
|
||||
{-
|
||||
main = do
|
||||
sb <- newSimpleBuffer
|
||||
pc <- newPacker sb
|
||||
|
||||
pack pc [(1,2),(2,3),(3::Int,4::Int)]
|
||||
pack pc [4,5,6::Int]
|
||||
pack pc "hoge"
|
||||
|
||||
bs <- simpleBufferData sb
|
||||
print bs
|
||||
|
||||
up <- newUnpacker defaultInitialBufferSize
|
||||
|
||||
unpackerFeed up bs
|
||||
instance Arbitrary a => Arbitrary (Assoc a) where
|
||||
arbitrary = liftM Assoc arbitrary
|
||||
|
||||
let f = do
|
||||
res <- unpackerExecute up
|
||||
when (res==1) $ do
|
||||
obj <- unpackerData up
|
||||
print obj
|
||||
f
|
||||
|
||||
f
|
||||
mid :: (Packable a, Unpackable a) => a -> a
|
||||
mid = unpack . pack
|
||||
|
||||
return ()
|
||||
-}
|
||||
prop_mid_int a = a == mid a
|
||||
where types = a :: Int
|
||||
prop_mid_nil a = a == mid a
|
||||
where types = a :: ()
|
||||
prop_mid_bool a = a == mid a
|
||||
where types = a :: Bool
|
||||
prop_mid_double a = a == mid a
|
||||
where types = a :: Double
|
||||
prop_mid_string a = a == mid a
|
||||
where types = a :: String
|
||||
prop_mid_bytestring a = B.pack a == mid (B.pack a)
|
||||
where types = a :: String
|
||||
prop_mid_lazy_bytestring a = (L.pack a) == mid (L.pack a)
|
||||
where types = a :: String
|
||||
prop_mid_array_int a = a == mid a
|
||||
where types = a :: [Int]
|
||||
prop_mid_array_string a = a == mid a
|
||||
where types = a :: [String]
|
||||
prop_mid_pair2 a = a == mid a
|
||||
where types = a :: (Int, Int)
|
||||
prop_mid_pair3 a = a == mid a
|
||||
where types = a :: (Int, Int, Int)
|
||||
prop_mid_pair4 a = a == mid a
|
||||
where types = a :: (Int, Int, Int, Int)
|
||||
prop_mid_pair5 a = a == mid a
|
||||
where types = a :: (Int, Int, Int, Int, Int)
|
||||
prop_mid_list_int_double a = a == mid a
|
||||
where types = a :: [(Int, Double)]
|
||||
prop_mid_list_string_string a = a == mid a
|
||||
where types = a :: [(String, String)]
|
||||
prop_mid_map_string_int a = a == mid a
|
||||
where types = a :: Assoc [(String,Int)]
|
||||
|
||||
main = do
|
||||
bs <- packb [(1,2),(2,3),(3::Int,4::Int)]
|
||||
print bs
|
||||
dat <- unpackb bs
|
||||
print (dat :: Result [(Int, Int)])
|
||||
tests =
|
||||
[ testGroup "simple"
|
||||
[ testProperty "int" prop_mid_int
|
||||
, testProperty "nil" prop_mid_nil
|
||||
, testProperty "bool" prop_mid_bool
|
||||
, testProperty "double" prop_mid_double
|
||||
, testProperty "string" prop_mid_string
|
||||
, testProperty "bytestring" prop_mid_bytestring
|
||||
, testProperty "lazy-bytestring" prop_mid_lazy_bytestring
|
||||
, testProperty "[int]" prop_mid_array_int
|
||||
, testProperty "[string]" prop_mid_array_string
|
||||
, testProperty "(int, int)" prop_mid_pair2
|
||||
, testProperty "(int, int, int)" prop_mid_pair3
|
||||
, testProperty "(int, int, int, int)" prop_mid_pair4
|
||||
, testProperty "(int, int, int, int, int)" prop_mid_pair5
|
||||
, testProperty "[(int, double)]" prop_mid_list_int_double
|
||||
, testProperty "[(string, string)]" prop_mid_list_string_string
|
||||
, testProperty "Assoc [(string, int)]" prop_mid_map_string_int
|
||||
]
|
||||
]
|
||||
|
||||
main = defaultMain tests
|
||||
|
43
haskell/test/UserData.hs
Normal file
43
haskell/test/UserData.hs
Normal file
@@ -0,0 +1,43 @@
|
||||
{-# Language TemplateHaskell #-}
|
||||
|
||||
import Data.MessagePack
|
||||
import Data.MessagePack.Derive
|
||||
|
||||
data T
|
||||
= A Int String
|
||||
| B Double
|
||||
deriving (Show, Eq)
|
||||
|
||||
$(deriveObject ''T)
|
||||
|
||||
data U
|
||||
= C { c1 :: Int, c2 :: String }
|
||||
| D { d1 :: Double }
|
||||
deriving (Show, Eq)
|
||||
|
||||
$(deriveObject ''U)
|
||||
|
||||
data V
|
||||
= E String | F
|
||||
deriving (Show, Eq)
|
||||
|
||||
$(deriveObject ''V)
|
||||
|
||||
test :: (OBJECT a, Show a, Eq a) => a -> IO ()
|
||||
test v = do
|
||||
let bs = pack v
|
||||
print bs
|
||||
print (unpack bs == v)
|
||||
|
||||
let oa = toObject v
|
||||
print oa
|
||||
print (fromObject oa == v)
|
||||
|
||||
main = do
|
||||
test $ A 123 "hoge"
|
||||
test $ B 3.14
|
||||
test $ C 123 "hoge"
|
||||
test $ D 3.14
|
||||
test $ E "hello"
|
||||
test $ F
|
||||
return ()
|
@@ -1,5 +1,13 @@
|
||||
#Mon Apr 19 22:18:48 JST 2010
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
#Tue Apr 12 19:14:17 JST 2011
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
|
9
java/.settings/org.maven.ide.eclipse.prefs
Normal file
9
java/.settings/org.maven.ide.eclipse.prefs
Normal file
@@ -0,0 +1,9 @@
|
||||
#Mon Sep 27 07:43:27 JST 2010
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
fullBuildGoals=process-test-resources
|
||||
includeModules=false
|
||||
resolveWorkspaceProjects=true
|
||||
resourceFilterGoals=process-resources resources\:testResources
|
||||
skipCompilerPlugin=true
|
||||
version=1
|
1
java/AUTHORS
Normal file
1
java/AUTHORS
Normal file
@@ -0,0 +1 @@
|
||||
FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>
|
@@ -1,3 +1,97 @@
|
||||
|
||||
Release 0.5.2 - 2011/04/23
|
||||
NEW FEATURES
|
||||
MSGPACK-6 Added TemplatePrecompiler program
|
||||
|
||||
Added built-in templates of BigDecimal and Date classes.
|
||||
|
||||
Added @MessagePackBeans annotation that enables you to serialize/deserialize
|
||||
JavaBeans.
|
||||
|
||||
BUG FIXES
|
||||
MSGPACK-4 Fixes the deserialization routine of Long value
|
||||
|
||||
IMPROVEMENTS
|
||||
#35 Improves handling of ClassLoader on Javassist template builder.
|
||||
|
||||
MSGPACK-7 Improves compatibility with Java 1.5. Now it runs on JRE 5.
|
||||
It is tested on Jenkins CI: http://ci.msgpack.org/job/java-jre5/
|
||||
|
||||
|
||||
Release 0.5.1 - 2010/12/14
|
||||
BUG FIXES
|
||||
Fixes cast error on GenericArrayType
|
||||
|
||||
Throws MessagePackException instead of NullPointerException if target is null
|
||||
on pack method.
|
||||
|
||||
|
||||
Release 0.5.0 - 2010/12/09
|
||||
NEW FEATURES
|
||||
Dynamic template builder is rewritten. New ReflectionTemplateBuilder
|
||||
supports DalvikVM.
|
||||
|
||||
Some optimization for dynamic code generator.
|
||||
|
||||
@MessagePackMessage accepts default filed option.
|
||||
Added new field annotations: @Ignore, @Requred and @Index.
|
||||
|
||||
Supported pack/unpack/convertion of arrays including multidimensional arrays.
|
||||
|
||||
Added native pack/unpack routine of ByteBuffer. It will be zero-copy optimized
|
||||
under a specific condition.
|
||||
|
||||
|
||||
Release 0.4.3 - 2010/11/10
|
||||
NEW FEATURES
|
||||
Added FieldList class and MessagePack.register(Class<T>, FieldList) method
|
||||
to specify optional/nullable options on runtime without annotations.
|
||||
|
||||
Changed annotation name: @MessagePackNullable -> @Nullable
|
||||
Changed annotation name: @MessagePackOptional -> @Optional
|
||||
|
||||
Supported pack/unpack/convertion of enums.
|
||||
|
||||
Added MessagePack.unpack(buffer, T to) and MessagePackObject.convert(T to)
|
||||
methods. They can unpack/convert buffer/object into existing object and
|
||||
eliminate re-allocation overhead.
|
||||
|
||||
|
||||
Release 0.4.2 - 2010/11/09
|
||||
NEW FEATURES
|
||||
Added MessagePackNullable annotation and Tempalte.tNullable(Template)
|
||||
method.
|
||||
|
||||
Added <T> T MessagePackObject.unpack(Class<T>) method.
|
||||
|
||||
|
||||
Release 0.4.1 - 2010/11/05
|
||||
BUG FIXES
|
||||
Fixed dynamic code generation of unpack methods
|
||||
|
||||
|
||||
Release 0.4.0 - 2010/10/25
|
||||
NEW FEATURES
|
||||
Added MessagePackObject class and org.msgpack.object package that
|
||||
represent unpacked (=dynamically typed) objects.
|
||||
Unpacker.unpack method returns MessagePackObject instead of Object.
|
||||
|
||||
Added Templates class and org.msgpack.template package that provide
|
||||
type conversion feature.
|
||||
|
||||
User-defined classes annotated with MessagePackMessage can be
|
||||
pack/unpack/converted.
|
||||
|
||||
User-defined classes registered with MessagePack.register(Class) can be
|
||||
pack/unpack/converted.
|
||||
|
||||
Added dynamic code generation feature for user-defined classes.
|
||||
|
||||
Added MessagePackOptional annotation.
|
||||
|
||||
Added MessagePack class that implements typical useful methods.
|
||||
|
||||
|
||||
Release 0.3 - 2010/05/23
|
||||
NEW FEATURES
|
||||
Added Unbuffered API + Direct Conversion API to the Unpacker.
|
||||
|
17
java/msgpack.iml
Normal file
17
java/msgpack.iml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.8.1" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
64
java/pom.xml
64
java/pom.xml
@@ -3,11 +3,11 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.msgpack</groupId>
|
||||
<artifactId>msgpack</artifactId>
|
||||
<version>0.3</version>
|
||||
<version>0.5.2-devel</version>
|
||||
<description>MessagePack for Java</description>
|
||||
|
||||
<name>MessagePack for Java</name>
|
||||
<url>http://msgpack.sourceforge.net/</url>
|
||||
<url>http://msgpack.org/</url>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
@@ -29,6 +29,22 @@
|
||||
<version>4.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.4.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.4.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.12.1.GA</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -47,8 +63,8 @@
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -65,6 +81,20 @@
|
||||
<connectionUrl>scm:git://github.com/msgpack/msgpack.git</connectionUrl>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -97,29 +127,33 @@
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>msgpack.sourceforge.net</id>
|
||||
<id>msgpack.org</id>
|
||||
<name>MessagePack Maven2 Repository</name>
|
||||
<url>http://msgpack.sourceforge.net/maven2</url>
|
||||
<url>http://msgpack.org/maven2</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>msgpack.sourceforge.net</id>
|
||||
<name>MessagePack Maven2 Snapshot Repository</name>
|
||||
<url>http://msgpack.sourceforge.net/maven2-snapshot</url>
|
||||
<id>repository.jboss.org</id>
|
||||
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<uniqueVersion>false</uniqueVersion>
|
||||
<id>shell.sourceforge.net</id>
|
||||
<name>Repository at sourceforge.net</name>
|
||||
<url>scp://shell.sourceforge.net/home/groups/m/ms/msgpack/htdocs/maven2/</url>
|
||||
<id>msgpack.org</id>
|
||||
<name>Repository at msgpack.org</name>
|
||||
<url>file://${project.build.directory}/website/maven2/</url>
|
||||
<!--<url>${deploy-release-url}</url>-->
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<uniqueVersion>true</uniqueVersion>
|
||||
<id>shell.sourceforge.net</id>
|
||||
<name>Repository Name</name>
|
||||
<url>scp://shell.sourceforge.net/home/groups/m/ms/msgpack/htdocs/maven2-snapshot/</url>
|
||||
<id>msgpack.org</id>
|
||||
<name>Repository at msgpack.org</name>
|
||||
<url>file://${project.build.directory}/website/maven2/</url>
|
||||
<!--<url>${deploy-snapshot-url}</url>-->
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
|
26
java/src/main/java/org/msgpack/AbstractTemplate.java
Normal file
26
java/src/main/java/org/msgpack/AbstractTemplate.java
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2011 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.
|
||||
//
|
||||
package org.msgpack;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class AbstractTemplate implements Template {
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return convert(pac.unpackObject(), to);
|
||||
}
|
||||
}
|
@@ -19,12 +19,13 @@ package org.msgpack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
//import java.math.BigInteger;
|
||||
import java.math.BigInteger;
|
||||
|
||||
abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
int offset = 0;
|
||||
int filled = 0;
|
||||
byte[] buffer = null;
|
||||
boolean bufferReferenced = false; // TODO zero-copy buffer
|
||||
private ByteBuffer castBuffer = ByteBuffer.allocate(8);
|
||||
|
||||
abstract boolean fill() throws IOException;
|
||||
@@ -47,7 +48,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
offset = noffset;
|
||||
} while(!super.isFinished());
|
||||
|
||||
Object obj = super.getData();
|
||||
MessagePackObject obj = super.getData();
|
||||
super.reset();
|
||||
result.done(obj);
|
||||
|
||||
@@ -103,7 +104,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
case 0xcc: // unsigned int 8
|
||||
more(2);
|
||||
advance(2);
|
||||
return (int)((short)buffer[offset+1] & 0xff);
|
||||
return (int)((short)(buffer[offset-1]) & 0xff);
|
||||
case 0xcd: // unsigned int 16
|
||||
more(3);
|
||||
castBuffer.rewind();
|
||||
@@ -137,7 +138,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
case 0xd0: // signed int 8
|
||||
more(2);
|
||||
advance(2);
|
||||
return (int)buffer[offset+1];
|
||||
return (int)buffer[offset-1];
|
||||
case 0xd1: // signed int 16
|
||||
more(3);
|
||||
castBuffer.rewind();
|
||||
@@ -145,10 +146,10 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
advance(3);
|
||||
return (int)castBuffer.getShort(0);
|
||||
case 0xd2: // signed int 32
|
||||
more(4);
|
||||
more(5);
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(buffer, offset+1, 4);
|
||||
advance(4);
|
||||
advance(5);
|
||||
return (int)castBuffer.getInt(0);
|
||||
case 0xd3: // signed int 64
|
||||
more(9);
|
||||
@@ -178,7 +179,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
case 0xcc: // unsigned int 8
|
||||
more(2);
|
||||
advance(2);
|
||||
return (long)((short)buffer[offset+1] & 0xff);
|
||||
return (long)((short)(buffer[offset-1]) & 0xff);
|
||||
case 0xcd: // unsigned int 16
|
||||
more(3);
|
||||
castBuffer.rewind();
|
||||
@@ -198,8 +199,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
{
|
||||
long o = castBuffer.getLong(0);
|
||||
if(o < 0) {
|
||||
// FIXME
|
||||
throw new MessageTypeException("uint 64 bigger than 0x7fffffff is not supported");
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
advance(9);
|
||||
return o;
|
||||
@@ -207,7 +207,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
case 0xd0: // signed int 8
|
||||
more(2);
|
||||
advance(2);
|
||||
return (long)buffer[offset+1];
|
||||
return (long)buffer[offset-1];
|
||||
case 0xd1: // signed int 16
|
||||
more(3);
|
||||
castBuffer.rewind();
|
||||
@@ -215,10 +215,10 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
advance(3);
|
||||
return (long)castBuffer.getShort(0);
|
||||
case 0xd2: // signed int 32
|
||||
more(4);
|
||||
more(5);
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(buffer, offset+1, 4);
|
||||
advance(4);
|
||||
advance(5);
|
||||
return (long)castBuffer.getInt(0);
|
||||
case 0xd3: // signed int 64
|
||||
more(9);
|
||||
@@ -231,6 +231,26 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
}
|
||||
}
|
||||
|
||||
final BigInteger unpackBigInteger() throws IOException, MessageTypeException {
|
||||
more(1);
|
||||
int b = buffer[offset];
|
||||
if((b & 0xff) != 0xcf) {
|
||||
return BigInteger.valueOf(unpackLong());
|
||||
}
|
||||
|
||||
// unsigned int 64
|
||||
more(9);
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(buffer, offset+1, 8);
|
||||
advance(9);
|
||||
long o = castBuffer.getLong(0);
|
||||
if(o < 0) {
|
||||
return new BigInteger(1, castBuffer.array());
|
||||
} else {
|
||||
return BigInteger.valueOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
final float unpackFloat() throws IOException, MessageTypeException {
|
||||
more(1);
|
||||
int b = buffer[offset];
|
||||
@@ -398,7 +418,18 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
|
||||
final byte[] unpackByteArray() throws IOException, MessageTypeException {
|
||||
int length = unpackRaw();
|
||||
return unpackRawBody(length);
|
||||
byte[] body = unpackRawBody(length);
|
||||
return body;
|
||||
}
|
||||
|
||||
final ByteBuffer unpackByteBuffer() throws IOException, MessageTypeException {
|
||||
// TODO zero-copy buffer
|
||||
int length = unpackRaw();
|
||||
more(length);
|
||||
ByteBuffer buf = ByteBuffer.wrap(buffer, offset, length);
|
||||
bufferReferenced = true; // TODO fix magical code
|
||||
advance(length);
|
||||
return buf;
|
||||
}
|
||||
|
||||
final String unpackString() throws IOException, MessageTypeException {
|
||||
@@ -414,7 +445,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||
return s;
|
||||
}
|
||||
|
||||
final Object unpackObject() throws IOException {
|
||||
final MessagePackObject unpackObject() throws IOException {
|
||||
UnpackResult result = new UnpackResult();
|
||||
if(!next(result)) {
|
||||
super.reset();
|
||||
|
@@ -18,6 +18,6 @@
|
||||
package org.msgpack;
|
||||
|
||||
public interface MessageConvertable {
|
||||
public void messageConvert(Object obj) throws MessageTypeException;
|
||||
public void messageConvert(MessagePackObject obj) throws MessageTypeException;
|
||||
}
|
||||
|
||||
|
23
java/src/main/java/org/msgpack/MessageConverter.java
Normal file
23
java/src/main/java/org/msgpack/MessageConverter.java
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack;
|
||||
|
||||
public interface MessageConverter {
|
||||
Object convert(MessagePackObject from, Object to) throws MessageTypeException;
|
||||
}
|
||||
|
160
java/src/main/java/org/msgpack/MessagePack.java
Normal file
160
java/src/main/java/org/msgpack/MessagePack.java
Normal file
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2011 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.
|
||||
//
|
||||
package org.msgpack;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.template.TemplateRegistry;
|
||||
import org.msgpack.template.FieldList;
|
||||
|
||||
public class MessagePack {
|
||||
public static byte[] pack(Object obj) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
try {
|
||||
new Packer(out).pack(obj);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static void pack(OutputStream out, Object obj) throws IOException {
|
||||
new Packer(out).pack(obj);
|
||||
}
|
||||
|
||||
public static byte[] pack(Object obj, Template tmpl) throws MessageTypeException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
try {
|
||||
new Packer(out).pack(obj, tmpl);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static void pack(OutputStream out, Object obj, Template tmpl) throws IOException, MessageTypeException {
|
||||
new Packer(out).pack(obj, tmpl);
|
||||
}
|
||||
|
||||
|
||||
public static MessagePackObject unpack(byte[] buffer) throws MessageTypeException {
|
||||
Unpacker pac = new Unpacker();
|
||||
pac.wrap(buffer);
|
||||
try {
|
||||
return pac.unpackObject();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object unpack(byte[] buffer, Template tmpl) throws MessageTypeException {
|
||||
Unpacker pac = new Unpacker();
|
||||
pac.wrap(buffer);
|
||||
try {
|
||||
return pac.unpack(tmpl);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unpack(byte[] buffer, Template tmpl, T to) throws MessageTypeException {
|
||||
Unpacker pac = new Unpacker();
|
||||
pac.wrap(buffer);
|
||||
try {
|
||||
return pac.unpack(tmpl, to);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unpack(byte[] buffer, Class<T> klass) throws MessageTypeException {
|
||||
Unpacker pac = new Unpacker();
|
||||
pac.wrap(buffer);
|
||||
try {
|
||||
return pac.unpack(klass);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unpack(byte[] buffer, T to) throws MessageTypeException {
|
||||
Unpacker pac = new Unpacker();
|
||||
pac.wrap(buffer);
|
||||
try {
|
||||
return pac.unpack(to);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static MessagePackObject unpack(InputStream in) throws IOException {
|
||||
Unpacker pac = new Unpacker(in);
|
||||
return pac.unpackObject();
|
||||
}
|
||||
|
||||
public static Object unpack(InputStream in, Template tmpl) throws IOException, MessageTypeException {
|
||||
Unpacker pac = new Unpacker(in);
|
||||
try {
|
||||
return pac.unpack(tmpl);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unpack(InputStream in, Template tmpl, T to) throws IOException, MessageTypeException {
|
||||
Unpacker pac = new Unpacker(in);
|
||||
try {
|
||||
return pac.unpack(tmpl, to);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unpack(InputStream in, Class<T> klass) throws IOException, MessageTypeException {
|
||||
Unpacker pac = new Unpacker(in);
|
||||
try {
|
||||
return pac.unpack(klass);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unpack(InputStream in, T to) throws IOException, MessageTypeException {
|
||||
Unpacker pac = new Unpacker(in);
|
||||
try {
|
||||
return pac.unpack(to);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void register(Class<?> target) {
|
||||
TemplateRegistry.register(target);
|
||||
}
|
||||
|
||||
public static void register(Class<?> target, FieldList flist) throws NoSuchFieldException {
|
||||
TemplateRegistry.register(target, flist);
|
||||
}
|
||||
|
||||
public static void register(Class<?> target, Template tmpl) {
|
||||
TemplateRegistry.register(target, tmpl);
|
||||
}
|
||||
}
|
||||
|
160
java/src/main/java/org/msgpack/MessagePackObject.java
Normal file
160
java/src/main/java/org/msgpack/MessagePackObject.java
Normal file
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.math.BigInteger;
|
||||
import org.msgpack.template.TemplateRegistry;
|
||||
|
||||
public abstract class MessagePackObject implements Cloneable, MessagePackable {
|
||||
public boolean isNil() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isBooleanType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isIntegerType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFloatType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isArrayType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isMapType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isRawType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean asBoolean() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public byte asByte() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public short asShort() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public int asInt() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public long asLong() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public BigInteger asBigInteger() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public float asFloat() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public double asDouble() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public byte[] asByteArray() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public String asString() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public MessagePackObject[] asArray() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public List<MessagePackObject> asList() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public Map<MessagePackObject, MessagePackObject> asMap() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public BigInteger bigIntegerValue() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
abstract public Object clone();
|
||||
|
||||
public Object convert(Template tmpl) throws MessageTypeException {
|
||||
return convert(tmpl, null);
|
||||
}
|
||||
|
||||
public <T> T convert(Template tmpl, T to) throws MessageTypeException {
|
||||
return (T)tmpl.convert(this, to);
|
||||
}
|
||||
|
||||
public <T> T convert(Class<T> klass) throws MessageTypeException {
|
||||
return convert(klass, null);
|
||||
}
|
||||
|
||||
public <T> T convert(T to) throws MessageTypeException {
|
||||
return convert((Class<T>)to.getClass(), to);
|
||||
}
|
||||
|
||||
public <T> T convert(Class<T> klass, T to) throws MessageTypeException {
|
||||
if(isNil()) {
|
||||
return null;
|
||||
}
|
||||
return (T)convert(TemplateRegistry.lookup(klass), to);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2011 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.
|
||||
//
|
||||
package org.msgpack;
|
||||
|
||||
public interface MessagePackTemplateProvider {
|
||||
Template getTemplate();
|
||||
}
|
@@ -15,12 +15,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
package org.msgpack.schema;
|
||||
package org.msgpack;
|
||||
|
||||
import org.msgpack.Schema;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IArraySchema {
|
||||
public Schema getElementSchema(int index);
|
||||
public Object createFromArray(Object[] obj);
|
||||
public interface MessagePacker {
|
||||
void pack(Packer pk, Object target) throws IOException;
|
||||
}
|
||||
|
@@ -23,15 +23,13 @@ public class MessageTypeException extends RuntimeException {
|
||||
public MessageTypeException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public static MessageTypeException invalidConvert(Object from, Schema to) {
|
||||
return new MessageTypeException(from.getClass().getName()+" cannot be convert to "+to.getExpression());
|
||||
|
||||
public MessageTypeException(String s, Throwable t) {
|
||||
super(s, t);
|
||||
}
|
||||
|
||||
/* FIXME
|
||||
public static MessageTypeException schemaMismatch(Schema to) {
|
||||
return new MessageTypeException("schema mismatch "+to.getExpression());
|
||||
|
||||
public MessageTypeException(Throwable t) {
|
||||
super(t);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
@@ -15,13 +15,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
package org.msgpack.schema;
|
||||
package org.msgpack;
|
||||
|
||||
import org.msgpack.Schema;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IMapSchema {
|
||||
public Schema getKeySchema();
|
||||
public Schema getValueSchema();
|
||||
public Object createFromMap(Object[] obj);
|
||||
public interface MessageUnpacker {
|
||||
Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException;
|
||||
}
|
||||
|
@@ -21,7 +21,11 @@ import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.math.BigInteger;
|
||||
import org.msgpack.template.TemplateRegistry;
|
||||
|
||||
/**
|
||||
* Packer enables you to serialize objects into OutputStream.
|
||||
@@ -40,8 +44,10 @@ import java.util.Map;
|
||||
* You can serialize objects that implements {@link MessagePackable} interface.
|
||||
*/
|
||||
public class Packer {
|
||||
public static void load() { }
|
||||
|
||||
protected byte[] castBytes = new byte[9];
|
||||
protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes);
|
||||
//protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes);
|
||||
protected OutputStream out;
|
||||
|
||||
public Packer(OutputStream out) {
|
||||
@@ -64,7 +70,9 @@ public class Packer {
|
||||
if(d < -(1<<7)) {
|
||||
// signed 16
|
||||
castBytes[0] = (byte)0xd1;
|
||||
castBuffer.putShort(1, d);
|
||||
// castBuffer.putShort(1, d);
|
||||
castBytes[1] = (byte)(d >> 8);
|
||||
castBytes[2] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
// signed 8
|
||||
@@ -84,7 +92,9 @@ public class Packer {
|
||||
} else {
|
||||
// unsigned 16
|
||||
castBytes[0] = (byte)0xcd;
|
||||
castBuffer.putShort(1, d);
|
||||
// castBuffer.putShort(1, d);
|
||||
castBytes[1] = (byte)(d >> 8);
|
||||
castBytes[2] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
}
|
||||
}
|
||||
@@ -96,12 +106,18 @@ public class Packer {
|
||||
if(d < -(1<<15)) {
|
||||
// signed 32
|
||||
castBytes[0] = (byte)0xd2;
|
||||
castBuffer.putInt(1, d);
|
||||
// castBuffer.putInt(1, d);
|
||||
castBytes[1] = (byte)(d >> 24);
|
||||
castBytes[2] = (byte)(d >> 16);
|
||||
castBytes[3] = (byte)(d >> 8);
|
||||
castBytes[4] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 5);
|
||||
} else if(d < -(1<<7)) {
|
||||
// signed 16
|
||||
castBytes[0] = (byte)0xd1;
|
||||
castBuffer.putShort(1, (short)d);
|
||||
// castBuffer.putShort(1, (short)d);
|
||||
castBytes[1] = (byte)(d >> 8);
|
||||
castBytes[2] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
// signed 8
|
||||
@@ -121,12 +137,18 @@ public class Packer {
|
||||
} else if(d < (1<<16)) {
|
||||
// unsigned 16
|
||||
castBytes[0] = (byte)0xcd;
|
||||
castBuffer.putShort(1, (short)d);
|
||||
// castBuffer.putShort(1, (short)d);
|
||||
castBytes[1] = (byte)(d >> 8);
|
||||
castBytes[2] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
// unsigned 32
|
||||
castBytes[0] = (byte)0xce;
|
||||
castBuffer.putInt(1, d);
|
||||
// castBuffer.putInt(1, d);
|
||||
castBytes[1] = (byte)(d >> 24);
|
||||
castBytes[2] = (byte)(d >> 16);
|
||||
castBytes[3] = (byte)(d >> 8);
|
||||
castBytes[4] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
}
|
||||
@@ -139,19 +161,33 @@ public class Packer {
|
||||
if(d < -(1L<<31)) {
|
||||
// signed 64
|
||||
castBytes[0] = (byte)0xd3;
|
||||
castBuffer.putLong(1, d);
|
||||
// castBuffer.putLong(1, d);
|
||||
castBytes[1] = (byte)(d >> 56);
|
||||
castBytes[2] = (byte)(d >> 48);
|
||||
castBytes[3] = (byte)(d >> 40);
|
||||
castBytes[4] = (byte)(d >> 32);
|
||||
castBytes[5] = (byte)(d >> 24);
|
||||
castBytes[6] = (byte)(d >> 16);
|
||||
castBytes[7] = (byte)(d >> 8);
|
||||
castBytes[8] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 9);
|
||||
} else {
|
||||
// signed 32
|
||||
castBytes[0] = (byte)0xd2;
|
||||
castBuffer.putInt(1, (int)d);
|
||||
// castBuffer.putInt(1, (int)d);
|
||||
castBytes[1] = (byte)(d >> 24);
|
||||
castBytes[2] = (byte)(d >> 16);
|
||||
castBytes[3] = (byte)(d >> 8);
|
||||
castBytes[4] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
} else {
|
||||
if(d < -(1<<7)) {
|
||||
// signed 16
|
||||
castBytes[0] = (byte)0xd1;
|
||||
castBuffer.putShort(1, (short)d);
|
||||
// castBuffer.putShort(1, (short)d);
|
||||
castBytes[1] = (byte)(d >> 8);
|
||||
castBytes[2] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
// signed 8
|
||||
@@ -173,7 +209,9 @@ public class Packer {
|
||||
} else {
|
||||
// unsigned 16
|
||||
castBytes[0] = (byte)0xcd;
|
||||
castBuffer.putShort(1, (short)d);
|
||||
// castBuffer.putShort(1, (short)d);
|
||||
castBytes[1] = (byte)((d & 0x0000ff00) >> 8);
|
||||
castBytes[2] = (byte)((d & 0x000000ff) >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
//System.out.println("pack uint 16 "+(short)d);
|
||||
}
|
||||
@@ -181,12 +219,24 @@ public class Packer {
|
||||
if(d < (1L<<32)) {
|
||||
// unsigned 32
|
||||
castBytes[0] = (byte)0xce;
|
||||
castBuffer.putInt(1, (int)d);
|
||||
// castBuffer.putInt(1, (int)d);
|
||||
castBytes[1] = (byte)((d & 0xff000000) >> 24);
|
||||
castBytes[2] = (byte)((d & 0x00ff0000) >> 16);
|
||||
castBytes[3] = (byte)((d & 0x0000ff00) >> 8);
|
||||
castBytes[4] = (byte)((d & 0x000000ff) >> 0);
|
||||
out.write(castBytes, 0, 5);
|
||||
} else {
|
||||
// unsigned 64
|
||||
castBytes[0] = (byte)0xcf;
|
||||
castBuffer.putLong(1, d);
|
||||
// castBuffer.putLong(1, d);
|
||||
castBytes[1] = (byte)(d >> 56);
|
||||
castBytes[2] = (byte)(d >> 48);
|
||||
castBytes[3] = (byte)(d >> 40);
|
||||
castBytes[4] = (byte)(d >> 32);
|
||||
castBytes[5] = (byte)(d >> 24);
|
||||
castBytes[6] = (byte)(d >> 16);
|
||||
castBytes[7] = (byte)(d >> 8);
|
||||
castBytes[8] = (byte)(d >> 0);
|
||||
out.write(castBytes, 0, 9);
|
||||
}
|
||||
}
|
||||
@@ -194,16 +244,51 @@ public class Packer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packBigInteger(BigInteger d) throws IOException {
|
||||
if(d.bitLength() <= 63) {
|
||||
return packLong(d.longValue());
|
||||
} else if(d.bitLength() <= 64 && d.signum() >= 0) {
|
||||
castBytes[0] = (byte)0xcf;
|
||||
byte[] barray = d.toByteArray();
|
||||
castBytes[1] = barray[barray.length-8];
|
||||
castBytes[2] = barray[barray.length-7];
|
||||
castBytes[3] = barray[barray.length-6];
|
||||
castBytes[4] = barray[barray.length-5];
|
||||
castBytes[5] = barray[barray.length-4];
|
||||
castBytes[6] = barray[barray.length-3];
|
||||
castBytes[7] = barray[barray.length-2];
|
||||
castBytes[8] = barray[barray.length-1];
|
||||
out.write(castBytes, 0, 9);
|
||||
return this;
|
||||
} else {
|
||||
throw new MessageTypeException("can't pack BigInteger larger than 0xffffffffffffffff");
|
||||
}
|
||||
}
|
||||
|
||||
public Packer packFloat(float d) throws IOException {
|
||||
castBytes[0] = (byte)0xca;
|
||||
castBuffer.putFloat(1, d);
|
||||
// castBuffer.putFloat(1, d);
|
||||
int f = Float.floatToRawIntBits(d);
|
||||
castBytes[1] = (byte)(f >> 24);
|
||||
castBytes[2] = (byte)(f >> 16);
|
||||
castBytes[3] = (byte)(f >> 8);
|
||||
castBytes[4] = (byte)(f >> 0);
|
||||
out.write(castBytes, 0, 5);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packDouble(double d) throws IOException {
|
||||
castBytes[0] = (byte)0xcb;
|
||||
castBuffer.putDouble(1, d);
|
||||
// castBuffer.putDouble(1, d);
|
||||
long f = Double.doubleToRawLongBits(d);
|
||||
castBytes[1] = (byte)(f >> 56);
|
||||
castBytes[2] = (byte)(f >> 48);
|
||||
castBytes[3] = (byte)(f >> 40);
|
||||
castBytes[4] = (byte)(f >> 32);
|
||||
castBytes[5] = (byte)(f >> 24);
|
||||
castBytes[6] = (byte)(f >> 16);
|
||||
castBytes[7] = (byte)(f >> 8);
|
||||
castBytes[8] = (byte)(f >> 0);
|
||||
out.write(castBytes, 0, 9);
|
||||
return this;
|
||||
}
|
||||
@@ -233,11 +318,17 @@ public class Packer {
|
||||
out.write((byte)d);
|
||||
} else if(n < 65536) {
|
||||
castBytes[0] = (byte)0xdc;
|
||||
castBuffer.putShort(1, (short)n);
|
||||
// castBuffer.putShort(1, (short)n);
|
||||
castBytes[1] = (byte)(n >> 8);
|
||||
castBytes[2] = (byte)(n >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
castBytes[0] = (byte)0xdd;
|
||||
castBuffer.putInt(1, n);
|
||||
// castBuffer.putInt(1, n);
|
||||
castBytes[1] = (byte)(n >> 24);
|
||||
castBytes[2] = (byte)(n >> 16);
|
||||
castBytes[3] = (byte)(n >> 8);
|
||||
castBytes[4] = (byte)(n >> 0);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
return this;
|
||||
@@ -249,11 +340,17 @@ public class Packer {
|
||||
out.write((byte)d);
|
||||
} else if(n < 65536) {
|
||||
castBytes[0] = (byte)0xde;
|
||||
castBuffer.putShort(1, (short)n);
|
||||
// castBuffer.putShort(1, (short)n);
|
||||
castBytes[1] = (byte)(n >> 8);
|
||||
castBytes[2] = (byte)(n >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
castBytes[0] = (byte)0xdf;
|
||||
castBuffer.putInt(1, n);
|
||||
// castBuffer.putInt(1, n);
|
||||
castBytes[1] = (byte)(n >> 24);
|
||||
castBytes[2] = (byte)(n >> 16);
|
||||
castBytes[3] = (byte)(n >> 8);
|
||||
castBytes[4] = (byte)(n >> 0);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
return this;
|
||||
@@ -265,11 +362,17 @@ public class Packer {
|
||||
out.write((byte)d);
|
||||
} else if(n < 65536) {
|
||||
castBytes[0] = (byte)0xda;
|
||||
castBuffer.putShort(1, (short)n);
|
||||
// castBuffer.putShort(1, (short)n);
|
||||
castBytes[1] = (byte)(n >> 8);
|
||||
castBytes[2] = (byte)(n >> 0);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
castBytes[0] = (byte)0xdb;
|
||||
castBuffer.putInt(1, n);
|
||||
// castBuffer.putInt(1, n);
|
||||
castBytes[1] = (byte)(n >> 24);
|
||||
castBytes[2] = (byte)(n >> 16);
|
||||
castBytes[3] = (byte)(n >> 8);
|
||||
castBytes[4] = (byte)(n >> 0);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
return this;
|
||||
@@ -286,11 +389,20 @@ public class Packer {
|
||||
}
|
||||
|
||||
|
||||
public Packer packWithSchema(Object o, Schema s) throws IOException {
|
||||
s.pack(this, o);
|
||||
return this;
|
||||
public Packer packByteArray(byte[] b) throws IOException {
|
||||
packRaw(b.length);
|
||||
return packRawBody(b, 0, b.length);
|
||||
}
|
||||
|
||||
public Packer packByteArray(byte[] b, int off, int length) throws IOException {
|
||||
packRaw(length);
|
||||
return packRawBody(b, off, length);
|
||||
}
|
||||
|
||||
public Packer packByteBuffer(ByteBuffer buf) throws IOException {
|
||||
packRaw(buf.remaining());
|
||||
return packRawBody(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining());
|
||||
}
|
||||
|
||||
public Packer packString(String s) throws IOException {
|
||||
byte[] b = ((String)s).getBytes("UTF-8");
|
||||
@@ -299,39 +411,36 @@ public class Packer {
|
||||
}
|
||||
|
||||
|
||||
public Packer pack(String o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packString(o);
|
||||
}
|
||||
|
||||
public Packer pack(MessagePackable o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
o.messagePack(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer pack(byte[] o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packRaw(o.length);
|
||||
return packRawBody(o);
|
||||
}
|
||||
|
||||
public Packer pack(List o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packArray(o.size());
|
||||
for(Object i : o) { pack(i); }
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Packer pack(Map o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packMap(o.size());
|
||||
for(Map.Entry e : ((Map<Object,Object>)o).entrySet()) {
|
||||
pack(e.getKey());
|
||||
pack(e.getValue());
|
||||
public Packer pack(boolean o) throws IOException {
|
||||
if(o) {
|
||||
return packTrue();
|
||||
} else {
|
||||
return packFalse();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer pack(byte o) throws IOException {
|
||||
return packByte(o);
|
||||
}
|
||||
|
||||
public Packer pack(short o) throws IOException {
|
||||
return packShort(o);
|
||||
}
|
||||
|
||||
public Packer pack(int o) throws IOException {
|
||||
return packInt(o);
|
||||
}
|
||||
|
||||
public Packer pack(long o) throws IOException {
|
||||
return packLong(o);
|
||||
}
|
||||
|
||||
public Packer pack(float o) throws IOException {
|
||||
return packFloat(o);
|
||||
}
|
||||
|
||||
public Packer pack(double o) throws IOException {
|
||||
return packDouble(o);
|
||||
}
|
||||
|
||||
public Packer pack(Boolean o) throws IOException {
|
||||
@@ -363,6 +472,11 @@ public class Packer {
|
||||
return packLong(o);
|
||||
}
|
||||
|
||||
public Packer pack(BigInteger o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packBigInteger(o);
|
||||
}
|
||||
|
||||
public Packer pack(Float o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packFloat(o);
|
||||
@@ -373,56 +487,55 @@ public class Packer {
|
||||
return packDouble(o);
|
||||
}
|
||||
|
||||
public Packer pack(String o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packString(o);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Packer pack(Object o) throws IOException {
|
||||
if(o == null) {
|
||||
return packNil();
|
||||
} else if(o instanceof String) {
|
||||
byte[] b = ((String)o).getBytes("UTF-8");
|
||||
packRaw(b.length);
|
||||
return packRawBody(b);
|
||||
} else if(o instanceof MessagePackable) {
|
||||
((MessagePackable)o).messagePack(this);
|
||||
return this;
|
||||
} else if(o instanceof byte[]) {
|
||||
byte[] b = (byte[])o;
|
||||
packRaw(b.length);
|
||||
return packRawBody(b);
|
||||
} else if(o instanceof List) {
|
||||
List<Object> l = (List<Object>)o;
|
||||
packArray(l.size());
|
||||
for(Object i : l) { pack(i); }
|
||||
return this;
|
||||
} else if(o instanceof Map) {
|
||||
Map<Object,Object> m = (Map<Object,Object>)o;
|
||||
packMap(m.size());
|
||||
for(Map.Entry e : m.entrySet()) {
|
||||
pack(e.getKey());
|
||||
pack(e.getValue());
|
||||
}
|
||||
return this;
|
||||
} else if(o instanceof Boolean) {
|
||||
if((Boolean)o) {
|
||||
return packTrue();
|
||||
} else {
|
||||
return packFalse();
|
||||
}
|
||||
} else if(o instanceof Integer) {
|
||||
return packInt((Integer)o);
|
||||
} else if(o instanceof Long) {
|
||||
return packLong((Long)o);
|
||||
} else if(o instanceof Short) {
|
||||
return packShort((Short)o);
|
||||
} else if(o instanceof Byte) {
|
||||
return packByte((Byte)o);
|
||||
} else if(o instanceof Float) {
|
||||
return packFloat((Float)o);
|
||||
} else if(o instanceof Double) {
|
||||
return packDouble((Double)o);
|
||||
} else {
|
||||
throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")");
|
||||
public Packer pack(byte[] o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packRaw(o.length);
|
||||
return packRawBody(o);
|
||||
}
|
||||
|
||||
public Packer pack(ByteBuffer o) throws IOException {
|
||||
if (o == null) { return packNil(); }
|
||||
packRaw(o.remaining());
|
||||
return packRawBody(o.array(), o.arrayOffset() + o.position(), o.remaining());
|
||||
}
|
||||
|
||||
public Packer pack(List o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packArray(o.size());
|
||||
for(Object i : o) { pack(i); }
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer pack(Map o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packMap(o.size());
|
||||
for(Map.Entry<Object,Object> e : ((Map<Object,Object>)o).entrySet()) {
|
||||
pack(e.getKey());
|
||||
pack(e.getValue());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer pack(MessagePackable o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
o.messagePack(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer pack(Object o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
TemplateRegistry.lookup(o.getClass()).pack(this, o);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer pack(Object o, Template tmpl) throws IOException {
|
||||
tmpl.pack(this, o);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,78 +0,0 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.schema.SSchemaParser;
|
||||
//import org.msgpack.schema.ClassGenerator;
|
||||
|
||||
public abstract class Schema {
|
||||
public Schema() { }
|
||||
|
||||
public abstract String getClassName();
|
||||
public abstract String getExpression();
|
||||
|
||||
public static Schema parse(String source) {
|
||||
return SSchemaParser.parse(source);
|
||||
}
|
||||
|
||||
public static Schema load(String source) {
|
||||
return SSchemaParser.load(source);
|
||||
}
|
||||
|
||||
public abstract void pack(Packer pk, Object obj) throws IOException;
|
||||
public abstract Object convert(Object obj) throws MessageTypeException;
|
||||
|
||||
public Object createFromNil() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object createFromBoolean(boolean v) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromByte(byte v) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromShort(short v) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromInt(int v) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromLong(long v) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromFloat(float v) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromDouble(double v) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
}
|
||||
|
21
java/src/main/java/org/msgpack/Template.java
Normal file
21
java/src/main/java/org/msgpack/Template.java
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2011 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.
|
||||
//
|
||||
package org.msgpack;
|
||||
|
||||
public interface Template extends MessagePacker, MessageUnpacker, MessageConverter {
|
||||
}
|
119
java/src/main/java/org/msgpack/Templates.java
Normal file
119
java/src/main/java/org/msgpack/Templates.java
Normal file
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2011 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.
|
||||
//
|
||||
package org.msgpack;
|
||||
|
||||
import org.msgpack.template.*;
|
||||
|
||||
public class Templates {
|
||||
public static Template tNullable(Template elementTemplate) {
|
||||
return new NullableTemplate(elementTemplate);
|
||||
}
|
||||
|
||||
|
||||
public static final Template TAny = AnyTemplate.getInstance();
|
||||
public static Template tAny() {
|
||||
return TAny;
|
||||
}
|
||||
|
||||
|
||||
public static Template tList(Template elementTemplate) {
|
||||
return new ListTemplate(elementTemplate);
|
||||
}
|
||||
|
||||
public static Template tMap(Template keyTemplate, Template valueTemplate) {
|
||||
return new MapTemplate(keyTemplate, valueTemplate);
|
||||
}
|
||||
|
||||
public static Template tCollection(Template elementTemplate) {
|
||||
return new CollectionTemplate(elementTemplate);
|
||||
}
|
||||
|
||||
public static Template tClass(Class target) {
|
||||
Template tmpl = TemplateRegistry.lookup(target);
|
||||
if(tmpl == null) {
|
||||
// FIXME
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
public static final Template TByte = ByteTemplate.getInstance();
|
||||
public static Template tByte() {
|
||||
return TByte;
|
||||
}
|
||||
|
||||
public static final Template TShort = ShortTemplate.getInstance();
|
||||
public static Template tShort() {
|
||||
return TShort;
|
||||
}
|
||||
|
||||
public static final Template TInteger = IntegerTemplate.getInstance();
|
||||
public static Template tInteger() {
|
||||
return TInteger;
|
||||
}
|
||||
|
||||
public static final Template TLong = LongTemplate.getInstance();
|
||||
public static Template tLong() {
|
||||
return TLong;
|
||||
}
|
||||
|
||||
public static final Template TBigInteger = BigIntegerTemplate.getInstance();
|
||||
public static Template tBigInteger() {
|
||||
return TBigInteger;
|
||||
}
|
||||
|
||||
public static final Template TBigDecimal = BigDecimalTemplate.getInstance();
|
||||
public static Template tBigDecimal() {
|
||||
return TBigDecimal;
|
||||
}
|
||||
|
||||
public static final Template TFloat = FloatTemplate.getInstance();
|
||||
public static Template tFloat() {
|
||||
return TFloat;
|
||||
}
|
||||
|
||||
public static final Template TDouble = DoubleTemplate.getInstance();
|
||||
public static Template tDouble() {
|
||||
return TDouble;
|
||||
}
|
||||
|
||||
public static final Template TBoolean = BooleanTemplate.getInstance();
|
||||
public static Template tBoolean() {
|
||||
return TBoolean;
|
||||
}
|
||||
|
||||
public static final Template TString = StringTemplate.getInstance();
|
||||
public static Template tString() {
|
||||
return TString;
|
||||
}
|
||||
|
||||
public static final Template TByteArray = ByteArrayTemplate.getInstance();
|
||||
public static Template tByteArray() {
|
||||
return TByteArray;
|
||||
}
|
||||
|
||||
public static final Template TByteBuffer = ByteBufferTemplate.getInstance();
|
||||
public static Template tByteBuffer() {
|
||||
return TByteBuffer;
|
||||
}
|
||||
|
||||
public static final Template TDate = DateTemplate.getInstance();
|
||||
public static Template tDate() {
|
||||
return TDate;
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class UnpackIterator extends UnpackResult implements Iterator<Object> {
|
||||
public class UnpackIterator extends UnpackResult implements Iterator<MessagePackObject> {
|
||||
private Unpacker pac;
|
||||
|
||||
UnpackIterator(Unpacker pac) {
|
||||
@@ -38,7 +38,7 @@ public class UnpackIterator extends UnpackResult implements Iterator<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
public MessagePackObject next() {
|
||||
if(!finished && !hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
@@ -19,13 +19,13 @@ package org.msgpack;
|
||||
|
||||
public class UnpackResult {
|
||||
protected boolean finished = false;
|
||||
protected Object data = null;
|
||||
protected MessagePackObject data = null;
|
||||
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
public MessagePackObject getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class UnpackResult {
|
||||
data = null;
|
||||
}
|
||||
|
||||
void done(Object obj) {
|
||||
void done(MessagePackObject obj) {
|
||||
finished = true;
|
||||
data = obj;
|
||||
}
|
||||
|
@@ -22,12 +22,14 @@ import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.math.BigInteger;
|
||||
import org.msgpack.template.TemplateRegistry;
|
||||
|
||||
/**
|
||||
* Unpacker enables you to deserialize objects from stream.
|
||||
*
|
||||
* Unpacker provides Buffered API, Unbuffered API, Schema API
|
||||
* and Direct Conversion API.
|
||||
* Unpacker provides Buffered API, Unbuffered API and
|
||||
* Direct Conversion API.
|
||||
*
|
||||
* Buffered API uses the internal buffer of the Unpacker.
|
||||
* Following code uses Buffered API with an InputStream:
|
||||
@@ -39,7 +41,7 @@ import java.nio.ByteBuffer;
|
||||
* UnpackResult result = pac.next();
|
||||
*
|
||||
* // use an iterator.
|
||||
* for(Object obj : pac) {
|
||||
* for(MessagePackObject obj : pac) {
|
||||
* // use MessageConvertable interface to convert the
|
||||
* // the generic object to the specific type.
|
||||
* }
|
||||
@@ -56,7 +58,7 @@ import java.nio.ByteBuffer;
|
||||
* pac.feed(input_bytes);
|
||||
*
|
||||
* // use next() method or iterators.
|
||||
* for(Object obj : pac) {
|
||||
* for(MessagePackObject obj : pac) {
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
@@ -75,7 +77,7 @@ import java.nio.ByteBuffer;
|
||||
* System.in.read(pac.getBuffer(), pac.getBufferOffset(), pac.getBufferCapacity());
|
||||
*
|
||||
* // use next() method or iterators.
|
||||
* for(Object obj : pac) {
|
||||
* for(MessagePackObject obj : pac) {
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
@@ -96,13 +98,12 @@ import java.nio.ByteBuffer;
|
||||
*
|
||||
* // take out object if deserialized object is ready.
|
||||
* if(pac.isFinished()) {
|
||||
* Object obj = pac.getData();
|
||||
* MessagePackObject obj = pac.getData();
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public class Unpacker implements Iterable<Object> {
|
||||
|
||||
public class Unpacker implements Iterable<MessagePackObject> {
|
||||
// buffer:
|
||||
// +---------------------------------------------+
|
||||
// | [object] | [obje| unparsed ... | unused ...|
|
||||
@@ -170,16 +171,6 @@ public class Unpacker implements Iterable<Object> {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets schema to convert deserialized object into specific type.
|
||||
* Default schema is {@link GenericSchema} that leaves objects for generic type. Use {@link MessageConvertable#messageConvert(Object)} method to convert the generic object.
|
||||
* @param s schem to use
|
||||
*/
|
||||
public Unpacker useSchema(Schema s) {
|
||||
impl.setSchema(s);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the input stream.
|
||||
@@ -241,6 +232,7 @@ public class Unpacker implements Iterable<Object> {
|
||||
impl.buffer = buffer;
|
||||
impl.offset = offset;
|
||||
impl.filled = length;
|
||||
impl.bufferReferenced = false; // TODO zero-copy buffer
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,7 +247,7 @@ public class Unpacker implements Iterable<Object> {
|
||||
/**
|
||||
* Returns the iterator that calls {@link next()} method repeatedly.
|
||||
*/
|
||||
public Iterator<Object> iterator() {
|
||||
public Iterator<MessagePackObject> iterator() {
|
||||
return new UnpackIterator(this);
|
||||
}
|
||||
|
||||
@@ -285,13 +277,16 @@ public class Unpacker implements Iterable<Object> {
|
||||
if(impl.buffer == null) {
|
||||
int nextSize = (bufferReserveSize < require) ? require : bufferReserveSize;
|
||||
impl.buffer = new byte[nextSize];
|
||||
impl.bufferReferenced = false; // TODO zero-copy buffer
|
||||
return;
|
||||
}
|
||||
|
||||
if(impl.filled <= impl.offset) {
|
||||
// rewind the buffer
|
||||
impl.filled = 0;
|
||||
impl.offset = 0;
|
||||
if(!impl.bufferReferenced) { // TODO zero-copy buffer
|
||||
if(impl.filled <= impl.offset) {
|
||||
// rewind the buffer
|
||||
impl.filled = 0;
|
||||
impl.offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(impl.buffer.length - impl.filled >= require) {
|
||||
@@ -310,6 +305,7 @@ public class Unpacker implements Iterable<Object> {
|
||||
impl.buffer = tmp;
|
||||
impl.filled = notParsed;
|
||||
impl.offset = 0;
|
||||
impl.bufferReferenced = false; // TODO zero-copy buffer
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,8 +372,7 @@ public class Unpacker implements Iterable<Object> {
|
||||
* @return offset position that is parsed.
|
||||
*/
|
||||
public int execute(byte[] buffer, int offset, int length) throws UnpackException {
|
||||
int noffset = impl.execute(buffer, offset + impl.offset, length);
|
||||
impl.offset = noffset - offset;
|
||||
int noffset = impl.execute(buffer, offset, length);
|
||||
if(impl.isFinished()) {
|
||||
impl.resetState();
|
||||
}
|
||||
@@ -387,7 +382,7 @@ public class Unpacker implements Iterable<Object> {
|
||||
/**
|
||||
* Gets the object deserialized by {@link execute(byte[])} method.
|
||||
*/
|
||||
public Object getData() {
|
||||
public MessagePackObject getData() {
|
||||
return impl.getData();
|
||||
}
|
||||
|
||||
@@ -462,6 +457,15 @@ public class Unpacker implements Iterable<Object> {
|
||||
return impl.unpackLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets one {@code BigInteger} value from the buffer.
|
||||
* This method calls {@link fill()} method if needed.
|
||||
* @throws MessageTypeException the first value of the buffer is not a {@code BigInteger}.
|
||||
*/
|
||||
public BigInteger unpackBigInteger() throws IOException, MessageTypeException {
|
||||
return impl.unpackBigInteger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets one {@code float} value from the buffer.
|
||||
* This method calls {@link fill()} method if needed.
|
||||
@@ -536,14 +540,23 @@ public class Unpacker implements Iterable<Object> {
|
||||
return impl.unpackRawBody(length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets one raw bytes from the buffer.
|
||||
* Gets one raw object (header + body) from the buffer.
|
||||
* This method calls {@link fill()} method if needed.
|
||||
*/
|
||||
public byte[] unpackByteArray() throws IOException {
|
||||
return impl.unpackByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets one raw object (header + body) from the buffer.
|
||||
* This method calls {@link fill()} method if needed.
|
||||
*/
|
||||
public ByteBuffer unpackByteBuffer() throws IOException {
|
||||
return impl.unpackByteBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets one {@code String} value from the buffer.
|
||||
* This method calls {@link fill()} method if needed.
|
||||
@@ -557,16 +570,41 @@ public class Unpacker implements Iterable<Object> {
|
||||
* Gets one {@code Object} value from the buffer.
|
||||
* This method calls {@link fill()} method if needed.
|
||||
*/
|
||||
final public Object unpackObject() throws IOException {
|
||||
final public MessagePackObject unpackObject() throws IOException {
|
||||
return impl.unpackObject();
|
||||
}
|
||||
|
||||
final public boolean tryUnpackNull() throws IOException {
|
||||
return impl.tryUnpackNull();
|
||||
}
|
||||
|
||||
final public void unpack(MessageUnpackable obj) throws IOException, MessageTypeException {
|
||||
obj.messageUnpack(this);
|
||||
}
|
||||
|
||||
final public boolean tryUnpackNull() throws IOException {
|
||||
return impl.tryUnpackNull();
|
||||
//final public MessagePackObject unpack() throws IOException {
|
||||
// return unpackObject();
|
||||
//}
|
||||
|
||||
final public <T> T unpack(T to) throws IOException, MessageTypeException {
|
||||
return unpack((Class<T>)to.getClass(), to);
|
||||
}
|
||||
|
||||
final public <T> T unpack(Class<T> klass) throws IOException, MessageTypeException {
|
||||
return unpack(klass, null);
|
||||
}
|
||||
|
||||
final public <T> T unpack(Class<T> klass, T to) throws IOException, MessageTypeException {
|
||||
if(tryUnpackNull()) { return null; }
|
||||
return (T)TemplateRegistry.lookup(klass).unpack(this, to);
|
||||
}
|
||||
|
||||
final public Object unpack(Template tmpl) throws IOException, MessageTypeException {
|
||||
return unpack(tmpl, null);
|
||||
}
|
||||
|
||||
final public <T> T unpack(Template tmpl, T to) throws IOException, MessageTypeException {
|
||||
return (T)tmpl.unpack(this, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -18,11 +18,8 @@
|
||||
package org.msgpack;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
//import java.math.BigInteger;
|
||||
import org.msgpack.*;
|
||||
import org.msgpack.schema.GenericSchema;
|
||||
import org.msgpack.schema.IMapSchema;
|
||||
import org.msgpack.schema.IArraySchema;
|
||||
import java.math.BigInteger;
|
||||
import org.msgpack.object.*;
|
||||
|
||||
public class UnpackerImpl {
|
||||
static final int CS_HEADER = 0x00;
|
||||
@@ -55,30 +52,19 @@ public class UnpackerImpl {
|
||||
private int[] stack_ct = new int[MAX_STACK_SIZE];
|
||||
private int[] stack_count = new int[MAX_STACK_SIZE];
|
||||
private Object[] stack_obj = new Object[MAX_STACK_SIZE];
|
||||
private Schema[] stack_schema = new Schema[MAX_STACK_SIZE];
|
||||
private int top_ct;
|
||||
private int top_count;
|
||||
private Object top_obj;
|
||||
private Schema top_schema;
|
||||
private ByteBuffer castBuffer = ByteBuffer.allocate(8);
|
||||
private boolean finished = false;
|
||||
private Object data = null;
|
||||
|
||||
private static final Schema GENERIC_SCHEMA = new GenericSchema();
|
||||
private Schema rootSchema;
|
||||
private MessagePackObject data = null;
|
||||
|
||||
public UnpackerImpl()
|
||||
{
|
||||
setSchema(GENERIC_SCHEMA);
|
||||
}
|
||||
|
||||
public void setSchema(Schema schema)
|
||||
{
|
||||
this.rootSchema = schema;
|
||||
reset();
|
||||
}
|
||||
|
||||
public final Object getData()
|
||||
public final MessagePackObject getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
@@ -94,7 +80,6 @@ public class UnpackerImpl {
|
||||
top_ct = 0;
|
||||
top_count = 0;
|
||||
top_obj = null;
|
||||
top_schema = rootSchema;
|
||||
}
|
||||
|
||||
public final void reset()
|
||||
@@ -127,20 +112,20 @@ public class UnpackerImpl {
|
||||
|
||||
if((b & 0x80) == 0) { // Positive Fixnum
|
||||
//System.out.println("positive fixnum "+b);
|
||||
obj = top_schema.createFromByte((byte)b);
|
||||
obj = IntegerType.create((byte)b);
|
||||
break _push;
|
||||
}
|
||||
|
||||
if((b & 0xe0) == 0xe0) { // Negative Fixnum
|
||||
//System.out.println("negative fixnum "+b);
|
||||
obj = top_schema.createFromByte((byte)b);
|
||||
obj = IntegerType.create((byte)b);
|
||||
break _push;
|
||||
}
|
||||
|
||||
if((b & 0xe0) == 0xa0) { // FixRaw
|
||||
trail = b & 0x1f;
|
||||
if(trail == 0) {
|
||||
obj = top_schema.createFromRaw(new byte[0], 0, 0);
|
||||
obj = RawType.create(new byte[0]);
|
||||
break _push;
|
||||
}
|
||||
cs = ACS_RAW_VALUE;
|
||||
@@ -151,25 +136,20 @@ public class UnpackerImpl {
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IArraySchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
count = b & 0x0f;
|
||||
//System.out.println("fixarray count:"+count);
|
||||
obj = new Object[count];
|
||||
obj = new MessagePackObject[count];
|
||||
if(count == 0) {
|
||||
obj = ((IArraySchema)top_schema).createFromArray((Object[])obj);
|
||||
obj = ArrayType.create((MessagePackObject[])obj);
|
||||
break _push;
|
||||
}
|
||||
++top;
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_ARRAY_ITEM;
|
||||
top_count = count;
|
||||
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
|
||||
break _header_again;
|
||||
}
|
||||
|
||||
@@ -177,13 +157,10 @@ public class UnpackerImpl {
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IMapSchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
count = b & 0x0f;
|
||||
obj = new Object[count*2];
|
||||
obj = new MessagePackObject[count*2];
|
||||
if(count == 0) {
|
||||
obj = ((IMapSchema)top_schema).createFromMap((Object[])obj);
|
||||
obj = MapType.create((MessagePackObject[])obj);
|
||||
break _push;
|
||||
}
|
||||
//System.out.println("fixmap count:"+count);
|
||||
@@ -191,23 +168,21 @@ public class UnpackerImpl {
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_MAP_KEY;
|
||||
top_count = count;
|
||||
top_schema = ((IMapSchema)top_schema).getKeySchema();
|
||||
break _header_again;
|
||||
}
|
||||
|
||||
switch(b & 0xff) { // FIXME
|
||||
case 0xc0: // nil
|
||||
obj = top_schema.createFromNil();
|
||||
obj = NilType.create();
|
||||
break _push;
|
||||
case 0xc2: // false
|
||||
obj = top_schema.createFromBoolean(false);
|
||||
obj = BooleanType.create(false);
|
||||
break _push;
|
||||
case 0xc3: // true
|
||||
obj = top_schema.createFromBoolean(true);
|
||||
obj = BooleanType.create(true);
|
||||
break _push;
|
||||
case 0xca: // float
|
||||
case 0xcb: // double
|
||||
@@ -251,13 +226,13 @@ public class UnpackerImpl {
|
||||
case CS_FLOAT:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
obj = top_schema.createFromFloat( castBuffer.getFloat(0) );
|
||||
obj = FloatType.create( castBuffer.getFloat(0) );
|
||||
//System.out.println("float "+obj);
|
||||
break _push;
|
||||
case CS_DOUBLE:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 8);
|
||||
obj = top_schema.createFromDouble( castBuffer.getDouble(0) );
|
||||
obj = FloatType.create( castBuffer.getDouble(0) );
|
||||
//System.out.println("double "+obj);
|
||||
break _push;
|
||||
case CS_UINT_8:
|
||||
@@ -265,7 +240,7 @@ public class UnpackerImpl {
|
||||
//System.out.println(src[n]);
|
||||
//System.out.println(src[n+1]);
|
||||
//System.out.println(src[n-1]);
|
||||
obj = top_schema.createFromShort( (short)((src[n]) & 0xff) );
|
||||
obj = IntegerType.create( (short)((src[n]) & 0xff) );
|
||||
//System.out.println("uint8 "+obj);
|
||||
break _push;
|
||||
case CS_UINT_16:
|
||||
@@ -273,13 +248,13 @@ public class UnpackerImpl {
|
||||
//System.out.println(src[n+1]);
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
obj = top_schema.createFromInt( ((int)castBuffer.getShort(0)) & 0xffff );
|
||||
obj = IntegerType.create( ((int)castBuffer.getShort(0)) & 0xffff );
|
||||
//System.out.println("uint 16 "+obj);
|
||||
break _push;
|
||||
case CS_UINT_32:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
obj = top_schema.createFromLong( ((long)castBuffer.getInt(0)) & 0xffffffffL );
|
||||
obj = IntegerType.create( ((long)castBuffer.getInt(0)) & 0xffffffffL );
|
||||
//System.out.println("uint 32 "+obj);
|
||||
break _push;
|
||||
case CS_UINT_64:
|
||||
@@ -288,38 +263,36 @@ public class UnpackerImpl {
|
||||
{
|
||||
long o = castBuffer.getLong(0);
|
||||
if(o < 0) {
|
||||
// FIXME
|
||||
//obj = GenericBigInteger.valueOf(o & 0x7fffffffL).setBit(31);
|
||||
throw new UnpackException("uint 64 bigger than 0x7fffffff is not supported");
|
||||
obj = IntegerType.create(new BigInteger(1, castBuffer.array()));
|
||||
} else {
|
||||
obj = top_schema.createFromLong( o );
|
||||
obj = IntegerType.create(o);
|
||||
}
|
||||
}
|
||||
break _push;
|
||||
case CS_INT_8:
|
||||
obj = top_schema.createFromByte( src[n] );
|
||||
obj = IntegerType.create( src[n] );
|
||||
break _push;
|
||||
case CS_INT_16:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
obj = top_schema.createFromShort( castBuffer.getShort(0) );
|
||||
obj = IntegerType.create( castBuffer.getShort(0) );
|
||||
break _push;
|
||||
case CS_INT_32:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
obj = top_schema.createFromInt( castBuffer.getInt(0) );
|
||||
obj = IntegerType.create( castBuffer.getInt(0) );
|
||||
break _push;
|
||||
case CS_INT_64:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 8);
|
||||
obj = top_schema.createFromLong( castBuffer.getLong(0) );
|
||||
obj = IntegerType.create( castBuffer.getLong(0) );
|
||||
break _push;
|
||||
case CS_RAW_16:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
trail = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||
if(trail == 0) {
|
||||
obj = top_schema.createFromRaw(new byte[0], 0, 0);
|
||||
obj = RawType.create(new byte[0]);
|
||||
break _push;
|
||||
}
|
||||
cs = ACS_RAW_VALUE;
|
||||
@@ -330,77 +303,69 @@ public class UnpackerImpl {
|
||||
// FIXME overflow check
|
||||
trail = castBuffer.getInt(0) & 0x7fffffff;
|
||||
if(trail == 0) {
|
||||
obj = top_schema.createFromRaw(new byte[0], 0, 0);
|
||||
obj = RawType.create(new byte[0]);
|
||||
break _push;
|
||||
}
|
||||
cs = ACS_RAW_VALUE;
|
||||
case ACS_RAW_VALUE:
|
||||
obj = top_schema.createFromRaw(src, n, trail);
|
||||
break _fixed_trail_again;
|
||||
case ACS_RAW_VALUE: {
|
||||
// TODO zero-copy buffer
|
||||
byte[] raw = new byte[trail];
|
||||
System.arraycopy(src, n, raw, 0, trail);
|
||||
obj = RawType.create(raw);
|
||||
}
|
||||
break _push;
|
||||
case CS_ARRAY_16:
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IArraySchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
count = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||
obj = new Object[count];
|
||||
obj = new MessagePackObject[count];
|
||||
if(count == 0) {
|
||||
obj = ((IArraySchema)top_schema).createFromArray((Object[])obj);
|
||||
obj = ArrayType.create((MessagePackObject[])obj);
|
||||
break _push;
|
||||
}
|
||||
++top;
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_ARRAY_ITEM;
|
||||
top_count = count;
|
||||
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
|
||||
break _header_again;
|
||||
case CS_ARRAY_32:
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IArraySchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
// FIXME overflow check
|
||||
count = castBuffer.getInt(0) & 0x7fffffff;
|
||||
obj = new Object[count];
|
||||
obj = new MessagePackObject[count];
|
||||
if(count == 0) {
|
||||
obj = ((IArraySchema)top_schema).createFromArray((Object[])obj);
|
||||
obj = ArrayType.create((MessagePackObject[])obj);
|
||||
break _push;
|
||||
}
|
||||
++top;
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_ARRAY_ITEM;
|
||||
top_count = count;
|
||||
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
|
||||
break _header_again;
|
||||
case CS_MAP_16:
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IMapSchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
count = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||
obj = new Object[count*2];
|
||||
obj = new MessagePackObject[count*2];
|
||||
if(count == 0) {
|
||||
obj = ((IMapSchema)top_schema).createFromMap((Object[])obj);
|
||||
obj = MapType.create((MessagePackObject[])obj);
|
||||
break _push;
|
||||
}
|
||||
//System.out.println("fixmap count:"+count);
|
||||
@@ -408,26 +373,21 @@ public class UnpackerImpl {
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_MAP_KEY;
|
||||
top_count = count;
|
||||
top_schema = ((IMapSchema)top_schema).getKeySchema();
|
||||
break _header_again;
|
||||
case CS_MAP_32:
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IMapSchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
// FIXME overflow check
|
||||
count = castBuffer.getInt(0) & 0x7fffffff;
|
||||
obj = new Object[count*2];
|
||||
obj = new MessagePackObject[count*2];
|
||||
if(count == 0) {
|
||||
obj = ((IMapSchema)top_schema).createFromMap((Object[])obj);
|
||||
obj = MapType.create((MessagePackObject[])obj);
|
||||
break _push;
|
||||
}
|
||||
//System.out.println("fixmap count:"+count);
|
||||
@@ -435,11 +395,9 @@ public class UnpackerImpl {
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_MAP_KEY;
|
||||
top_count = count;
|
||||
top_schema = ((IMapSchema)top_schema).getKeySchema();
|
||||
break _header_again;
|
||||
default:
|
||||
throw new UnpackException("parse error");
|
||||
@@ -454,7 +412,7 @@ public class UnpackerImpl {
|
||||
//System.out.println("push top:"+top);
|
||||
if(top == -1) {
|
||||
++i;
|
||||
data = obj;
|
||||
data = (MessagePackObject)obj;
|
||||
finished = true;
|
||||
break _out;
|
||||
}
|
||||
@@ -468,14 +426,10 @@ public class UnpackerImpl {
|
||||
top_obj = stack_obj[top];
|
||||
top_ct = stack_ct[top];
|
||||
top_count = stack_count[top];
|
||||
top_schema = stack_schema[top];
|
||||
obj = ((IArraySchema)top_schema).createFromArray(ar);
|
||||
obj = ArrayType.create((MessagePackObject[])ar);
|
||||
stack_obj[top] = null;
|
||||
stack_schema[top] = null;
|
||||
--top;
|
||||
break _push;
|
||||
} else {
|
||||
top_schema = ((IArraySchema)stack_schema[top]).getElementSchema(ar.length - top_count);
|
||||
}
|
||||
break _header_again;
|
||||
}
|
||||
@@ -484,7 +438,6 @@ public class UnpackerImpl {
|
||||
Object[] mp = (Object[])top_obj;
|
||||
mp[mp.length - top_count*2] = obj;
|
||||
top_ct = CT_MAP_VALUE;
|
||||
top_schema = ((IMapSchema)stack_schema[top]).getValueSchema();
|
||||
break _header_again;
|
||||
}
|
||||
case CT_MAP_VALUE: {
|
||||
@@ -495,10 +448,8 @@ public class UnpackerImpl {
|
||||
top_obj = stack_obj[top];
|
||||
top_ct = stack_ct[top];
|
||||
top_count = stack_count[top];
|
||||
top_schema = stack_schema[top];
|
||||
obj = ((IMapSchema)top_schema).createFromMap(mp);
|
||||
obj = MapType.create((MessagePackObject[])mp);
|
||||
stack_obj[top] = null;
|
||||
stack_schema[top] = null;
|
||||
--top;
|
||||
break _push;
|
||||
}
|
||||
|
28
java/src/main/java/org/msgpack/annotation/Ignore.java
Normal file
28
java/src/main/java/org/msgpack/annotation/Ignore.java
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Ignore {
|
||||
}
|
29
java/src/main/java/org/msgpack/annotation/Index.java
Normal file
29
java/src/main/java/org/msgpack/annotation/Index.java
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Index {
|
||||
int value();
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2011 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.msgpack.template.FieldOption;
|
||||
|
||||
/**
|
||||
* Annotation for java beans class
|
||||
* @author takeshita
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MessagePackBeans {
|
||||
FieldOption value() default FieldOption.DEFAULT;
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MessagePackDelegate {
|
||||
String value();
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.msgpack.template.FieldOption;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MessagePackMessage {
|
||||
FieldOption value() default FieldOption.DEFAULT;
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MessagePackOrdinalEnum {
|
||||
}
|
28
java/src/main/java/org/msgpack/annotation/Nullable.java
Normal file
28
java/src/main/java/org/msgpack/annotation/Nullable.java
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Nullable {
|
||||
}
|
28
java/src/main/java/org/msgpack/annotation/Optional.java
Normal file
28
java/src/main/java/org/msgpack/annotation/Optional.java
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Optional {
|
||||
}
|
28
java/src/main/java/org/msgpack/annotation/Required.java
Normal file
28
java/src/main/java/org/msgpack/annotation/Required.java
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Required {
|
||||
}
|
462
java/src/main/java/org/msgpack/buffer/VectoredByteBuffer.java
Normal file
462
java/src/main/java/org/msgpack/buffer/VectoredByteBuffer.java
Normal file
@@ -0,0 +1,462 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2010 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.
|
||||
//
|
||||
package org.msgpack.buffer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.GatheringByteChannel;
|
||||
import java.nio.channels.ScatteringByteChannel;
|
||||
|
||||
public class VectoredByteBuffer implements GatheringByteChannel, ScatteringByteChannel {
|
||||
private List<ByteBuffer> vec = new ArrayList<ByteBuffer>();
|
||||
private ByteBuffer internalBuffer;
|
||||
private ByteBuffer lastInternalBuffer;
|
||||
private int chunkSize;
|
||||
private int referenceThreshold;
|
||||
|
||||
public VectoredByteBuffer() {
|
||||
this(32*1024);
|
||||
}
|
||||
|
||||
public VectoredByteBuffer(int chunkSize) {
|
||||
this(chunkSize, 32);
|
||||
}
|
||||
|
||||
public VectoredByteBuffer(int chunkSize, int referenceThreshold) {
|
||||
this.chunkSize = chunkSize;
|
||||
this.referenceThreshold = referenceThreshold;
|
||||
internalBuffer = ByteBuffer.allocateDirect(chunkSize);
|
||||
}
|
||||
|
||||
|
||||
public void setChunkSize(int chunkSize) {
|
||||
this.chunkSize = chunkSize;
|
||||
}
|
||||
|
||||
public int getChunkSize(int chunkSize) {
|
||||
return this.chunkSize;
|
||||
}
|
||||
|
||||
public void setReferenceThreshold(int referenceThreshold) {
|
||||
this.referenceThreshold = referenceThreshold;
|
||||
}
|
||||
|
||||
public int getReferenceThreshold(int referenceThreshold) {
|
||||
return this.referenceThreshold;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return true; // FIXME?
|
||||
}
|
||||
|
||||
|
||||
public synchronized void reset() {
|
||||
vec.clear();
|
||||
lastInternalBuffer = null;
|
||||
}
|
||||
|
||||
|
||||
public void write(byte[] b) {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) {
|
||||
if(off < 0 || len < 0 || b.length < off+len) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
if(referenceThreshold >= 0 && len > referenceThreshold) {
|
||||
writeReference(b, off, len);
|
||||
} else {
|
||||
writeCopy(b, off, len);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int b) {
|
||||
byte[] ba = new byte[1];
|
||||
ba[0] = (byte)b;
|
||||
write(ba);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ByteBuffer src) {
|
||||
int slen = src.remaining();
|
||||
if(referenceThreshold >= 0 && slen > referenceThreshold) {
|
||||
writeCopy(src);
|
||||
} else {
|
||||
writeReference(src);
|
||||
}
|
||||
return slen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long write(ByteBuffer[] srcs) {
|
||||
return write(srcs, 0, srcs.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long write(ByteBuffer[] srcs, int offset, int length) {
|
||||
if(offset < 0 || length < 0 || srcs.length < offset+length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
long total = 0;
|
||||
for(int i=offset; offset < length; offset++) {
|
||||
ByteBuffer src = srcs[i];
|
||||
total += write(src);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private synchronized void writeCopy(byte[] b, int off, int len) {
|
||||
int ipos = internalBuffer.position();
|
||||
if(internalBuffer.capacity() - ipos < len) {
|
||||
// allocate new buffer
|
||||
int nsize = chunkSize > len ? chunkSize : len;
|
||||
internalBuffer = ByteBuffer.allocateDirect(nsize);
|
||||
ipos = 0;
|
||||
} else if(internalBuffer == lastInternalBuffer) {
|
||||
// optimization: concatenates to the last buffer instead
|
||||
// of adding new reference
|
||||
ByteBuffer dup = vec.get(vec.size()-1);
|
||||
internalBuffer.put(b, off, len);
|
||||
dup.limit(ipos + len);
|
||||
return;
|
||||
}
|
||||
internalBuffer.put(b, off, len);
|
||||
ByteBuffer dup = internalBuffer.duplicate();
|
||||
dup.position(ipos);
|
||||
dup.mark();
|
||||
dup.limit(ipos + len);
|
||||
vec.add(dup);
|
||||
lastInternalBuffer = internalBuffer;
|
||||
}
|
||||
|
||||
private synchronized void writeCopy(ByteBuffer src) {
|
||||
int slen = src.remaining();
|
||||
int ipos = internalBuffer.position();
|
||||
if(internalBuffer.capacity() - ipos < slen) {
|
||||
// allocate new buffer
|
||||
int nsize = chunkSize > slen ? chunkSize : slen;
|
||||
internalBuffer = ByteBuffer.allocateDirect(nsize);
|
||||
ipos = 0;
|
||||
} else if(internalBuffer == lastInternalBuffer) {
|
||||
// optimization: concatenates to the last buffer instead
|
||||
// of adding new reference
|
||||
ByteBuffer dup = vec.get(vec.size()-1);
|
||||
int dpos = dup.position();
|
||||
internalBuffer.put(src);
|
||||
ByteBuffer dup2 = internalBuffer.duplicate();
|
||||
dup2.position(dpos);
|
||||
dup2.limit(ipos + slen);
|
||||
vec.set(vec.size()-1, dup2);
|
||||
return;
|
||||
}
|
||||
internalBuffer.put(src);
|
||||
ByteBuffer dup = internalBuffer.duplicate();
|
||||
dup.position(ipos);
|
||||
dup.mark();
|
||||
dup.limit(ipos + slen);
|
||||
vec.add(dup);
|
||||
lastInternalBuffer = internalBuffer;
|
||||
}
|
||||
|
||||
private synchronized void writeReference(byte[] b, int off, int len) {
|
||||
ByteBuffer buf = ByteBuffer.wrap(b, off, len);
|
||||
vec.add(buf);
|
||||
lastInternalBuffer = null;
|
||||
}
|
||||
|
||||
private synchronized void writeReference(ByteBuffer src) {
|
||||
ByteBuffer buf = src.duplicate();
|
||||
vec.add(buf);
|
||||
lastInternalBuffer = null;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void writeTo(java.io.OutputStream out) throws IOException {
|
||||
byte[] tmpbuf = null;
|
||||
for(int i=0; i < vec.size(); i++) {
|
||||
ByteBuffer r = vec.get(i);
|
||||
int rpos = r.position();
|
||||
int rlen = r.limit() - rpos;
|
||||
if(r.hasArray()) {
|
||||
byte[] array = r.array();
|
||||
out.write(array, rpos, rlen);
|
||||
} else {
|
||||
if(tmpbuf == null) {
|
||||
int max = rlen;
|
||||
for(int j=i+1; j < vec.size(); j++) {
|
||||
ByteBuffer c = vec.get(j);
|
||||
int clen = c.remaining();
|
||||
if(max < clen) {
|
||||
max = clen;
|
||||
}
|
||||
}
|
||||
tmpbuf = new byte[max];
|
||||
}
|
||||
r.get(tmpbuf, 0, rlen);
|
||||
r.position(rpos);
|
||||
out.write(tmpbuf, 0, rlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized byte[] toByteArray() {
|
||||
byte[] out = new byte[available()];
|
||||
int off = 0;
|
||||
for(ByteBuffer r: vec) {
|
||||
int rpos = r.position();
|
||||
int rlen = r.limit() - rpos;
|
||||
r.get(out, off, rlen);
|
||||
r.position(rpos);
|
||||
off += rlen;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
public synchronized int available() {
|
||||
int total = 0;
|
||||
for(ByteBuffer r : vec) {
|
||||
total += r.remaining();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public synchronized int read(byte[] b) {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
public synchronized int read(byte[] b, int off, int len) {
|
||||
if(off < 0 || len < 0 || b.length < off+len) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int start = len;
|
||||
while(!vec.isEmpty()) {
|
||||
ByteBuffer r = vec.get(0);
|
||||
int rlen = r.remaining();
|
||||
if(rlen <= len) {
|
||||
r.get(b, off, rlen);
|
||||
vec.remove(0);
|
||||
off += rlen;
|
||||
len -= rlen;
|
||||
} else {
|
||||
r.get(b, off, len);
|
||||
return start;
|
||||
}
|
||||
}
|
||||
return start - len;
|
||||
}
|
||||
|
||||
public synchronized int read() {
|
||||
byte[] ba = new byte[1];
|
||||
if(read(ba) >= 1) {
|
||||
return ba[0];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int read(ByteBuffer dst) {
|
||||
int len = dst.remaining();
|
||||
int start = len;
|
||||
while(!vec.isEmpty()) {
|
||||
ByteBuffer r = vec.get(0);
|
||||
int rlen = r.remaining();
|
||||
if(rlen <= len) {
|
||||
dst.put(r);
|
||||
vec.remove(0);
|
||||
len -= rlen;
|
||||
} else {
|
||||
int blim = r.limit();
|
||||
r.limit(len);
|
||||
try {
|
||||
dst.put(r);
|
||||
} finally {
|
||||
r.limit(blim);
|
||||
}
|
||||
return start;
|
||||
}
|
||||
}
|
||||
return start - len;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long read(ByteBuffer[] dsts) {
|
||||
return read(dsts, 0, dsts.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long read(ByteBuffer[] dsts, int offset, int length) {
|
||||
if(offset < 0 || length < 0 || dsts.length < offset+length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
long total = 0;
|
||||
for(int i=offset; i < length; i++) {
|
||||
ByteBuffer dst = dsts[i];
|
||||
int dlen = dst.remaining();
|
||||
int rlen = read(dsts[i]);
|
||||
total += rlen;
|
||||
if(rlen < dlen) {
|
||||
return total;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public synchronized long read(GatheringByteChannel to) throws IOException {
|
||||
long total = to.write(vec.toArray(new ByteBuffer[0]));
|
||||
while(!vec.isEmpty()) {
|
||||
ByteBuffer r = vec.get(0);
|
||||
if(r.remaining() == 0) {
|
||||
vec.remove(0);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public synchronized long skip(long len) {
|
||||
if(len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
long start = len;
|
||||
while(!vec.isEmpty()) {
|
||||
ByteBuffer r = vec.get(0);
|
||||
int rlen = r.remaining();
|
||||
if(rlen <= len) {
|
||||
r.position(r.position()+rlen);
|
||||
vec.remove(0);
|
||||
len -= rlen;
|
||||
} else {
|
||||
r.position((int)(r.position()+len));
|
||||
return start;
|
||||
}
|
||||
}
|
||||
return start - len;
|
||||
}
|
||||
|
||||
|
||||
public final static class OutputStream extends java.io.OutputStream {
|
||||
private VectoredByteBuffer vbb;
|
||||
|
||||
OutputStream(VectoredByteBuffer vbb) {
|
||||
this.vbb = vbb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) {
|
||||
vbb.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) {
|
||||
vbb.write(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) {
|
||||
vbb.write(b);
|
||||
}
|
||||
|
||||
public int write(ByteBuffer src) {
|
||||
return vbb.write(src);
|
||||
}
|
||||
|
||||
public long write(ByteBuffer[] srcs) {
|
||||
return vbb.write(srcs);
|
||||
}
|
||||
|
||||
public long write(ByteBuffer[] srcs, int offset, int length) {
|
||||
return vbb.write(srcs, offset, length);
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
vbb.writeTo(out);
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return vbb.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public final static class InputStream extends java.io.InputStream {
|
||||
private VectoredByteBuffer vbb;
|
||||
|
||||
InputStream(VectoredByteBuffer vbb) {
|
||||
this.vbb = vbb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return vbb.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) {
|
||||
return vbb.read(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) {
|
||||
return vbb.read(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() {
|
||||
return vbb.read();
|
||||
}
|
||||
|
||||
public int read(ByteBuffer dst) {
|
||||
return vbb.read(dst);
|
||||
}
|
||||
|
||||
public long read(ByteBuffer[] dsts, int offset, int length) {
|
||||
return vbb.read(dsts, offset, length);
|
||||
}
|
||||
|
||||
public long read(GatheringByteChannel to) throws IOException {
|
||||
return vbb.read(to);
|
||||
}
|
||||
|
||||
public long skip(long len) {
|
||||
return vbb.skip(len);
|
||||
}
|
||||
}
|
||||
|
||||
public OutputStream outputStream() {
|
||||
return new OutputStream(this);
|
||||
}
|
||||
|
||||
public InputStream inputStream() {
|
||||
return new InputStream(this);
|
||||
}
|
||||
}
|
||||
|
81
java/src/main/java/org/msgpack/object/ArrayType.java
Normal file
81
java/src/main/java/org/msgpack/object/ArrayType.java
Normal file
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.object;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ArrayType extends MessagePackObject {
|
||||
private MessagePackObject[] array;
|
||||
|
||||
ArrayType(MessagePackObject[] array) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public static ArrayType create(MessagePackObject[] array) {
|
||||
return new ArrayType(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isArrayType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessagePackObject[] asArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MessagePackObject> asList() {
|
||||
return Arrays.asList(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagePack(Packer pk) throws IOException {
|
||||
pk.packArray(array.length);
|
||||
for(int i=0; i < array.length; i++) {
|
||||
array[i].messagePack(pk);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
return Arrays.equals(((ArrayType)obj).array, array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return array.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
MessagePackObject[] copy = new MessagePackObject[array.length];
|
||||
for(int i=0; i < array.length; i++) {
|
||||
copy[i] = (MessagePackObject)array[i].clone();
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
131
java/src/main/java/org/msgpack/object/BigIntegerTypeIMPL.java
Normal file
131
java/src/main/java/org/msgpack/object/BigIntegerTypeIMPL.java
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.object;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
class BigIntegerTypeIMPL extends IntegerType {
|
||||
private BigInteger value;
|
||||
|
||||
BigIntegerTypeIMPL(BigInteger value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte asByte() {
|
||||
if(value.compareTo(BigInteger.valueOf((long)Byte.MAX_VALUE)) > 0) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
return value.byteValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short asShort() {
|
||||
if(value.compareTo(BigInteger.valueOf((long)Short.MAX_VALUE)) > 0) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
return value.shortValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int asInt() {
|
||||
if(value.compareTo(BigInteger.valueOf((long)Integer.MAX_VALUE)) > 0) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long asLong() {
|
||||
if(value.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
|
||||
throw new MessageTypeException("type error");
|
||||
}
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger asBigInteger() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte byteValue() {
|
||||
return value.byteValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short shortValue() {
|
||||
return value.shortValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger bigIntegerValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return value.floatValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return value.doubleValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagePack(Packer pk) throws IOException {
|
||||
pk.packBigInteger(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj.getClass() != getClass()) {
|
||||
if(obj.getClass() == ShortIntegerTypeIMPL.class) {
|
||||
return BigInteger.valueOf(((ShortIntegerTypeIMPL)obj).longValue()).equals(value);
|
||||
} else if(obj.getClass() == LongIntegerTypeIMPL.class) {
|
||||
return BigInteger.valueOf(((LongIntegerTypeIMPL)obj).longValue()).equals(value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return ((BigIntegerTypeIMPL)obj).value.equals(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new BigIntegerTypeIMPL(value);
|
||||
}
|
||||
}
|
||||
|
@@ -15,50 +15,57 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
package org.msgpack.schema;
|
||||
package org.msgpack.object;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class BooleanSchema extends Schema {
|
||||
public BooleanSchema() { }
|
||||
public class BooleanType extends MessagePackObject {
|
||||
private boolean value;
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "Boolean";
|
||||
BooleanType(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static BooleanType create(boolean value) {
|
||||
return new BooleanType(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "boolean";
|
||||
public boolean isBooleanType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
if(obj instanceof Boolean) {
|
||||
pk.packBoolean((Boolean)obj);
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
public boolean asBoolean() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagePack(Packer pk) throws IOException {
|
||||
pk.packBoolean(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
return ((BooleanType)obj).value == value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if(value) {
|
||||
return 1231;
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
return 1237;
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean convertBoolean(Object obj) throws MessageTypeException {
|
||||
if(obj instanceof Boolean) {
|
||||
return (Boolean)obj;
|
||||
}
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
return convertBoolean(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromBoolean(boolean v) {
|
||||
return v;
|
||||
public Object clone() {
|
||||
return new BooleanType(value);
|
||||
}
|
||||
}
|
||||
|
101
java/src/main/java/org/msgpack/object/DoubleTypeIMPL.java
Normal file
101
java/src/main/java/org/msgpack/object/DoubleTypeIMPL.java
Normal file
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 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.
|
||||
//
|
||||
package org.msgpack.object;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
class DoubleTypeIMPL extends FloatType {
|
||||
private double value;
|
||||
|
||||
public DoubleTypeIMPL(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float asFloat() {
|
||||
// FIXME check overflow, underflow?
|
||||
return (float)value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double asDouble() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte byteValue() {
|
||||
return (byte)value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short shortValue() {
|
||||
return (short)value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return (long)value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger bigIntegerValue() {
|
||||
return BigInteger.valueOf((long)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return (float)value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return (double)value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagePack(Packer pk) throws IOException {
|
||||
pk.packDouble(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
return ((DoubleTypeIMPL)obj).value == value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
long v = Double.doubleToLongBits(value);
|
||||
return (int)(v^(v>>>32));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new DoubleTypeIMPL(value);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user