mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-10-21 15:51:44 +02:00
Compare commits
454 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
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 | ||
![]() |
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 | ||
![]() |
ff0e1bbbc0 | ||
![]() |
18c712cd99 | ||
![]() |
8de1f764fd | ||
![]() |
a91c1ec6d9 | ||
![]() |
78f542f6c0 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.o
|
||||
*.so
|
||||
ruby/Makefile
|
@@ -1,5 +1,16 @@
|
||||
|
||||
2010-07-27 version 0.5.3:
|
||||
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
|
||||
|
@@ -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.3)
|
||||
AM_INIT_AUTOMAKE(msgpack, 0.5.5)
|
||||
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,7 +24,7 @@ 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\
|
||||
@@ -40,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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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; }
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#define MSGPACK_TYPE_FIXINT_HPP__
|
||||
|
||||
#include "msgpack/object.hpp"
|
||||
#include "msgpack/type/int.hpp"
|
||||
|
||||
namespace msgpack {
|
||||
|
||||
@@ -29,10 +30,13 @@ 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:
|
||||
const T value;
|
||||
T value;
|
||||
};
|
||||
|
||||
|
||||
@@ -50,6 +54,32 @@ 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; }
|
||||
@@ -66,6 +96,7 @@ 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; }
|
||||
@@ -83,6 +114,58 @@ 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();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
|
@@ -22,3 +22,34 @@ TEST(fixint, size)
|
||||
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>();
|
||||
}
|
||||
|
||||
|
@@ -126,7 +126,7 @@ pack_(List) when is_list(List) ->
|
||||
pack_({Map}) when is_list(Map) ->
|
||||
pack_map(Map);
|
||||
pack_(Other) ->
|
||||
throw({error, {badarg, Other}}).
|
||||
throw({badarg, Other}).
|
||||
|
||||
|
||||
-spec pack_uint_(non_neg_integer()) -> binary().
|
||||
@@ -387,4 +387,9 @@ benchmark_test()->
|
||||
{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.
|
||||
|
@@ -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,48 @@
|
||||
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.4.0.1
|
||||
Synopsis: A Haskell binding to 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 binding to 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-2010, 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.1 && < 0.2.2,
|
||||
MonadCatchIO-transformers >= 0.2.2 && < 0.2.3,
|
||||
bytestring >= 0.9 && < 0.10,
|
||||
vector >= 0.6.0 && < 0.6.1,
|
||||
iteratee >= 0.4 && < 0.5,
|
||||
attoparsec >= 0.8.1 && < 0.8.2,
|
||||
binary >= 0.5.0 && < 0.5.1,
|
||||
data-binary-ieee754 >= 0.4 && < 0.5,
|
||||
deepseq >= 1.1 && <1.2,
|
||||
template-haskell >= 2.4 && < 2.5
|
||||
|
||||
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.Pack
|
||||
Data.MessagePack.Unpack
|
||||
Data.MessagePack.Object
|
||||
Data.MessagePack.Iteratee
|
||||
Data.MessagePack.Derive
|
||||
|
||||
C-Sources:
|
||||
cbits/msgpack.c
|
||||
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,91 @@
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack(
|
||||
module Data.MessagePack.Base,
|
||||
module Data.MessagePack.Class,
|
||||
module Data.MessagePack.Feed,
|
||||
module Data.MessagePack.Monad,
|
||||
module Data.MessagePack.Stream,
|
||||
module Data.MessagePack.Pack,
|
||||
module Data.MessagePack.Unpack,
|
||||
module Data.MessagePack.Object,
|
||||
module Data.MessagePack.Iteratee,
|
||||
module Data.MessagePack.Derive,
|
||||
|
||||
-- * Pack and Unpack
|
||||
packb,
|
||||
unpackb,
|
||||
-- * Pack functions
|
||||
packToString,
|
||||
packToHandle,
|
||||
packToHandle',
|
||||
packToFile,
|
||||
|
||||
-- * Unpack functions
|
||||
unpackFromString,
|
||||
unpackFromHandle,
|
||||
unpackFromFile,
|
||||
unpackFromStringI,
|
||||
unpackFromHandleI,
|
||||
unpackFromFileI,
|
||||
|
||||
-- * Pure version of Pack and Unpack
|
||||
packb',
|
||||
unpackb',
|
||||
) where
|
||||
|
||||
import Data.ByteString (ByteString)
|
||||
import System.IO.Unsafe
|
||||
import qualified Control.Monad.CatchIO as CIO
|
||||
import Control.Monad.IO.Class
|
||||
import qualified Data.Attoparsec as A
|
||||
import Data.Binary.Put
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Lazy as L
|
||||
import qualified Data.Iteratee as I
|
||||
import System.IO
|
||||
|
||||
import Data.MessagePack.Base
|
||||
import Data.MessagePack.Class
|
||||
import Data.MessagePack.Feed
|
||||
import Data.MessagePack.Monad
|
||||
import Data.MessagePack.Stream
|
||||
import Data.MessagePack.Pack
|
||||
import Data.MessagePack.Unpack
|
||||
import Data.MessagePack.Object
|
||||
import Data.MessagePack.Iteratee
|
||||
import Data.MessagePack.Derive
|
||||
|
||||
-- | 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
|
||||
bufferSize :: Int
|
||||
bufferSize = 4 * 1024
|
||||
|
||||
-- | 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
|
||||
-- | Pack to ByteString.
|
||||
packToString :: Put -> L.ByteString
|
||||
packToString = runPut
|
||||
|
||||
-- | Pure version of 'packb'.
|
||||
packb' :: OBJECT a => a -> ByteString
|
||||
packb' dat = unsafePerformIO $ packb dat
|
||||
-- | Pack to Handle
|
||||
packToHandle :: Handle -> Put -> IO ()
|
||||
packToHandle h = L.hPutStr h . packToString
|
||||
|
||||
-- | Pure version of 'unpackb'.
|
||||
unpackb' :: OBJECT a => ByteString -> Result a
|
||||
unpackb' bs = unsafePerformIO $ unpackb bs
|
||||
-- | Pack to Handle and Flush Handle
|
||||
packToHandle' :: Handle -> Put -> IO ()
|
||||
packToHandle' h p = packToHandle h p >> hFlush h
|
||||
|
||||
-- | Pack to File
|
||||
packToFile :: FilePath -> Put -> IO ()
|
||||
packToFile path = L.writeFile path . packToString
|
||||
|
||||
-- | Unpack from ByteString
|
||||
unpackFromString :: (Monad m, IsByteString s) => s -> A.Parser a -> m a
|
||||
unpackFromString bs =
|
||||
unpackFromStringI bs . parserToIteratee
|
||||
|
||||
-- | Unpack from Handle
|
||||
unpackFromHandle :: CIO.MonadCatchIO m => Handle -> A.Parser a -> m a
|
||||
unpackFromHandle h =
|
||||
unpackFromHandleI h .parserToIteratee
|
||||
|
||||
-- | Unpack from File
|
||||
unpackFromFile :: CIO.MonadCatchIO m => FilePath -> A.Parser a -> m a
|
||||
unpackFromFile path =
|
||||
unpackFromFileI path . parserToIteratee
|
||||
|
||||
-- | Iteratee interface to unpack from ByteString
|
||||
unpackFromStringI :: (Monad m, IsByteString s) => s -> I.Iteratee B.ByteString m a -> m a
|
||||
unpackFromStringI bs =
|
||||
I.run . I.joinIM . I.enumPure1Chunk (toBS bs)
|
||||
|
||||
-- | Iteratee interface to unpack from Handle
|
||||
unpackFromHandleI :: CIO.MonadCatchIO m => Handle -> I.Iteratee B.ByteString m a -> m a
|
||||
unpackFromHandleI h =
|
||||
I.run . I.joinIM . enumHandleNonBlocking bufferSize h
|
||||
|
||||
-- | Iteratee interface to unpack from File
|
||||
unpackFromFileI :: CIO.MonadCatchIO m => FilePath -> I.Iteratee B.ByteString m a -> m a
|
||||
unpackFromFileI path p =
|
||||
CIO.bracket
|
||||
(liftIO $ openBinaryFile path ReadMode)
|
||||
(liftIO . hClose)
|
||||
(flip unpackFromHandleI p)
|
||||
|
@@ -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
|
82
haskell/src/Data/MessagePack/Iteratee.hs
Normal file
82
haskell/src/Data/MessagePack/Iteratee.hs
Normal file
@@ -0,0 +1,82 @@
|
||||
--------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : Data.MessagePack.Iteratee
|
||||
-- Copyright : (c) Hideyuki Tanaka, 2009-2010
|
||||
-- License : BSD3
|
||||
--
|
||||
-- Maintainer: tanaka.hideyuki@gmail.com
|
||||
-- Stability : experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- MessagePack Deserializer interface to @Data.Iteratee@
|
||||
--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
module Data.MessagePack.Iteratee(
|
||||
-- * Iteratee version of deserializer
|
||||
getI,
|
||||
-- * Non Blocking Enumerator
|
||||
enumHandleNonBlocking,
|
||||
-- * Convert Parser to Iteratee
|
||||
parserToIteratee,
|
||||
) where
|
||||
|
||||
import Control.Exception
|
||||
import Control.Monad.IO.Class
|
||||
import qualified Data.Attoparsec as A
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.Iteratee as I
|
||||
import System.IO
|
||||
|
||||
import Data.MessagePack.Unpack
|
||||
|
||||
-- | Deserialize a value
|
||||
getI :: (Monad m, Unpackable a) => I.Iteratee B.ByteString m a
|
||||
getI = parserToIteratee get
|
||||
|
||||
-- | Enumerator
|
||||
enumHandleNonBlocking :: MonadIO m => Int -> Handle -> I.Enumerator B.ByteString m a
|
||||
enumHandleNonBlocking bufSize h =
|
||||
I.enumFromCallback $ readSome bufSize h
|
||||
|
||||
readSome :: MonadIO m => Int -> Handle -> m (Either SomeException (Bool, B.ByteString))
|
||||
readSome bufSize h = liftIO $ do
|
||||
ebs <- try $ hGetSome bufSize h
|
||||
case ebs of
|
||||
Left exc ->
|
||||
return $ Left (exc :: SomeException)
|
||||
Right bs | B.null bs ->
|
||||
return $ Right (False, B.empty)
|
||||
Right bs ->
|
||||
return $ Right (True, bs)
|
||||
|
||||
hGetSome :: Int -> Handle -> IO B.ByteString
|
||||
hGetSome bufSize h = do
|
||||
bs <- B.hGetNonBlocking h bufSize
|
||||
if B.null bs
|
||||
then do
|
||||
hd <- B.hGet h 1
|
||||
if B.null hd
|
||||
then do
|
||||
return B.empty
|
||||
else do
|
||||
rest <- B.hGetNonBlocking h (bufSize - 1)
|
||||
return $ B.cons (B.head hd) rest
|
||||
else do
|
||||
return bs
|
||||
|
||||
-- | Convert Parser to Iteratee
|
||||
parserToIteratee :: Monad m => A.Parser a -> I.Iteratee B.ByteString m a
|
||||
parserToIteratee p = I.icont (itr (A.parse p)) Nothing
|
||||
where
|
||||
itr pcont s = case s of
|
||||
I.EOF _ ->
|
||||
I.throwErr (I.setEOF s)
|
||||
I.Chunk bs ->
|
||||
case pcont bs of
|
||||
A.Fail _ _ msg ->
|
||||
I.throwErr (I.iterStrExc msg)
|
||||
A.Partial cont ->
|
||||
I.icont (itr cont) Nothing
|
||||
A.Done remain ret ->
|
||||
I.idone ret (I.Chunk remain)
|
@@ -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)
|
301
haskell/src/Data/MessagePack/Object.hs
Normal file
301
haskell/src/Data/MessagePack/Object.hs
Normal file
@@ -0,0 +1,301 @@
|
||||
{-# Language TypeSynonymInstances #-}
|
||||
{-# Language FlexibleInstances #-}
|
||||
{-# Language OverlappingInstances #-}
|
||||
{-# 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.Char8 as C8
|
||||
import Data.Typeable
|
||||
|
||||
import Data.MessagePack.Pack
|
||||
import Data.MessagePack.Unpack
|
||||
|
||||
-- | Object Representation of MessagePack data.
|
||||
data Object =
|
||||
ObjectNil
|
||||
| ObjectBool Bool
|
||||
| ObjectInteger Int
|
||||
| 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
|
||||
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 ObjectDouble get
|
||||
, liftM ObjectRAW get
|
||||
, liftM ObjectArray get
|
||||
, liftM ObjectMap get
|
||||
]
|
||||
|
||||
instance Packable Object where
|
||||
put obj =
|
||||
case obj of
|
||||
ObjectInteger n ->
|
||||
put n
|
||||
ObjectNil ->
|
||||
put ()
|
||||
ObjectBool b ->
|
||||
put b
|
||||
ObjectDouble d ->
|
||||
put d
|
||||
ObjectRAW raw ->
|
||||
put raw
|
||||
ObjectArray arr ->
|
||||
put arr
|
||||
ObjectMap m ->
|
||||
put 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 B.ByteString where
|
||||
toObject = ObjectRAW
|
||||
tryFromObject (ObjectRAW bs) = Right bs
|
||||
tryFromObject _ = tryFromObjectError
|
||||
|
||||
instance OBJECT String where
|
||||
toObject = toObject . C8.pack
|
||||
tryFromObject obj = liftM C8.unpack $ tryFromObject obj
|
||||
|
||||
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 [(a, b)] where
|
||||
toObject =
|
||||
ObjectMap . map (\(a, b) -> (toObject a, toObject b))
|
||||
tryFromObject (ObjectMap mem) = do
|
||||
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
|
186
haskell/src/Data/MessagePack/Pack.hs
Normal file
186
haskell/src/Data/MessagePack/Pack.hs
Normal file
@@ -0,0 +1,186 @@
|
||||
{-# Language FlexibleInstances #-}
|
||||
{-# Language IncoherentInstances #-}
|
||||
{-# Language OverlappingInstances #-}
|
||||
{-# 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.Char8 as B8
|
||||
import qualified Data.ByteString.Lazy as L
|
||||
import qualified Data.Vector as V
|
||||
|
||||
-- | Serializable class
|
||||
class Packable a where
|
||||
-- | Serialize a value
|
||||
put :: a -> Put
|
||||
|
||||
-- | Pack Haskell data to MessagePack string.
|
||||
pack :: Packable a => a -> L.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 Double where
|
||||
put d = do
|
||||
putWord8 0xCB
|
||||
putFloat64be d
|
||||
|
||||
instance Packable String where
|
||||
put = putString length (putByteString . B8.pack)
|
||||
|
||||
instance Packable B.ByteString where
|
||||
put = putString B.length putByteString
|
||||
|
||||
instance Packable L.ByteString where
|
||||
put = putString (fromIntegral . L.length) putLazyByteString
|
||||
|
||||
putString :: (s -> Int) -> (s -> Put) -> s -> Put
|
||||
putString lf pf str = do
|
||||
case lf str 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 str
|
||||
|
||||
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 [(k, v)] where
|
||||
put = putMap length (mapM_ putPair)
|
||||
|
||||
instance (Packable k, Packable v) => Packable (V.Vector (k, v)) where
|
||||
put = putMap V.length (V.mapM_ putPair)
|
||||
|
||||
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
|
308
haskell/src/Data/MessagePack/Unpack.hs
Normal file
308
haskell/src/Data/MessagePack/Unpack.hs
Normal file
@@ -0,0 +1,308 @@
|
||||
{-# Language FlexibleInstances #-}
|
||||
{-# Language IncoherentInstances #-}
|
||||
{-# Language OverlappingInstances #-}
|
||||
{-# 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.Char8 as B8
|
||||
import qualified Data.ByteString.Lazy as L
|
||||
import Data.Int
|
||||
import Data.Typeable
|
||||
import qualified Data.Vector as V
|
||||
import Data.Word
|
||||
import Text.Printf
|
||||
|
||||
-- | 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 L.ByteString where
|
||||
toBS = B.concat . L.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 Double where
|
||||
get = do
|
||||
c <- A.anyWord8
|
||||
case c of
|
||||
0xCA ->
|
||||
return . realToFrac . runGet getFloat32be . toLBS =<< A.take 4
|
||||
0xCB ->
|
||||
return . runGet getFloat64be . toLBS =<< A.take 8
|
||||
_ ->
|
||||
fail $ printf "invlid double tag: 0x%02X" c
|
||||
|
||||
instance Unpackable String where
|
||||
get = parseString (\n -> return . B8.unpack =<< A.take n)
|
||||
|
||||
instance Unpackable B.ByteString where
|
||||
get = parseString A.take
|
||||
|
||||
instance Unpackable L.ByteString where
|
||||
get = parseString (\n -> do bs <- A.take n; return $ L.fromChunks [bs])
|
||||
|
||||
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 [(k, v)] where
|
||||
get = parseMap (flip replicateM parsePair)
|
||||
|
||||
instance (Unpackable k, Unpackable v) => Unpackable (V.Vector (k, v)) where
|
||||
get = 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
|
||||
|
||||
toLBS :: B.ByteString -> L.ByteString
|
||||
toLBS bs = L.fromChunks [bs]
|
@@ -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,64 @@
|
||||
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
|
||||
mid :: (Packable a, Unpackable a) => a -> a
|
||||
mid = unpack . pack
|
||||
|
||||
let f = do
|
||||
res <- unpackerExecute up
|
||||
when (res==1) $ do
|
||||
obj <- unpackerData up
|
||||
print obj
|
||||
f
|
||||
|
||||
f
|
||||
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_map_int_double a = a == mid a
|
||||
where types = a :: [(Int, Double)]
|
||||
prop_mid_map_string_string a = a == mid a
|
||||
where types = a :: [(String, String)]
|
||||
|
||||
return ()
|
||||
-}
|
||||
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_map_int_double
|
||||
, testProperty "[(string, string)]" prop_mid_map_string_string
|
||||
]
|
||||
]
|
||||
|
||||
main = do
|
||||
bs <- packb [(1,2),(2,3),(3::Int,4::Int)]
|
||||
print bs
|
||||
dat <- unpackb bs
|
||||
print (dat :: Result [(Int, 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
java/AUTHORS
Normal file
1
java/AUTHORS
Normal file
@@ -0,0 +1 @@
|
||||
FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>
|
@@ -1,3 +1,78 @@
|
||||
|
||||
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.
|
||||
|
25
java/pom.xml
25
java/pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.msgpack</groupId>
|
||||
<artifactId>msgpack</artifactId>
|
||||
<version>0.3</version>
|
||||
<version>0.5.1-devel</version>
|
||||
<description>MessagePack for Java</description>
|
||||
|
||||
<name>MessagePack for Java</name>
|
||||
@@ -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>
|
||||
@@ -101,6 +117,13 @@
|
||||
<name>MessagePack Maven2 Repository</name>
|
||||
<url>http://msgpack.org/maven2</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>repository.jboss.org</id>
|
||||
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<distributionManagement>
|
||||
|
27
java/src/main/java/org/msgpack/AbstractTemplate.java
Normal file
27
java/src/main/java/org/msgpack/AbstractTemplate.java
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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.IOException;
|
||||
|
||||
public abstract class AbstractTemplate implements Template {
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return convert(pac.unpackObject(), to);
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ 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;
|
||||
@@ -417,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 {
|
||||
|
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;
|
||||
}
|
||||
|
161
java/src/main/java/org/msgpack/MessagePack.java
Normal file
161
java/src/main/java/org/msgpack/MessagePack.java
Normal file
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// 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.OutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.template.TemplateRegistry;
|
||||
import org.msgpack.template.TemplateBuilder;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ 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() {
|
||||
@@ -132,5 +133,28 @@ public abstract class MessagePackObject implements Cloneable, MessagePackable {
|
||||
}
|
||||
|
||||
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,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 MessagePackTemplateProvider {
|
||||
|
||||
Template getTemplate();
|
||||
}
|
25
java/src/main/java/org/msgpack/MessagePacker.java
Normal file
25
java/src/main/java/org/msgpack/MessagePacker.java
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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.IOException;
|
||||
|
||||
public interface MessagePacker {
|
||||
void pack(Packer pk, Object target) throws IOException;
|
||||
}
|
||||
|
@@ -23,5 +23,13 @@ public class MessageTypeException extends RuntimeException {
|
||||
public MessageTypeException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public MessageTypeException(String s, Throwable t) {
|
||||
super(s, t);
|
||||
}
|
||||
|
||||
public MessageTypeException(Throwable t) {
|
||||
super(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
25
java/src/main/java/org/msgpack/MessageUnpacker.java
Normal file
25
java/src/main/java/org/msgpack/MessageUnpacker.java
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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.IOException;
|
||||
|
||||
public interface MessageUnpacker {
|
||||
Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException;
|
||||
}
|
||||
|
@@ -21,8 +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.
|
||||
@@ -41,8 +44,10 @@ import java.math.BigInteger;
|
||||
* 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) {
|
||||
@@ -65,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
|
||||
@@ -85,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);
|
||||
}
|
||||
}
|
||||
@@ -97,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
|
||||
@@ -122,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);
|
||||
}
|
||||
}
|
||||
@@ -140,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
|
||||
@@ -174,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);
|
||||
}
|
||||
@@ -182,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);
|
||||
}
|
||||
}
|
||||
@@ -209,7 +258,7 @@ public class Packer {
|
||||
castBytes[6] = barray[barray.length-3];
|
||||
castBytes[7] = barray[barray.length-2];
|
||||
castBytes[8] = barray[barray.length-1];
|
||||
out.write(castBytes);
|
||||
out.write(castBytes, 0, 9);
|
||||
return this;
|
||||
} else {
|
||||
throw new MessageTypeException("can't pack BigInteger larger than 0xffffffffffffffff");
|
||||
@@ -218,14 +267,28 @@ public class Packer {
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -255,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;
|
||||
@@ -271,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;
|
||||
@@ -287,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;
|
||||
@@ -308,6 +389,21 @@ public class Packer {
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
packRaw(b.length);
|
||||
@@ -396,18 +492,18 @@ public class Packer {
|
||||
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(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());
|
||||
@@ -425,57 +521,21 @@ public class Packer {
|
||||
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();
|
||||
} 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<Object,Object> 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 if(o instanceof BigInteger) {
|
||||
return packBigInteger((BigInteger)o);
|
||||
} else {
|
||||
throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")");
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
22
java/src/main/java/org/msgpack/Template.java
Normal file
22
java/src/main/java/org/msgpack/Template.java
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// 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 Template extends MessagePacker, MessageUnpacker, MessageConverter {
|
||||
}
|
||||
|
109
java/src/main/java/org/msgpack/Templates.java
Normal file
109
java/src/main/java/org/msgpack/Templates.java
Normal file
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// 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 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 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;
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ 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.
|
||||
@@ -103,7 +104,6 @@ import java.math.BigInteger;
|
||||
* </pre>
|
||||
*/
|
||||
public class Unpacker implements Iterable<MessagePackObject> {
|
||||
|
||||
// buffer:
|
||||
// +---------------------------------------------+
|
||||
// | [object] | [obje| unparsed ... | unused ...|
|
||||
@@ -232,6 +232,7 @@ public class Unpacker implements Iterable<MessagePackObject> {
|
||||
impl.buffer = buffer;
|
||||
impl.offset = offset;
|
||||
impl.filled = length;
|
||||
impl.bufferReferenced = false; // TODO zero-copy buffer
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,13 +277,16 @@ public class Unpacker implements Iterable<MessagePackObject> {
|
||||
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) {
|
||||
@@ -301,6 +305,7 @@ public class Unpacker implements Iterable<MessagePackObject> {
|
||||
impl.buffer = tmp;
|
||||
impl.filled = notParsed;
|
||||
impl.offset = 0;
|
||||
impl.bufferReferenced = false; // TODO zero-copy buffer
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,8 +372,7 @@ public class Unpacker implements Iterable<MessagePackObject> {
|
||||
* @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();
|
||||
}
|
||||
@@ -536,14 +540,23 @@ public class Unpacker implements Iterable<MessagePackObject> {
|
||||
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.
|
||||
@@ -561,12 +574,37 @@ public class Unpacker implements Iterable<MessagePackObject> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -309,6 +309,7 @@ public class UnpackerImpl {
|
||||
cs = ACS_RAW_VALUE;
|
||||
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);
|
||||
|
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})
|
||||
@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})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Index {
|
||||
int value();
|
||||
}
|
@@ -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})
|
||||
@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})
|
||||
@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})
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
54
java/src/main/java/org/msgpack/template/AnyTemplate.java
Normal file
54
java/src/main/java/org/msgpack/template/AnyTemplate.java
Normal file
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class AnyTemplate implements Template {
|
||||
private AnyTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(target instanceof MessagePackObject) {
|
||||
pk.pack((MessagePackObject)target);
|
||||
} else if(target == null) {
|
||||
pk.packNil();
|
||||
} else {
|
||||
TemplateRegistry.lookup(target.getClass()).pack(pk, target);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackObject();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from;
|
||||
}
|
||||
|
||||
static public AnyTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final AnyTemplate instance = new AnyTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(MessagePackObject.class, instance);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class BigIntegerTemplate implements Template {
|
||||
private BigIntegerTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packBigInteger((BigInteger)target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackBigInteger();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asBigInteger();
|
||||
}
|
||||
|
||||
static public BigIntegerTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final BigIntegerTemplate instance = new BigIntegerTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(BigInteger.class, instance);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class BooleanArrayTemplate implements Template {
|
||||
private BooleanArrayTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(!(target instanceof boolean[])) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
boolean[] array = (boolean[])target;
|
||||
try {
|
||||
pk.packArray(array.length);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
for(boolean a : array) {
|
||||
pk.pack(a);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
boolean[] array;
|
||||
if(to != null && to instanceof boolean[] && ((boolean[])to).length == length) {
|
||||
array = (boolean[])to;
|
||||
} else {
|
||||
array = new boolean[length];
|
||||
}
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = pac.unpackBoolean();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] src = from.asArray();
|
||||
boolean[] array;
|
||||
if(to != null && to instanceof boolean[] && ((boolean[])to).length == src.length) {
|
||||
array = (boolean[])to;
|
||||
} else {
|
||||
array = new boolean[src.length];
|
||||
}
|
||||
for(int i=0; i < src.length; i++) {
|
||||
MessagePackObject s = src[i];
|
||||
array[i] = s.asBoolean();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
static public BooleanArrayTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final BooleanArrayTemplate instance = new BooleanArrayTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(boolean[].class, instance);
|
||||
}
|
||||
}
|
||||
|
53
java/src/main/java/org/msgpack/template/BooleanTemplate.java
Normal file
53
java/src/main/java/org/msgpack/template/BooleanTemplate.java
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class BooleanTemplate implements Template {
|
||||
private BooleanTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packBoolean((Boolean)target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackBoolean();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asBoolean();
|
||||
}
|
||||
|
||||
static public BooleanTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final BooleanTemplate instance = new BooleanTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(Boolean.class, instance);
|
||||
TemplateRegistry.register(boolean.class, instance);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
public class BuiltInTemplateLoader {
|
||||
public static void load() {
|
||||
AnyTemplate.getInstance();
|
||||
BigIntegerTemplate.getInstance();
|
||||
BooleanArrayTemplate.getInstance();
|
||||
BooleanTemplate.getInstance();
|
||||
ByteArrayTemplate.getInstance();
|
||||
ByteBufferTemplate.getInstance();
|
||||
ByteTemplate.getInstance();
|
||||
DoubleArrayTemplate.getInstance();
|
||||
DoubleTemplate.getInstance();
|
||||
FloatArrayTemplate.getInstance();
|
||||
FloatTemplate.getInstance();
|
||||
IntArrayTemplate.getInstance();
|
||||
IntegerTemplate.getInstance();
|
||||
LongArrayTemplate.getInstance();
|
||||
LongTemplate.getInstance();
|
||||
ShortArrayTemplate.getInstance();
|
||||
ShortTemplate.getInstance();
|
||||
StringTemplate.getInstance();
|
||||
|
||||
CollectionTemplate.load();
|
||||
ListTemplate.load();
|
||||
MapTemplate.load();
|
||||
NullableTemplate.load();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ByteArrayTemplate implements Template {
|
||||
private ByteArrayTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packByteArray((byte[])target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackByteArray();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asByteArray();
|
||||
}
|
||||
|
||||
static public ByteArrayTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final ByteArrayTemplate instance = new ByteArrayTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(byte[].class, instance);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ByteBufferTemplate implements Template {
|
||||
private ByteBufferTemplate() {
|
||||
}
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packByteBuffer((ByteBuffer) target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackByteBuffer();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to)
|
||||
throws MessageTypeException {
|
||||
// FIXME
|
||||
byte[] bytes = from.asByteArray();
|
||||
return ByteBuffer.wrap(bytes);
|
||||
}
|
||||
|
||||
static public ByteBufferTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final ByteBufferTemplate instance = new ByteBufferTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(ByteBuffer.class, instance);
|
||||
}
|
||||
}
|
53
java/src/main/java/org/msgpack/template/ByteTemplate.java
Normal file
53
java/src/main/java/org/msgpack/template/ByteTemplate.java
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ByteTemplate implements Template {
|
||||
private ByteTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packByte((Byte)target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackByte();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asByte();
|
||||
}
|
||||
|
||||
static public ByteTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final ByteTemplate instance = new ByteTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(Byte.class, instance);
|
||||
TemplateRegistry.register(byte.class, instance);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.msgpack.MessagePackObject;
|
||||
import org.msgpack.MessageTypeException;
|
||||
import org.msgpack.Packer;
|
||||
import org.msgpack.Template;
|
||||
import org.msgpack.Unpacker;
|
||||
|
||||
public class CollectionTemplate implements Template {
|
||||
public static void load() { }
|
||||
|
||||
private Template elementTemplate;
|
||||
|
||||
public CollectionTemplate(Template elementTemplate) {
|
||||
this.elementTemplate = elementTemplate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if (! (target instanceof Collection)) {
|
||||
if (target == null) {
|
||||
throw new MessageTypeException(new NullPointerException("target is null."));
|
||||
}
|
||||
throw new MessageTypeException("target is not Collection type: " + target.getClass());
|
||||
}
|
||||
Collection<Object> collection = (Collection<Object>) target;
|
||||
pk.packArray(collection.size());
|
||||
for(Object element : collection) {
|
||||
elementTemplate.pack(pk, element);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
Collection<Object> c;
|
||||
if(to == null) {
|
||||
c = new LinkedList<Object>();
|
||||
} else {
|
||||
// TODO: optimize if list is instanceof ArrayList
|
||||
c = (Collection<Object>) to;
|
||||
c.clear();
|
||||
}
|
||||
for(; length > 0; length--) {
|
||||
c.add(elementTemplate.unpack(pac, null));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] array = from.asArray();
|
||||
Collection<Object> c;
|
||||
if(to == null) {
|
||||
c = new LinkedList<Object>();
|
||||
} else {
|
||||
// TODO: optimize if list is instanceof ArrayList
|
||||
c = (Collection<Object>) to;
|
||||
c.clear();
|
||||
}
|
||||
for(MessagePackObject element : array) {
|
||||
c.add(elementTemplate.convert(element, null));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static {
|
||||
TemplateRegistry.registerGeneric(Collection.class, new GenericTemplate1(CollectionTemplate.class));
|
||||
TemplateRegistry.register(Collection.class, new CollectionTemplate(AnyTemplate.getInstance()));
|
||||
}
|
||||
}
|
||||
|
96
java/src/main/java/org/msgpack/template/DefaultTemplate.java
Normal file
96
java/src/main/java/org/msgpack/template/DefaultTemplate.java
Normal file
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class DefaultTemplate implements Template {
|
||||
private Class<?> targetClass;
|
||||
private Type lookupType;
|
||||
private boolean messagePackable;
|
||||
private boolean messageUnpackable;
|
||||
private boolean messageConvertable;
|
||||
|
||||
public DefaultTemplate(Class<?> targetClass) {
|
||||
this(targetClass, (Type)targetClass);
|
||||
}
|
||||
|
||||
public DefaultTemplate(Class<?> targetClass, Type lookupType) {
|
||||
this.targetClass = targetClass;
|
||||
this.lookupType = lookupType;
|
||||
this.messagePackable = MessagePackable.class.isAssignableFrom(targetClass);
|
||||
this.messageUnpackable = MessageUnpackable.class.isAssignableFrom(targetClass);
|
||||
this.messageConvertable = MessageConvertable.class.isAssignableFrom(targetClass);
|
||||
}
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(messagePackable) {
|
||||
if(target == null) {
|
||||
throw new MessageTypeException("target is null.");
|
||||
}
|
||||
((MessagePackable)target).messagePack(pk);
|
||||
return;
|
||||
}
|
||||
Template tmpl = TemplateRegistry.tryLookup(lookupType);
|
||||
if(tmpl == this || tmpl == null) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
tmpl.pack(pk, target);
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
if(messageUnpackable) {
|
||||
if(to == null) {
|
||||
try {
|
||||
to = targetClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new MessageTypeException(e);
|
||||
}
|
||||
}
|
||||
((MessageUnpackable)to).messageUnpack(pac);
|
||||
return to;
|
||||
}
|
||||
Template tmpl = TemplateRegistry.tryLookup(lookupType);
|
||||
if(tmpl == this || tmpl == null) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
return tmpl.unpack(pac, to);
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
if(messageConvertable) {
|
||||
if(to == null) {
|
||||
try {
|
||||
to = targetClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new MessageTypeException(e);
|
||||
}
|
||||
}
|
||||
((MessageConvertable)to).messageConvert(from);
|
||||
return from;
|
||||
}
|
||||
Template tmpl = TemplateRegistry.tryLookup(lookupType);
|
||||
if(tmpl == this || tmpl == null) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
return tmpl.convert(from, to);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class DoubleArrayTemplate implements Template {
|
||||
private DoubleArrayTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(!(target instanceof double[])) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
double[] array = (double[])target;
|
||||
try {
|
||||
pk.packArray(array.length);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
for(double a : array) {
|
||||
pk.pack(a);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
double[] array;
|
||||
if(to != null && to instanceof double[] && ((double[])to).length == length) {
|
||||
array = (double[])to;
|
||||
} else {
|
||||
array = new double[length];
|
||||
}
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = pac.unpackDouble();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] src = from.asArray();
|
||||
double[] array;
|
||||
if(to != null && to instanceof double[] && ((double[])to).length == src.length) {
|
||||
array = (double[])to;
|
||||
} else {
|
||||
array = new double[src.length];
|
||||
}
|
||||
for(int i=0; i < src.length; i++) {
|
||||
MessagePackObject s = src[i];
|
||||
array[i] = s.asDouble();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
static public DoubleArrayTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final DoubleArrayTemplate instance = new DoubleArrayTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(double[].class, instance);
|
||||
}
|
||||
}
|
||||
|
53
java/src/main/java/org/msgpack/template/DoubleTemplate.java
Normal file
53
java/src/main/java/org/msgpack/template/DoubleTemplate.java
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class DoubleTemplate implements Template {
|
||||
private DoubleTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packDouble(((Double)target));
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackDouble();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asDouble();
|
||||
}
|
||||
|
||||
static public DoubleTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final DoubleTemplate instance = new DoubleTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(Double.class, instance);
|
||||
TemplateRegistry.register(double.class, instance);
|
||||
}
|
||||
}
|
||||
|
96
java/src/main/java/org/msgpack/template/FieldList.java
Normal file
96
java/src/main/java/org/msgpack/template/FieldList.java
Normal file
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class FieldList {
|
||||
public static class Entry {
|
||||
public Entry() {
|
||||
this.name = null;
|
||||
this.option = FieldOption.IGNORE;
|
||||
}
|
||||
|
||||
public Entry(String name, FieldOption option) {
|
||||
this.name = name;
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
private String name;
|
||||
private FieldOption option;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public FieldOption getOption() {
|
||||
return option;
|
||||
}
|
||||
|
||||
boolean isAvailable() {
|
||||
return this.option != FieldOption.IGNORE;
|
||||
}
|
||||
|
||||
boolean isRequired() {
|
||||
return this.option == FieldOption.REQUIRED;
|
||||
}
|
||||
|
||||
boolean isOptional() {
|
||||
return this.option == FieldOption.OPTIONAL;
|
||||
}
|
||||
|
||||
boolean isNullable() {
|
||||
return this.option == FieldOption.NULLABLE;
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<Entry> list;
|
||||
|
||||
public FieldList() {
|
||||
list = new ArrayList<Entry>();
|
||||
}
|
||||
|
||||
public void add(final String name) {
|
||||
add(name, FieldOption.REQUIRED);
|
||||
}
|
||||
|
||||
public void add(final String name, final FieldOption option) {
|
||||
list.add(new Entry(name, option));
|
||||
}
|
||||
|
||||
public void put(int index, final String name) {
|
||||
put(index, name, FieldOption.REQUIRED);
|
||||
}
|
||||
|
||||
public void put(int index, final String name, final FieldOption option) {
|
||||
if(list.size() < index) {
|
||||
do {
|
||||
list.add(new Entry());
|
||||
} while(list.size() < index);
|
||||
list.add(new Entry(name, option));
|
||||
} else {
|
||||
list.set(index, new Entry(name, option));
|
||||
}
|
||||
}
|
||||
|
||||
List<Entry> getList() {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
27
java/src/main/java/org/msgpack/template/FieldOption.java
Normal file
27
java/src/main/java/org/msgpack/template/FieldOption.java
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
public enum FieldOption {
|
||||
IGNORE,
|
||||
REQUIRED,
|
||||
OPTIONAL,
|
||||
NULLABLE,
|
||||
DEFAULT;
|
||||
}
|
||||
|
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class FloatArrayTemplate implements Template {
|
||||
private FloatArrayTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(!(target instanceof float[])) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
float[] array = (float[])target;
|
||||
try {
|
||||
pk.packArray(array.length);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
for(float a : array) {
|
||||
pk.pack(a);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
float[] array;
|
||||
if(to != null && to instanceof float[] && ((float[])to).length == length) {
|
||||
array = (float[])to;
|
||||
} else {
|
||||
array = new float[length];
|
||||
}
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = pac.unpackFloat();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] src = from.asArray();
|
||||
float[] array;
|
||||
if(to != null && to instanceof float[] && ((float[])to).length == src.length) {
|
||||
array = (float[])to;
|
||||
} else {
|
||||
array = new float[src.length];
|
||||
}
|
||||
for(int i=0; i < src.length; i++) {
|
||||
MessagePackObject s = src[i];
|
||||
array[i] = s.asFloat();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
static public FloatArrayTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final FloatArrayTemplate instance = new FloatArrayTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(float[].class, instance);
|
||||
}
|
||||
}
|
||||
|
53
java/src/main/java/org/msgpack/template/FloatTemplate.java
Normal file
53
java/src/main/java/org/msgpack/template/FloatTemplate.java
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class FloatTemplate implements Template {
|
||||
private FloatTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packFloat((Float)target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackFloat();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asFloat();
|
||||
}
|
||||
|
||||
static public FloatTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final FloatTemplate instance = new FloatTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(Float.class, instance);
|
||||
TemplateRegistry.register(float.class, instance);
|
||||
}
|
||||
}
|
||||
|
25
java/src/main/java/org/msgpack/template/GenericTemplate.java
Normal file
25
java/src/main/java/org/msgpack/template/GenericTemplate.java
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import org.msgpack.Template;
|
||||
|
||||
public interface GenericTemplate {
|
||||
public Template build(Template[] params);
|
||||
}
|
||||
|
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import org.msgpack.Template;
|
||||
|
||||
public class GenericTemplate1 implements GenericTemplate {
|
||||
Constructor<? extends Template> constructor;
|
||||
|
||||
public GenericTemplate1(Class<? extends Template> tmpl) {
|
||||
try {
|
||||
this.constructor = tmpl.getConstructor(new Class<?>[]{Template.class});
|
||||
constructor.newInstance(new Object[]{AnyTemplate.getInstance()});
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Template build(Template[] params) {
|
||||
try {
|
||||
return constructor.newInstance(params);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import org.msgpack.Template;
|
||||
|
||||
public class GenericTemplate2 implements GenericTemplate {
|
||||
Constructor<? extends Template> constructor;
|
||||
|
||||
public GenericTemplate2(Class<? extends Template> tmpl) {
|
||||
try {
|
||||
this.constructor = tmpl.getConstructor(new Class<?>[]{Template.class, Template.class});
|
||||
constructor.newInstance(new Object[]{AnyTemplate.getInstance(), AnyTemplate.getInstance()});
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Template build(Template[] params) {
|
||||
try {
|
||||
return constructor.newInstance(params);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class IntArrayTemplate implements Template {
|
||||
private IntArrayTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(!(target instanceof int[])) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
int[] array = (int[])target;
|
||||
try {
|
||||
pk.packArray(array.length);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
for(int a : array) {
|
||||
pk.pack(a);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
int[] array;
|
||||
if(to != null && to instanceof int[] && ((int[])to).length == length) {
|
||||
array = (int[])to;
|
||||
} else {
|
||||
array = new int[length];
|
||||
}
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = pac.unpackInt();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] src = from.asArray();
|
||||
int[] array;
|
||||
if(to != null && to instanceof int[] && ((int[])to).length == src.length) {
|
||||
array = (int[])to;
|
||||
} else {
|
||||
array = new int[src.length];
|
||||
}
|
||||
for(int i=0; i < src.length; i++) {
|
||||
MessagePackObject s = src[i];
|
||||
array[i] = s.asInt();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
static public IntArrayTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final IntArrayTemplate instance = new IntArrayTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(int[].class, instance);
|
||||
}
|
||||
}
|
||||
|
53
java/src/main/java/org/msgpack/template/IntegerTemplate.java
Normal file
53
java/src/main/java/org/msgpack/template/IntegerTemplate.java
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class IntegerTemplate implements Template {
|
||||
private IntegerTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packInt((Integer)target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackInt();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asInt();
|
||||
}
|
||||
|
||||
static public IntegerTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final IntegerTemplate instance = new IntegerTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(Integer.class, instance);
|
||||
TemplateRegistry.register(int.class, instance);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,592 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.msgpack.*;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtConstructor;
|
||||
import javassist.CtMethod;
|
||||
import javassist.CtNewConstructor;
|
||||
import javassist.CtNewMethod;
|
||||
import javassist.LoaderClassPath;
|
||||
import javassist.NotFoundException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class JavassistTemplateBuilder extends TemplateBuilder {
|
||||
private static Logger LOG = LoggerFactory.getLogger(JavassistTemplateBuilder.class);
|
||||
|
||||
private static JavassistTemplateBuilder instance;
|
||||
|
||||
public synchronized static JavassistTemplateBuilder getInstance() {
|
||||
if(instance == null) {
|
||||
instance = new JavassistTemplateBuilder();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void addClassLoader(ClassLoader cl) {
|
||||
getInstance().pool.appendClassPath(new LoaderClassPath(cl));
|
||||
}
|
||||
|
||||
private JavassistTemplateBuilder() {
|
||||
this.pool = ClassPool.getDefault();
|
||||
}
|
||||
|
||||
protected ClassPool pool;
|
||||
|
||||
private int seqId = 0;
|
||||
|
||||
CtClass makeCtClass(String className) {
|
||||
return pool.makeClass(className);
|
||||
}
|
||||
|
||||
CtClass getCtClass(String className) throws NotFoundException {
|
||||
return pool.get(className);
|
||||
}
|
||||
|
||||
int nextSeqId() {
|
||||
return seqId++;
|
||||
}
|
||||
|
||||
private static abstract class BuildContextBase {
|
||||
protected JavassistTemplateBuilder director;
|
||||
|
||||
protected String tmplName;
|
||||
|
||||
protected CtClass tmplCtClass;
|
||||
|
||||
protected abstract void setSuperClass() throws CannotCompileException, NotFoundException;
|
||||
|
||||
protected abstract void buildConstructor() throws CannotCompileException, NotFoundException;
|
||||
|
||||
protected void buildMethodInit() { }
|
||||
|
||||
protected abstract String buildPackMethodBody();
|
||||
|
||||
protected abstract String buildUnpackMethodBody();
|
||||
|
||||
protected abstract String buildConvertMethodBody();
|
||||
|
||||
protected abstract Template buildInstance(Class<?> c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException;
|
||||
|
||||
public BuildContextBase(JavassistTemplateBuilder director) {
|
||||
this.director = director;
|
||||
}
|
||||
|
||||
protected Template build(final String className) {
|
||||
try {
|
||||
reset(className);
|
||||
buildClass();
|
||||
buildConstructor();
|
||||
buildMethodInit();
|
||||
buildPackMethod();
|
||||
buildUnpackMethod();
|
||||
buildConvertMethod();
|
||||
return buildInstance(createClass());
|
||||
} catch (Exception e) {
|
||||
String code = getBuiltString();
|
||||
if(code != null) {
|
||||
LOG.error("builder: " + code, e);
|
||||
throw new TemplateBuildException("cannot compile: " + code, e);
|
||||
} else {
|
||||
throw new TemplateBuildException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void reset(String className) {
|
||||
tmplName = className + "_$$_Template" + director.nextSeqId();
|
||||
tmplCtClass = director.makeCtClass(tmplName);
|
||||
}
|
||||
|
||||
protected void buildClass() throws CannotCompileException, NotFoundException {
|
||||
setSuperClass();
|
||||
tmplCtClass.addInterface(director.getCtClass(Template.class.getName()));
|
||||
}
|
||||
|
||||
protected void buildPackMethod() throws CannotCompileException, NotFoundException {
|
||||
String mbody = buildPackMethodBody();
|
||||
int mod = javassist.Modifier.PUBLIC;
|
||||
CtClass returnType = CtClass.voidType;
|
||||
String mname = "pack";
|
||||
CtClass[] paramTypes = new CtClass[] {
|
||||
director.getCtClass(Packer.class.getName()),
|
||||
director.getCtClass(Object.class.getName())
|
||||
};
|
||||
CtClass[] exceptTypes = new CtClass[] {
|
||||
director.getCtClass(IOException.class.getName())
|
||||
};
|
||||
CtMethod newCtMethod = CtNewMethod.make(
|
||||
mod, returnType, mname,
|
||||
paramTypes, exceptTypes, mbody, tmplCtClass);
|
||||
tmplCtClass.addMethod(newCtMethod);
|
||||
}
|
||||
|
||||
protected void buildUnpackMethod() throws CannotCompileException, NotFoundException {
|
||||
String mbody = buildUnpackMethodBody();
|
||||
int mod = javassist.Modifier.PUBLIC;
|
||||
CtClass returnType = director.getCtClass(Object.class.getName());
|
||||
String mname = "unpack";
|
||||
CtClass[] paramTypes = new CtClass[] {
|
||||
director.getCtClass(Unpacker.class.getName()),
|
||||
director.getCtClass(Object.class.getName())
|
||||
};
|
||||
CtClass[] exceptTypes = new CtClass[] {
|
||||
director.getCtClass(MessageTypeException.class.getName())
|
||||
};
|
||||
CtMethod newCtMethod = CtNewMethod.make(
|
||||
mod, returnType, mname,
|
||||
paramTypes, exceptTypes, mbody, tmplCtClass);
|
||||
tmplCtClass.addMethod(newCtMethod);
|
||||
}
|
||||
|
||||
protected void buildConvertMethod() throws CannotCompileException, NotFoundException {
|
||||
String mbody = buildConvertMethodBody();
|
||||
int mod = javassist.Modifier.PUBLIC;
|
||||
CtClass returnType = director.getCtClass(Object.class.getName());
|
||||
String mname = "convert";
|
||||
CtClass[] paramTypes = new CtClass[] {
|
||||
director.getCtClass(MessagePackObject.class.getName()),
|
||||
director.getCtClass(Object.class.getName())
|
||||
};
|
||||
CtClass[] exceptTypes = new CtClass[] {
|
||||
director.getCtClass(MessageTypeException.class.getName())
|
||||
};
|
||||
CtMethod newCtMethod = CtNewMethod.make(
|
||||
mod, returnType, mname,
|
||||
paramTypes, exceptTypes, mbody, tmplCtClass);
|
||||
tmplCtClass.addMethod(newCtMethod);
|
||||
}
|
||||
|
||||
protected Class<?> createClass() throws CannotCompileException {
|
||||
return (Class<?>) tmplCtClass.toClass(null, null);
|
||||
}
|
||||
|
||||
protected StringBuilder stringBuilder = null;
|
||||
|
||||
protected void resetStringBuilder() {
|
||||
stringBuilder = new StringBuilder();
|
||||
}
|
||||
|
||||
protected void buildString(String str) {
|
||||
stringBuilder.append(str);
|
||||
}
|
||||
|
||||
protected void buildString(String format, Object... args) {
|
||||
stringBuilder.append(String.format(format, args));
|
||||
}
|
||||
|
||||
protected String getBuiltString() {
|
||||
if(stringBuilder == null) {
|
||||
return null;
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class JavassistTemplate extends AbstractTemplate {
|
||||
public Class<?> targetClass;
|
||||
public Template[] templates;
|
||||
|
||||
public JavassistTemplate(Class<?> targetClass, Template[] templates) {
|
||||
this.targetClass = targetClass;
|
||||
this.templates = templates;
|
||||
}
|
||||
}
|
||||
|
||||
private static class BuildContext extends BuildContextBase {
|
||||
protected FieldEntry[] entries;
|
||||
protected Class<?> origClass;
|
||||
protected String origName;
|
||||
protected Template[] templates;
|
||||
protected int minimumArrayLength;
|
||||
|
||||
public BuildContext(JavassistTemplateBuilder director) {
|
||||
super(director);
|
||||
}
|
||||
|
||||
public Template buildTemplate(Class<?> targetClass, FieldEntry[] entries, Template[] templates) {
|
||||
this.entries = entries;
|
||||
this.templates = templates;
|
||||
this.origClass = targetClass;
|
||||
this.origName = this.origClass.getName();
|
||||
return build(this.origName);
|
||||
}
|
||||
|
||||
protected void setSuperClass() throws CannotCompileException, NotFoundException {
|
||||
this.tmplCtClass.setSuperclass(
|
||||
director.getCtClass(JavassistTemplate.class.getName()));
|
||||
}
|
||||
|
||||
protected void buildConstructor() throws CannotCompileException, NotFoundException {
|
||||
// Constructor(Class targetClass, Template[] templates)
|
||||
CtConstructor newCtCons = CtNewConstructor.make(
|
||||
new CtClass[] {
|
||||
director.getCtClass(Class.class.getName()),
|
||||
director.getCtClass(Template.class.getName()+"[]")
|
||||
},
|
||||
new CtClass[0],
|
||||
this.tmplCtClass);
|
||||
this.tmplCtClass.addConstructor(newCtCons);
|
||||
}
|
||||
|
||||
protected Template buildInstance(Class<?> c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||
Constructor<?> cons = c.getConstructor(new Class[] {
|
||||
Class.class,
|
||||
Template[].class
|
||||
});
|
||||
Object tmpl = cons.newInstance(new Object[] {
|
||||
this.origClass,
|
||||
this.templates
|
||||
});
|
||||
return (Template)tmpl;
|
||||
}
|
||||
|
||||
protected void buildMethodInit() {
|
||||
this.minimumArrayLength = 0;
|
||||
for(int i=0; i < entries.length; i++) {
|
||||
FieldEntry e = entries[i];
|
||||
if(e.isRequired() || e.isNullable()) {
|
||||
this.minimumArrayLength = i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String buildPackMethodBody() {
|
||||
resetStringBuilder();
|
||||
buildString("{");
|
||||
buildString("%s _$$_t = (%s)$2;", this.origName, this.origName);
|
||||
buildString("$1.packArray(%d);", entries.length);
|
||||
for(int i=0; i < entries.length; i++) {
|
||||
FieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
buildString("$1.packNil();");
|
||||
continue;
|
||||
}
|
||||
Class<?> type = e.getType();
|
||||
if(type.isPrimitive()) {
|
||||
buildString("$1.%s(_$$_t.%s);", primitivePackName(type), e.getName());
|
||||
} else {
|
||||
buildString("if(_$$_t.%s == null) {", e.getName());
|
||||
if(!e.isNullable() && !e.isOptional()) {
|
||||
buildString("throw new %s();", MessageTypeException.class.getName());
|
||||
} else {
|
||||
buildString("$1.packNil();");
|
||||
}
|
||||
buildString("} else {");
|
||||
buildString(" this.templates[%d].pack($1, _$$_t.%s);", i, e.getName());
|
||||
buildString("}");
|
||||
}
|
||||
}
|
||||
buildString("}");
|
||||
return getBuiltString();
|
||||
}
|
||||
|
||||
protected String buildUnpackMethodBody() {
|
||||
resetStringBuilder();
|
||||
buildString("{ ");
|
||||
|
||||
buildString("%s _$$_t;", this.origName);
|
||||
buildString("if($2 == null) {");
|
||||
buildString(" _$$_t = new %s();", this.origName);
|
||||
buildString("} else {");
|
||||
buildString(" _$$_t = (%s)$2;", this.origName);
|
||||
buildString("}");
|
||||
|
||||
buildString("int length = $1.unpackArray();");
|
||||
buildString("if(length < %d) {", this.minimumArrayLength);
|
||||
buildString(" throw new %s();", MessageTypeException.class.getName());
|
||||
buildString("}");
|
||||
|
||||
int i;
|
||||
for(i=0; i < this.minimumArrayLength; i++) {
|
||||
FieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
buildString("$1.unpackObject();");
|
||||
continue;
|
||||
}
|
||||
|
||||
buildString("if($1.tryUnpackNull()) {");
|
||||
if(e.isRequired()) {
|
||||
// Required + nil => exception
|
||||
buildString("throw new %s();", MessageTypeException.class.getName());
|
||||
} else if(e.isOptional()) {
|
||||
// Optional + nil => keep default value
|
||||
} else { // Nullable
|
||||
// Nullable + nil => set null
|
||||
buildString("_$$_t.%s = null;", e.getName());
|
||||
}
|
||||
buildString("} else {");
|
||||
Class<?> type = e.getType();
|
||||
if(type.isPrimitive()) {
|
||||
buildString("_$$_t.%s = $1.%s();", e.getName(), primitiveUnpackName(type));
|
||||
} else {
|
||||
buildString("_$$_t.%s = (%s)this.templates[%d].unpack($1, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName());
|
||||
}
|
||||
buildString("}");
|
||||
}
|
||||
|
||||
for(; i < entries.length; i++) {
|
||||
buildString("if(length <= %d) { return _$$_t; }", i);
|
||||
|
||||
FieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
buildString("$1.unpackObject();");
|
||||
continue;
|
||||
}
|
||||
|
||||
buildString("if($1.tryUnpackNull()) {");
|
||||
// this is Optional field becaue i >= minimumArrayLength
|
||||
// Optional + nil => keep default value
|
||||
buildString("} else {");
|
||||
Class<?> type = e.getType();
|
||||
if(type.isPrimitive()) {
|
||||
buildString("_$$_t.%s = $1.%s();", e.getName(), primitiveUnpackName(type));
|
||||
} else {
|
||||
buildString("_$$_t.%s = (%s)this.templates[%d].unpack($1, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName());
|
||||
}
|
||||
buildString("}");
|
||||
}
|
||||
|
||||
// latter entries are all Optional + nil => keep default value
|
||||
|
||||
buildString("for(int i=%d; i < length; i++) {", i);
|
||||
buildString(" $1.unpackObject();");
|
||||
buildString("}");
|
||||
|
||||
buildString("return _$$_t;");
|
||||
|
||||
buildString("}");
|
||||
return getBuiltString();
|
||||
}
|
||||
|
||||
protected String buildConvertMethodBody() {
|
||||
resetStringBuilder();
|
||||
buildString("{ ");
|
||||
|
||||
buildString("%s _$$_t;", this.origName);
|
||||
buildString("if($2 == null) {");
|
||||
buildString(" _$$_t = new %s();", this.origName);
|
||||
buildString("} else {");
|
||||
buildString(" _$$_t = (%s)$2;", this.origName);
|
||||
buildString("}");
|
||||
|
||||
buildString("%s[] array = $1.asArray();", MessagePackObject.class.getName());
|
||||
buildString("int length = array.length;");
|
||||
buildString("if(length < %d) {", this.minimumArrayLength);
|
||||
buildString(" throw new %s();", MessageTypeException.class.getName());
|
||||
buildString("}");
|
||||
|
||||
buildString("%s obj;", MessagePackObject.class.getName());
|
||||
|
||||
int i;
|
||||
for(i=0; i < this.minimumArrayLength; i++) {
|
||||
FieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
buildString("obj = array[%d];", i);
|
||||
buildString("if(obj.isNil()) {");
|
||||
if(e.isRequired()) {
|
||||
// Required + nil => exception
|
||||
buildString("throw new %s();", MessageTypeException.class.getName());
|
||||
} else if(e.isOptional()) {
|
||||
// Optional + nil => keep default value
|
||||
} else { // Nullable
|
||||
// Nullable + nil => set null
|
||||
buildString("_$$_t.%s = null;", e.getName());
|
||||
}
|
||||
buildString("} else {");
|
||||
Class<?> type = e.getType();
|
||||
if(type.isPrimitive()) {
|
||||
buildString("_$$_t.%s = obj.%s();", e.getName(), primitiveConvertName(type));
|
||||
} else {
|
||||
buildString("_$$_t.%s = (%s)this.templates[%d].convert(obj, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName());
|
||||
}
|
||||
buildString("}");
|
||||
}
|
||||
|
||||
for(; i < entries.length; i++) {
|
||||
buildString("if(length <= %d) { return _$$_t; }", i);
|
||||
|
||||
FieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
buildString("obj = array[%d];", i);
|
||||
buildString("if(obj.isNil()) {");
|
||||
// this is Optional field becaue i >= minimumArrayLength
|
||||
// Optional + nil => keep default value
|
||||
buildString("} else {");
|
||||
Class<?> type = e.getType();
|
||||
if(type.isPrimitive()) {
|
||||
buildString("_$$_t.%s = obj.%s();", e.getName(), primitiveConvertName(type));
|
||||
} else {
|
||||
buildString("_$$_t.%s = (%s)this.templates[%d].convert(obj, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName());
|
||||
}
|
||||
buildString("}");
|
||||
}
|
||||
|
||||
// latter entries are all Optional + nil => keep default value
|
||||
|
||||
buildString("return _$$_t;");
|
||||
|
||||
buildString("}");
|
||||
return getBuiltString();
|
||||
}
|
||||
|
||||
protected String primitivePackName(Class<?> type) {
|
||||
if(type == boolean.class) {
|
||||
return "packBoolean";
|
||||
} else if(type == byte.class) {
|
||||
return "packByte";
|
||||
} else if(type == short.class) {
|
||||
return "packShort";
|
||||
} else if(type == int.class) {
|
||||
return "packInt";
|
||||
} else if(type == long.class) {
|
||||
return "packLong";
|
||||
} else if(type == float.class) {
|
||||
return "packFloat";
|
||||
} else if(type == double.class) {
|
||||
return "packDouble";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String primitiveUnpackName(Class<?> type) {
|
||||
if(type == boolean.class) {
|
||||
return "unpackBoolean";
|
||||
} else if(type == byte.class) {
|
||||
return "unpackByte";
|
||||
} else if(type == short.class) {
|
||||
return "unpackShort";
|
||||
} else if(type == int.class) {
|
||||
return "unpackInt";
|
||||
} else if(type == long.class) {
|
||||
return "unpackLong";
|
||||
} else if(type == float.class) {
|
||||
return "unpackFloat";
|
||||
} else if(type == double.class) {
|
||||
return "unpackDouble";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String primitiveConvertName(Class<?> type) {
|
||||
if(type == boolean.class) {
|
||||
return "asBoolean";
|
||||
} else if(type == byte.class) {
|
||||
return "asByte";
|
||||
} else if(type == short.class) {
|
||||
return "asShort";
|
||||
} else if(type == int.class) {
|
||||
return "asInt";
|
||||
} else if(type == long.class) {
|
||||
return "asLong";
|
||||
} else if(type == float.class) {
|
||||
return "asFloat";
|
||||
} else if(type == double.class) {
|
||||
return "asDouble";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Template buildTemplate(Class<?> targetClass, FieldEntry[] entries) {
|
||||
// FIXME private / packagefields
|
||||
//for(FieldEntry e : entries) {
|
||||
// Field f = e.getField();
|
||||
// int mod = f.getModifiers();
|
||||
// if(!Modifier.isPublic(mod)) {
|
||||
// f.setAccessible(true);
|
||||
// }
|
||||
//}
|
||||
|
||||
Template[] tmpls = new Template[entries.length];
|
||||
for(int i=0; i < entries.length; i++) {
|
||||
FieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
tmpls[i] = null;
|
||||
} else {
|
||||
Template tmpl = TemplateRegistry.lookup(e.getGenericType(), true);
|
||||
tmpls[i] = tmpl;
|
||||
}
|
||||
}
|
||||
|
||||
BuildContext bc = new BuildContext(this);
|
||||
return bc.buildTemplate(targetClass, entries, tmpls);
|
||||
}
|
||||
|
||||
static class JavassistOrdinalEnumTemplate extends ReflectionTemplateBuilder.ReflectionOrdinalEnumTemplate {
|
||||
JavassistOrdinalEnumTemplate(Enum<?>[] entries) {
|
||||
super(entries);
|
||||
}
|
||||
}
|
||||
|
||||
public Template buildOrdinalEnumTemplate(Class<?> targetClass, Enum<?>[] entries) {
|
||||
return new JavassistOrdinalEnumTemplate(entries);
|
||||
}
|
||||
|
||||
public Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class<?> baseClass, int dim) {
|
||||
if(dim == 1) {
|
||||
if(baseClass == boolean.class) {
|
||||
return BooleanArrayTemplate.getInstance();
|
||||
} else if(baseClass == short.class) {
|
||||
return ShortArrayTemplate.getInstance();
|
||||
} else if(baseClass == int.class) {
|
||||
return IntArrayTemplate.getInstance();
|
||||
} else if(baseClass == long.class) {
|
||||
return LongArrayTemplate.getInstance();
|
||||
} else if(baseClass == float.class) {
|
||||
return FloatArrayTemplate.getInstance();
|
||||
} else if(baseClass == double.class) {
|
||||
return DoubleArrayTemplate.getInstance();
|
||||
} else {
|
||||
// FIXME
|
||||
Template baseTemplate = TemplateRegistry.lookup(genericBaseType);
|
||||
return new ReflectionTemplateBuilder.ReflectionObjectArrayTemplate(baseClass, baseTemplate);
|
||||
}
|
||||
} else if(dim == 2) {
|
||||
// FIXME
|
||||
Class<?> componentClass = Array.newInstance(baseClass, 0).getClass();
|
||||
Template componentTemplate = buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1);
|
||||
return new ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate);
|
||||
} else {
|
||||
// FIXME
|
||||
ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate componentTemplate = (ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate)
|
||||
buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1);
|
||||
Class<?> componentClass = Array.newInstance(componentTemplate.getComponentClass(), 0).getClass();
|
||||
return new ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
91
java/src/main/java/org/msgpack/template/ListTemplate.java
Normal file
91
java/src/main/java/org/msgpack/template/ListTemplate.java
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ListTemplate implements Template {
|
||||
static void load() { }
|
||||
|
||||
private Template elementTemplate;
|
||||
|
||||
public ListTemplate(Template elementTemplate) {
|
||||
this.elementTemplate = elementTemplate;
|
||||
}
|
||||
|
||||
public Template getElementTemplate() {
|
||||
return elementTemplate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if (! (target instanceof List)) {
|
||||
if (target == null) {
|
||||
throw new MessageTypeException(new NullPointerException("target is null."));
|
||||
}
|
||||
throw new MessageTypeException("target is not List type: " + target.getClass());
|
||||
}
|
||||
List<Object> list = (List<Object>)target;
|
||||
pk.packArray(list.size());
|
||||
for(Object element : list) {
|
||||
elementTemplate.pack(pk, element);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
List<Object> list;
|
||||
if(to == null) {
|
||||
list = new ArrayList<Object>(length);
|
||||
} else {
|
||||
list = (List<Object>) to;
|
||||
list.clear();
|
||||
}
|
||||
for(; length > 0; length--) {
|
||||
list.add( elementTemplate.unpack(pac, null) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] array = from.asArray();
|
||||
List<Object> list;
|
||||
if(to == null) {
|
||||
list = new ArrayList<Object>(array.length);
|
||||
} else {
|
||||
// TODO: optimize if list is instanceof ArrayList
|
||||
list = (List<Object>) to;
|
||||
list.clear();
|
||||
}
|
||||
for(MessagePackObject element : array) {
|
||||
list.add( elementTemplate.convert(element, null) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static {
|
||||
TemplateRegistry.registerGeneric(List.class, new GenericTemplate1(ListTemplate.class));
|
||||
TemplateRegistry.register(List.class, new ListTemplate(AnyTemplate.getInstance()));
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class LongArrayTemplate implements Template {
|
||||
private LongArrayTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(!(target instanceof long[])) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
long[] array = (long[])target;
|
||||
try {
|
||||
pk.packArray(array.length);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
for(long a : array) {
|
||||
pk.pack(a);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
long[] array;
|
||||
if(to != null && to instanceof long[] && ((long[])to).length == length) {
|
||||
array = (long[])to;
|
||||
} else {
|
||||
array = new long[length];
|
||||
}
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = pac.unpackLong();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] src = from.asArray();
|
||||
long[] array;
|
||||
if(to != null && to instanceof long[] && ((long[])to).length == src.length) {
|
||||
array = (long[])to;
|
||||
} else {
|
||||
array = new long[src.length];
|
||||
}
|
||||
for(int i=0; i < src.length; i++) {
|
||||
MessagePackObject s = src[i];
|
||||
array[i] = s.asLong();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
static public LongArrayTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final LongArrayTemplate instance = new LongArrayTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(long[].class, instance);
|
||||
}
|
||||
}
|
||||
|
53
java/src/main/java/org/msgpack/template/LongTemplate.java
Normal file
53
java/src/main/java/org/msgpack/template/LongTemplate.java
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class LongTemplate implements Template {
|
||||
private LongTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packLong((Long)target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackLong();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asLong();
|
||||
}
|
||||
|
||||
static public LongTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final LongTemplate instance = new LongTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(Long.class, instance);
|
||||
TemplateRegistry.register(long.class, instance);
|
||||
}
|
||||
}
|
||||
|
101
java/src/main/java/org/msgpack/template/MapTemplate.java
Normal file
101
java/src/main/java/org/msgpack/template/MapTemplate.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.template;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class MapTemplate implements Template {
|
||||
static void load() { }
|
||||
|
||||
private Template keyTemplate;
|
||||
private Template valueTemplate;
|
||||
|
||||
public MapTemplate(Template keyTemplate, Template valueTemplate) {
|
||||
this.keyTemplate = keyTemplate;
|
||||
this.valueTemplate = valueTemplate;
|
||||
}
|
||||
|
||||
public Template getKeyTemplate() {
|
||||
return keyTemplate;
|
||||
}
|
||||
|
||||
public Template getValueTemplate() {
|
||||
return valueTemplate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(!(target instanceof Map)) {
|
||||
if (target == null) {
|
||||
throw new MessageTypeException(new NullPointerException("target is null."));
|
||||
}
|
||||
throw new MessageTypeException("target is not Map type: " + target.getClass());
|
||||
}
|
||||
Map<Object,Object> map = (Map<Object,Object>) target;
|
||||
pk.packMap(map.size());
|
||||
for(Map.Entry<Object,Object> pair : map.entrySet()) {
|
||||
keyTemplate.pack(pk, pair.getKey());
|
||||
valueTemplate.pack(pk, pair.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackMap();
|
||||
Map<Object,Object> map;
|
||||
if(to == null) {
|
||||
map = new HashMap<Object,Object>(length);
|
||||
} else {
|
||||
map = (Map<Object,Object>) to;
|
||||
map.clear();
|
||||
}
|
||||
for(; length > 0; length--) {
|
||||
Object key = keyTemplate.unpack(pac, null);
|
||||
Object value = valueTemplate.unpack(pac, null);
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
Map<MessagePackObject,MessagePackObject> src = from.asMap();
|
||||
Map<Object,Object> map;
|
||||
if(to == null) {
|
||||
map = new HashMap<Object,Object>(src.size());
|
||||
} else {
|
||||
map = (Map<Object,Object>) to;
|
||||
map.clear();
|
||||
}
|
||||
for(Map.Entry<MessagePackObject,MessagePackObject> pair : src.entrySet()) {
|
||||
Object key = keyTemplate.convert(pair.getKey(), null);
|
||||
Object value = valueTemplate.convert(pair.getValue(), null);
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
static {
|
||||
TemplateRegistry.registerGeneric(Map.class, new GenericTemplate2(MapTemplate.class));
|
||||
TemplateRegistry.register(Map.class, new MapTemplate(AnyTemplate.getInstance(), AnyTemplate.getInstance()));
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class NullableTemplate implements Template {
|
||||
static void load() { }
|
||||
|
||||
private Template elementTemplate;
|
||||
|
||||
public NullableTemplate(Template elementTemplate) {
|
||||
this.elementTemplate = elementTemplate;
|
||||
}
|
||||
|
||||
public Template getElementTemplate() {
|
||||
return elementTemplate;
|
||||
}
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(target == null) {
|
||||
pk.packNil();
|
||||
} else {
|
||||
elementTemplate.pack(pk, target);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
if(pac.tryUnpackNull()) {
|
||||
return null;
|
||||
}
|
||||
return elementTemplate.unpack(pac, to);
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
if(from.isNil()) {
|
||||
return null;
|
||||
}
|
||||
return elementTemplate.convert(from, to);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class OptionalTemplate implements Template {
|
||||
private Template elementTemplate;
|
||||
private Object defaultObject;
|
||||
|
||||
public OptionalTemplate(Template elementTemplate) {
|
||||
this(elementTemplate, null);
|
||||
}
|
||||
|
||||
public OptionalTemplate(Template elementTemplate, Object defaultObject) {
|
||||
this.elementTemplate = elementTemplate;
|
||||
this.defaultObject = defaultObject;
|
||||
}
|
||||
|
||||
public Template getElementTemplate() {
|
||||
return elementTemplate;
|
||||
}
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(target == null) {
|
||||
pk.pack(defaultObject);
|
||||
} else {
|
||||
elementTemplate.pack(pk, target);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
if(pac.tryUnpackNull()) {
|
||||
return defaultObject; // FIXME return to?
|
||||
}
|
||||
return elementTemplate.unpack(pac, to);
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
if(from.isNil()) {
|
||||
return defaultObject; // FIXME return to?
|
||||
}
|
||||
return elementTemplate.convert(from, to);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,569 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ReflectionTemplateBuilder extends TemplateBuilder {
|
||||
private static ReflectionTemplateBuilder instance;
|
||||
public synchronized static ReflectionTemplateBuilder getInstance() {
|
||||
if(instance == null) {
|
||||
instance = new ReflectionTemplateBuilder();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ReflectionTemplateBuilder() {
|
||||
}
|
||||
|
||||
static abstract class ReflectionFieldEntry extends FieldEntry {
|
||||
ReflectionFieldEntry(FieldEntry e) {
|
||||
super(e.getField(), e.getOption());
|
||||
}
|
||||
|
||||
public abstract void pack(Object target, Packer pac) throws IOException;
|
||||
|
||||
public abstract void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException;
|
||||
|
||||
public abstract void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException;
|
||||
|
||||
public void setNull(Object target) throws IllegalAccessException {
|
||||
getField().set(target, null);
|
||||
}
|
||||
}
|
||||
|
||||
static class NullFieldEntry extends ReflectionFieldEntry {
|
||||
NullFieldEntry(FieldEntry e) {
|
||||
super(e);
|
||||
}
|
||||
public void pack(Object target, Packer pac) throws IOException { }
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { }
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { }
|
||||
}
|
||||
|
||||
static class ObjectFieldEntry extends ReflectionFieldEntry {
|
||||
private Template template;
|
||||
|
||||
ObjectFieldEntry(FieldEntry e, Template template) {
|
||||
super(e);
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public void pack(Object target, Packer pac) throws IOException {
|
||||
template.pack(pac, target);
|
||||
}
|
||||
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
|
||||
Field f = getField();
|
||||
Class<Object> type = (Class<Object>)f.getType();
|
||||
Object fieldReference = f.get(target);
|
||||
Object valueReference = template.convert(obj, fieldReference);
|
||||
if(valueReference != fieldReference) {
|
||||
f.set(target, valueReference);
|
||||
}
|
||||
}
|
||||
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
|
||||
Field f = getField();
|
||||
Class<Object> type = (Class<Object>)f.getType();
|
||||
Object fieldReference = f.get(target);
|
||||
Object valueReference = template.unpack(pac, fieldReference);
|
||||
if(valueReference != fieldReference) {
|
||||
f.set(target, valueReference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class BooleanFieldEntry extends ReflectionFieldEntry {
|
||||
BooleanFieldEntry(FieldEntry e) {
|
||||
super(e);
|
||||
}
|
||||
public void pack(Object target, Packer pac) throws IOException {
|
||||
pac.pack((boolean)(Boolean)target);
|
||||
}
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
|
||||
getField().setBoolean(target, obj.asBoolean());
|
||||
}
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
|
||||
getField().setBoolean(target, pac.unpackBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
static class ByteFieldEntry extends ReflectionFieldEntry {
|
||||
ByteFieldEntry(FieldEntry e) {
|
||||
super(e);
|
||||
}
|
||||
public void pack(Object target, Packer pac) throws IOException {
|
||||
pac.pack((byte)(Byte)target);
|
||||
}
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
|
||||
getField().setByte(target, obj.asByte());
|
||||
}
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
|
||||
getField().setByte(target, pac.unpackByte());
|
||||
}
|
||||
}
|
||||
|
||||
static class ShortFieldEntry extends ReflectionFieldEntry {
|
||||
ShortFieldEntry(FieldEntry e) {
|
||||
super(e);
|
||||
}
|
||||
public void pack(Object target, Packer pac) throws IOException {
|
||||
pac.pack((short)(Short)target);
|
||||
}
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
|
||||
getField().setShort(target, obj.asShort());
|
||||
}
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
|
||||
getField().setShort(target, pac.unpackShort());
|
||||
}
|
||||
}
|
||||
|
||||
static class IntFieldEntry extends ReflectionFieldEntry {
|
||||
IntFieldEntry(FieldEntry e) {
|
||||
super(e);
|
||||
}
|
||||
public void pack(Object target, Packer pac) throws IOException {
|
||||
pac.pack((int)(Integer)target);
|
||||
}
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
|
||||
getField().setInt(target, obj.asInt());
|
||||
}
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
|
||||
getField().setInt(target, pac.unpackInt());
|
||||
}
|
||||
}
|
||||
|
||||
static class LongFieldEntry extends ReflectionFieldEntry {
|
||||
LongFieldEntry(FieldEntry e) {
|
||||
super(e);
|
||||
}
|
||||
public void pack(Object target, Packer pac) throws IOException {
|
||||
pac.pack((long)(Long)target);
|
||||
}
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
|
||||
getField().setLong(target, obj.asLong());
|
||||
}
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
|
||||
getField().setLong(target, pac.unpackLong());
|
||||
}
|
||||
}
|
||||
|
||||
static class FloatFieldEntry extends ReflectionFieldEntry {
|
||||
FloatFieldEntry(FieldEntry e) {
|
||||
super(e);
|
||||
}
|
||||
public void pack(Object target, Packer pac) throws IOException {
|
||||
pac.pack((float)(Float)target);
|
||||
}
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
|
||||
getField().setFloat(target, obj.asFloat());
|
||||
}
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
|
||||
getField().setFloat(target, pac.unpackFloat());
|
||||
}
|
||||
}
|
||||
|
||||
static class DoubleFieldEntry extends ReflectionFieldEntry {
|
||||
DoubleFieldEntry(FieldEntry e) {
|
||||
super(e);
|
||||
}
|
||||
public void pack(Object target, Packer pac) throws IOException {
|
||||
pac.pack((double)(Double)target);
|
||||
}
|
||||
public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
|
||||
getField().setDouble(target, obj.asDouble());
|
||||
}
|
||||
public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
|
||||
getField().setDouble(target, pac.unpackDouble());
|
||||
}
|
||||
}
|
||||
|
||||
static class ReflectionTemplate extends AbstractTemplate {
|
||||
protected Class<?> targetClass;
|
||||
protected ReflectionFieldEntry[] entries;
|
||||
protected int minimumArrayLength;
|
||||
|
||||
ReflectionTemplate(Class<?> targetClass, ReflectionFieldEntry[] entries) {
|
||||
this.targetClass = targetClass;
|
||||
this.entries = entries;
|
||||
this.minimumArrayLength = 0;
|
||||
for(int i=0; i < entries.length; i++) {
|
||||
ReflectionFieldEntry e = entries[i];
|
||||
if(e.isRequired() || e.isNullable()) {
|
||||
this.minimumArrayLength = i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packArray(entries.length);
|
||||
for(ReflectionFieldEntry e : entries) {
|
||||
if(!e.isAvailable()) {
|
||||
pk.packNil();
|
||||
continue;
|
||||
}
|
||||
Object obj = e.getField().get(target);
|
||||
if(obj == null) {
|
||||
if(!e.isNullable() && !e.isOptional()) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
pk.packNil();
|
||||
} else {
|
||||
e.pack(obj, pk);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (MessageTypeException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new MessageTypeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
try {
|
||||
if(to == null) {
|
||||
to = targetClass.newInstance();
|
||||
}
|
||||
|
||||
int length = pac.unpackArray();
|
||||
if(length < minimumArrayLength) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i=0; i < minimumArrayLength; i++) {
|
||||
ReflectionFieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
pac.unpackObject();
|
||||
continue;
|
||||
}
|
||||
|
||||
if(pac.tryUnpackNull()) {
|
||||
if(e.isRequired()) {
|
||||
// Required + nil => exception
|
||||
throw new MessageTypeException();
|
||||
} else if(e.isOptional()) {
|
||||
// Optional + nil => keep default value
|
||||
} else { // Nullable
|
||||
// Nullable + nil => set null
|
||||
e.setNull(to);
|
||||
}
|
||||
} else {
|
||||
e.unpack(to, pac);
|
||||
}
|
||||
}
|
||||
|
||||
int max = length < entries.length ? length : entries.length;
|
||||
for(; i < max; i++) {
|
||||
ReflectionFieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
pac.unpackObject();
|
||||
continue;
|
||||
}
|
||||
|
||||
if(pac.tryUnpackNull()) {
|
||||
// this is Optional field becaue i >= minimumArrayLength
|
||||
// Optional + nil => keep default value
|
||||
} else {
|
||||
e.unpack(to, pac);
|
||||
}
|
||||
}
|
||||
|
||||
// latter entries are all Optional + nil => keep default value
|
||||
|
||||
for(; i < length; i++) {
|
||||
pac.unpackObject();
|
||||
}
|
||||
|
||||
return to;
|
||||
|
||||
} catch (MessageTypeException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new MessageTypeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
try {
|
||||
if(to == null) {
|
||||
to = targetClass.newInstance();
|
||||
}
|
||||
|
||||
MessagePackObject[] array = from.asArray();
|
||||
int length = array.length;
|
||||
if(length < minimumArrayLength) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i=0; i < minimumArrayLength; i++) {
|
||||
ReflectionFieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MessagePackObject obj = array[i];
|
||||
if(obj.isNil()) {
|
||||
if(e.isRequired()) {
|
||||
// Required + nil => exception
|
||||
throw new MessageTypeException();
|
||||
} else if(e.isOptional()) {
|
||||
// Optional + nil => keep default value
|
||||
} else { // Nullable
|
||||
// Nullable + nil => set null
|
||||
e.setNull(to);
|
||||
}
|
||||
} else {
|
||||
e.convert(to, obj);
|
||||
}
|
||||
}
|
||||
|
||||
int max = length < entries.length ? length : entries.length;
|
||||
for(; i < max; i++) {
|
||||
ReflectionFieldEntry e = entries[i];
|
||||
if(!e.isAvailable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MessagePackObject obj = array[i];
|
||||
if(obj.isNil()) {
|
||||
// this is Optional field becaue i >= minimumArrayLength
|
||||
// Optional + nil => keep default value
|
||||
} else {
|
||||
e.convert(to, obj);
|
||||
}
|
||||
}
|
||||
|
||||
// latter entries are all Optional + nil => keep default value
|
||||
|
||||
return to;
|
||||
|
||||
} catch (MessageTypeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new MessageTypeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Template buildTemplate(Class<?> targetClass, FieldEntry[] entries) {
|
||||
for(FieldEntry e : entries) {
|
||||
Field f = e.getField();
|
||||
int mod = f.getModifiers();
|
||||
if(!Modifier.isPublic(mod)) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
ReflectionFieldEntry[] res = new ReflectionFieldEntry[entries.length];
|
||||
for(int i=0; i < entries.length; i++) {
|
||||
FieldEntry e = entries[i];
|
||||
Class<?> type = e.getType();
|
||||
if(!e.isAvailable()) {
|
||||
res[i] = new NullFieldEntry(e);
|
||||
} else if(type.equals(boolean.class)) {
|
||||
res[i] = new BooleanFieldEntry(e);
|
||||
} else if(type.equals(byte.class)) {
|
||||
res[i] = new ByteFieldEntry(e);
|
||||
} else if(type.equals(short.class)) {
|
||||
res[i] = new ShortFieldEntry(e);
|
||||
} else if(type.equals(int.class)) {
|
||||
res[i] = new IntFieldEntry(e);
|
||||
} else if(type.equals(long.class)) {
|
||||
res[i] = new LongFieldEntry(e);
|
||||
} else if(type.equals(float.class)) {
|
||||
res[i] = new FloatFieldEntry(e);
|
||||
} else if(type.equals(double.class)) {
|
||||
res[i] = new DoubleFieldEntry(e);
|
||||
} else {
|
||||
Template tmpl = TemplateRegistry.lookup(e.getGenericType(), true);
|
||||
res[i] = new ObjectFieldEntry(e, tmpl);
|
||||
}
|
||||
}
|
||||
|
||||
return new ReflectionTemplate(targetClass, res);
|
||||
}
|
||||
|
||||
static class ReflectionOrdinalEnumTemplate extends AbstractTemplate {
|
||||
protected Enum<?>[] entries;
|
||||
protected Map<Enum<?>, Integer> reverse;
|
||||
|
||||
ReflectionOrdinalEnumTemplate(Enum<?>[] entries) {
|
||||
this.entries = entries;
|
||||
this.reverse = new HashMap<Enum<?>, Integer>();
|
||||
for(int i=0; i < entries.length; i++) {
|
||||
this.reverse.put(entries[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
Integer ord = reverse.get(target);
|
||||
if(ord == null) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
pk.pack((int)ord);
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int ord = pac.unpackInt();
|
||||
if(entries.length <= ord) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
return entries[ord];
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
int ord = from.asInt();
|
||||
if(entries.length <= ord) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
return entries[ord];
|
||||
}
|
||||
}
|
||||
|
||||
public Template buildOrdinalEnumTemplate(Class<?> targetClass, Enum<?>[] entries) {
|
||||
return new ReflectionOrdinalEnumTemplate(entries);
|
||||
}
|
||||
|
||||
|
||||
static class ReflectionObjectArrayTemplate extends AbstractTemplate {
|
||||
private Class<?> componentClass;
|
||||
private Template elementTemplate;
|
||||
|
||||
public ReflectionObjectArrayTemplate(Class<?> componentClass, Template elementTemplate) {
|
||||
this.componentClass = componentClass;
|
||||
this.elementTemplate = elementTemplate;
|
||||
}
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(!(target instanceof Object[]) || !componentClass.isAssignableFrom(target.getClass().getComponentType())) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
Object[] array = (Object[])target;
|
||||
int length = array.length;
|
||||
pk.packArray(length);
|
||||
for(int i=0; i < length; i++) {
|
||||
elementTemplate.pack(pk, array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException {
|
||||
int length = pac.unpackArray();
|
||||
Object[] array = (Object[])Array.newInstance(componentClass, length);
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = elementTemplate.unpack(pac, null);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] src = from.asArray();
|
||||
int length = src.length;
|
||||
Object[] array = (Object[])Array.newInstance(componentClass, length);
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = elementTemplate.convert(src[i], null);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
static class ReflectionMultidimentionalArrayTemplate extends AbstractTemplate {
|
||||
private Class<?> componentClass;
|
||||
private Template componentTemplate;
|
||||
|
||||
public ReflectionMultidimentionalArrayTemplate(Class<?> componentClass, Template componentTemplate) {
|
||||
this.componentClass = componentClass;
|
||||
this.componentTemplate = componentTemplate;
|
||||
}
|
||||
|
||||
Class<?> getComponentClass() {
|
||||
return componentClass;
|
||||
}
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
Object[] array = (Object[])target;
|
||||
int length = array.length;
|
||||
pk.packArray(length);
|
||||
for(int i=0; i < length; i++) {
|
||||
componentTemplate.pack(pk, array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
Object[] array = (Object[])Array.newInstance(componentClass, length);
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = componentTemplate.unpack(pac, null);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] src = from.asArray();
|
||||
int length = src.length;
|
||||
Object[] array = (Object[])Array.newInstance(componentClass, length);
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = componentTemplate.convert(src[i], null);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class<?> baseClass, int dim) {
|
||||
if(dim == 1) {
|
||||
if(baseClass == boolean.class) {
|
||||
return BooleanArrayTemplate.getInstance();
|
||||
} else if(baseClass == short.class) {
|
||||
return ShortArrayTemplate.getInstance();
|
||||
} else if(baseClass == int.class) {
|
||||
return IntArrayTemplate.getInstance();
|
||||
} else if(baseClass == long.class) {
|
||||
return LongArrayTemplate.getInstance();
|
||||
} else if(baseClass == float.class) {
|
||||
return FloatArrayTemplate.getInstance();
|
||||
} else if(baseClass == double.class) {
|
||||
return DoubleArrayTemplate.getInstance();
|
||||
} else {
|
||||
Template baseTemplate = TemplateRegistry.lookup(genericBaseType);
|
||||
return new ReflectionObjectArrayTemplate(baseClass, baseTemplate);
|
||||
}
|
||||
} else if(dim == 2) {
|
||||
Class<?> componentClass = Array.newInstance(baseClass, 0).getClass();
|
||||
Template componentTemplate = buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1);
|
||||
return new ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate);
|
||||
} else {
|
||||
ReflectionMultidimentionalArrayTemplate componentTemplate = (ReflectionMultidimentionalArrayTemplate)
|
||||
buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1);
|
||||
Class<?> componentClass = Array.newInstance(componentTemplate.getComponentClass(), 0).getClass();
|
||||
return new ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ShortArrayTemplate implements Template {
|
||||
private ShortArrayTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
if(!(target instanceof short[])) {
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
short[] array = (short[])target;
|
||||
try {
|
||||
pk.packArray(array.length);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
for(short a : array) {
|
||||
pk.pack(a);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
int length = pac.unpackArray();
|
||||
short[] array;
|
||||
if(to != null && to instanceof short[] && ((short[])to).length == length) {
|
||||
array = (short[])to;
|
||||
} else {
|
||||
array = new short[length];
|
||||
}
|
||||
for(int i=0; i < length; i++) {
|
||||
array[i] = pac.unpackShort();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
MessagePackObject[] src = from.asArray();
|
||||
short[] array;
|
||||
if(to != null && to instanceof short[] && ((short[])to).length == src.length) {
|
||||
array = (short[])to;
|
||||
} else {
|
||||
array = new short[src.length];
|
||||
}
|
||||
for(int i=0; i < src.length; i++) {
|
||||
MessagePackObject s = src[i];
|
||||
array[i] = s.asShort();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
static public ShortArrayTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final ShortArrayTemplate instance = new ShortArrayTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(short[].class, instance);
|
||||
}
|
||||
}
|
||||
|
53
java/src/main/java/org/msgpack/template/ShortTemplate.java
Normal file
53
java/src/main/java/org/msgpack/template/ShortTemplate.java
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ShortTemplate implements Template {
|
||||
private ShortTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packShort((Short)target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackShort();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asShort();
|
||||
}
|
||||
|
||||
static public ShortTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final ShortTemplate instance = new ShortTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(Short.class, instance);
|
||||
TemplateRegistry.register(short.class, instance);
|
||||
}
|
||||
}
|
||||
|
52
java/src/main/java/org/msgpack/template/StringTemplate.java
Normal file
52
java/src/main/java/org/msgpack/template/StringTemplate.java
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class StringTemplate implements Template {
|
||||
private StringTemplate() { }
|
||||
|
||||
public void pack(Packer pk, Object target) throws IOException {
|
||||
try {
|
||||
pk.packString((String)target);
|
||||
} catch (NullPointerException e) {
|
||||
throw new MessageTypeException("target is null.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
|
||||
return pac.unpackString();
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
|
||||
return from.asString();
|
||||
}
|
||||
|
||||
static public StringTemplate getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static final StringTemplate instance = new StringTemplate();
|
||||
|
||||
static {
|
||||
TemplateRegistry.register(String.class, instance);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TemplateBuildException extends RuntimeException {
|
||||
|
||||
public TemplateBuildException(String reason) {
|
||||
super(reason);
|
||||
}
|
||||
|
||||
public TemplateBuildException(String reason, Throwable t) {
|
||||
super(reason, t);
|
||||
}
|
||||
|
||||
public TemplateBuildException(Throwable t) {
|
||||
super(t);
|
||||
}
|
||||
}
|
||||
|
381
java/src/main/java/org/msgpack/template/TemplateBuilder.java
Normal file
381
java/src/main/java/org/msgpack/template/TemplateBuilder.java
Normal file
@@ -0,0 +1,381 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.annotation.*;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import org.msgpack.*;
|
||||
import org.msgpack.annotation.*;
|
||||
|
||||
public abstract class TemplateBuilder {
|
||||
public static class FieldEntry {
|
||||
private Field field;
|
||||
private FieldOption option;
|
||||
|
||||
public FieldEntry() {
|
||||
this.field = null;
|
||||
this.option = FieldOption.IGNORE;
|
||||
}
|
||||
|
||||
public FieldEntry(FieldEntry e) {
|
||||
this.field = e.field;
|
||||
this.option = e.option;
|
||||
}
|
||||
|
||||
public FieldEntry(Field field, FieldOption option) {
|
||||
this.field = field;
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public Field getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return field.getName();
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return field.getType();
|
||||
}
|
||||
|
||||
public String getJavaTypeName() {
|
||||
Class<?> type = field.getType();
|
||||
if(type.isArray()) {
|
||||
return arrayTypeToString(type);
|
||||
} else {
|
||||
return type.getName();
|
||||
}
|
||||
}
|
||||
|
||||
public Type getGenericType() {
|
||||
return field.getGenericType();
|
||||
}
|
||||
|
||||
public FieldOption getOption() {
|
||||
return option;
|
||||
}
|
||||
|
||||
public boolean isAvailable() {
|
||||
return option != FieldOption.IGNORE;
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return option == FieldOption.REQUIRED;
|
||||
}
|
||||
|
||||
public boolean isOptional() {
|
||||
return option == FieldOption.OPTIONAL;
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
return option == FieldOption.NULLABLE;
|
||||
}
|
||||
|
||||
static String arrayTypeToString(Class<?> type) {
|
||||
int dim = 1;
|
||||
Class<?> baseType = type.getComponentType();
|
||||
while(baseType.isArray()) {
|
||||
baseType = baseType.getComponentType();
|
||||
dim += 1;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(baseType.getName());
|
||||
for (int i = 0; i < dim; ++i) {
|
||||
sb.append("[]");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// Override this method
|
||||
public abstract Template buildTemplate(Class<?> targetClass, FieldEntry[] entries);
|
||||
|
||||
// Override this method
|
||||
public abstract Template buildOrdinalEnumTemplate(Class<?> targetClass, Enum<?>[] entries);
|
||||
|
||||
// Override this method
|
||||
public abstract Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class<?> baseClass, int dim);
|
||||
|
||||
|
||||
public Template buildTemplate(Class<?> targetClass, FieldList flist) throws NoSuchFieldException {
|
||||
checkValidation(targetClass);
|
||||
return buildTemplate(targetClass, convertFieldEntries(targetClass, flist));
|
||||
}
|
||||
|
||||
public Template buildTemplate(Class<?> targetClass, FieldOption implicitOption) {
|
||||
checkValidation(targetClass);
|
||||
return buildTemplate(targetClass, readFieldEntries(targetClass, implicitOption));
|
||||
}
|
||||
|
||||
public Template buildTemplate(Class<?> targetClass) {
|
||||
FieldOption implicitOption = readImplicitFieldOption(targetClass);
|
||||
return buildTemplate(targetClass, implicitOption);
|
||||
}
|
||||
|
||||
public Template buildOrdinalEnumTemplate(Class<?> targetClass) {
|
||||
checkOrdinalEnumValidation(targetClass);
|
||||
Enum<?>[] entries = (Enum<?>[])targetClass.getEnumConstants();
|
||||
return buildOrdinalEnumTemplate(targetClass, entries);
|
||||
}
|
||||
|
||||
public Template buildArrayTemplate(Type arrayType) {
|
||||
Type baseType;
|
||||
Class<?> baseClass;
|
||||
int dim = 1;
|
||||
if(arrayType instanceof GenericArrayType) {
|
||||
GenericArrayType type = (GenericArrayType)arrayType;
|
||||
baseType = type.getGenericComponentType();
|
||||
while(baseType instanceof GenericArrayType) {
|
||||
baseType = ((GenericArrayType)baseType).getGenericComponentType();
|
||||
dim += 1;
|
||||
}
|
||||
if(baseType instanceof ParameterizedType) {
|
||||
baseClass = (Class<?>)((ParameterizedType)baseType).getRawType();
|
||||
} else {
|
||||
baseClass = (Class<?>)baseType;
|
||||
}
|
||||
} else {
|
||||
Class<?> type = (Class<?>)arrayType;
|
||||
baseClass = type.getComponentType();
|
||||
while(baseClass.isArray()) {
|
||||
baseClass = baseClass.getComponentType();
|
||||
dim += 1;
|
||||
}
|
||||
baseType = baseClass;
|
||||
}
|
||||
return buildArrayTemplate(arrayType, baseType, baseClass, dim);
|
||||
}
|
||||
|
||||
private static Type getComponentType(Type arrayType) {
|
||||
if(arrayType instanceof GenericArrayType) {
|
||||
return ((GenericArrayType)arrayType).getGenericComponentType();
|
||||
} else {
|
||||
return ((Class<?>)arrayType).getComponentType();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static TemplateBuilder instance;
|
||||
static {
|
||||
instance = selectDefaultTemplateBuilder();
|
||||
}
|
||||
|
||||
private static TemplateBuilder selectDefaultTemplateBuilder() {
|
||||
try {
|
||||
// FIXME JavassistTemplateBuilder doesn't work on DalvikVM
|
||||
if(System.getProperty("java.vm.name").equals("Dalvik")) {
|
||||
return ReflectionTemplateBuilder.getInstance();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return JavassistTemplateBuilder.getInstance();
|
||||
}
|
||||
|
||||
synchronized static void setInstance(TemplateBuilder builder) {
|
||||
instance = builder;
|
||||
}
|
||||
|
||||
public static Template build(Class<?> targetClass) {
|
||||
return instance.buildTemplate(targetClass);
|
||||
}
|
||||
|
||||
public static Template build(Class<?> targetClass, FieldOption implicitOption) {
|
||||
return instance.buildTemplate(targetClass, implicitOption);
|
||||
}
|
||||
|
||||
public static Template build(Class<?> targetClass, FieldList flist) throws NoSuchFieldException {
|
||||
return instance.buildTemplate(targetClass, flist);
|
||||
}
|
||||
|
||||
public static Template buildOrdinalEnum(Class<?> targetClass) {
|
||||
return instance.buildOrdinalEnumTemplate(targetClass);
|
||||
}
|
||||
|
||||
public static Template buildArray(Type arrayType) {
|
||||
return instance.buildArrayTemplate(arrayType);
|
||||
}
|
||||
|
||||
|
||||
private static void checkValidation(Class<?> targetClass) {
|
||||
if(targetClass.isInterface()) {
|
||||
throw new TemplateBuildException("cannot build template of interface");
|
||||
}
|
||||
if(targetClass.isArray()) {
|
||||
throw new TemplateBuildException("cannot build template of array class");
|
||||
}
|
||||
if(targetClass.isPrimitive()) {
|
||||
throw new TemplateBuildException("cannot build template of primitive type");
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkOrdinalEnumValidation(Class<?> targetClass) {
|
||||
if(!targetClass.isEnum()) {
|
||||
throw new TemplateBuildException("tried to build ordinal enum template of non-enum class");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FieldEntry[] convertFieldEntries(Class<?> targetClass, FieldList flist) throws NoSuchFieldException {
|
||||
List<FieldList.Entry> src = flist.getList();
|
||||
FieldEntry[] result = new FieldEntry[src.size()];
|
||||
for(int i=0; i < src.size(); i++) {
|
||||
FieldList.Entry s = src.get(i);
|
||||
if(s.isAvailable()) {
|
||||
result[i] = new FieldEntry(targetClass.getDeclaredField(s.getName()), s.getOption());
|
||||
} else {
|
||||
result[i] = new FieldEntry();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static FieldEntry[] readFieldEntries(Class<?> targetClass, FieldOption implicitOption) {
|
||||
Field[] allFields = readAllFields(targetClass);
|
||||
|
||||
/* index:
|
||||
* @Index(0) int field_a; // 0
|
||||
* int field_b; // 1
|
||||
* @Index(3) int field_c; // 3
|
||||
* int field_d; // 4
|
||||
* @Index(2) int field_e; // 2
|
||||
* int field_f; // 5
|
||||
*/
|
||||
List<FieldEntry> indexed = new ArrayList<FieldEntry>();
|
||||
int maxIndex = -1;
|
||||
for(Field f : allFields) {
|
||||
FieldOption opt = readFieldOption(f, implicitOption);
|
||||
if(opt == FieldOption.IGNORE) {
|
||||
// skip
|
||||
continue;
|
||||
}
|
||||
|
||||
int index = readFieldIndex(f, maxIndex);
|
||||
|
||||
if(indexed.size() > index && indexed.get(index) != null) {
|
||||
throw new TemplateBuildException("duplicated index: "+index);
|
||||
}
|
||||
if(index < 0) {
|
||||
throw new TemplateBuildException("invalid index: "+index);
|
||||
}
|
||||
|
||||
while(indexed.size() <= index) {
|
||||
indexed.add(null);
|
||||
}
|
||||
indexed.set(index, new FieldEntry(f, opt));
|
||||
|
||||
if(maxIndex < index) {
|
||||
maxIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
FieldEntry[] result = new FieldEntry[maxIndex+1];
|
||||
for(int i=0; i < indexed.size(); i++) {
|
||||
FieldEntry e = indexed.get(i);
|
||||
if(e == null) {
|
||||
result[i] = new FieldEntry();
|
||||
} else {
|
||||
result[i] = e;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Field[] readAllFields(Class<?> targetClass) {
|
||||
// order: [fields of super class, ..., fields of this class]
|
||||
List<Field[]> succ = new ArrayList<Field[]>();
|
||||
int total = 0;
|
||||
for(Class<?> c = targetClass; c != Object.class; c = c.getSuperclass()) {
|
||||
Field[] fields = c.getDeclaredFields();
|
||||
total += fields.length;
|
||||
succ.add(fields);
|
||||
}
|
||||
Field[] result = new Field[total];
|
||||
int off = 0;
|
||||
for(int i=succ.size()-1; i >= 0; i--) {
|
||||
Field[] fields = succ.get(i);
|
||||
System.arraycopy(fields, 0, result, off, fields.length);
|
||||
off += fields.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static FieldOption readImplicitFieldOption(Class<?> targetClass) {
|
||||
MessagePackMessage a = targetClass.getAnnotation(MessagePackMessage.class);
|
||||
if(a == null) {
|
||||
return FieldOption.DEFAULT;
|
||||
}
|
||||
return a.value();
|
||||
}
|
||||
|
||||
private static FieldOption readFieldOption(Field field, FieldOption implicitOption) {
|
||||
int mod = field.getModifiers();
|
||||
if(Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
|
||||
return FieldOption.IGNORE;
|
||||
}
|
||||
|
||||
if(isAnnotated(field, Ignore.class)) {
|
||||
return FieldOption.IGNORE;
|
||||
} else if(isAnnotated(field, Required.class)) {
|
||||
return FieldOption.REQUIRED;
|
||||
} else if(isAnnotated(field, Optional.class)) {
|
||||
return FieldOption.OPTIONAL;
|
||||
} else if(isAnnotated(field, Nullable.class)) {
|
||||
if(field.getDeclaringClass().isPrimitive()) {
|
||||
return FieldOption.REQUIRED;
|
||||
} else {
|
||||
return FieldOption.NULLABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if(implicitOption != FieldOption.DEFAULT) {
|
||||
return implicitOption;
|
||||
}
|
||||
|
||||
// default mode:
|
||||
// transient : Ignore
|
||||
// public : Required
|
||||
// others : Ignore
|
||||
if(Modifier.isTransient(mod)) {
|
||||
return FieldOption.IGNORE;
|
||||
} else if(Modifier.isPublic(mod)) {
|
||||
return FieldOption.REQUIRED;
|
||||
} else {
|
||||
return FieldOption.IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
private static int readFieldIndex(Field field, int maxIndex) {
|
||||
Index a = field.getAnnotation(Index.class);
|
||||
if(a == null) {
|
||||
return maxIndex + 1;
|
||||
} else {
|
||||
return a.value();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAnnotated(AccessibleObject ao, Class<? extends Annotation> with) {
|
||||
return ao.getAnnotation(with) != null;
|
||||
}
|
||||
}
|
||||
|
205
java/src/main/java/org/msgpack/template/TemplateRegistry.java
Normal file
205
java/src/main/java/org/msgpack/template/TemplateRegistry.java
Normal file
@@ -0,0 +1,205 @@
|
||||
//
|
||||
// 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.template;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.annotation.Annotation;
|
||||
import org.msgpack.annotation.MessagePackMessage;
|
||||
import org.msgpack.annotation.MessagePackDelegate;
|
||||
import org.msgpack.annotation.MessagePackOrdinalEnum;
|
||||
import org.msgpack.Template;
|
||||
import org.msgpack.Templates;
|
||||
|
||||
public class TemplateRegistry {
|
||||
private static Map<Type, Template> map;
|
||||
private static Map<Type, GenericTemplate> genericMap;
|
||||
|
||||
static {
|
||||
map = new HashMap<Type, Template>();
|
||||
genericMap = new HashMap<Type, GenericTemplate>();
|
||||
BuiltInTemplateLoader.load();
|
||||
}
|
||||
|
||||
public static void register(Class<?> target) { // auto-detect
|
||||
if(target.isEnum()) {
|
||||
register(target, TemplateBuilder.buildOrdinalEnum(target));
|
||||
} else {
|
||||
register(target, TemplateBuilder.build(target));
|
||||
}
|
||||
}
|
||||
|
||||
public static void register(Class<?> target, FieldOption implicitOption) {
|
||||
register(target, TemplateBuilder.build(target, implicitOption));
|
||||
}
|
||||
|
||||
public static void register(Class<?> target, FieldList flist) throws NoSuchFieldException {
|
||||
register(target, TemplateBuilder.build(target, flist));
|
||||
}
|
||||
|
||||
public static synchronized void register(Type rawType, Template tmpl) {
|
||||
if(rawType instanceof ParameterizedType) {
|
||||
rawType = ((ParameterizedType)rawType).getRawType();
|
||||
}
|
||||
map.put(rawType, tmpl);
|
||||
}
|
||||
|
||||
public static synchronized void registerGeneric(Type rawType, GenericTemplate gtmpl) {
|
||||
if(rawType instanceof ParameterizedType) {
|
||||
rawType = ((ParameterizedType)rawType).getRawType();
|
||||
}
|
||||
genericMap.put(rawType, gtmpl);
|
||||
}
|
||||
|
||||
public static synchronized Template lookup(Type targetType) {
|
||||
return lookupImpl(targetType, false, true);
|
||||
}
|
||||
|
||||
public static synchronized Template lookup(Type targetType, boolean forceBuild) {
|
||||
return lookupImpl(targetType, forceBuild, true);
|
||||
}
|
||||
|
||||
public static synchronized Template tryLookup(Type targetType) {
|
||||
return lookupImpl(targetType, false, false);
|
||||
}
|
||||
|
||||
public static synchronized Template tryLookup(Type targetType, boolean forceBuild) {
|
||||
return lookupImpl(targetType, forceBuild, false);
|
||||
}
|
||||
|
||||
private static synchronized Template lookupImpl(Type targetType, boolean forceBuild, boolean fallbackDefault) {
|
||||
Template tmpl;
|
||||
|
||||
if(targetType instanceof ParameterizedType) {
|
||||
// ParameterizedType is not a Class<?>?
|
||||
tmpl = lookupGenericImpl((ParameterizedType)targetType);
|
||||
if(tmpl != null) {
|
||||
return tmpl;
|
||||
}
|
||||
targetType = ((ParameterizedType)targetType).getRawType();
|
||||
}
|
||||
|
||||
tmpl = map.get(targetType);
|
||||
if(tmpl != null) {
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
if(targetType instanceof GenericArrayType) {
|
||||
// GenericArrayType is not a Class<?>
|
||||
tmpl = TemplateBuilder.buildArray(targetType);
|
||||
register(targetType, tmpl);
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
Class<?> target = (Class<?>)targetType;
|
||||
|
||||
if(target.isArray()) {
|
||||
// FIXME can't distinguish type-erased T<>[]?
|
||||
tmpl = TemplateBuilder.buildArray(target);
|
||||
register(target, tmpl);
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
if(isAnnotated(target, MessagePackMessage.class)) {
|
||||
tmpl = TemplateBuilder.build(target);
|
||||
register(target, tmpl);
|
||||
return tmpl;
|
||||
} else if(isAnnotated(target, MessagePackDelegate.class)) {
|
||||
// TODO DelegateTemplate
|
||||
throw new UnsupportedOperationException("not supported yet. : " + target.getName());
|
||||
} else if(isAnnotated(target, MessagePackOrdinalEnum.class)) {
|
||||
tmpl = TemplateBuilder.buildOrdinalEnum(target);
|
||||
register(target, tmpl);
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
for(Class<?> i : target.getInterfaces()) {
|
||||
tmpl = map.get(i);
|
||||
if(tmpl != null) {
|
||||
register(target, tmpl);
|
||||
return tmpl;
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> c = target.getSuperclass();
|
||||
if(c != null) {
|
||||
for(; c != Object.class; c = c.getSuperclass()) {
|
||||
tmpl = map.get(c);
|
||||
if(tmpl != null) {
|
||||
register(target, tmpl);
|
||||
return tmpl;
|
||||
}
|
||||
}
|
||||
|
||||
if(forceBuild) {
|
||||
tmpl = TemplateBuilder.build(target);
|
||||
register(target, tmpl);
|
||||
return tmpl;
|
||||
}
|
||||
}
|
||||
|
||||
if(fallbackDefault) {
|
||||
tmpl = new DefaultTemplate((Class<?>)target);
|
||||
register(target, tmpl);
|
||||
return tmpl;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized Template lookupGeneric(Type targetType) {
|
||||
if(targetType instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType)targetType;
|
||||
Template tmpl = lookupGenericImpl(parameterizedType);
|
||||
if(tmpl != null) {
|
||||
return tmpl;
|
||||
}
|
||||
return new DefaultTemplate((Class<?>)parameterizedType.getRawType(), parameterizedType);
|
||||
} else {
|
||||
throw new IllegalArgumentException("actual types of the generic type are erased: "+targetType);
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized Template lookupGenericImpl(ParameterizedType type) {
|
||||
Type rawType = type.getRawType();
|
||||
GenericTemplate gtmpl = genericMap.get(rawType);
|
||||
if(gtmpl == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Type[] types = type.getActualTypeArguments();
|
||||
Template[] tmpls = new Template[types.length];
|
||||
for(int i=0; i < types.length; i++) {
|
||||
tmpls[i] = lookup(types[i]);
|
||||
}
|
||||
|
||||
return gtmpl.build(tmpls);
|
||||
}
|
||||
|
||||
private static boolean isAnnotated(Class<?> ao, Class<? extends Annotation> with) {
|
||||
return ao.getAnnotation(with) != null;
|
||||
}
|
||||
|
||||
public static void setTemplateBuilder(TemplateBuilder builder) {
|
||||
TemplateBuilder.setInstance(builder);
|
||||
}
|
||||
}
|
||||
|
69
java/src/main/java/org/msgpack/type/Raw.java
Normal file
69
java/src/main/java/org/msgpack/type/Raw.java
Normal file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// 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.type;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import org.msgpack.*;
|
||||
|
||||
public final class Raw {
|
||||
private byte[] bytes;
|
||||
private String string;
|
||||
|
||||
public Raw(byte[] bytes) {
|
||||
this.bytes = bytes;
|
||||
this.string = null;
|
||||
}
|
||||
|
||||
public Raw(String string) {
|
||||
this.bytes = null;
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if(string == null) {
|
||||
try {
|
||||
string = new String(bytes, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
if(bytes == null) {
|
||||
try {
|
||||
bytes = string.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public ByteBuffer toByteBuffer() {
|
||||
return ByteBuffer.wrap(toByteArray());
|
||||
}
|
||||
|
||||
static {
|
||||
RawTemplate.load();
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user