mirror of
				https://github.com/msgpack/msgpack-c.git
				synced 2025-10-22 08:02:08 +02:00 
			
		
		
		
	Compare commits
	
		
			285 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 9684c8664f | ||
|   | 3c75361e5a | ||
|   | c44c9ab74d | ||
|   | 8cc9c871b7 | ||
|   | 31d211cded | ||
|   | c42cba1d54 | ||
|   | c87f7cb9ac | ||
|   | 421bee3871 | ||
|   | 2c7573a032 | ||
|   | fe2a0f5089 | ||
|   | 59ba8dec4e | ||
|   | 8de1f764fd | ||
|   | a91c1ec6d9 | ||
|   | c8e351b31e | ||
|   | b4c98584db | ||
|   | 1d17836b7d | ||
|   | 193a739749 | ||
|   | 48da2b8353 | ||
|   | 40dc9de6c9 | ||
|   | d7469e4694 | ||
|   | fdfabc9f88 | ||
|   | 5658ca5b90 | ||
|   | 8b79e6d3c7 | ||
|   | 8c67087a15 | ||
|   | 057f73a73e | ||
|   | d3bb37d113 | ||
|   | 6c91b862c9 | ||
|   | cba47b635a | ||
|   | cd83388f8b | ||
|   | 02ae247536 | ||
|   | 1621a68191 | ||
|   | 2aef495d62 | ||
|   | 227c168b65 | ||
|   | dcbcf5842f | ||
|   | 8a3ac6d9bd | ||
|   | 6cabad19d5 | ||
|   | dad7a03d19 | ||
|   | 7b152640d9 | ||
|   | 78fddff34e | ||
|   | f8a016edb5 | ||
|   | f5453d38ec | ||
|   | 331bf0af21 | ||
|   | 9ac69337e8 | ||
|   | ca0c844f32 | ||
|   | e629e8784f | ||
|   | e944c1ee93 | ||
|   | 02c882bda3 | ||
|   | 2c29377abf | ||
|   | 21992f1b9e | ||
|   | 8a3f090684 | ||
|   | a4258505a9 | ||
|   | ba4a971bfa | ||
|   | 6abc120279 | ||
|   | 64c36b7a8f | ||
|   | 64b9f0762c | ||
|   | e799082e5c | ||
|   | eab66a022e | ||
|   | 485915c27a | ||
|   | 45fb482ab4 | ||
|   | 167e2475d8 | ||
|   | fe77251242 | ||
|   | 0c331d2887 | ||
|   | 39facd5dc6 | ||
|   | a2bd5ae638 | ||
|   | c57f616141 | ||
|   | 3af10a1d00 | ||
|   | b3987e2402 | ||
|   | 71dd44f430 | ||
|   | 584462f9b9 | ||
|   | ff5d5d7cbc | ||
|   | 370e92b1a6 | ||
|   | 2469768a85 | ||
|   | acb8fa613e | ||
|   | 83b4b7d83d | ||
|   | 33a7d56042 | ||
|   | 20de730541 | ||
|   | 134c27c900 | ||
|   | 123ae024c6 | ||
|   | 34a29cd0a5 | ||
|   | 9fffa9800a | ||
|   | 8f7f23a0e5 | ||
|   | 358457f49d | ||
|   | 90e305d789 | ||
|   | b471e52e28 | ||
|   | 9b5fc37399 | ||
|   | 537322e3b5 | ||
|   | 279121f87f | ||
|   | a1b2b41cdc | ||
|   | 0cca90c21d | ||
|   | ad052cb510 | ||
|   | 57f0598373 | ||
|   | 92d192277e | ||
|   | 2cdfbd8970 | ||
|   | bc0c5f0cdc | ||
|   | 230ee3a03b | ||
|   | ab0bf37d30 | ||
|   | b1e66256ce | ||
|   | fd80693420 | ||
|   | f222f5ed9b | ||
|   | 59603b902a | ||
|   | 82a5dd6cf9 | ||
|   | a97f9081a3 | ||
|   | b3e0ad1303 | ||
|   | 251090406a | ||
|   | 9c3ed173b1 | ||
|   | 7cd41aeb72 | ||
|   | 8ecaf7ad4c | ||
|   | d4049fe593 | ||
|   | 989b14b519 | ||
|   | fb3e11408c | ||
|   | 3d3af3284e | ||
|   | eabcf15790 | ||
|   | 684bca203a | ||
|   | d42ecccf6f | ||
|   | 5a92c861e3 | ||
|   | 103b14ea3c | ||
|   | e49f091b4e | ||
|   | 6056f93910 | ||
|   | 18fa2d1af4 | ||
|   | 062ed8a4c4 | ||
|   | 49f3872d04 | ||
|   | d9b467098a | ||
|   | 7d1e51437e | ||
|   | f5a7d444e2 | ||
|   | a0071c2f9f | ||
|   | 98a5e43883 | ||
|   | f40ebe5b43 | ||
|   | d7d78d9a2b | ||
|   | 5a12d36a0a | ||
|   | e61dc76ae1 | ||
|   | 0da22193bd | ||
|   | d43921823e | ||
|   | 6b5b76b0c9 | ||
|   | 602971408b | ||
|   | 2f5d83f07d | ||
|   | 81b0c316cd | ||
|   | 6df86384ca | ||
|   | 3fbcde4bd7 | ||
|   | 293293c23c | ||
|   | 47185d757e | ||
|   | 94c3998507 | ||
|   | 5fa589691c | ||
|   | 26bc835c7e | ||
|   | fc7da17fa2 | ||
|   | dbebe9771b | ||
|   | d0af8aa9f1 | ||
|   | f8173e93f5 | ||
|   | fa6ea6848f | ||
|   | 5982970e21 | ||
|   | c43e5e0c95 | ||
|   | b4fc79c38e | ||
|   | b9cb270b8f | ||
|   | 1fe35d7efe | ||
|   | ec8c19b1f0 | ||
|   | c2525bcc05 | ||
|   | 985c31b378 | ||
|   | 135a9f5586 | ||
|   | 979ff80982 | ||
|   | 6cde9f3a9d | ||
|   | 5cad81bf4c | ||
|   | 18967162cf | ||
|   | 6ea75f3a9f | ||
|   | f51123d009 | ||
|   | be6376ee2d | ||
|   | 120a85a3e5 | ||
|   | 262fe96c29 | ||
|   | 1864df5ed0 | ||
|   | 09bae0a9e8 | ||
|   | ebe41a24f1 | ||
|   | f0f574a15b | ||
|   | 9420436c09 | ||
|   | 2b8f853b96 | ||
|   | 2c2bf60d0c | ||
|   | 62b82448d5 | ||
|   | 2f12e6c3d0 | ||
|   | 8ce23f8e3e | ||
|   | dbe760d6e2 | ||
|   | 674c26d9c7 | ||
|   | 7b68b04efd | ||
|   | e0b65bf196 | ||
|   | 77f5cb1f1f | ||
|   | 2a222737f8 | ||
|   | 77d48f9cee | ||
|   | c77eac325e | ||
|   | 517ced2a54 | ||
|   | 70d2c47367 | ||
|   | e57084f6df | ||
|   | 8783cf8ec3 | ||
|   | 2af7a7c6ac | ||
|   | 91a1f8d9e1 | ||
|   | fc5e8ddca1 | ||
|   | 6352472c5f | ||
|   | 833ee6484c | ||
|   | dda3d24bca | ||
|   | f77d76a320 | ||
|   | c51fabf6ed | ||
|   | b10cb658ca | ||
|   | 68f60568ac | ||
|   | 9fbca83ac0 | ||
|   | d19bfaa2cb | ||
|   | 53d5ddb345 | ||
|   | 0a5c2e7ab9 | ||
|   | 35802ba949 | ||
|   | 72160aac9a | ||
|   | 9df6916029 | ||
|   | 9bfa2354ff | ||
|   | 7d945d3c8e | ||
|   | 05e28752f1 | ||
|   | 01b6673528 | ||
|   | 4e85ebbf98 | ||
|   | 120e8bffd7 | ||
|   | 8335823748 | ||
|   | c9fcf4020f | ||
|   | b10a736744 | ||
|   | 60fbaf7612 | ||
|   | d24193630e | ||
|   | 354af69f62 | ||
|   | bccac610a4 | ||
|   | 5aa6209664 | ||
|   | d693d92702 | ||
|   | f2622e54e3 | ||
|   | 20fe9b6dde | ||
|   | 11f7aa4212 | ||
|   | f53c351fd2 | ||
|   | fb96617377 | ||
|   | 05b8c00ee7 | ||
|   | 58854fdae9 | ||
|   | fd31ff772f | ||
|   | ab8e0c9e31 | ||
|   | abeed3be84 | ||
|   | a65438c6fe | ||
|   | c3f43fb0cf | ||
|   | 2807504a81 | ||
|   | 08b716c96d | ||
|   | b4b1f0a2c9 | ||
|   | 228f742b2f | ||
|   | a55affe4d5 | ||
|   | a6ec726ed7 | ||
|   | 87835a4e60 | ||
|   | 1f18af4395 | ||
|   | e79747a600 | ||
|   | bd36ac2c0c | ||
|   | c6186f2c01 | ||
|   | d639f57470 | ||
|   | 99a2d28592 | ||
|   | 254ee80c16 | ||
|   | e43f57fe1a | ||
|   | f88c029a4c | ||
|   | 93c3cbeaef | ||
|   | 88c77b793f | ||
|   | 11286524a5 | ||
|   | 7c863c341e | ||
|   | 3416cf984e | ||
|   | 1784746e7e | ||
|   | 6c6df1adaf | ||
|   | f91e1c17c0 | ||
|   | 58201b95f2 | ||
|   | fcce8f6d51 | ||
|   | f7bdda8828 | ||
|   | df5a60fd5b | ||
|   | 5782ab7ccc | ||
|   | 72e3f98213 | ||
|   | 1b1433a664 | ||
|   | 568704ed22 | ||
|   | 05a7e4eb64 | ||
|   | 7a0acf2838 | ||
|   | 27787505e0 | ||
|   | 2c8048115d | ||
|   | 7df1780853 | ||
|   | d5609f3207 | ||
|   | cd10fbc1fe | ||
|   | ca0b085d15 | ||
|   | 9a034234d8 | ||
|   | 66ef6c9e4c | ||
|   | 7df60b259b | ||
|   | 34b3bbc883 | ||
|   | e02d20dd74 | ||
|   | 1a11608f1f | ||
|   | 9e2c9d7812 | ||
|   | 404a393315 | ||
|   | c69092e110 | ||
|   | ebc0eeac79 | ||
|   | 2b72f35c32 | ||
|   | d8212ad620 | ||
|   | 1066bb38a8 | 
							
								
								
									
										13
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Makefile.am
									
									
									
									
									
								
							| @@ -1,13 +0,0 @@ | |||||||
| if ENABLE_CXX |  | ||||||
| SUBDIRS = c cpp |  | ||||||
| else |  | ||||||
| SUBDIRS = c |  | ||||||
| endif |  | ||||||
|  |  | ||||||
| nobase_include_HEADERS = \ |  | ||||||
| 		msgpack/pack_define.h \ |  | ||||||
| 		msgpack/pack_template.h \ |  | ||||||
| 		msgpack/unpack_define.h \ |  | ||||||
| 		msgpack/unpack_template.h \ |  | ||||||
| 		msgpack/sysdep.h |  | ||||||
|  |  | ||||||
							
								
								
									
										70
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								README
									
									
									
									
									
								
							| @@ -1,70 +0,0 @@ | |||||||
| MessagePack |  | ||||||
| ----------- |  | ||||||
| Binary-based efficient data interchange format. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| *Requirements |  | ||||||
|  |  | ||||||
|   MessagePack is only tested on Linux and Mac OS X, but it may run on other |  | ||||||
|   UNIX-like platforms. |  | ||||||
|  |  | ||||||
|   gcc >= 4.1 is required to build. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| *Installation |  | ||||||
|  |  | ||||||
|   Simply run ./configure && make && make install to install C and C++ binding. |  | ||||||
|  |  | ||||||
|     $ ./configure |  | ||||||
|     $ make |  | ||||||
|     $ sudo make install |  | ||||||
|  |  | ||||||
|   To install Ruby binding, run ./gengem.sh script on ruby/ directory and install |  | ||||||
|   generated gem package. |  | ||||||
|  |  | ||||||
|     $ cd ruby |  | ||||||
|     $ ./gengem.sh |  | ||||||
|     $ gem install gem/pkg/msgpack-*.gem |  | ||||||
|  |  | ||||||
|  |  | ||||||
| *Usage |  | ||||||
|  |  | ||||||
|   C++: |  | ||||||
|     include msgpack.hpp header and link libmsgpack library. |  | ||||||
|     see example/simple.cc for example. |  | ||||||
|  |  | ||||||
|       g++ simple.cc -lmsgpack |  | ||||||
|       g++ stream.cc -lmsgpack -lpthread |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   C: |  | ||||||
|     include msgpack.h   header and link libmsgpackc library. |  | ||||||
|     see example/simple.c  for example. |  | ||||||
|  |  | ||||||
|       gcc simple.c  -lmsgpackc |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   Ruby: |  | ||||||
|     require msgpack library. |  | ||||||
|     see example/simple.rb for example. |  | ||||||
|  |  | ||||||
| 	  ruby -rubygems simple.rb |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   API Document is available at http://msgpack.sourceforge.jp/. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Copyright (C) 2008-2009 FURUHASHI Sadayuki |  | ||||||
|  |  | ||||||
|    Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|    you may not use this file except in compliance with the License. |  | ||||||
|    You may obtain a copy of the License at |  | ||||||
|  |  | ||||||
|        http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  |  | ||||||
|    Unless required by applicable law or agreed to in writing, software |  | ||||||
|    distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|    See the License for the specific language governing permissions and |  | ||||||
|    limitations under the License. |  | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | MessagePack | ||||||
|  | =========== | ||||||
|  | Extremely efficient object serialization library. It's like JSON, but very fast and small. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## What's MessagePack? | ||||||
|  |  | ||||||
|  | MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small. | ||||||
|  |  | ||||||
|  | Typical small integer (like flags or error code) is saved only in 1 byte, and typical short string only needs 1 byte except the length of the string itself. \[1,2,3\] (3 elements array) is serialized in 4 bytes using MessagePack as follows: | ||||||
|  |  | ||||||
|  |     require 'msgpack' | ||||||
|  |     msg = [1,2,3].to_msgpack  #=> "\x93\x01\x02\x03" | ||||||
|  |     MessagePack.unpack(msg)   #=> [1,2,3] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## Performance | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | In this test, it measured the elapsed time of serializing and deserializing 200,000 target objects. The target object consists of the three integers and 512 bytes string. | ||||||
|  | The source code of this test is available from [frsyuki' serializer-speed-test repository.](http://github.com/frsyuki/serializer-speed-test) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## Getting Started | ||||||
|  |  | ||||||
|  | Usage and other documents about implementations in each language are found at [the web site.](http://msgpack.sourceforge.net/) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## Learn More | ||||||
|  |  | ||||||
|  |   - [Project Web Site](http://msgpack.sourceforge.net/) | ||||||
|  |   - [MessagePack format specification](http://msgpack.sourceforge.net/spec) | ||||||
|  |   - [Repository at github](http://github.com/msgpack/msgpack) | ||||||
|  |   - [Wiki](http://msgpack.sourceforge.net/start) | ||||||
|  |   - [MessagePack-RPC](http://github.com/msgpack/msgpack-rpc) | ||||||
|  |  | ||||||
| @@ -1,28 +0,0 @@ | |||||||
| lib_LTLIBRARIES = libmsgpackc.la |  | ||||||
|  |  | ||||||
| libmsgpackc_la_SOURCES = \ |  | ||||||
| 		unpack.c \ |  | ||||||
| 		object.c \ |  | ||||||
| 		vrefbuffer.c \ |  | ||||||
| 		zone.c |  | ||||||
|  |  | ||||||
| nobase_include_HEADERS = \ |  | ||||||
| 		msgpack.h \ |  | ||||||
| 		msgpack/sbuffer.h \ |  | ||||||
| 		msgpack/vrefbuffer.h \ |  | ||||||
| 		msgpack/pack.h \ |  | ||||||
| 		msgpack/unpack.h \ |  | ||||||
| 		msgpack/object.h \ |  | ||||||
| 		msgpack/zone.h |  | ||||||
|  |  | ||||||
| # -version-info CURRENT:REVISION:AGE |  | ||||||
| libmsgpackc_la_LDFLAGS = -version-info 2:0:0 |  | ||||||
|  |  | ||||||
| check_PROGRAMS = \ |  | ||||||
|   msgpackc_test |  | ||||||
|  |  | ||||||
| msgpackc_test_SOURCES = test.cpp |  | ||||||
| msgpackc_test_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/c |  | ||||||
| msgpackc_test_LDFLAGS = libmsgpackc.la -lgtest_main |  | ||||||
|  |  | ||||||
| TESTS = $(check_PROGRAMS) |  | ||||||
							
								
								
									
										323
									
								
								c/bench.c
									
									
									
									
									
								
							
							
						
						
									
										323
									
								
								c/bench.c
									
									
									
									
									
								
							| @@ -1,323 +0,0 @@ | |||||||
| #include <stdlib.h> |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <string.h> |  | ||||||
| #include <sys/time.h> |  | ||||||
|  |  | ||||||
| #include <msgpack/pack.h> |  | ||||||
| #include <msgpack/unpack.h> |  | ||||||
| #include <yajl/yajl_parse.h> |  | ||||||
| #include <yajl/yajl_gen.h> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static struct timeval g_timer; |  | ||||||
|  |  | ||||||
| void reset_timer() |  | ||||||
| { |  | ||||||
| 	gettimeofday(&g_timer, NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void show_timer(size_t bufsz) |  | ||||||
| { |  | ||||||
| 	struct timeval endtime; |  | ||||||
| 	gettimeofday(&endtime, NULL); |  | ||||||
| 	double sec = (endtime.tv_sec - g_timer.tv_sec) |  | ||||||
| 		+ (double)(endtime.tv_usec - g_timer.tv_usec) / 1000 / 1000; |  | ||||||
| 	printf("%f sec\n", sec); |  | ||||||
| 	printf("%f MB\n", ((double)bufsz)/1024/1024); |  | ||||||
| 	printf("%f Mbps\n", ((double)bufsz)*8/sec/1000/1000); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static int reformat_null(void * ctx) { return 1; } |  | ||||||
| static int reformat_boolean(void * ctx, int boolean) { return 1; } |  | ||||||
| static int reformat_number(void * ctx, const char * s, unsigned int l) { return 1; } |  | ||||||
| static int reformat_string(void * ctx, const unsigned char * stringVal, unsigned int stringLen) { return 1; } |  | ||||||
| static int reformat_map_key(void * ctx, const unsigned char * stringVal, unsigned int stringLen) { return 1; } |  | ||||||
| static int reformat_start_map(void * ctx) { return 1; } |  | ||||||
| static int reformat_end_map(void * ctx) { return 1; } |  | ||||||
| static int reformat_start_array(void * ctx) { return 1; } |  | ||||||
| static int reformat_end_array(void * ctx) { return 1; } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static void* unpack_uint8(void* data, uint8_t d) { return NULL; } |  | ||||||
| static void* unpack_uint16(void* data, uint16_t d) { return NULL; } |  | ||||||
| static void* unpack_uint32(void* data, uint32_t d) { return NULL; } |  | ||||||
| static void* unpack_uint64(void* data, uint64_t d) { return NULL; } |  | ||||||
| static void* unpack_int8(void* data, int8_t d) { return NULL; } |  | ||||||
| static void* unpack_int16(void* data, int16_t d) { return NULL; } |  | ||||||
| static void* unpack_int32(void* data, int32_t d) { return NULL; } |  | ||||||
| static void* unpack_int64(void* data, int64_t d) { return NULL; } |  | ||||||
| static void* unpack_float(void* data, float d) { return NULL; } |  | ||||||
| static void* unpack_double(void* data, double d) { return NULL; } |  | ||||||
| static void* unpack_nil(void* data) { return NULL; } |  | ||||||
| static void* unpack_true(void* data) { return NULL; } |  | ||||||
| static void* unpack_false(void* data) { return NULL; } |  | ||||||
| static void* unpack_array(void* data, unsigned int n) { return NULL; } |  | ||||||
| static void unpack_array_item(void* data, void* c, void* o) { } |  | ||||||
| static void* unpack_map(void* data, unsigned int n) { return NULL; } |  | ||||||
| static void unpack_map_item(void* data, void* c, void* k, void* v) { } |  | ||||||
| static void* unpack_raw(void* data, const char* b, const char* p, unsigned int l) { /*printf("unpack raw %p %lu\n",p,l);*/ return NULL; } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct { |  | ||||||
| 	size_t allocated; |  | ||||||
| 	size_t length; |  | ||||||
| 	char* buffer; |  | ||||||
| } pack_buffer; |  | ||||||
|  |  | ||||||
| static const size_t PACK_INITIAL_BUFFER_SIZE = 32*1024; |  | ||||||
|  |  | ||||||
| static void pack_buffer_init(pack_buffer* data) |  | ||||||
| { |  | ||||||
| 	data->buffer = malloc(PACK_INITIAL_BUFFER_SIZE); |  | ||||||
| 	data->length = 0; |  | ||||||
| 	data->allocated = PACK_INITIAL_BUFFER_SIZE; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void pack_buffer_reset(pack_buffer* data) |  | ||||||
| { |  | ||||||
| 	data->buffer = realloc(data->buffer, PACK_INITIAL_BUFFER_SIZE); |  | ||||||
| 	data->allocated = PACK_INITIAL_BUFFER_SIZE; |  | ||||||
| 	data->length = 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void pack_buffer_free(pack_buffer* data) |  | ||||||
| { |  | ||||||
| 	free(data->buffer); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void pack_append_buffer(void* user, const char* b, unsigned int l) |  | ||||||
| { |  | ||||||
| 	pack_buffer* data = (pack_buffer*)user; |  | ||||||
| 	if(data->allocated - data->length < l) { |  | ||||||
| 		data->buffer = realloc(data->buffer, data->allocated*2); |  | ||||||
| 		data->allocated *= 2; |  | ||||||
| 	} |  | ||||||
| 	memcpy(data->buffer + data->length, b, l); |  | ||||||
| 	data->length += l; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static const unsigned int TASK_INT_NUM = 1<<24; |  | ||||||
| static const unsigned int TASK_STR_LEN = 1<<15; |  | ||||||
| //static const unsigned int TASK_INT_NUM = 1<<20; |  | ||||||
| //static const unsigned int TASK_STR_LEN = 1<<12; |  | ||||||
| static const char* TASK_STR_PTR; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void bench_json(void) |  | ||||||
| { |  | ||||||
| 	puts("== JSON =="); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	yajl_gen_config gcfg = {0, NULL}; |  | ||||||
| 	yajl_gen g = yajl_gen_alloc(&gcfg); |  | ||||||
|  |  | ||||||
| 	yajl_parser_config hcfg = { 0, 0 }; |  | ||||||
| 	yajl_callbacks callbacks = { |  | ||||||
| 	    reformat_null, |  | ||||||
| 	    reformat_boolean, |  | ||||||
| 	    NULL, |  | ||||||
| 	    NULL, |  | ||||||
| 	    reformat_number, |  | ||||||
| 		reformat_string, |  | ||||||
| 	    reformat_start_map, |  | ||||||
| 	    reformat_map_key, |  | ||||||
| 	    reformat_end_map, |  | ||||||
| 	    reformat_start_array, |  | ||||||
| 	    reformat_end_array |  | ||||||
| 	}; |  | ||||||
| 	yajl_handle h = yajl_alloc(&callbacks, &hcfg, NULL); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	const unsigned char * buf; |  | ||||||
| 	unsigned int len; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	puts("generate integer"); |  | ||||||
| 	reset_timer(); |  | ||||||
| 	{ |  | ||||||
| 		unsigned int i; |  | ||||||
| 		yajl_gen_array_open(g); |  | ||||||
| 		for(i=0; i < TASK_INT_NUM; ++i) { |  | ||||||
| 			yajl_gen_integer(g, i); |  | ||||||
| 		} |  | ||||||
| 		yajl_gen_array_close(g); |  | ||||||
| 	} |  | ||||||
| 	show_timer(len); |  | ||||||
|  |  | ||||||
| 	yajl_gen_get_buf(g, &buf, &len); |  | ||||||
|  |  | ||||||
| 	puts("----"); |  | ||||||
| 	puts("parse integer"); |  | ||||||
| 	reset_timer(); |  | ||||||
| 	{ |  | ||||||
| 		yajl_status stat = yajl_parse(h, buf, len); |  | ||||||
| 		if (stat != yajl_status_ok && stat != yajl_status_insufficient_data) { |  | ||||||
| 			unsigned char * str = yajl_get_error(h, 1, buf, len); |  | ||||||
| 			fprintf(stderr, (const char *) str); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	show_timer(len); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	//yajl_gen_clear(g); |  | ||||||
| 	yajl_gen_free(g); |  | ||||||
| 	g = yajl_gen_alloc(&gcfg); |  | ||||||
| 	yajl_free(h); |  | ||||||
| 	h = yajl_alloc(&callbacks, &hcfg, NULL); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	puts("----"); |  | ||||||
| 	puts("generate string"); |  | ||||||
| 	reset_timer(); |  | ||||||
| 	{ |  | ||||||
| 		unsigned int i; |  | ||||||
| 		yajl_gen_array_open(g); |  | ||||||
| 		for(i=0; i < TASK_STR_LEN; ++i) { |  | ||||||
| 			yajl_gen_string(g, (const unsigned char*)TASK_STR_PTR, i); |  | ||||||
| 		} |  | ||||||
| 		yajl_gen_array_close(g); |  | ||||||
| 	} |  | ||||||
| 	show_timer(len); |  | ||||||
|  |  | ||||||
| 	yajl_gen_get_buf(g, &buf, &len); |  | ||||||
|  |  | ||||||
| 	puts("----"); |  | ||||||
| 	puts("parse string"); |  | ||||||
| 	reset_timer(); |  | ||||||
| 	{ |  | ||||||
| 		yajl_status stat = yajl_parse(h, buf, len); |  | ||||||
| 		if (stat != yajl_status_ok && stat != yajl_status_insufficient_data) { |  | ||||||
| 			unsigned char * str = yajl_get_error(h, 1, buf, len); |  | ||||||
| 			fprintf(stderr, (const char *) str); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	show_timer(len); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	yajl_gen_free(g); |  | ||||||
| 	yajl_free(h); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void bench_msgpack(void) |  | ||||||
| { |  | ||||||
| 	puts("== MessagePack =="); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	pack_buffer mpkbuf; |  | ||||||
| 	pack_buffer_init(&mpkbuf); |  | ||||||
|  |  | ||||||
| 	msgpack_pack_t* mpk = msgpack_pack_new( |  | ||||||
| 			&mpkbuf, pack_append_buffer); |  | ||||||
|  |  | ||||||
| 	msgpack_unpack_callback cb = { |  | ||||||
| 		unpack_uint8, |  | ||||||
| 		unpack_uint16, |  | ||||||
| 		unpack_uint32, |  | ||||||
| 		unpack_uint64, |  | ||||||
| 		unpack_int8, |  | ||||||
| 		unpack_int16, |  | ||||||
| 		unpack_int32, |  | ||||||
| 		unpack_int64, |  | ||||||
| 		unpack_float, |  | ||||||
| 		unpack_double, |  | ||||||
| 		unpack_nil, |  | ||||||
| 		unpack_true, |  | ||||||
| 		unpack_false, |  | ||||||
| 		unpack_array, |  | ||||||
| 		unpack_array_item, |  | ||||||
| 		unpack_map, |  | ||||||
| 		unpack_map_item, |  | ||||||
| 		unpack_raw, |  | ||||||
| 	}; |  | ||||||
| 	msgpack_unpack_t* mupk = msgpack_unpack_new(NULL, &cb); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	size_t len; |  | ||||||
| 	const char* buf; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	puts("pack integer"); |  | ||||||
| 	reset_timer(); |  | ||||||
| 	{ |  | ||||||
| 		unsigned int i; |  | ||||||
| 		msgpack_pack_array(mpk, TASK_INT_NUM); |  | ||||||
| 		for(i=0; i < TASK_INT_NUM; ++i) { |  | ||||||
| 			msgpack_pack_unsigned_int(mpk, i); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	show_timer(mpkbuf.length); |  | ||||||
|  |  | ||||||
| 	len = mpkbuf.length; |  | ||||||
| 	buf = mpkbuf.buffer; |  | ||||||
|  |  | ||||||
| 	puts("----"); |  | ||||||
| 	puts("unpack integer"); |  | ||||||
| 	reset_timer(); |  | ||||||
| 	{ |  | ||||||
| 		size_t off = 0; |  | ||||||
| 		int ret = msgpack_unpack_execute(mupk, buf, len, &off); |  | ||||||
| 		if(ret < 0) { |  | ||||||
| 			fprintf(stderr, "Parse error.\n"); |  | ||||||
| 		} else if(ret == 0) { |  | ||||||
| 			fprintf(stderr, "Not finished.\n"); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	show_timer(mpkbuf.length); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	pack_buffer_reset(&mpkbuf); |  | ||||||
| 	msgpack_unpack_reset(mupk); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	puts("----"); |  | ||||||
| 	puts("pack string"); |  | ||||||
| 	reset_timer(); |  | ||||||
| 	{ |  | ||||||
| 		unsigned int i; |  | ||||||
| 		msgpack_pack_array(mpk, TASK_STR_LEN); |  | ||||||
| 		for(i=0; i < TASK_STR_LEN; ++i) { |  | ||||||
| 			msgpack_pack_raw(mpk, i); |  | ||||||
| 			msgpack_pack_raw_body(mpk, TASK_STR_PTR, i); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	show_timer(mpkbuf.length); |  | ||||||
|  |  | ||||||
| 	len = mpkbuf.length; |  | ||||||
| 	buf = mpkbuf.buffer; |  | ||||||
|  |  | ||||||
| 	puts("----"); |  | ||||||
| 	puts("unpack string"); |  | ||||||
| 	reset_timer(); |  | ||||||
| 	{ |  | ||||||
| 		size_t off = 0; |  | ||||||
| 		int ret = msgpack_unpack_execute(mupk, buf, len, &off); |  | ||||||
| 		if(ret < 0) { |  | ||||||
| 			fprintf(stderr, "Parse error.\n"); |  | ||||||
| 		} else if(ret == 0) { |  | ||||||
| 			fprintf(stderr, "Not finished.\n"); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	show_timer(mpkbuf.length); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	msgpack_unpack_free(mupk); |  | ||||||
| 	msgpack_pack_free(mpk); |  | ||||||
| 	pack_buffer_free(&mpkbuf); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int main(int argc, char* argv[]) |  | ||||||
| { |  | ||||||
| 	char* str = malloc(TASK_STR_LEN); |  | ||||||
| 	memset(str, 'a', TASK_STR_LEN); |  | ||||||
| 	TASK_STR_PTR = str; |  | ||||||
|  |  | ||||||
| 	bench_msgpack(); |  | ||||||
| 	bench_json(); |  | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1,9 +0,0 @@ | |||||||
|  |  | ||||||
| CFLAGS  += -Wall -g -I. -I.. -O4 |  | ||||||
| LDFLAGS += -lyajl |  | ||||||
|  |  | ||||||
| all: bench |  | ||||||
|  |  | ||||||
| bench: bench.o pack.o unpack.o pack.h unpack.h |  | ||||||
| 	$(CC) bench.o pack.o unpack.o $(CFLAGS) $(LDFLAGS) -o $@ |  | ||||||
|  |  | ||||||
							
								
								
									
										123
									
								
								c/unpack.h
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								c/unpack.h
									
									
									
									
									
								
							| @@ -1,123 +0,0 @@ | |||||||
| /* |  | ||||||
|  * MessagePack for C unpacking routine |  | ||||||
|  * |  | ||||||
|  * Copyright (C) 2008-2009 FURUHASHI Sadayuki |  | ||||||
|  * |  | ||||||
|  *    Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  *    you may not use this file except in compliance with the License. |  | ||||||
|  *    You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *        http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  *    Unless required by applicable law or agreed to in writing, software |  | ||||||
|  *    distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  *    See the License for the specific language governing permissions and |  | ||||||
|  *    limitations under the License. |  | ||||||
|  */ |  | ||||||
| #ifndef MSGPACK_UNPACKER_H__ |  | ||||||
| #define MSGPACK_UNPACKER_H__ |  | ||||||
|  |  | ||||||
| #include "msgpack/zone.h" |  | ||||||
| #include "msgpack/object.h" |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| extern "C" { |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct msgpack_unpacker { |  | ||||||
| 	char* buffer; |  | ||||||
| 	size_t used; |  | ||||||
| 	size_t free; |  | ||||||
| 	size_t off; |  | ||||||
| 	size_t parsed; |  | ||||||
| 	msgpack_zone* z; |  | ||||||
| 	size_t initial_buffer_size; |  | ||||||
| 	void* ctx; |  | ||||||
| } msgpack_unpacker; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size); |  | ||||||
| void msgpack_unpacker_destroy(msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size); |  | ||||||
| void msgpack_unpacker_free(msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| static inline bool   msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size); |  | ||||||
| static inline char*  msgpack_unpacker_buffer(msgpack_unpacker* mpac); |  | ||||||
| static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac); |  | ||||||
| static inline void   msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| int msgpack_unpacker_execute(msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| void msgpack_unpacker_reset(msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef enum { |  | ||||||
| 	MSGPACK_UNPACK_SUCCESS				=  2, |  | ||||||
| 	MSGPACK_UNPACK_EXTRA_BYTES			=  1, |  | ||||||
| 	MSGPACK_UNPACK_CONTINUE				=  0, |  | ||||||
| 	MSGPACK_UNPACK_PARSE_ERROR			= -1, |  | ||||||
| } msgpack_unpack_return; |  | ||||||
|  |  | ||||||
| msgpack_unpack_return |  | ||||||
| msgpack_unpack(const char* data, size_t len, size_t* off, |  | ||||||
| 		msgpack_zone* z, msgpack_object* result); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac); |  | ||||||
|  |  | ||||||
| bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size); |  | ||||||
|  |  | ||||||
| bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size) |  | ||||||
| { |  | ||||||
| 	if(mpac->free >= size) { return true; } |  | ||||||
| 	return msgpack_unpacker_expand_buffer(mpac, size); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| char* msgpack_unpacker_buffer(msgpack_unpacker* mpac) |  | ||||||
| { |  | ||||||
| 	return mpac->buffer + mpac->used; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac) |  | ||||||
| { |  | ||||||
| 	return mpac->free; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size) |  | ||||||
| { |  | ||||||
| 	mpac->used += size; |  | ||||||
| 	mpac->free -= size; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac) |  | ||||||
| { |  | ||||||
| 	return mpac->parsed - mpac->off + mpac->used; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac) |  | ||||||
| { |  | ||||||
| 	return mpac->parsed; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #endif /* msgpack/unpack.h */ |  | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								configure.in
									
									
									
									
									
								
							| @@ -1,39 +0,0 @@ | |||||||
| AC_INIT(msgpack/unpack_template.h) |  | ||||||
| AC_CONFIG_AUX_DIR(ac) |  | ||||||
| AM_INIT_AUTOMAKE(msgpack, 0.4.0) |  | ||||||
| AC_CONFIG_HEADER(config.h) |  | ||||||
|  |  | ||||||
| AC_SUBST(CFLAGS) |  | ||||||
| if test "" = "$CFLAGS"; then |  | ||||||
| 	CFLAGS="-g -O4" |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| AC_PROG_CC |  | ||||||
|  |  | ||||||
| CFLAGS="-O4 -Wall $CFLAGS -I.." |  | ||||||
|  |  | ||||||
|  |  | ||||||
| AC_MSG_CHECKING([if c++ api is enabled]) |  | ||||||
| AC_ARG_ENABLE(cxx, |  | ||||||
| 	AS_HELP_STRING([--disable-cxx], |  | ||||||
| 				   [don't build c++ api.]) ) |  | ||||||
| AC_MSG_RESULT($enable_cxx) |  | ||||||
| if test "$enable_cxx" != "no"; then |  | ||||||
| 	AC_SUBST(CXXFLAGS) |  | ||||||
| 	if test "" = "$CXXFLAGS"; then |  | ||||||
| 		CXXFLAGS="-g -O4" |  | ||||||
| 	fi |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| # FIXME |  | ||||||
| AC_PROG_CXX |  | ||||||
|  |  | ||||||
| CXXFLAGS="-O4 -Wall $CXXFLAGS -I.. -I../c" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| AM_CONDITIONAL(ENABLE_CXX, test "$enable_cxx" != "no") |  | ||||||
|  |  | ||||||
| AC_PROG_LIBTOOL |  | ||||||
|  |  | ||||||
| AC_OUTPUT([Makefile c/Makefile cpp/Makefile]) |  | ||||||
|  |  | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| Copyright (C) 2008-2009 FURUHASHI Sadayuki | Copyright (C) 2008-2010 FURUHASHI Sadayuki | ||||||
| 
 | 
 | ||||||
|    Licensed under the Apache License, Version 2.0 (the "License"); |    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|    you may not use this file except in compliance with the License. |    you may not use this file except in compliance with the License. | ||||||
							
								
								
									
										37
									
								
								cpp/ChangeLog
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								cpp/ChangeLog
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  |  | ||||||
|  | 2010-08-29 version 0.5.4: | ||||||
|  |  | ||||||
|  |   * includes msgpack_vc2008.vcproj file in source package | ||||||
|  |   * fixes type::fix_int types | ||||||
|  |  | ||||||
|  | 2010-08-27 version 0.5.3: | ||||||
|  |  | ||||||
|  |   * adds type::fix_{u,}int{8,16,32,64} types | ||||||
|  |   * adds msgpack_pack_fix_{u,}int{8,16,32,64} functions | ||||||
|  |   * adds packer<Stream>::pack_fix_{u,}int{8,16,32,64} functions | ||||||
|  |   * fixes include paths | ||||||
|  |  | ||||||
|  | 2010-07-14 version 0.5.2: | ||||||
|  |  | ||||||
|  |   * type::raw::str(), operator==, operator!=, operator< and operator> are now const | ||||||
|  |   * generates version.h using AC_OUTPUT macro in ./configure | ||||||
|  |  | ||||||
|  | 2010-07-06 version 0.5.1: | ||||||
|  |  | ||||||
|  |   * Add msgpack_vrefbuffer_new and msgpack_vrefbuffer_free | ||||||
|  |   * Add msgpack_sbuffer_new and msgpack_sbuffer_free | ||||||
|  |   * Add msgpack_unpacker_next and msgpack_unpack_next | ||||||
|  |   * msgpack::unpack returns void | ||||||
|  |   * Add MSGPACK_VERSION{,_MAJOR,_MINOR} macros to check header version | ||||||
|  |   * Add msgpack_version{,_major,_minor} functions to check library version | ||||||
|  |   * ./configure supports --disable-cxx option not to build C++ API | ||||||
|  |  | ||||||
|  | 2010-04-29 version 0.5.0: | ||||||
|  |  | ||||||
|  |   * msgpack_object_type is changed. MSGPACK_OBJECT_NIL is now 0x00. | ||||||
|  |   * New safe streaming deserializer API. | ||||||
|  |   * Add object::object(const T&) and object::operator=(const T&) | ||||||
|  |   * Add operator==(object, const T&) | ||||||
|  |   * MSGPACK_DEFINE macro defines msgpack_object(object* obj, zone* z) | ||||||
|  |   * C++ programs doesn't need to link "msgpackc" library. | ||||||
|  |  | ||||||
							
								
								
									
										1552
									
								
								cpp/Doxyfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1552
									
								
								cpp/Doxyfile
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,44 +1,20 @@ | |||||||
| lib_LTLIBRARIES = libmsgpack.la | SUBDIRS = src test | ||||||
|  |  | ||||||
| libmsgpack_la_SOURCES = \ | DOC_FILES = \ | ||||||
| 		object.cpp | 		README.md \ | ||||||
|  | 		LICENSE \ | ||||||
|  | 		NOTICE \ | ||||||
|  | 		msgpack_vc8.vcproj \ | ||||||
|  | 		msgpack_vc8.sln \ | ||||||
|  | 		msgpack_vc2008.vcproj \ | ||||||
|  | 		msgpack_vc2008.sln \ | ||||||
|  | 		msgpack_vc.postbuild.bat | ||||||
|  |  | ||||||
| nobase_include_HEADERS = \ | EXTRA_DIST = \ | ||||||
| 		msgpack.hpp \ | 		$(DOC_FILES) | ||||||
| 		msgpack/sbuffer.hpp \ |  | ||||||
| 		msgpack/vrefbuffer.hpp \ |  | ||||||
| 		msgpack/pack.hpp \ |  | ||||||
| 		msgpack/unpack.hpp \ |  | ||||||
| 		msgpack/object.hpp \ |  | ||||||
| 		msgpack/zone.hpp \ |  | ||||||
| 		msgpack/type.hpp \ |  | ||||||
| 		msgpack/type/bool.hpp \ |  | ||||||
| 		msgpack/type/float.hpp \ |  | ||||||
| 		msgpack/type/int.hpp \ |  | ||||||
| 		msgpack/type/list.hpp \ |  | ||||||
| 		msgpack/type/deque.hpp \ |  | ||||||
| 		msgpack/type/map.hpp \ |  | ||||||
| 		msgpack/type/nil.hpp \ |  | ||||||
| 		msgpack/type/pair.hpp \ |  | ||||||
| 		msgpack/type/raw.hpp \ |  | ||||||
| 		msgpack/type/set.hpp \ |  | ||||||
| 		msgpack/type/string.hpp \ |  | ||||||
| 		msgpack/type/vector.hpp \ |  | ||||||
| 		msgpack/type/tuple.hpp \ |  | ||||||
| 		msgpack/type/define.hpp \ |  | ||||||
| 		msgpack/type/tr1/unordered_map.hpp \ |  | ||||||
| 		msgpack/type/tr1/unordered_set.hpp |  | ||||||
|  |  | ||||||
| libmsgpack_la_LIBADD = -L../c -lmsgpackc | doxygen: | ||||||
|  | 	./preprocess clean | ||||||
|  | 	cd src && $(MAKE) doxygen | ||||||
|  | 	./preprocess | ||||||
|  |  | ||||||
| # -version-info CURRENT:REVISION:AGE |  | ||||||
| libmsgpack_la_LDFLAGS = -version-info 2:0:0 |  | ||||||
|  |  | ||||||
| check_PROGRAMS = \ |  | ||||||
|   msgpack_test |  | ||||||
|  |  | ||||||
| msgpack_test_SOURCES = test.cpp |  | ||||||
| msgpack_test_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/c -I$(top_srcdir)/cpp |  | ||||||
| msgpack_test_LDFLAGS = libmsgpack.la -lgtest_main |  | ||||||
|  |  | ||||||
| TESTS = $(check_PROGRAMS) |  | ||||||
|   | |||||||
							
								
								
									
										73
									
								
								cpp/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								cpp/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | MessagePack for C/C++ | ||||||
|  | ===================== | ||||||
|  | Binary-based efficient object serialization library. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## Installation | ||||||
|  |  | ||||||
|  | Download latest package from [releases of MessagePack](http://sourceforge.net/projects/msgpack/files/) and extract it. | ||||||
|  |  | ||||||
|  | On UNIX-like platform, run ./configure && make && sudo make install: | ||||||
|  |  | ||||||
|  |     $ ./configure | ||||||
|  |     $ make | ||||||
|  |     $ sudo make install | ||||||
|  |  | ||||||
|  | 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" library. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## Example | ||||||
|  |  | ||||||
|  |     #include <msgpack.hpp> | ||||||
|  |     #include <vector> | ||||||
|  |      | ||||||
|  |     int main(void) { | ||||||
|  |         // This is target object. | ||||||
|  |         std::vector<std::string> target; | ||||||
|  |         target.push_back("Hello,"); | ||||||
|  |         target.push_back("World!"); | ||||||
|  |      | ||||||
|  |         // Serialize it. | ||||||
|  |         msgpack::sbuffer buffer;  // simple buffer | ||||||
|  |         msgpack::pack(&buffer, target); | ||||||
|  |      | ||||||
|  |         // Deserialize the serialized data. | ||||||
|  |         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!"] | ||||||
|  |      | ||||||
|  |         // Convert the deserialized object to staticaly typed object. | ||||||
|  |         std::vector<std::string> result; | ||||||
|  |         obj.convert(&result); | ||||||
|  |      | ||||||
|  |         // If the type is mismatched, it throws msgpack::type_error. | ||||||
|  |         obj.as<int>();  // type is mismatched, msgpack::type_error is thrown | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | 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. | ||||||
|  |  | ||||||
|  | See also NOTICE file. | ||||||
|  |  | ||||||
							
								
								
									
										188
									
								
								cpp/bench.cpp
									
									
									
									
									
								
							
							
						
						
									
										188
									
								
								cpp/bench.cpp
									
									
									
									
									
								
							| @@ -1,188 +0,0 @@ | |||||||
| #include <msgpack/unpack.hpp> |  | ||||||
| #include <msgpack/pack.hpp> |  | ||||||
| #include <string.h> |  | ||||||
| #include <sys/time.h> |  | ||||||
| #include <iostream> |  | ||||||
| #include <stdexcept> |  | ||||||
| #include <string> |  | ||||||
|  |  | ||||||
| static const unsigned int TASK_INT_NUM = 1<<24; |  | ||||||
| static const unsigned int TASK_STR_LEN = 1<<15; |  | ||||||
| //static const unsigned int TASK_INT_NUM = 1<<22; |  | ||||||
| //static const unsigned int TASK_STR_LEN = 1<<13; |  | ||||||
| static const char* TASK_STR_PTR; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class simple_timer { |  | ||||||
| public: |  | ||||||
| 	void reset() { gettimeofday(&m_timeval, NULL); } |  | ||||||
| 	void show_stat(size_t bufsz) |  | ||||||
| 	{ |  | ||||||
| 		struct timeval endtime; |  | ||||||
| 		gettimeofday(&endtime, NULL); |  | ||||||
| 		double sec = (endtime.tv_sec - m_timeval.tv_sec) |  | ||||||
| 			+ (double)(endtime.tv_usec - m_timeval.tv_usec) / 1000 / 1000; |  | ||||||
| 		std::cout << sec << " sec" << std::endl; |  | ||||||
| 		std::cout << (double(bufsz)/1024/1024) << " MB" << std::endl; |  | ||||||
| 		std::cout << (bufsz/sec/1000/1000*8) << " Mbps" << std::endl; |  | ||||||
| 	} |  | ||||||
| private: |  | ||||||
| 	timeval m_timeval; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class simple_buffer { |  | ||||||
| public: |  | ||||||
| 	static const size_t DEFAULT_INITIAL_SIZE = 32*1024;//512*1024*1024*2; |  | ||||||
|  |  | ||||||
| 	simple_buffer(size_t initial_size = DEFAULT_INITIAL_SIZE) : |  | ||||||
| 		m_storage((char*)malloc(initial_size)), |  | ||||||
| 		m_allocated(initial_size), |  | ||||||
| 		m_used(0) |  | ||||||
| 	{ |  | ||||||
| 		if(!m_storage) { throw std::bad_alloc(); } |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	~simple_buffer() |  | ||||||
| 	{ |  | ||||||
| 		free(m_storage); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| public: |  | ||||||
| 	inline void write(const char* buf, size_t len) |  | ||||||
| 	{ |  | ||||||
| 		if(m_allocated - m_used < len) { |  | ||||||
| 			expand_buffer(len); |  | ||||||
| 		} |  | ||||||
| 		memcpy(m_storage + m_used, buf, len); |  | ||||||
| 		m_used += len; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void clear() |  | ||||||
| 	{ |  | ||||||
| 		m_used = 0; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| private: |  | ||||||
| 	void expand_buffer(size_t req) |  | ||||||
| 	{ |  | ||||||
| 		size_t nsize = m_allocated * 2; |  | ||||||
| 		size_t at_least = m_used + req; |  | ||||||
| 		while(nsize < at_least) { nsize *= 2; } |  | ||||||
| 		char* tmp = (char*)realloc(m_storage, nsize); |  | ||||||
| 		if(!tmp) { throw std::bad_alloc(); } |  | ||||||
| 		m_storage = tmp; |  | ||||||
| 		m_allocated = nsize; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| public: |  | ||||||
| 	size_t size() const { return m_used; } |  | ||||||
| 	const char* data() const { return m_storage; } |  | ||||||
|  |  | ||||||
| private: |  | ||||||
| 	char* m_storage; |  | ||||||
| 	size_t m_allocated; |  | ||||||
| 	size_t m_used; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void bench_msgpack_int() |  | ||||||
| { |  | ||||||
| 	simple_buffer buf; |  | ||||||
| 	simple_timer timer; |  | ||||||
|  |  | ||||||
| 	std::cout << "----" << std::endl; |  | ||||||
| 	std::cout << "pack integer" << std::endl; |  | ||||||
|  |  | ||||||
| 	timer.reset(); |  | ||||||
| 	{ |  | ||||||
| 		msgpack::packer<simple_buffer> pk(buf); |  | ||||||
| 		pk.pack_array(TASK_INT_NUM); |  | ||||||
| 		for(unsigned int i=0; i < TASK_INT_NUM; ++i) { |  | ||||||
| 			pk.pack_unsigned_int(i); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	timer.show_stat(buf.size()); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	std::cout << "----" << std::endl; |  | ||||||
| 	std::cout << "unpack integer" << std::endl; |  | ||||||
|  |  | ||||||
| 	msgpack::zone z; |  | ||||||
| 	msgpack::object obj; |  | ||||||
|  |  | ||||||
| 	timer.reset(); |  | ||||||
| 	{ |  | ||||||
| 		obj = msgpack::unpack(buf.data(), buf.size(), z); |  | ||||||
| 	} |  | ||||||
| 	timer.show_stat(buf.size()); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	std::cout << "----" << std::endl; |  | ||||||
| 	std::cout << "dynamic pack integer" << std::endl; |  | ||||||
|  |  | ||||||
| 	buf.clear(); |  | ||||||
|  |  | ||||||
| 	timer.reset(); |  | ||||||
| 	msgpack::pack(buf, obj); |  | ||||||
| 	timer.show_stat(buf.size()); |  | ||||||
| 	*/ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void bench_msgpack_str() |  | ||||||
| { |  | ||||||
| 	simple_buffer buf; |  | ||||||
| 	simple_timer timer; |  | ||||||
|  |  | ||||||
| 	std::cout << "----" << std::endl; |  | ||||||
| 	std::cout << "pack string" << std::endl; |  | ||||||
|  |  | ||||||
| 	timer.reset(); |  | ||||||
| 	{ |  | ||||||
| 		msgpack::packer<simple_buffer> pk(buf); |  | ||||||
| 		pk.pack_array(TASK_STR_LEN); |  | ||||||
| 		for(unsigned int i=0; i < TASK_STR_LEN; ++i) { |  | ||||||
| 			pk.pack_raw(i); |  | ||||||
| 			pk.pack_raw_body(TASK_STR_PTR, i); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	timer.show_stat(buf.size()); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	std::cout << "----" << std::endl; |  | ||||||
| 	std::cout << "unpack string" << std::endl; |  | ||||||
|  |  | ||||||
| 	msgpack::zone z; |  | ||||||
| 	msgpack::object obj; |  | ||||||
|  |  | ||||||
| 	timer.reset(); |  | ||||||
| 	{ |  | ||||||
| 		obj = msgpack::unpack(buf.data(), buf.size(), z); |  | ||||||
| 	} |  | ||||||
| 	timer.show_stat(buf.size()); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	std::cout << "----" << std::endl; |  | ||||||
| 	std::cout << "dynamic pack string" << std::endl; |  | ||||||
|  |  | ||||||
| 	buf.clear(); |  | ||||||
|  |  | ||||||
| 	timer.reset(); |  | ||||||
| 	msgpack::pack(buf, obj); |  | ||||||
| 	timer.show_stat(buf.size()); |  | ||||||
| 	*/ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int main(void) |  | ||||||
| { |  | ||||||
| 	char* str = (char*)malloc(TASK_STR_LEN); |  | ||||||
| 	memset(str, 'a', TASK_STR_LEN); |  | ||||||
| 	TASK_STR_PTR = str; |  | ||||||
|  |  | ||||||
| 	bench_msgpack_int(); |  | ||||||
| 	bench_msgpack_str(); |  | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| @@ -1,9 +0,0 @@ | |||||||
|  |  | ||||||
| CXXFLAGS  += -Wall -g -I. -I.. -O4 |  | ||||||
| LDFLAGS += |  | ||||||
|  |  | ||||||
| all: bench |  | ||||||
|  |  | ||||||
| bench: bench.o unpack.o zone.o object.o pack.hpp unpack.hpp zone.hpp object.hpp |  | ||||||
| 	$(CXX) bench.o unpack.o zone.o object.o $(CXXFLAGS) $(LDFLAGS) -o $@ |  | ||||||
|  |  | ||||||
| @@ -32,7 +32,16 @@ fi | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| mkdir -p ac | mkdir -p ac | ||||||
| (cd cpp && ./preprocess.sh $@; cd ..) | test -f AUTHORS   || touch AUTHORS | ||||||
|  | test -f COPYING   || touch COPYING | ||||||
|  | test -f ChangeLog || touch ChangeLog | ||||||
|  | test -f NEWS      || touch NEWS | ||||||
|  | test -f README    || cp -f README.md README | ||||||
|  | 
 | ||||||
|  | if ! ./preprocess; then | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ACLOCAL="aclocal" | ACLOCAL="aclocal" | ||||||
							
								
								
									
										75
									
								
								cpp/configure.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								cpp/configure.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | AC_INIT(src/object.cpp) | ||||||
|  | AC_CONFIG_AUX_DIR(ac) | ||||||
|  | AM_INIT_AUTOMAKE(msgpack, 0.5.4) | ||||||
|  | AC_CONFIG_HEADER(config.h) | ||||||
|  |  | ||||||
|  | AC_SUBST(CFLAGS) | ||||||
|  | CFLAGS="-O4 -Wall $CFLAGS" | ||||||
|  |  | ||||||
|  | AC_SUBST(CXXFLAGS) | ||||||
|  | CXXFLAGS="-O4 -Wall $CXXFLAGS" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | AC_PROG_CC | ||||||
|  |  | ||||||
|  |  | ||||||
|  | AC_MSG_CHECKING([if C++ API is enabled]) | ||||||
|  | AC_ARG_ENABLE(cxx, | ||||||
|  | 	AS_HELP_STRING([--disable-cxx], | ||||||
|  | 				   [don't build C++ API]) ) | ||||||
|  | AC_MSG_RESULT([$enable_cxx]) | ||||||
|  | if test "$enable_cxx" != "no"; then | ||||||
|  | 	AC_PROG_CXX | ||||||
|  | 	AM_PROG_CC_C_O | ||||||
|  | fi | ||||||
|  | AM_CONDITIONAL(ENABLE_CXX, test "$enable_cxx" != "no") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | AC_PROG_LIBTOOL | ||||||
|  | AM_PROG_AS | ||||||
|  |  | ||||||
|  |  | ||||||
|  | AC_MSG_CHECKING([if debug option is enabled]) | ||||||
|  | AC_ARG_ENABLE(debug, | ||||||
|  | 	AS_HELP_STRING([--disable-debug], | ||||||
|  | 				   [disable assert macros and omit -g option]) ) | ||||||
|  | AC_MSG_RESULT([$enable_debug]) | ||||||
|  | if test "$enable_debug" != "no"; then | ||||||
|  | 	CXXFLAGS="$CXXFLAGS -g" | ||||||
|  | 	CFLAGS="$CFLAGS -g" | ||||||
|  | else | ||||||
|  | 	CXXFLAGS="$CXXFLAGS -DNDEBUG" | ||||||
|  | 	CFLAGS="$CFLAGS -DNDEBUG" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  |  | ||||||
|  | AC_CACHE_CHECK([for __sync_* atomic operations], msgpack_cv_atomic_ops, [ | ||||||
|  | 	AC_TRY_LINK([ | ||||||
|  | 		int atomic_sub(int i) { return __sync_sub_and_fetch(&i, 1); } | ||||||
|  | 		int atomic_add(int i) { return __sync_add_and_fetch(&i, 1); } | ||||||
|  | 	], [], msgpack_cv_atomic_ops="yes") | ||||||
|  | 	]) | ||||||
|  | if test "$msgpack_cv_atomic_ops" != "yes"; then | ||||||
|  | 	AC_MSG_ERROR([__sync_* atomic operations are not supported. | ||||||
|  |  | ||||||
|  | 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: | ||||||
|  |  | ||||||
|  |   $ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686" | ||||||
|  | ]) | ||||||
|  | fi | ||||||
|  |  | ||||||
|  |  | ||||||
|  | major=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` | ||||||
|  | minor=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` | ||||||
|  | AC_SUBST(VERSION_MAJOR, $major) | ||||||
|  | AC_SUBST(VERSION_MINOR, $minor) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | AC_OUTPUT([Makefile | ||||||
|  | 		   src/Makefile | ||||||
|  | 		   src/msgpack/version.h | ||||||
|  | 		   test/Makefile]) | ||||||
|  |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| . |  | ||||||
							
								
								
									
										45
									
								
								cpp/msgpack_vc.postbuild.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								cpp/msgpack_vc.postbuild.bat
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | IF NOT EXIST include                  MKDIR include | ||||||
|  | IF NOT EXIST include\msgpack          MKDIR include\msgpack | ||||||
|  | IF NOT EXIST include\msgpack\type     MKDIR include\msgpack\type | ||||||
|  | IF NOT EXIST include\msgpack\type\tr1 MKDIR include\msgpack\type\tr1 | ||||||
|  | copy src\msgpack\pack_define.h      include\msgpack\ | ||||||
|  | copy src\msgpack\pack_template.h    include\msgpack\ | ||||||
|  | copy src\msgpack\unpack_define.h    include\msgpack\ | ||||||
|  | copy src\msgpack\unpack_template.h  include\msgpack\ | ||||||
|  | copy src\msgpack\sysdep.h           include\msgpack\ | ||||||
|  | copy src\msgpack.h                     include\ | ||||||
|  | copy src\msgpack\sbuffer.h             include\msgpack\ | ||||||
|  | copy src\msgpack\version.h             include\msgpack\ | ||||||
|  | copy src\msgpack\vrefbuffer.h          include\msgpack\ | ||||||
|  | copy src\msgpack\zbuffer.h             include\msgpack\ | ||||||
|  | copy src\msgpack\pack.h                include\msgpack\ | ||||||
|  | copy src\msgpack\unpack.h              include\msgpack\ | ||||||
|  | copy src\msgpack\object.h              include\msgpack\ | ||||||
|  | copy src\msgpack\zone.h                include\msgpack\ | ||||||
|  | copy src\msgpack.hpp                   include\ | ||||||
|  | copy src\msgpack\sbuffer.hpp           include\msgpack\ | ||||||
|  | copy src\msgpack\vrefbuffer.hpp        include\msgpack\ | ||||||
|  | copy src\msgpack\zbuffer.hpp           include\msgpack\ | ||||||
|  | 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\bool.hpp         include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\deque.hpp        include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\fixint.hpp       include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\float.hpp        include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\int.hpp          include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\list.hpp         include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\map.hpp          include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\nil.hpp          include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\pair.hpp         include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\raw.hpp          include\msgpack\type\ | ||||||
|  | copy src\msgpack\type\set.hpp          include\msgpack\type\ | ||||||
|  | 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\ | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								cpp/msgpack_vc8.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								cpp/msgpack_vc8.sln
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  |  | ||||||
|  | Microsoft Visual Studio Solution File, Format Version 9.00 | ||||||
|  | # Visual C++ Express 2008 | ||||||
|  | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "msgpack_vc8.vcproj", "{122A2EA4-B283-4241-9655-786DE78283B2}" | ||||||
|  | EndProject | ||||||
|  | Global | ||||||
|  | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
|  | 		Debug|Win32 = Debug|Win32 | ||||||
|  | 		Release|Win32 = Release|Win32 | ||||||
|  | 	EndGlobalSection | ||||||
|  | 	GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||||||
|  | 		{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|Win32.ActiveCfg = Debug|Win32 | ||||||
|  | 		{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|Win32.Build.0 = Debug|Win32 | ||||||
|  | 		{122A2EA4-B283-4241-9655-786DE78283B2}.Release|Win32.ActiveCfg = Release|Win32 | ||||||
|  | 		{122A2EA4-B283-4241-9655-786DE78283B2}.Release|Win32.Build.0 = Release|Win32 | ||||||
|  | 	EndGlobalSection | ||||||
|  | 	GlobalSection(SolutionProperties) = preSolution | ||||||
|  | 		HideSolutionNode = FALSE | ||||||
|  | 	EndGlobalSection | ||||||
|  | EndGlobal | ||||||
							
								
								
									
										299
									
								
								cpp/msgpack_vc8.vcproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								cpp/msgpack_vc8.vcproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | |||||||
|  | <?xml version="1.0" encoding="Windows-1252"?> | ||||||
|  | <VisualStudioProject | ||||||
|  | 	ProjectType="Visual C++" | ||||||
|  | 	Version="8.00" | ||||||
|  | 	Name="MessagePack" | ||||||
|  | 	ProjectGUID="{122A2EA4-B283-4241-9655-786DE78283B2}" | ||||||
|  | 	RootNamespace="MessagePack" | ||||||
|  | 	Keyword="Win32Proj" | ||||||
|  | 	> | ||||||
|  | 	<Platforms> | ||||||
|  | 		<Platform | ||||||
|  | 			Name="Win32" | ||||||
|  | 		/> | ||||||
|  | 	</Platforms> | ||||||
|  | 	<ToolFiles> | ||||||
|  | 	</ToolFiles> | ||||||
|  | 	<Configurations> | ||||||
|  | 		<Configuration | ||||||
|  | 			Name="Debug|Win32" | ||||||
|  | 			OutputDirectory="$(SolutionDir)$(ConfigurationName)" | ||||||
|  | 			IntermediateDirectory="$(ConfigurationName)" | ||||||
|  | 			ConfigurationType="4" | ||||||
|  | 			CharacterSet="1" | ||||||
|  | 			> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCPreBuildEventTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCCustomBuildTool" | ||||||
|  | 				Description="Gathering header files" | ||||||
|  | 				CommandLine="msgpack_vc.postbuild.bat" | ||||||
|  | 				Outputs="include" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCXMLDataGeneratorTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCWebServiceProxyGeneratorTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCMIDLTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCCLCompilerTool" | ||||||
|  | 				Optimization="0" | ||||||
|  | 				AdditionalIncludeDirectories="." | ||||||
|  | 				PreprocessorDefinitions="WIN32;_DEBUG;_LIB" | ||||||
|  | 				MinimalRebuild="true" | ||||||
|  | 				BasicRuntimeChecks="1" | ||||||
|  | 				RuntimeLibrary="3" | ||||||
|  | 				UsePrecompiledHeader="0" | ||||||
|  | 				WarningLevel="3" | ||||||
|  | 				Detect64BitPortabilityProblems="true" | ||||||
|  | 				DebugInformationFormat="4" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCManagedResourceCompilerTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCResourceCompilerTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCPreLinkEventTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCLibrarianTool" | ||||||
|  | 				OutputFile="lib\msgpackd.lib" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCALinkTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCXDCMakeTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCBscMakeTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCFxCopTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCPostBuildEventTool" | ||||||
|  | 			/> | ||||||
|  | 		</Configuration> | ||||||
|  | 		<Configuration | ||||||
|  | 			Name="Release|Win32" | ||||||
|  | 			OutputDirectory="$(SolutionDir)$(ConfigurationName)" | ||||||
|  | 			IntermediateDirectory="$(ConfigurationName)" | ||||||
|  | 			ConfigurationType="4" | ||||||
|  | 			CharacterSet="1" | ||||||
|  | 			WholeProgramOptimization="1" | ||||||
|  | 			> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCPreBuildEventTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCCustomBuildTool" | ||||||
|  | 				Description="Gathering header files" | ||||||
|  | 				CommandLine="msgpack_vc.postbuild.bat" | ||||||
|  | 				Outputs="include" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCXMLDataGeneratorTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCWebServiceProxyGeneratorTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCMIDLTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCCLCompilerTool" | ||||||
|  | 				AdditionalIncludeDirectories="." | ||||||
|  | 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB" | ||||||
|  | 				RuntimeLibrary="2" | ||||||
|  | 				UsePrecompiledHeader="0" | ||||||
|  | 				WarningLevel="3" | ||||||
|  | 				Detect64BitPortabilityProblems="true" | ||||||
|  | 				DebugInformationFormat="3" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCManagedResourceCompilerTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCResourceCompilerTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCPreLinkEventTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCLibrarianTool" | ||||||
|  | 				OutputFile="lib\msgpack.lib" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCALinkTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCXDCMakeTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCBscMakeTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCFxCopTool" | ||||||
|  | 			/> | ||||||
|  | 			<Tool | ||||||
|  | 				Name="VCPostBuildEventTool" | ||||||
|  | 			/> | ||||||
|  | 		</Configuration> | ||||||
|  | 	</Configurations> | ||||||
|  | 	<References> | ||||||
|  | 	</References> | ||||||
|  | 	<Files> | ||||||
|  | 		<Filter | ||||||
|  | 			Name="Source Files" | ||||||
|  | 			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" | ||||||
|  | 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" | ||||||
|  | 			> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\objectc.c" | ||||||
|  | 				> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Debug|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Release|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\unpack.c" | ||||||
|  | 				> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Debug|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Release|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\version.c" | ||||||
|  | 				> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Debug|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Release|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\vrefbuffer.c" | ||||||
|  | 				> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Debug|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Release|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\zone.c" | ||||||
|  | 				> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Debug|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 				<FileConfiguration | ||||||
|  | 					Name="Release|Win32" | ||||||
|  | 					> | ||||||
|  | 					<Tool | ||||||
|  | 						Name="VCCLCompilerTool" | ||||||
|  | 						CompileAs="2" | ||||||
|  | 					/> | ||||||
|  | 				</FileConfiguration> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\object.cpp" | ||||||
|  | 				> | ||||||
|  | 			</File> | ||||||
|  | 		</Filter> | ||||||
|  | 		<Filter | ||||||
|  | 			Name="Header Files" | ||||||
|  | 			Filter="h;hpp;hxx;hm;inl;inc;xsd" | ||||||
|  | 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" | ||||||
|  | 			> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\msgpack\pack_define.h" | ||||||
|  | 				> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\msgpack\pack_template.h" | ||||||
|  | 				> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\msgpack\sysdep.h" | ||||||
|  | 				> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\msgpack\unpack_define.h" | ||||||
|  | 				> | ||||||
|  | 			</File> | ||||||
|  | 			<File | ||||||
|  | 				RelativePath=".\src\msgpack\unpack_template.h" | ||||||
|  | 				> | ||||||
|  | 			</File> | ||||||
|  | 		</Filter> | ||||||
|  | 		<Filter | ||||||
|  | 			Name="Resource Files" | ||||||
|  | 			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" | ||||||
|  | 			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" | ||||||
|  | 			> | ||||||
|  | 		</Filter> | ||||||
|  | 	</Files> | ||||||
|  | 	<Globals> | ||||||
|  | 	</Globals> | ||||||
|  | </VisualStudioProject> | ||||||
							
								
								
									
										34
									
								
								cpp/preprocess
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										34
									
								
								cpp/preprocess
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | #!/bin/sh | ||||||
|  |  | ||||||
|  | preprocess() { | ||||||
|  | 	ruby -r erb -e 'puts ERB.new(ARGF.read).result' $1.erb > $1.tmp | ||||||
|  | 	if [ "$?" != 0 ]; then | ||||||
|  | 		echo "" | ||||||
|  | 		echo "** preprocess failed **" | ||||||
|  | 		echo "" | ||||||
|  | 		exit 1 | ||||||
|  | 	else | ||||||
|  | 		mv $1.tmp $1 | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if [ "$1" == "clean" ];then | ||||||
|  | 	rm -f src/msgpack/type/tuple.hpp | ||||||
|  | 	rm -f src/msgpack/type/define.hpp | ||||||
|  | 	rm -f src/msgpack/zone.hpp | ||||||
|  | else | ||||||
|  | 	preprocess src/msgpack/type/tuple.hpp | ||||||
|  | 	preprocess src/msgpack/type/define.hpp | ||||||
|  | 	preprocess src/msgpack/zone.hpp | ||||||
|  | fi | ||||||
|  | cp -f ../msgpack/sysdep.h          src/msgpack/ | ||||||
|  | cp -f ../msgpack/pack_define.h     src/msgpack/ | ||||||
|  | cp -f ../msgpack/pack_template.h   src/msgpack/ | ||||||
|  | cp -f ../msgpack/unpack_define.h   src/msgpack/ | ||||||
|  | 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 | ||||||
|  |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
|  |  | ||||||
| preprocess() { |  | ||||||
| 	ruby -r erb -e 'puts ERB.new(ARGF.read).result' $1.erb > $1.tmp |  | ||||||
| 	if [ "$?" != 0 ]; then |  | ||||||
| 		echo "" |  | ||||||
| 		echo "** preprocess failed **" |  | ||||||
| 		echo "" |  | ||||||
| 	else |  | ||||||
| 		mv $1.tmp $1 |  | ||||||
| 	fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| preprocess msgpack/type/tuple.hpp |  | ||||||
| preprocess msgpack/type/define.hpp |  | ||||||
| preprocess msgpack/zone.hpp |  | ||||||
|  |  | ||||||
							
								
								
									
										101
									
								
								cpp/src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								cpp/src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | |||||||
|  |  | ||||||
|  | lib_LTLIBRARIES = libmsgpack.la | ||||||
|  |  | ||||||
|  | libmsgpack_la_SOURCES = \ | ||||||
|  | 		unpack.c \ | ||||||
|  | 		objectc.c \ | ||||||
|  | 		version.c \ | ||||||
|  | 		vrefbuffer.c \ | ||||||
|  | 		zone.c | ||||||
|  |  | ||||||
|  | if ENABLE_CXX | ||||||
|  | libmsgpack_la_SOURCES += \ | ||||||
|  | 		object.cpp | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | # -version-info CURRENT:REVISION:AGE | ||||||
|  | libmsgpack_la_LDFLAGS = -version-info 3:0:0 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # backward compatibility | ||||||
|  | lib_LTLIBRARIES += libmsgpackc.la | ||||||
|  |  | ||||||
|  | libmsgpackc_la_SOURCES = \ | ||||||
|  | 		unpack.c \ | ||||||
|  | 		objectc.c \ | ||||||
|  | 		version.c \ | ||||||
|  | 		vrefbuffer.c \ | ||||||
|  | 		zone.c | ||||||
|  |  | ||||||
|  | libmsgpackc_la_LDFLAGS = -version-info 2:0:0 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | nobase_include_HEADERS = \ | ||||||
|  | 		msgpack/pack_define.h \ | ||||||
|  | 		msgpack/pack_template.h \ | ||||||
|  | 		msgpack/unpack_define.h \ | ||||||
|  | 		msgpack/unpack_template.h \ | ||||||
|  | 		msgpack/sysdep.h \ | ||||||
|  | 		msgpack.h \ | ||||||
|  | 		msgpack/sbuffer.h \ | ||||||
|  | 		msgpack/version.h \ | ||||||
|  | 		msgpack/vrefbuffer.h \ | ||||||
|  | 		msgpack/zbuffer.h \ | ||||||
|  | 		msgpack/pack.h \ | ||||||
|  | 		msgpack/unpack.h \ | ||||||
|  | 		msgpack/object.h \ | ||||||
|  | 		msgpack/zone.h | ||||||
|  |  | ||||||
|  | if ENABLE_CXX | ||||||
|  | nobase_include_HEADERS += \ | ||||||
|  | 		msgpack.hpp \ | ||||||
|  | 		msgpack/sbuffer.hpp \ | ||||||
|  | 		msgpack/vrefbuffer.hpp \ | ||||||
|  | 		msgpack/zbuffer.hpp \ | ||||||
|  | 		msgpack/pack.hpp \ | ||||||
|  | 		msgpack/unpack.hpp \ | ||||||
|  | 		msgpack/object.hpp \ | ||||||
|  | 		msgpack/zone.hpp \ | ||||||
|  | 		msgpack/type.hpp \ | ||||||
|  | 		msgpack/type/bool.hpp \ | ||||||
|  | 		msgpack/type/deque.hpp \ | ||||||
|  | 		msgpack/type/float.hpp \ | ||||||
|  | 		msgpack/type/fixint.hpp \ | ||||||
|  | 		msgpack/type/int.hpp \ | ||||||
|  | 		msgpack/type/list.hpp \ | ||||||
|  | 		msgpack/type/map.hpp \ | ||||||
|  | 		msgpack/type/nil.hpp \ | ||||||
|  | 		msgpack/type/pair.hpp \ | ||||||
|  | 		msgpack/type/raw.hpp \ | ||||||
|  | 		msgpack/type/set.hpp \ | ||||||
|  | 		msgpack/type/string.hpp \ | ||||||
|  | 		msgpack/type/vector.hpp \ | ||||||
|  | 		msgpack/type/tuple.hpp \ | ||||||
|  | 		msgpack/type/define.hpp \ | ||||||
|  | 		msgpack/type/tr1/unordered_map.hpp \ | ||||||
|  | 		msgpack/type/tr1/unordered_set.hpp | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | EXTRA_DIST = \ | ||||||
|  | 		msgpack/version.h.in \ | ||||||
|  | 		msgpack/zone.hpp.erb \ | ||||||
|  | 		msgpack/type/define.hpp.erb \ | ||||||
|  | 		msgpack/type/tuple.hpp.erb | ||||||
|  |  | ||||||
|  |  | ||||||
|  | doxygen_c: | ||||||
|  | 	cat ../Doxyfile > Doxyfile_c | ||||||
|  | 	echo "FILE_PATTERNS      = *.h" >> Doxyfile_c | ||||||
|  | 	echo "OUTPUT_DIRECTORY   = doc_c" >> Doxyfile_c | ||||||
|  | 	echo "PROJECT_NAME       = \"MessagePack for C\"" >> Doxyfile_c | ||||||
|  | 	doxygen Doxyfile_c | ||||||
|  |  | ||||||
|  | doxygen_cpp: | ||||||
|  | 	cat ../Doxyfile > Doxyfile_cpp | ||||||
|  | 	echo "FILE_PATTERNS      = *.hpp" >> Doxyfile_cpp | ||||||
|  | 	echo "OUTPUT_DIRECTORY   = doc_cpp" >> Doxyfile_cpp | ||||||
|  | 	echo "PROJECT_NAME       = \"MessagePack for C++\"" >> Doxyfile_cpp | ||||||
|  | 	doxygen Doxyfile_cpp | ||||||
|  |  | ||||||
|  | doxygen: doxygen_c doxygen_cpp | ||||||
|  |  | ||||||
| @@ -15,9 +15,16 @@ | |||||||
|  *    See the License for the specific language governing permissions and |  *    See the License for the specific language governing permissions and | ||||||
|  *    limitations under the License. |  *    limitations under the License. | ||||||
|  */ |  */ | ||||||
|  | /**
 | ||||||
|  |  * @defgroup msgpack MessagePack C | ||||||
|  |  * @{ | ||||||
|  |  * @} | ||||||
|  |  */ | ||||||
| #include "msgpack/object.h" | #include "msgpack/object.h" | ||||||
| #include "msgpack/zone.h" | #include "msgpack/zone.h" | ||||||
| #include "msgpack/pack.h" | #include "msgpack/pack.h" | ||||||
| #include "msgpack/unpack.h" | #include "msgpack/unpack.h" | ||||||
| #include "msgpack/sbuffer.h" | #include "msgpack/sbuffer.h" | ||||||
| #include "msgpack/vrefbuffer.h" | #include "msgpack/vrefbuffer.h" | ||||||
|  | #include "msgpack/version.h" | ||||||
|  | 
 | ||||||
| @@ -18,8 +18,7 @@ | |||||||
| #ifndef MSGPACK_OBJECT_H__ | #ifndef MSGPACK_OBJECT_H__ | ||||||
| #define MSGPACK_OBJECT_H__ | #define MSGPACK_OBJECT_H__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/zone.h" | #include "zone.h" | ||||||
| #include "msgpack/sysdep.h" |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| @@ -27,15 +26,21 @@ extern "C" { | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * @defgroup msgpack_object Dynamically typed object | ||||||
|  |  * @ingroup msgpack | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| 	MSGPACK_OBJECT_NIL					= 0x01, | 	MSGPACK_OBJECT_NIL					= 0x00, | ||||||
| 	MSGPACK_OBJECT_BOOLEAN				= 0x02, | 	MSGPACK_OBJECT_BOOLEAN				= 0x01, | ||||||
| 	MSGPACK_OBJECT_POSITIVE_INTEGER		= 0x03, | 	MSGPACK_OBJECT_POSITIVE_INTEGER		= 0x02, | ||||||
| 	MSGPACK_OBJECT_NEGATIVE_INTEGER		= 0x04, | 	MSGPACK_OBJECT_NEGATIVE_INTEGER		= 0x03, | ||||||
| 	MSGPACK_OBJECT_DOUBLE				= 0x05, | 	MSGPACK_OBJECT_DOUBLE				= 0x04, | ||||||
| 	MSGPACK_OBJECT_RAW					= 0x06, | 	MSGPACK_OBJECT_RAW					= 0x05, | ||||||
| 	MSGPACK_OBJECT_ARRAY				= 0x07, | 	MSGPACK_OBJECT_ARRAY				= 0x06, | ||||||
| 	MSGPACK_OBJECT_MAP					= 0x08, | 	MSGPACK_OBJECT_MAP					= 0x07, | ||||||
| } msgpack_object_type; | } msgpack_object_type; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -80,6 +85,10 @@ typedef struct msgpack_object_kv { | |||||||
| 
 | 
 | ||||||
| void msgpack_object_print(FILE* out, msgpack_object o); | void msgpack_object_print(FILE* out, msgpack_object o); | ||||||
| 
 | 
 | ||||||
|  | bool msgpack_object_equal(const msgpack_object x, const msgpack_object y); | ||||||
|  | 
 | ||||||
|  | /** @} */ | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| @@ -18,8 +18,9 @@ | |||||||
| #ifndef MSGPACK_OBJECT_HPP__ | #ifndef MSGPACK_OBJECT_HPP__ | ||||||
| #define MSGPACK_OBJECT_HPP__ | #define MSGPACK_OBJECT_HPP__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/object.h" | #include "object.h" | ||||||
| #include "msgpack/pack.hpp" | #include "pack.hpp" | ||||||
|  | #include "zone.hpp" | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| #include <typeinfo> | #include <typeinfo> | ||||||
| @@ -34,14 +35,14 @@ class type_error : public std::bad_cast { }; | |||||||
| 
 | 
 | ||||||
| namespace type { | namespace type { | ||||||
| 	enum object_type { | 	enum object_type { | ||||||
| 		NIL					= 0x01, | 		NIL					= MSGPACK_OBJECT_NIL, | ||||||
| 		BOOLEAN				= 0x02, | 		BOOLEAN				= MSGPACK_OBJECT_BOOLEAN, | ||||||
| 		POSITIVE_INTEGER	= 0x03, | 		POSITIVE_INTEGER	= MSGPACK_OBJECT_POSITIVE_INTEGER, | ||||||
| 		NEGATIVE_INTEGER	= 0x04, | 		NEGATIVE_INTEGER	= MSGPACK_OBJECT_NEGATIVE_INTEGER, | ||||||
| 		DOUBLE				= 0x05, | 		DOUBLE				= MSGPACK_OBJECT_DOUBLE, | ||||||
| 		RAW					= 0x06, | 		RAW					= MSGPACK_OBJECT_RAW, | ||||||
| 		ARRAY				= 0x07, | 		ARRAY				= MSGPACK_OBJECT_ARRAY, | ||||||
| 		MAP					= 0x08, | 		MAP					= MSGPACK_OBJECT_MAP, | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -88,8 +89,21 @@ struct object { | |||||||
| 	void convert(T* v) const; | 	void convert(T* v) const; | ||||||
| 
 | 
 | ||||||
| 	object(); | 	object(); | ||||||
| 	object(msgpack_object obj); | 
 | ||||||
| 	operator msgpack_object(); | 	object(msgpack_object o); | ||||||
|  | 
 | ||||||
|  | 	template <typename T> | ||||||
|  | 	explicit object(const T& v); | ||||||
|  | 
 | ||||||
|  | 	template <typename T> | ||||||
|  | 	object(const T& v, zone* z); | ||||||
|  | 
 | ||||||
|  | 	template <typename T> | ||||||
|  | 	object& operator=(const T& v); | ||||||
|  | 
 | ||||||
|  | 	operator msgpack_object() const; | ||||||
|  | 
 | ||||||
|  | 	struct with_zone; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	struct implicit_type; | 	struct implicit_type; | ||||||
| @@ -103,18 +117,44 @@ struct object_kv { | |||||||
| 	object val; | 	object val; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct object::with_zone : object { | ||||||
|  | 	with_zone(msgpack::zone* zone) : zone(zone) { } | ||||||
|  | 	msgpack::zone* zone; | ||||||
|  | private: | ||||||
|  | 	with_zone(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| bool operator==(const object x, const object y); | bool operator==(const object x, const object y); | ||||||
| bool operator!=(const object x, const object y); | bool operator!=(const object x, const object y); | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | bool operator==(const object x, const T& y); | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | bool operator==(const T& y, const object x); | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | bool operator!=(const object x, const T& y); | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | bool operator!=(const T& y, const object x); | ||||||
|  | 
 | ||||||
| std::ostream& operator<< (std::ostream& s, const object o); | std::ostream& operator<< (std::ostream& s, const object o); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | // serialize operator
 | ||||||
| template <typename Stream, typename T> | template <typename Stream, typename T> | ||||||
| packer<Stream>& operator<< (packer<Stream>& o, const T& v); | packer<Stream>& operator<< (packer<Stream>& o, const T& v); | ||||||
| 
 | 
 | ||||||
|  | // convert operator
 | ||||||
| template <typename T> | template <typename T> | ||||||
| T& operator>> (object o, T& v); | T& operator>> (object o, T& v); | ||||||
| 
 | 
 | ||||||
|  | // deconvert operator
 | ||||||
|  | template <typename T> | ||||||
|  | void operator<< (object::with_zone& o, const T& v); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| struct object::implicit_type { | struct object::implicit_type { | ||||||
| 	implicit_type(object o) : obj(o) { } | 	implicit_type(object o) : obj(o) { } | ||||||
| @@ -179,26 +219,40 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const T& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | void operator<< (object::with_zone& o, const T& v) | ||||||
|  | { | ||||||
|  | 	v.msgpack_object(static_cast<object*>(&o), o.zone); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | inline bool operator==(const object x, const object y) | ||||||
|  | { | ||||||
|  | 	return msgpack_object_equal(x, y); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline bool operator==(const object x, const T& y) | ||||||
|  | try { | ||||||
|  | 	return x == object(y); | ||||||
|  | } catch (msgpack::type_error&) { | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| inline bool operator!=(const object x, const object y) | inline bool operator!=(const object x, const object y) | ||||||
| { return !(x == y); } | { return !(x == y); } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline bool operator==(const T& y, const object x) | ||||||
|  | { return x == y; } | ||||||
| 
 | 
 | ||||||
| inline object::object() { } | template <typename T> | ||||||
|  | inline bool operator!=(const object x, const T& y) | ||||||
|  | { return !(x == y); } | ||||||
| 
 | 
 | ||||||
| inline object::object(msgpack_object obj) | template <typename T> | ||||||
| { | inline bool operator!=(const T& y, const object x) | ||||||
| 	// FIXME beter way?
 | { return x != y; } | ||||||
| 	::memcpy(this, &obj, sizeof(obj)); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| inline object::operator msgpack_object() |  | ||||||
| { |  | ||||||
| 	// FIXME beter way?
 |  | ||||||
| 	msgpack_object obj; |  | ||||||
| 	::memcpy(&obj, this, sizeof(obj)); |  | ||||||
| 	return obj; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| inline object::implicit_type object::convert() const | inline object::implicit_type object::convert() const | ||||||
| @@ -221,6 +275,55 @@ inline T object::as() const | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | inline object::object() | ||||||
|  | { | ||||||
|  | 	type = type::NIL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline object::object(const T& v) | ||||||
|  | { | ||||||
|  | 	*this << v; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline object& object::operator=(const T& v) | ||||||
|  | { | ||||||
|  | 	*this = object(v); | ||||||
|  | 	return *this; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | object::object(const T& v, zone* z) | ||||||
|  | { | ||||||
|  | 	with_zone oz(z); | ||||||
|  | 	oz << v; | ||||||
|  | 	type = oz.type; | ||||||
|  | 	via = oz.via; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | inline object::object(msgpack_object o) | ||||||
|  | { | ||||||
|  | 	// FIXME beter way?
 | ||||||
|  | 	::memcpy(this, &o, sizeof(o)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, msgpack_object v) | ||||||
|  | { | ||||||
|  | 	// FIXME beter way?
 | ||||||
|  | 	::memcpy(&o, &v, sizeof(v)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline object::operator msgpack_object() const | ||||||
|  | { | ||||||
|  | 	// FIXME beter way?
 | ||||||
|  | 	msgpack_object obj; | ||||||
|  | 	::memcpy(&obj, this, sizeof(obj)); | ||||||
|  | 	return obj; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| // obsolete
 | // obsolete
 | ||||||
| template <typename T> | template <typename T> | ||||||
| inline void convert(T& v, object o) | inline void convert(T& v, object o) | ||||||
| @@ -260,35 +363,15 @@ packer<Stream>& operator<< (packer<Stream>& o, const object& v) | |||||||
| 		return o; | 		return o; | ||||||
| 
 | 
 | ||||||
| 	case type::POSITIVE_INTEGER: | 	case type::POSITIVE_INTEGER: | ||||||
| 		if(v.via.u64 <= (uint64_t)std::numeric_limits<uint16_t>::max()) { | 		o.pack_uint64(v.via.u64); | ||||||
| 			if(v.via.u64 <= (uint16_t)std::numeric_limits<uint8_t>::max()) { |  | ||||||
| 				o.pack_uint8(v.via.u64); |  | ||||||
| 			} else { |  | ||||||
| 				o.pack_uint16(v.via.u64); |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			if(v.via.u64 <= (uint64_t)std::numeric_limits<uint32_t>::max()) { |  | ||||||
| 				o.pack_uint32(v.via.u64); |  | ||||||
| 			} else { |  | ||||||
| 				o.pack_uint64(v.via.u64); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return o; | 		return o; | ||||||
| 
 | 
 | ||||||
| 	case type::NEGATIVE_INTEGER: | 	case type::NEGATIVE_INTEGER: | ||||||
| 		if(v.via.i64 >= (int64_t)std::numeric_limits<int16_t>::min()) { | 		o.pack_int64(v.via.i64); | ||||||
| 			if(v.via.i64 >= (int64_t)std::numeric_limits<int8_t>::min()) { | 		return o; | ||||||
| 				o.pack_int8(v.via.i64); | 
 | ||||||
| 			} else { | 	case type::DOUBLE: | ||||||
| 				o.pack_int16(v.via.i64); | 		o.pack_double(v.via.dec); | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			if(v.via.i64 >= (int64_t)std::numeric_limits<int32_t>::min()) { |  | ||||||
| 				o.pack_int64(v.via.i64); |  | ||||||
| 			} else { |  | ||||||
| 				o.pack_int64(v.via.i64); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return o; | 		return o; | ||||||
| 
 | 
 | ||||||
| 	case type::RAW: | 	case type::RAW: | ||||||
| @@ -18,8 +18,8 @@ | |||||||
| #ifndef MSGPACK_PACK_H__ | #ifndef MSGPACK_PACK_H__ | ||||||
| #define MSGPACK_PACK_H__ | #define MSGPACK_PACK_H__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/pack_define.h" | #include "pack_define.h" | ||||||
| #include "msgpack/object.h" | #include "object.h" | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| @@ -27,6 +27,19 @@ extern "C" { | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * @defgroup msgpack_buffer Buffers | ||||||
|  |  * @ingroup msgpack | ||||||
|  |  * @{ | ||||||
|  |  * @} | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @defgroup msgpack_pack Serializer | ||||||
|  |  * @ingroup msgpack | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| typedef int (*msgpack_packer_write)(void* data, const char* buf, unsigned int len); | typedef int (*msgpack_packer_write)(void* data, const char* buf, unsigned int len); | ||||||
| 
 | 
 | ||||||
| typedef struct msgpack_packer { | typedef struct msgpack_packer { | ||||||
| @@ -57,6 +70,15 @@ static int msgpack_pack_int16(msgpack_packer* pk, int16_t d); | |||||||
| static int msgpack_pack_int32(msgpack_packer* pk, int32_t d); | static int msgpack_pack_int32(msgpack_packer* pk, int32_t d); | ||||||
| static int msgpack_pack_int64(msgpack_packer* pk, int64_t d); | static int msgpack_pack_int64(msgpack_packer* pk, int64_t d); | ||||||
| 
 | 
 | ||||||
|  | static int msgpack_pack_fix_uint8(msgpack_packer* pk, uint8_t d); | ||||||
|  | static int msgpack_pack_fix_uint16(msgpack_packer* pk, uint16_t d); | ||||||
|  | static int msgpack_pack_fix_uint32(msgpack_packer* pk, uint32_t d); | ||||||
|  | static int msgpack_pack_fix_uint64(msgpack_packer* pk, uint64_t d); | ||||||
|  | static int msgpack_pack_fix_int8(msgpack_packer* pk, int8_t d); | ||||||
|  | static int msgpack_pack_fix_int16(msgpack_packer* pk, int16_t d); | ||||||
|  | static int msgpack_pack_fix_int32(msgpack_packer* pk, int32_t d); | ||||||
|  | static int msgpack_pack_fix_int64(msgpack_packer* pk, int64_t d); | ||||||
|  | 
 | ||||||
| static int msgpack_pack_float(msgpack_packer* pk, float d); | static int msgpack_pack_float(msgpack_packer* pk, float d); | ||||||
| static int msgpack_pack_double(msgpack_packer* pk, double d); | static int msgpack_pack_double(msgpack_packer* pk, double d); | ||||||
| 
 | 
 | ||||||
| @@ -74,6 +96,8 @@ static int msgpack_pack_raw_body(msgpack_packer* pk, const void* b, size_t l); | |||||||
| int msgpack_pack_object(msgpack_packer* pk, msgpack_object d); | int msgpack_pack_object(msgpack_packer* pk, msgpack_object d); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /** @} */ | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| #define msgpack_pack_inline_func(name) \ | #define msgpack_pack_inline_func(name) \ | ||||||
| 	inline int msgpack_pack ## name | 	inline int msgpack_pack ## name | ||||||
| @@ -81,12 +105,18 @@ int msgpack_pack_object(msgpack_packer* pk, msgpack_object d); | |||||||
| #define msgpack_pack_inline_func_cint(name) \ | #define msgpack_pack_inline_func_cint(name) \ | ||||||
| 	inline int msgpack_pack ## name | 	inline int msgpack_pack ## name | ||||||
| 
 | 
 | ||||||
|  | #define msgpack_pack_inline_func_cint(name) \ | ||||||
|  | 	inline int msgpack_pack ## name | ||||||
|  | 
 | ||||||
|  | #define msgpack_pack_inline_func_fixint(name) \ | ||||||
|  | 	inline int msgpack_pack_fix ## name | ||||||
|  | 
 | ||||||
| #define msgpack_pack_user msgpack_packer* | #define msgpack_pack_user msgpack_packer* | ||||||
| 
 | 
 | ||||||
| #define msgpack_pack_append_buffer(user, buf, len) \ | #define msgpack_pack_append_buffer(user, buf, len) \ | ||||||
| 	return (*(user)->callback)((user)->data, (const char*)buf, len) | 	return (*(user)->callback)((user)->data, (const char*)buf, len) | ||||||
| 
 | 
 | ||||||
| #include "msgpack/pack_template.h" | #include "pack_template.h" | ||||||
| 
 | 
 | ||||||
| inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback) | inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback) | ||||||
| { | { | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| //
 | //
 | ||||||
| // MessagePack for C++ serializing routine
 | // MessagePack for C++ serializing routine
 | ||||||
| //
 | //
 | ||||||
| // Copyright (C) 2008-2009 FURUHASHI Sadayuki
 | // Copyright (C) 2008-2010 FURUHASHI Sadayuki
 | ||||||
| //
 | //
 | ||||||
| //    Licensed under the Apache License, Version 2.0 (the "License");
 | //    Licensed under the Apache License, Version 2.0 (the "License");
 | ||||||
| //    you may not use this file except in compliance with the License.
 | //    you may not use this file except in compliance with the License.
 | ||||||
| @@ -18,7 +18,7 @@ | |||||||
| #ifndef MSGPACK_PACK_HPP__ | #ifndef MSGPACK_PACK_HPP__ | ||||||
| #define MSGPACK_PACK_HPP__ | #define MSGPACK_PACK_HPP__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/pack_define.h" | #include "pack_define.h" | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| #include <limits.h> | #include <limits.h> | ||||||
| 
 | 
 | ||||||
| @@ -28,6 +28,7 @@ namespace msgpack { | |||||||
| template <typename Stream> | template <typename Stream> | ||||||
| class packer { | class packer { | ||||||
| public: | public: | ||||||
|  | 	packer(Stream* s); | ||||||
| 	packer(Stream& s); | 	packer(Stream& s); | ||||||
| 	~packer(); | 	~packer(); | ||||||
| 
 | 
 | ||||||
| @@ -39,12 +40,21 @@ public: | |||||||
| 	packer<Stream>& pack_uint16(uint16_t d); | 	packer<Stream>& pack_uint16(uint16_t d); | ||||||
| 	packer<Stream>& pack_uint32(uint32_t d); | 	packer<Stream>& pack_uint32(uint32_t d); | ||||||
| 	packer<Stream>& pack_uint64(uint64_t d); | 	packer<Stream>& pack_uint64(uint64_t d); | ||||||
| 	packer<Stream>& pack_int8(uint8_t d); | 	packer<Stream>& pack_int8(int8_t d); | ||||||
| 	packer<Stream>& pack_int16(uint16_t d); | 	packer<Stream>& pack_int16(int16_t d); | ||||||
| 	packer<Stream>& pack_int32(uint32_t d); | 	packer<Stream>& pack_int32(int32_t d); | ||||||
| 	packer<Stream>& pack_int64(uint64_t d); | 	packer<Stream>& pack_int64(int64_t d); | ||||||
| 
 | 
 | ||||||
| 	packer<Stream>& pack_short(int d); | 	packer<Stream>& pack_fix_uint8(uint8_t d); | ||||||
|  | 	packer<Stream>& pack_fix_uint16(uint16_t d); | ||||||
|  | 	packer<Stream>& pack_fix_uint32(uint32_t d); | ||||||
|  | 	packer<Stream>& pack_fix_uint64(uint64_t d); | ||||||
|  | 	packer<Stream>& pack_fix_int8(int8_t d); | ||||||
|  | 	packer<Stream>& pack_fix_int16(int16_t d); | ||||||
|  | 	packer<Stream>& pack_fix_int32(int32_t d); | ||||||
|  | 	packer<Stream>& pack_fix_int64(int64_t d); | ||||||
|  | 
 | ||||||
|  | 	packer<Stream>& pack_short(short d); | ||||||
| 	packer<Stream>& pack_int(int d); | 	packer<Stream>& pack_int(int d); | ||||||
| 	packer<Stream>& pack_long(long d); | 	packer<Stream>& pack_long(long d); | ||||||
| 	packer<Stream>& pack_long_long(long long d); | 	packer<Stream>& pack_long_long(long long d); | ||||||
| @@ -77,6 +87,15 @@ private: | |||||||
| 	static void _pack_int32(Stream& x, int32_t d); | 	static void _pack_int32(Stream& x, int32_t d); | ||||||
| 	static void _pack_int64(Stream& x, int64_t d); | 	static void _pack_int64(Stream& x, int64_t d); | ||||||
| 
 | 
 | ||||||
|  | 	static void _pack_fix_uint8(Stream& x, uint8_t d); | ||||||
|  | 	static void _pack_fix_uint16(Stream& x, uint16_t d); | ||||||
|  | 	static void _pack_fix_uint32(Stream& x, uint32_t d); | ||||||
|  | 	static void _pack_fix_uint64(Stream& x, uint64_t d); | ||||||
|  | 	static void _pack_fix_int8(Stream& x, int8_t d); | ||||||
|  | 	static void _pack_fix_int16(Stream& x, int16_t d); | ||||||
|  | 	static void _pack_fix_int32(Stream& x, int32_t d); | ||||||
|  | 	static void _pack_fix_int64(Stream& x, int64_t d); | ||||||
|  | 
 | ||||||
| 	static void _pack_short(Stream& x, short d); | 	static void _pack_short(Stream& x, short d); | ||||||
| 	static void _pack_int(Stream& x, int d); | 	static void _pack_int(Stream& x, int d); | ||||||
| 	static void _pack_long(Stream& x, long d); | 	static void _pack_long(Stream& x, long d); | ||||||
| @@ -111,6 +130,12 @@ private: | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | template <typename Stream, typename T> | ||||||
|  | inline void pack(Stream* s, const T& v) | ||||||
|  | { | ||||||
|  | 	packer<Stream>(s).pack(v); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| template <typename Stream, typename T> | template <typename Stream, typename T> | ||||||
| inline void pack(Stream& s, const T& v) | inline void pack(Stream& s, const T& v) | ||||||
| { | { | ||||||
| @@ -126,19 +151,27 @@ inline void pack(Stream& s, const T& v) | |||||||
| 	template <typename Stream> \ | 	template <typename Stream> \ | ||||||
| 	inline void packer<Stream>::_pack ## name | 	inline void packer<Stream>::_pack ## name | ||||||
| 
 | 
 | ||||||
|  | #define msgpack_pack_inline_func_fixint(name) \ | ||||||
|  | 	template <typename Stream> \ | ||||||
|  | 	inline void packer<Stream>::_pack_fix ## name | ||||||
|  | 
 | ||||||
| #define msgpack_pack_user Stream& | #define msgpack_pack_user Stream& | ||||||
| 
 | 
 | ||||||
| #define msgpack_pack_append_buffer append_buffer | #define msgpack_pack_append_buffer append_buffer | ||||||
| 
 | 
 | ||||||
| #include "msgpack/pack_template.h" | #include "pack_template.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | packer<Stream>::packer(Stream* s) : m_stream(*s) { } | ||||||
|  | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| packer<Stream>::packer(Stream& s) : m_stream(s) { } | packer<Stream>::packer(Stream& s) : m_stream(s) { } | ||||||
| 
 | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| packer<Stream>::~packer() { } | packer<Stream>::~packer() { } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| inline packer<Stream>& packer<Stream>::pack_uint8(uint8_t d) | inline packer<Stream>& packer<Stream>::pack_uint8(uint8_t d) | ||||||
| { _pack_uint8(m_stream, d); return *this; } | { _pack_uint8(m_stream, d); return *this; } | ||||||
| @@ -156,24 +189,57 @@ inline packer<Stream>& packer<Stream>::pack_uint64(uint64_t d) | |||||||
| { _pack_uint64(m_stream, d); return *this; } | { _pack_uint64(m_stream, d); return *this; } | ||||||
| 
 | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| inline packer<Stream>& packer<Stream>::pack_int8(uint8_t d) | inline packer<Stream>& packer<Stream>::pack_int8(int8_t d) | ||||||
| { _pack_int8(m_stream, d); return *this; } | { _pack_int8(m_stream, d); return *this; } | ||||||
| 
 | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| inline packer<Stream>& packer<Stream>::pack_int16(uint16_t d) | inline packer<Stream>& packer<Stream>::pack_int16(int16_t d) | ||||||
| { _pack_int16(m_stream, d); return *this; } | { _pack_int16(m_stream, d); return *this; } | ||||||
| 
 | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| inline packer<Stream>& packer<Stream>::pack_int32(uint32_t d) | inline packer<Stream>& packer<Stream>::pack_int32(int32_t d) | ||||||
| { _pack_int32(m_stream, d); return *this; } | { _pack_int32(m_stream, d); return *this; } | ||||||
| 
 | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| inline packer<Stream>& packer<Stream>::pack_int64(uint64_t d) | inline packer<Stream>& packer<Stream>::pack_int64(int64_t d) | ||||||
| { _pack_int64(m_stream, d); return *this;} | { _pack_int64(m_stream, d); return *this;} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| inline packer<Stream>& packer<Stream>::pack_short(int d) | inline packer<Stream>& packer<Stream>::pack_fix_uint8(uint8_t d) | ||||||
|  | { _pack_fix_uint8(m_stream, d); return *this; } | ||||||
|  | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& packer<Stream>::pack_fix_uint16(uint16_t d) | ||||||
|  | { _pack_fix_uint16(m_stream, d); return *this; } | ||||||
|  | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& packer<Stream>::pack_fix_uint32(uint32_t d) | ||||||
|  | { _pack_fix_uint32(m_stream, d); return *this; } | ||||||
|  | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& packer<Stream>::pack_fix_uint64(uint64_t d) | ||||||
|  | { _pack_fix_uint64(m_stream, d); return *this; } | ||||||
|  | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& packer<Stream>::pack_fix_int8(int8_t d) | ||||||
|  | { _pack_fix_int8(m_stream, d); return *this; } | ||||||
|  | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& packer<Stream>::pack_fix_int16(int16_t d) | ||||||
|  | { _pack_fix_int16(m_stream, d); return *this; } | ||||||
|  | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& packer<Stream>::pack_fix_int32(int32_t d) | ||||||
|  | { _pack_fix_int32(m_stream, d); return *this; } | ||||||
|  | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& packer<Stream>::pack_fix_int64(int64_t d) | ||||||
|  | { _pack_fix_int64(m_stream, d); return *this;} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& packer<Stream>::pack_short(short d) | ||||||
| { _pack_short(m_stream, d); return *this; } | { _pack_short(m_stream, d); return *this; } | ||||||
| 
 | 
 | ||||||
| template <typename Stream> | template <typename Stream> | ||||||
| @@ -21,14 +21,17 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| 
 | 
 | ||||||
| #ifndef MSGPACK_SBUFFER_INIT_SIZE |  | ||||||
| #define MSGPACK_SBUFFER_INIT_SIZE 2048 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @defgroup msgpack_sbuffer Simple buffer | ||||||
|  |  * @ingroup msgpack_buffer | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| typedef struct msgpack_sbuffer { | typedef struct msgpack_sbuffer { | ||||||
| 	size_t size; | 	size_t size; | ||||||
| 	char* data; | 	char* data; | ||||||
| @@ -45,6 +48,22 @@ static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf) | |||||||
| 	free(sbuf->data); | 	free(sbuf->data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static inline msgpack_sbuffer* msgpack_sbuffer_new(void) | ||||||
|  | { | ||||||
|  | 	return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf) | ||||||
|  | { | ||||||
|  | 	if(sbuf == NULL) { return; } | ||||||
|  | 	msgpack_sbuffer_destroy(sbuf); | ||||||
|  | 	free(sbuf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifndef MSGPACK_SBUFFER_INIT_SIZE | ||||||
|  | #define MSGPACK_SBUFFER_INIT_SIZE 8192 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| static inline int msgpack_sbuffer_write(void* data, const char* buf, unsigned int len) | static inline int msgpack_sbuffer_write(void* data, const char* buf, unsigned int len) | ||||||
| { | { | ||||||
| 	msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data; | 	msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data; | ||||||
| @@ -76,6 +95,13 @@ static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf) | |||||||
| 	return tmp; | 	return tmp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf) | ||||||
|  | { | ||||||
|  | 	sbuf->size = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** @} */ | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| @@ -18,7 +18,7 @@ | |||||||
| #ifndef MSGPACK_SBUFFER_HPP__ | #ifndef MSGPACK_SBUFFER_HPP__ | ||||||
| #define MSGPACK_SBUFFER_HPP__ | #define MSGPACK_SBUFFER_HPP__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/sbuffer.h" | #include "sbuffer.h" | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| 
 | 
 | ||||||
| namespace msgpack { | namespace msgpack { | ||||||
| @@ -72,6 +72,11 @@ public: | |||||||
| 		return msgpack_sbuffer_release(this); | 		return msgpack_sbuffer_release(this); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void clear() | ||||||
|  | 	{ | ||||||
|  | 		msgpack_sbuffer_clear(this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
| 	void expand_buffer(size_t len) | 	void expand_buffer(size_t len) | ||||||
| 	{ | 	{ | ||||||
							
								
								
									
										16
									
								
								cpp/src/msgpack/type.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								cpp/src/msgpack/type.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | #include "type/bool.hpp" | ||||||
|  | #include "type/deque.hpp" | ||||||
|  | #include "type/fixint.hpp" | ||||||
|  | #include "type/float.hpp" | ||||||
|  | #include "type/int.hpp" | ||||||
|  | #include "type/list.hpp" | ||||||
|  | #include "type/map.hpp" | ||||||
|  | #include "type/nil.hpp" | ||||||
|  | #include "type/pair.hpp" | ||||||
|  | #include "type/raw.hpp" | ||||||
|  | #include "type/set.hpp" | ||||||
|  | #include "type/string.hpp" | ||||||
|  | #include "type/vector.hpp" | ||||||
|  | #include "type/tuple.hpp" | ||||||
|  | #include "type/define.hpp" | ||||||
|  |  | ||||||
| @@ -39,6 +39,15 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const bool& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | inline void operator<< (object& o, bool v) | ||||||
|  | { | ||||||
|  | 	o.type = type::BOOLEAN; | ||||||
|  | 	o.via.boolean = v; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, bool v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -27,6 +27,11 @@ | |||||||
| 	void msgpack_unpack(msgpack::object o) \ | 	void msgpack_unpack(msgpack::object o) \ | ||||||
| 	{ \ | 	{ \ | ||||||
| 		msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \ | 		msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \ | ||||||
|  | 	}\ | ||||||
|  | 	template <typename MSGPACK_OBJECT> \ | ||||||
|  | 	void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \ | ||||||
|  | 	{ \ | ||||||
|  | 		msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| namespace msgpack { | namespace msgpack { | ||||||
| @@ -51,6 +56,12 @@ struct define<> { | |||||||
| 	{ | 	{ | ||||||
| 		if(o.type != type::ARRAY) { throw type_error(); } | 		if(o.type != type::ARRAY) { throw type_error(); } | ||||||
| 	} | 	} | ||||||
|  | 	void msgpack_object(msgpack::object* o, msgpack::zone* z) const | ||||||
|  | 	{ | ||||||
|  | 		o->type = type::ARRAY; | ||||||
|  | 		o->via.array.ptr = NULL; | ||||||
|  | 		o->via.array.size = 0; | ||||||
|  | 	} | ||||||
| }; | }; | ||||||
| <%0.upto(GENERATION_LIMIT) {|i|%> | <%0.upto(GENERATION_LIMIT) {|i|%> | ||||||
| template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> | template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> | ||||||
| @@ -73,6 +84,14 @@ struct define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> { | |||||||
| 		<%0.upto(i) {|j|%> | 		<%0.upto(i) {|j|%> | ||||||
| 		if(size <= <%=j%>) { return; } o.via.array.ptr[<%=j%>].convert(&a<%=j%>);<%}%> | 		if(size <= <%=j%>) { return; } o.via.array.ptr[<%=j%>].convert(&a<%=j%>);<%}%> | ||||||
| 	} | 	} | ||||||
|  | 	void msgpack_object(msgpack::object* o, msgpack::zone* z) const | ||||||
|  | 	{ | ||||||
|  | 		o->type = type::ARRAY; | ||||||
|  | 		o->via.array.ptr = (object*)z->malloc(sizeof(object)*<%=i+1%>); | ||||||
|  | 		o->via.array.size = <%=i+1%>; | ||||||
|  | 		<%0.upto(i) {|j|%> | ||||||
|  | 		o->via.array.ptr[<%=j%>] = object(a<%=j%>, z);<%}%> | ||||||
|  | 	} | ||||||
| 	<%0.upto(i) {|j|%> | 	<%0.upto(i) {|j|%> | ||||||
| 	A<%=j%>& a<%=j%>;<%}%> | 	A<%=j%>& a<%=j%>;<%}%> | ||||||
| }; | }; | ||||||
| @@ -49,6 +49,27 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::deque<T>& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::deque<T>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.array.ptr = NULL; | ||||||
|  | 		o.via.array.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); | ||||||
|  | 		object* const pend = p + v.size(); | ||||||
|  | 		o.via.array.ptr = p; | ||||||
|  | 		o.via.array.size = v.size(); | ||||||
|  | 		typename std::deque<T>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			*p = object(*it, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
							
								
								
									
										172
									
								
								cpp/src/msgpack/type/fixint.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								cpp/src/msgpack/type/fixint.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | |||||||
|  | // | ||||||
|  | // MessagePack for C++ static resolution routine | ||||||
|  | // | ||||||
|  | // Copyright (C) 2020 FURUHASHI Sadayuki | ||||||
|  | // | ||||||
|  | //    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | //    you may not use this file except in compliance with the License. | ||||||
|  | //    You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | //        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | //    Unless required by applicable law or agreed to in writing, software | ||||||
|  | //    distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | //    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | //    See the License for the specific language governing permissions and | ||||||
|  | //    limitations under the License. | ||||||
|  | // | ||||||
|  | #ifndef MSGPACK_TYPE_FIXINT_HPP__ | ||||||
|  | #define MSGPACK_TYPE_FIXINT_HPP__ | ||||||
|  |  | ||||||
|  | #include "msgpack/object.hpp" | ||||||
|  | #include "msgpack/type/int.hpp" | ||||||
|  |  | ||||||
|  | namespace msgpack { | ||||||
|  |  | ||||||
|  | namespace type { | ||||||
|  |  | ||||||
|  |  | ||||||
|  | template <typename T> | ||||||
|  | struct fix_int { | ||||||
|  | 	fix_int() : value(0) { } | ||||||
|  | 	fix_int(T value) : value(value) { } | ||||||
|  |  | ||||||
|  | 	operator T() const { return value; } | ||||||
|  |  | ||||||
|  | 	T get() const { return value; } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	T value; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | typedef fix_int<uint8_t>  fix_uint8; | ||||||
|  | typedef fix_int<uint16_t> fix_uint16; | ||||||
|  | typedef fix_int<uint32_t> fix_uint32; | ||||||
|  | typedef fix_int<uint64_t> fix_uint64; | ||||||
|  |  | ||||||
|  | typedef fix_int<int8_t>  fix_int8; | ||||||
|  | typedef fix_int<int16_t> fix_int16; | ||||||
|  | typedef fix_int<int32_t> fix_int32; | ||||||
|  | typedef fix_int<int64_t> fix_int64; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | }  // namespace type | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline type::fix_int8& operator>> (object o, type::fix_int8& v) | ||||||
|  | 	{ v = type::detail::convert_integer<int8_t>(o); return v; } | ||||||
|  |  | ||||||
|  | inline type::fix_int16& operator>> (object o, type::fix_int16& v) | ||||||
|  | 	{ v = type::detail::convert_integer<int16_t>(o); return v; } | ||||||
|  |  | ||||||
|  | inline type::fix_int32& operator>> (object o, type::fix_int32& v) | ||||||
|  | 	{ v = type::detail::convert_integer<int32_t>(o); return v; } | ||||||
|  |  | ||||||
|  | inline type::fix_int64& operator>> (object o, type::fix_int64& v) | ||||||
|  | 	{ v = type::detail::convert_integer<int64_t>(o); return v; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline type::fix_uint8& operator>> (object o, type::fix_uint8& v) | ||||||
|  | 	{ v = type::detail::convert_integer<uint8_t>(o); return v; } | ||||||
|  |  | ||||||
|  | inline type::fix_uint16& operator>> (object o, type::fix_uint16& v) | ||||||
|  | 	{ v = type::detail::convert_integer<uint16_t>(o); return v; } | ||||||
|  |  | ||||||
|  | inline type::fix_uint32& operator>> (object o, type::fix_uint32& v) | ||||||
|  | 	{ v = type::detail::convert_integer<uint32_t>(o); return v; } | ||||||
|  |  | ||||||
|  | inline type::fix_uint64& operator>> (object o, type::fix_uint64& v) | ||||||
|  | 	{ v = type::detail::convert_integer<uint64_t>(o); return v; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int8& v) | ||||||
|  | 	{ o.pack_fix_int8(v); return o; } | ||||||
|  |  | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int16& v) | ||||||
|  | 	{ o.pack_fix_int16(v); return o; } | ||||||
|  |  | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int32& v) | ||||||
|  | 	{ o.pack_fix_int32(v); return o; } | ||||||
|  |  | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int64& v) | ||||||
|  | 	{ o.pack_fix_int64(v); return o; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint8& v) | ||||||
|  | 	{ o.pack_fix_uint8(v); return o; } | ||||||
|  |  | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint16& v) | ||||||
|  | 	{ o.pack_fix_uint16(v); return o; } | ||||||
|  |  | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint32& v) | ||||||
|  | 	{ o.pack_fix_uint32(v); return o; } | ||||||
|  |  | ||||||
|  | template <typename Stream> | ||||||
|  | inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint64& v) | ||||||
|  | 	{ o.pack_fix_uint64(v); return o; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline void operator<< (object& o, type::fix_int8 v) | ||||||
|  | 	{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } | ||||||
|  |  | ||||||
|  | inline void operator<< (object& o, type::fix_int16 v) | ||||||
|  | 	{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } | ||||||
|  |  | ||||||
|  | inline void operator<< (object& o, type::fix_int32 v) | ||||||
|  | 	{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } | ||||||
|  |  | ||||||
|  | inline void operator<< (object& o, type::fix_int64 v) | ||||||
|  | 	{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline void operator<< (object& o, type::fix_uint8 v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } | ||||||
|  |  | ||||||
|  | inline void operator<< (object& o, type::fix_uint16 v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } | ||||||
|  |  | ||||||
|  | inline void operator<< (object& o, type::fix_uint32 v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } | ||||||
|  |  | ||||||
|  | inline void operator<< (object& o, type::fix_uint64 v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline void operator<< (object::with_zone& o, type::fix_int8 v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  |  | ||||||
|  | inline void operator<< (object::with_zone& o, type::fix_int16 v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  |  | ||||||
|  | inline void operator<< (object::with_zone& o, type::fix_int32 v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  |  | ||||||
|  | inline void operator<< (object::with_zone& o, type::fix_int64 v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline void operator<< (object::with_zone& o, type::fix_uint8 v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  |  | ||||||
|  | inline void operator<< (object::with_zone& o, type::fix_uint16 v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  |  | ||||||
|  | inline void operator<< (object::with_zone& o, type::fix_uint32 v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  |  | ||||||
|  | inline void operator<< (object::with_zone& o, type::fix_uint64 v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | }  // namespace msgpack | ||||||
|  |  | ||||||
|  | #endif /* msgpack/type/fixint.hpp */ | ||||||
|  |  | ||||||
| @@ -57,6 +57,25 @@ 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; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, double v) | ||||||
|  | { | ||||||
|  | 	o.type = type::DOUBLE; | ||||||
|  | 	o.via.dec = v; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, float v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, double v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| #endif /* msgpack/type/float.hpp */ | #endif /* msgpack/type/float.hpp */ | ||||||
| @@ -141,6 +141,70 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long long& | |||||||
| 	{ o.pack_unsigned_long_long(v); return o; } | 	{ o.pack_unsigned_long_long(v); return o; } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | inline void operator<< (object& o, signed char v) | ||||||
|  | 	{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, signed short v) | ||||||
|  | 	{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, signed int v) | ||||||
|  | 	{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, signed long v) | ||||||
|  | 	{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, signed long long v) | ||||||
|  | 	{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, unsigned char v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, unsigned short v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, unsigned int v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, unsigned long v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object& o, unsigned long long v) | ||||||
|  | 	{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, signed char v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, signed short v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, signed int v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, signed long v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, signed long long v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, unsigned char v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, unsigned short v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, unsigned int v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, unsigned long v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, unsigned long long v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| #endif /* msgpack/type/int.hpp */ | #endif /* msgpack/type/int.hpp */ | ||||||
| @@ -49,6 +49,27 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::list<T>& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::list<T>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.array.ptr = NULL; | ||||||
|  | 		o.via.array.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); | ||||||
|  | 		object* const pend = p + v.size(); | ||||||
|  | 		o.via.array.ptr = p; | ||||||
|  | 		o.via.array.size = v.size(); | ||||||
|  | 		typename std::list<T>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			*p = object(*it, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -70,6 +70,28 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const type::assoc_vector<K | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename K, typename V> | ||||||
|  | inline void operator<< (object::with_zone& o, const type::assoc_vector<K,V>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::MAP; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.map.ptr  = NULL; | ||||||
|  | 		o.via.map.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); | ||||||
|  | 		object_kv* const pend = p + v.size(); | ||||||
|  | 		o.via.map.ptr  = p; | ||||||
|  | 		o.via.map.size = v.size(); | ||||||
|  | 		typename type::assoc_vector<K,V>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			p->key = object(it->first, o.zone); | ||||||
|  | 			p->val = object(it->second, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| template <typename K, typename V> | template <typename K, typename V> | ||||||
| inline std::map<K, V> operator>> (object o, std::map<K, V>& v) | inline std::map<K, V> operator>> (object o, std::map<K, V>& v) | ||||||
| @@ -104,6 +126,28 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::map<K,V>& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename K, typename V> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::map<K,V>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::MAP; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.map.ptr  = NULL; | ||||||
|  | 		o.via.map.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); | ||||||
|  | 		object_kv* const pend = p + v.size(); | ||||||
|  | 		o.via.map.ptr  = p; | ||||||
|  | 		o.via.map.size = v.size(); | ||||||
|  | 		typename std::map<K,V>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			p->key = object(it->first, o.zone); | ||||||
|  | 			p->val = object(it->second, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| template <typename K, typename V> | template <typename K, typename V> | ||||||
| inline std::multimap<K, V> operator>> (object o, std::multimap<K, V>& v) | inline std::multimap<K, V> operator>> (object o, std::multimap<K, V>& v) | ||||||
| @@ -132,6 +176,28 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::multimap<K,V>& | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename K, typename V> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::multimap<K,V>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::MAP; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.map.ptr  = NULL; | ||||||
|  | 		o.via.map.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); | ||||||
|  | 		object_kv* const pend = p + v.size(); | ||||||
|  | 		o.via.map.ptr  = p; | ||||||
|  | 		o.via.map.size = v.size(); | ||||||
|  | 		typename std::multimap<K,V>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			p->key = object(it->first, o.zone); | ||||||
|  | 			p->val = object(it->second, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -42,6 +42,22 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const type::nil& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | inline void operator<< (object& o, type::nil v) | ||||||
|  | { | ||||||
|  | 	o.type = type::NIL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, type::nil v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template <> | ||||||
|  | inline void object::as<void>() const | ||||||
|  | { | ||||||
|  | 	msgpack::type::nil v; | ||||||
|  | 	convert(&v); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -43,6 +43,17 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::pair<T1, T2>& v | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T1, typename T2> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::pair<T1, T2>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	object* p = (object*)o.zone->malloc(sizeof(object)*2); | ||||||
|  | 	o.via.array.ptr = p; | ||||||
|  | 	o.via.array.size = 2; | ||||||
|  | 	p[0] = object(v.first, o.zone); | ||||||
|  | 	p[1] = object(v.second, o.zone); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -33,25 +33,25 @@ struct raw_ref { | |||||||
| 	uint32_t size; | 	uint32_t size; | ||||||
| 	const char* ptr; | 	const char* ptr; | ||||||
| 
 | 
 | ||||||
| 	std::string str() { return std::string(ptr, size); } | 	std::string str() const { return std::string(ptr, size); } | ||||||
| 
 | 
 | ||||||
| 	bool operator== (const raw_ref& x) | 	bool operator== (const raw_ref& x) const | ||||||
| 	{ | 	{ | ||||||
| 		return size == x.size && memcmp(ptr, x.ptr, size) == 0; | 		return size == x.size && memcmp(ptr, x.ptr, size) == 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool operator!= (const raw_ref& x) | 	bool operator!= (const raw_ref& x) const | ||||||
| 	{ | 	{ | ||||||
| 		return !(*this != x); | 		return !(*this != x); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool operator< (const raw_ref& x) | 	bool operator< (const raw_ref& x) const | ||||||
| 	{ | 	{ | ||||||
| 		if(size == x.size) { return memcmp(ptr, x.ptr, size) < 0; } | 		if(size == x.size) { return memcmp(ptr, x.ptr, size) < 0; } | ||||||
| 		else { return size < x.size; } | 		else { return size < x.size; } | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool operator> (const raw_ref& x) | 	bool operator> (const raw_ref& x) const | ||||||
| 	{ | 	{ | ||||||
| 		if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; } | 		if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; } | ||||||
| 		else { return size > x.size; } | 		else { return size > x.size; } | ||||||
| @@ -77,6 +77,16 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const type::raw_ref& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | inline void operator<< (object& o, const type::raw_ref& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::RAW; | ||||||
|  | 	o.via.raw.ptr = v.ptr; | ||||||
|  | 	o.via.raw.size = v.size; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline void operator<< (object::with_zone& o, const type::raw_ref& v) | ||||||
|  | 	{ static_cast<object&>(o) << v; } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -48,6 +48,27 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::set<T>& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::set<T>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.array.ptr = NULL; | ||||||
|  | 		o.via.array.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); | ||||||
|  | 		object* const pend = p + v.size(); | ||||||
|  | 		o.via.array.ptr = p; | ||||||
|  | 		o.via.array.size = v.size(); | ||||||
|  | 		typename std::set<T>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			*p = object(*it, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| inline std::multiset<T>& operator>> (object o, std::multiset<T>& v) | inline std::multiset<T>& operator>> (object o, std::multiset<T>& v) | ||||||
| @@ -73,6 +94,27 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::multiset<T>& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::multiset<T>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.array.ptr = NULL; | ||||||
|  | 		o.via.array.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); | ||||||
|  | 		object* const pend = p + v.size(); | ||||||
|  | 		o.via.array.ptr = p; | ||||||
|  | 		o.via.array.size = v.size(); | ||||||
|  | 		typename std::multiset<T>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			*p = object(*it, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -39,6 +39,22 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::string& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 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(); | ||||||
|  | 	memcpy(ptr, v.data(), v.size()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -50,6 +50,28 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_ | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename K, typename V> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::tr1::unordered_map<K,V>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::MAP; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.map.ptr  = NULL; | ||||||
|  | 		o.via.map.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); | ||||||
|  | 		object_kv* const pend = p + v.size(); | ||||||
|  | 		o.via.map.ptr  = p; | ||||||
|  | 		o.via.map.size = v.size(); | ||||||
|  | 		typename std::tr1::unordered_map<K,V>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			p->key = object(it->first, o.zone); | ||||||
|  | 			p->val = object(it->second, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| template <typename K, typename V> | template <typename K, typename V> | ||||||
| inline std::tr1::unordered_multimap<K, V> operator>> (object o, std::tr1::unordered_multimap<K, V>& v) | inline std::tr1::unordered_multimap<K, V> operator>> (object o, std::tr1::unordered_multimap<K, V>& v) | ||||||
| @@ -78,6 +100,28 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_ | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename K, typename V> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::tr1::unordered_multimap<K,V>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::MAP; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.map.ptr  = NULL; | ||||||
|  | 		o.via.map.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); | ||||||
|  | 		object_kv* const pend = p + v.size(); | ||||||
|  | 		o.via.map.ptr  = p; | ||||||
|  | 		o.via.map.size = v.size(); | ||||||
|  | 		typename std::tr1::unordered_multimap<K,V>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			p->key = object(it->first, o.zone); | ||||||
|  | 			p->val = object(it->second, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -48,6 +48,27 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_ | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::tr1::unordered_set<T>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.array.ptr = NULL; | ||||||
|  | 		o.via.array.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); | ||||||
|  | 		object* const pend = p + v.size(); | ||||||
|  | 		o.via.array.ptr = p; | ||||||
|  | 		o.via.array.size = v.size(); | ||||||
|  | 		typename std::tr1::unordered_set<T>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			*p = object(*it, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| inline std::tr1::unordered_multiset<T>& operator>> (object o, std::tr1::unordered_multiset<T>& v) | inline std::tr1::unordered_multiset<T>& operator>> (object o, std::tr1::unordered_multiset<T>& v) | ||||||
| @@ -73,6 +94,27 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_ | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::tr1::unordered_multiset<T>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.array.ptr = NULL; | ||||||
|  | 		o.via.array.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); | ||||||
|  | 		object* const pend = p + v.size(); | ||||||
|  | 		o.via.array.ptr = p; | ||||||
|  | 		o.via.array.size = v.size(); | ||||||
|  | 		typename std::tr1::unordered_multiset<T>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			*p = object(*it, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -141,7 +141,7 @@ type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& operator>> ( | |||||||
| 	if(o.type != type::ARRAY) { throw type_error(); } | 	if(o.type != type::ARRAY) { throw type_error(); } | ||||||
| 	if(o.via.array.size < <%=i+1%>) { throw type_error(); } | 	if(o.via.array.size < <%=i+1%>) { throw type_error(); } | ||||||
| 	<%0.upto(i) {|j|%> | 	<%0.upto(i) {|j|%> | ||||||
| 	o.via.array.ptr[<%=j%>].convert<A<%=j%>>(&v.template get<<%=j%>>());<%}%> | 	o.via.array.ptr[<%=j%>].convert<typename type::tuple_type<A<%=j%>>::type>(&v.template get<<%=j%>>());<%}%> | ||||||
| 	return v; | 	return v; | ||||||
| } | } | ||||||
| <%}%> | <%}%> | ||||||
| @@ -165,7 +165,42 @@ const packer<Stream>& operator<< ( | |||||||
| } | } | ||||||
| <%}%> | <%}%> | ||||||
| 
 | 
 | ||||||
|  | inline void operator<< ( | ||||||
|  | 		object::with_zone& o, | ||||||
|  | 		const type::tuple<>& v) { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	o.via.array.ptr = NULL; | ||||||
|  | 	o.via.array.size = 0; | ||||||
|  | } | ||||||
|  | <%0.upto(GENERATION_LIMIT) {|i|%> | ||||||
|  | template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> | ||||||
|  | inline void operator<< ( | ||||||
|  | 		object::with_zone& o, | ||||||
|  | 		const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	o.via.array.ptr = (object*)o.zone->malloc(sizeof(object)*<%=i+1%>); | ||||||
|  | 	o.via.array.size = <%=i+1%>; | ||||||
|  | 	<%0.upto(i) {|j|%> | ||||||
|  | 	o.via.array.ptr[<%=j%>] = object(v.template get<<%=j%>>(), o.zone);<%}%> | ||||||
|  | } | ||||||
|  | <%}%> | ||||||
|  | 
 | ||||||
| }  // namespace msgpack | }  // namespace msgpack | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | //inline std::ostream& operator<< (std::ostream& o, const msgpack::type::tuple<>& v) { | ||||||
|  | //  return o << "[]"; | ||||||
|  | //} | ||||||
|  | //<%0.upto(GENERATION_LIMIT) {|i|%> | ||||||
|  | //template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> | ||||||
|  | //inline std::ostream& operator<< (std::ostream& o, | ||||||
|  | //		const msgpack::type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) { | ||||||
|  | //	return o << "[" | ||||||
|  | //	<%0.upto(i) {|j|%> | ||||||
|  | //	<<<%if j != 0 then%> ", " <<<%end%> v.template get<<%=j%>>()<%}%> | ||||||
|  | //	<< "]"; | ||||||
|  | //} | ||||||
|  | //<%}%> | ||||||
|  | 
 | ||||||
| #endif /* msgpack/type/tuple.hpp */ | #endif /* msgpack/type/tuple.hpp */ | ||||||
| 
 | 
 | ||||||
| @@ -29,11 +29,15 @@ inline std::vector<T>& operator>> (object o, std::vector<T>& v) | |||||||
| { | { | ||||||
| 	if(o.type != type::ARRAY) { throw type_error(); } | 	if(o.type != type::ARRAY) { throw type_error(); } | ||||||
| 	v.resize(o.via.array.size); | 	v.resize(o.via.array.size); | ||||||
| 	object* p = o.via.array.ptr; | 	if(o.via.array.size > 0) { | ||||||
| 	object* const pend = o.via.array.ptr + o.via.array.size; | 		object* p = o.via.array.ptr; | ||||||
| 	T* it = &v.front(); | 		object* const pend = o.via.array.ptr + o.via.array.size; | ||||||
| 	for(; p < pend; ++p, ++it) { | 		T* it = &v[0]; | ||||||
| 		p->convert(it); | 		do { | ||||||
|  | 			p->convert(it); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
| 	} | 	} | ||||||
| 	return v; | 	return v; | ||||||
| } | } | ||||||
| @@ -49,6 +53,27 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const std::vector<T>& v) | |||||||
| 	return o; | 	return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void operator<< (object::with_zone& o, const std::vector<T>& v) | ||||||
|  | { | ||||||
|  | 	o.type = type::ARRAY; | ||||||
|  | 	if(v.empty()) { | ||||||
|  | 		o.via.array.ptr = NULL; | ||||||
|  | 		o.via.array.size = 0; | ||||||
|  | 	} else { | ||||||
|  | 		object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); | ||||||
|  | 		object* const pend = p + v.size(); | ||||||
|  | 		o.via.array.ptr = p; | ||||||
|  | 		o.via.array.size = v.size(); | ||||||
|  | 		typename std::vector<T>::const_iterator it(v.begin()); | ||||||
|  | 		do { | ||||||
|  | 			*p = object(*it, o.zone); | ||||||
|  | 			++p; | ||||||
|  | 			++it; | ||||||
|  | 		} while(p < pend); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
							
								
								
									
										260
									
								
								cpp/src/msgpack/unpack.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								cpp/src/msgpack/unpack.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,260 @@ | |||||||
|  | /* | ||||||
|  |  * MessagePack for C unpacking routine | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2008-2009 FURUHASHI Sadayuki | ||||||
|  |  * | ||||||
|  |  *    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *    you may not use this file except in compliance with the License. | ||||||
|  |  *    You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  *    Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *    distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *    See the License for the specific language governing permissions and | ||||||
|  |  *    limitations under the License. | ||||||
|  |  */ | ||||||
|  | #ifndef MSGPACK_UNPACKER_H__ | ||||||
|  | #define MSGPACK_UNPACKER_H__ | ||||||
|  |  | ||||||
|  | #include "zone.h" | ||||||
|  | #include "object.h" | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @defgroup msgpack_unpack Deserializer | ||||||
|  |  * @ingroup msgpack | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | typedef struct msgpack_unpacked { | ||||||
|  | 	msgpack_zone* zone; | ||||||
|  | 	msgpack_object data; | ||||||
|  | } msgpack_unpacked; | ||||||
|  |  | ||||||
|  | bool msgpack_unpack_next(msgpack_unpacked* result, | ||||||
|  | 		const char* data, size_t len, size_t* off); | ||||||
|  |  | ||||||
|  | /** @} */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @defgroup msgpack_unpacker Streaming deserializer | ||||||
|  |  * @ingroup msgpack | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | typedef struct msgpack_unpacker { | ||||||
|  | 	char* buffer; | ||||||
|  | 	size_t used; | ||||||
|  | 	size_t free; | ||||||
|  | 	size_t off; | ||||||
|  | 	size_t parsed; | ||||||
|  | 	msgpack_zone* z; | ||||||
|  | 	size_t initial_buffer_size; | ||||||
|  | 	void* ctx; | ||||||
|  | } msgpack_unpacker; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE | ||||||
|  | #define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Initializes a streaming deserializer. | ||||||
|  |  * The initialized deserializer must be destroyed by msgpack_unpacker_destroy(msgpack_unpacker*). | ||||||
|  |  */ | ||||||
|  | bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Destroys a streaming deserializer initialized by msgpack_unpacker_init(msgpack_unpacker*, size_t). | ||||||
|  |  */ | ||||||
|  | void msgpack_unpacker_destroy(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Creates a streaming deserializer. | ||||||
|  |  * The created deserializer must be destroyed by msgpack_unpacker_free(msgpack_unpacker*). | ||||||
|  |  */ | ||||||
|  | msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Frees a streaming deserializer created by msgpack_unpacker_new(size_t). | ||||||
|  |  */ | ||||||
|  | void msgpack_unpacker_free(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef MSGPACK_UNPACKER_RESERVE_SIZE | ||||||
|  | #define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Reserves free space of the internal buffer. | ||||||
|  |  * Use this function to fill the internal buffer with | ||||||
|  |  * msgpack_unpacker_buffer(msgpack_unpacker*), | ||||||
|  |  * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and | ||||||
|  |  * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). | ||||||
|  |  */ | ||||||
|  | static inline bool   msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Gets pointer to the free space of the internal buffer. | ||||||
|  |  * Use this function to fill the internal buffer with | ||||||
|  |  * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), | ||||||
|  |  * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and | ||||||
|  |  * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). | ||||||
|  |  */ | ||||||
|  | static inline char*  msgpack_unpacker_buffer(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Gets size of the free space of the internal buffer. | ||||||
|  |  * Use this function to fill the internal buffer with | ||||||
|  |  * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), | ||||||
|  |  * msgpack_unpacker_buffer(const msgpack_unpacker*) and | ||||||
|  |  * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). | ||||||
|  |  */ | ||||||
|  | static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Notifies the deserializer that the internal buffer filled. | ||||||
|  |  * Use this function to fill the internal buffer with | ||||||
|  |  * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), | ||||||
|  |  * msgpack_unpacker_buffer(msgpack_unpacker*) and | ||||||
|  |  * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*). | ||||||
|  |  */ | ||||||
|  | static inline void   msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Deserializes one object. | ||||||
|  |  * Returns true if it successes. Otherwise false is returned. | ||||||
|  |  * @param pac  pointer to an initialized msgpack_unpacked object. | ||||||
|  |  */ | ||||||
|  | bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* pac); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Initializes a msgpack_unpacked object. | ||||||
|  |  * The initialized object must be destroyed by msgpack_unpacked_destroy(msgpack_unpacker*). | ||||||
|  |  * Use the object with msgpack_unpacker_next(msgpack_unpacker*, msgpack_unpacked*) or | ||||||
|  |  * msgpack_unpack_next(msgpack_unpacked*, const char*, size_t, size_t*). | ||||||
|  |  */ | ||||||
|  | static inline void msgpack_unpacked_init(msgpack_unpacked* result); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Destroys a streaming deserializer initialized by msgpack_unpacked(). | ||||||
|  |  */ | ||||||
|  | static inline void msgpack_unpacked_destroy(msgpack_unpacked* result); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Releases the memory zone from msgpack_unpacked object. | ||||||
|  |  * The released zone must be freed by msgpack_zone_free(msgpack_zone*). | ||||||
|  |  */ | ||||||
|  | static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int msgpack_unpacker_execute(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | void msgpack_unpacker_reset(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** @} */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // obsolete | ||||||
|  | typedef enum { | ||||||
|  | 	MSGPACK_UNPACK_SUCCESS				=  2, | ||||||
|  | 	MSGPACK_UNPACK_EXTRA_BYTES			=  1, | ||||||
|  | 	MSGPACK_UNPACK_CONTINUE				=  0, | ||||||
|  | 	MSGPACK_UNPACK_PARSE_ERROR			= -1, | ||||||
|  | } msgpack_unpack_return; | ||||||
|  |  | ||||||
|  | // obsolete | ||||||
|  | msgpack_unpack_return | ||||||
|  | msgpack_unpack(const char* data, size_t len, size_t* off, | ||||||
|  | 		msgpack_zone* result_zone, msgpack_object* result); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac); | ||||||
|  |  | ||||||
|  | bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size); | ||||||
|  |  | ||||||
|  | bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size) | ||||||
|  | { | ||||||
|  | 	if(mpac->free >= size) { return true; } | ||||||
|  | 	return msgpack_unpacker_expand_buffer(mpac, size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char* msgpack_unpacker_buffer(msgpack_unpacker* mpac) | ||||||
|  | { | ||||||
|  | 	return mpac->buffer + mpac->used; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac) | ||||||
|  | { | ||||||
|  | 	return mpac->free; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size) | ||||||
|  | { | ||||||
|  | 	mpac->used += size; | ||||||
|  | 	mpac->free -= size; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac) | ||||||
|  | { | ||||||
|  | 	return mpac->parsed - mpac->off + mpac->used; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac) | ||||||
|  | { | ||||||
|  | 	return mpac->parsed; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void msgpack_unpacked_init(msgpack_unpacked* result) | ||||||
|  | { | ||||||
|  | 	memset(result, 0, sizeof(msgpack_unpacked)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void msgpack_unpacked_destroy(msgpack_unpacked* result) | ||||||
|  | { | ||||||
|  | 	if(result->zone != NULL) { | ||||||
|  | 		msgpack_zone_free(result->zone); | ||||||
|  | 		result->zone = NULL; | ||||||
|  | 		memset(&result->data, 0, sizeof(msgpack_object)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result) | ||||||
|  | { | ||||||
|  | 	if(result->zone != NULL) { | ||||||
|  | 		msgpack_zone* z = result->zone; | ||||||
|  | 		result->zone = NULL; | ||||||
|  | 		return z; | ||||||
|  | 	} | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif /* msgpack/unpack.h */ | ||||||
|  |  | ||||||
| @@ -18,14 +18,15 @@ | |||||||
| #ifndef MSGPACK_UNPACK_HPP__ | #ifndef MSGPACK_UNPACK_HPP__ | ||||||
| #define MSGPACK_UNPACK_HPP__ | #define MSGPACK_UNPACK_HPP__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/unpack.h" | #include "unpack.h" | ||||||
| #include "msgpack/object.hpp" | #include "object.hpp" | ||||||
| #include "msgpack/zone.hpp" | #include "zone.hpp" | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| 
 | 
 | ||||||
|  | // backward compatibility
 | ||||||
| #ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE | #ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE | ||||||
| #define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE (32*1024) | #define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE MSGPACK_UNPACKER_INIT_BUFFER_SIZE | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| namespace msgpack { | namespace msgpack { | ||||||
| @@ -37,14 +38,39 @@ struct unpack_error : public std::runtime_error { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class unpacked { | ||||||
|  | public: | ||||||
|  | 	unpacked() { } | ||||||
|  | 
 | ||||||
|  | 	unpacked(object obj, std::auto_ptr<msgpack::zone> z) : | ||||||
|  | 		m_obj(obj), m_zone(z) { } | ||||||
|  | 
 | ||||||
|  | 	object& get() | ||||||
|  | 		{ return m_obj; } | ||||||
|  | 
 | ||||||
|  | 	const object& get() const | ||||||
|  | 		{ return m_obj; } | ||||||
|  | 
 | ||||||
|  | 	std::auto_ptr<msgpack::zone>& zone() | ||||||
|  | 		{ return m_zone; } | ||||||
|  | 
 | ||||||
|  | 	const std::auto_ptr<msgpack::zone>& zone() const | ||||||
|  | 		{ return m_zone; } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	object m_obj; | ||||||
|  | 	std::auto_ptr<msgpack::zone> m_zone; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class unpacker : public msgpack_unpacker { | class unpacker : public msgpack_unpacker { | ||||||
| public: | public: | ||||||
| 	unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE); | 	unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE); | ||||||
| 	~unpacker(); | 	~unpacker(); | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 	/*! 1. reserve buffer. at least `size' bytes of capacity will be ready */ | 	/*! 1. reserve buffer. at least `size' bytes of capacity will be ready */ | ||||||
| 	void reserve_buffer(size_t size); | 	void reserve_buffer(size_t size = MSGPACK_UNPACKER_RESERVE_SIZE); | ||||||
| 
 | 
 | ||||||
| 	/*! 2. read data to the buffer() up to buffer_capacity() bytes */ | 	/*! 2. read data to the buffer() up to buffer_capacity() bytes */ | ||||||
| 	char* buffer(); | 	char* buffer(); | ||||||
| @@ -53,39 +79,22 @@ public: | |||||||
| 	/*! 3. specify the number of bytes actually copied */ | 	/*! 3. specify the number of bytes actually copied */ | ||||||
| 	void buffer_consumed(size_t size); | 	void buffer_consumed(size_t size); | ||||||
| 
 | 
 | ||||||
| 	/*! 4. repeat execute() until it retunrs false */ | 	/*! 4. repeat next() until it retunrs false */ | ||||||
| 	bool execute(); | 	bool next(unpacked* result); | ||||||
| 
 | 
 | ||||||
| 	/*! 5.1. if execute() returns true, take out the parsed object */ | 	/*! 5. check if the size of message doesn't exceed assumption. */ | ||||||
| 	object data(); |  | ||||||
| 
 |  | ||||||
| 	/*! 5.2. the object is valid until the zone is deleted */ |  | ||||||
| 	// Note that once release_zone() from unpacker, you must delete it
 |  | ||||||
| 	// otherwise the memrory will leak.
 |  | ||||||
| 	zone* release_zone(); |  | ||||||
| 
 |  | ||||||
| 	/*! 5.2. this method is equivalence to `delete release_zone()` */ |  | ||||||
| 	void reset_zone(); |  | ||||||
| 
 |  | ||||||
| 	/*! 5.3. after release_zone(), re-initialize unpacker */ |  | ||||||
| 	void reset(); |  | ||||||
| 
 |  | ||||||
| 	/*! 6. check if the size of message doesn't exceed assumption. */ |  | ||||||
| 	size_t message_size() const; | 	size_t message_size() const; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	// Basic usage of the unpacker is as following:
 | 	// Basic usage of the unpacker is as following:
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// msgpack::unpacker pac;
 | 	// msgpack::unpacker pac;
 | ||||||
| 	//
 | 	// while( /* input is readable */ ) {
 | ||||||
| 	// while( /* readable */ ) {
 |  | ||||||
| 	//
 | 	//
 | ||||||
| 	//     // 1.
 | 	//     // 1.
 | ||||||
| 	//     pac.reserve(1024);
 | 	//     pac.reserve_buffer(32*1024);
 | ||||||
| 	//
 | 	//
 | ||||||
| 	//     // 2.
 | 	//     // 2.
 | ||||||
| 	//     ssize_t bytes =
 | 	//     size_t bytes = input.readsome(pac.buffer(), pac.buffer_capacity());
 | ||||||
| 	//         read(the_source, pac.buffer(), pac.buffer_capacity());
 |  | ||||||
| 	//
 | 	//
 | ||||||
| 	//     // error handling ...
 | 	//     // error handling ...
 | ||||||
| 	//
 | 	//
 | ||||||
| @@ -93,25 +102,40 @@ public: | |||||||
| 	//     pac.buffer_consumed(bytes);
 | 	//     pac.buffer_consumed(bytes);
 | ||||||
| 	//
 | 	//
 | ||||||
| 	//     // 4.
 | 	//     // 4.
 | ||||||
| 	//     while(pac.execute()) {
 | 	//     msgpack::unpacked result;
 | ||||||
| 	//         // 5.1
 | 	//     while(pac.next(&result)) {
 | ||||||
| 	//         object o = pac.data();
 | 	//         // do some with the object with the zone.
 | ||||||
|  | 	//         msgpack::object obj = result.get();
 | ||||||
|  | 	//         std::auto_ptr<msgpack:zone> z = result.zone();
 | ||||||
|  | 	//         on_message(obj, z);
 | ||||||
| 	//
 | 	//
 | ||||||
| 	//         // 5.2
 | 	//         //// boost::shared_ptr is also usable:
 | ||||||
| 	//         std::auto_ptr<msgpack::zone> olife( pac.release_zone() );
 | 	//         // boost::shared_ptr<msgpack::zone> life(z.release());
 | ||||||
|  | 	//         // on_message(result.get(), life);
 | ||||||
|  | 	//     }
 | ||||||
| 	//
 | 	//
 | ||||||
| 	//         // boost::shared_ptr is also usable:
 | 	//     // 5.
 | ||||||
| 	//         // boost::shared_ptr<msgpack::zone> olife( pac.release_zone() );
 | 	//     if(pac.message_size() > 10*1024*1024) {
 | ||||||
| 	//
 | 	//         throw std::runtime_error("message is too large");
 | ||||||
| 	//         // 5.3
 |  | ||||||
| 	//         pac.reset();
 |  | ||||||
| 	//
 |  | ||||||
| 	//         // do some with the object with the old zone.
 |  | ||||||
| 	//         do_something(o, olife);
 |  | ||||||
| 	//     }
 | 	//     }
 | ||||||
| 	// }
 | 	// }
 | ||||||
| 	//
 | 	//
 | ||||||
| 
 | 
 | ||||||
|  | 	/*! for backward compatibility */ | ||||||
|  | 	bool execute(); | ||||||
|  | 
 | ||||||
|  | 	/*! for backward compatibility */ | ||||||
|  | 	object data(); | ||||||
|  | 
 | ||||||
|  | 	/*! for backward compatibility */ | ||||||
|  | 	zone* release_zone(); | ||||||
|  | 
 | ||||||
|  | 	/*! for backward compatibility */ | ||||||
|  | 	void reset_zone(); | ||||||
|  | 
 | ||||||
|  | 	/*! for backward compatibility */ | ||||||
|  | 	void reset(); | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
| 	// These functions are usable when non-MessagePack message follows after
 | 	// These functions are usable when non-MessagePack message follows after
 | ||||||
| 	// MessagePack message.
 | 	// MessagePack message.
 | ||||||
| @@ -137,6 +161,11 @@ private: | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | static void unpack(unpacked* result, | ||||||
|  | 		const char* data, size_t len, size_t* offset = NULL); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // obsolete
 | ||||||
| typedef enum { | typedef enum { | ||||||
| 	UNPACK_SUCCESS				=  2, | 	UNPACK_SUCCESS				=  2, | ||||||
| 	UNPACK_EXTRA_BYTES			=  1, | 	UNPACK_EXTRA_BYTES			=  1, | ||||||
| @@ -144,6 +173,7 @@ typedef enum { | |||||||
| 	UNPACK_PARSE_ERROR			= -1, | 	UNPACK_PARSE_ERROR			= -1, | ||||||
| } unpack_return; | } unpack_return; | ||||||
| 
 | 
 | ||||||
|  | // obsolete
 | ||||||
| static unpack_return unpack(const char* data, size_t len, size_t* off, | static unpack_return unpack(const char* data, size_t len, size_t* off, | ||||||
| 		zone* z, object* result); | 		zone* z, object* result); | ||||||
| 
 | 
 | ||||||
| @@ -187,6 +217,27 @@ inline void unpacker::buffer_consumed(size_t size) | |||||||
| 	return msgpack_unpacker_buffer_consumed(this, size); | 	return msgpack_unpacker_buffer_consumed(this, size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | inline bool unpacker::next(unpacked* result) | ||||||
|  | { | ||||||
|  | 	int ret = msgpack_unpacker_execute(this); | ||||||
|  | 
 | ||||||
|  | 	if(ret < 0) { | ||||||
|  | 		throw unpack_error("parse error"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if(ret == 0) { | ||||||
|  | 		result->zone().reset(); | ||||||
|  | 		result->get() = object(); | ||||||
|  | 		return false; | ||||||
|  | 
 | ||||||
|  | 	} else { | ||||||
|  | 		result->zone().reset( release_zone() ); | ||||||
|  | 		result->get() = data(); | ||||||
|  | 		reset(); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| inline bool unpacker::execute() | inline bool unpacker::execute() | ||||||
| { | { | ||||||
| @@ -230,12 +281,12 @@ inline void unpacker::reset() | |||||||
| 	msgpack_unpacker_reset(this); | 	msgpack_unpacker_reset(this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| inline size_t unpacker::message_size() const | inline size_t unpacker::message_size() const | ||||||
| { | { | ||||||
| 	return msgpack_unpacker_message_size(this); | 	return msgpack_unpacker_message_size(this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| inline size_t unpacker::parsed_size() const | inline size_t unpacker::parsed_size() const | ||||||
| { | { | ||||||
| 	return msgpack_unpacker_parsed_size(this); | 	return msgpack_unpacker_parsed_size(this); | ||||||
| @@ -262,6 +313,38 @@ inline void unpacker::remove_nonparsed_buffer() | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | inline void unpack(unpacked* result, | ||||||
|  | 		const char* data, size_t len, size_t* offset) | ||||||
|  | { | ||||||
|  | 	msgpack::object obj; | ||||||
|  | 	std::auto_ptr<msgpack::zone> z(new zone()); | ||||||
|  | 
 | ||||||
|  | 	unpack_return ret = (unpack_return)msgpack_unpack( | ||||||
|  | 			data, len, offset, z.get(), | ||||||
|  | 			reinterpret_cast<msgpack_object*>(&obj)); | ||||||
|  | 
 | ||||||
|  | 	switch(ret) { | ||||||
|  | 	case UNPACK_SUCCESS: | ||||||
|  | 		result->get() = obj; | ||||||
|  | 		result->zone() = z; | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	case UNPACK_EXTRA_BYTES: | ||||||
|  | 		result->get() = obj; | ||||||
|  | 		result->zone() = z; | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	case UNPACK_CONTINUE: | ||||||
|  | 		throw unpack_error("insufficient bytes"); | ||||||
|  | 
 | ||||||
|  | 	case UNPACK_PARSE_ERROR: | ||||||
|  | 	default: | ||||||
|  | 		throw unpack_error("parse error"); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // obsolete
 | ||||||
| inline unpack_return unpack(const char* data, size_t len, size_t* off, | inline unpack_return unpack(const char* data, size_t len, size_t* off, | ||||||
| 		zone* z, object* result) | 		zone* z, object* result) | ||||||
| { | { | ||||||
							
								
								
									
										40
									
								
								cpp/src/msgpack/version.h.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								cpp/src/msgpack/version.h.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | /* | ||||||
|  |  * MessagePack for C version information | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2008-2009 FURUHASHI Sadayuki | ||||||
|  |  * | ||||||
|  |  *    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *    you may not use this file except in compliance with the License. | ||||||
|  |  *    You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  *    Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *    distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *    See the License for the specific language governing permissions and | ||||||
|  |  *    limitations under the License. | ||||||
|  |  */ | ||||||
|  | #ifndef MSGPACK_VERSION_H__ | ||||||
|  | #define MSGPACK_VERSION_H__ | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const char* msgpack_version(void); | ||||||
|  | int msgpack_version_major(void); | ||||||
|  | int msgpack_version_minor(void); | ||||||
|  |  | ||||||
|  | #define MSGPACK_VERSION "@VERSION@" | ||||||
|  | #define MSGPACK_VERSION_MAJOR @VERSION_MAJOR@ | ||||||
|  | #define MSGPACK_VERSION_MINOR @VERSION_MINOR@ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif /* msgpack/version.h */ | ||||||
|  |  | ||||||
| @@ -18,7 +18,8 @@ | |||||||
| #ifndef MSGPACK_VREFBUFFER_H__ | #ifndef MSGPACK_VREFBUFFER_H__ | ||||||
| #define MSGPACK_VREFBUFFER_H__ | #define MSGPACK_VREFBUFFER_H__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/zone.h" | #include "zone.h" | ||||||
|  | #include <stdlib.h> | ||||||
| 
 | 
 | ||||||
| #ifndef _WIN32 | #ifndef _WIN32 | ||||||
| #include <sys/uio.h> | #include <sys/uio.h> | ||||||
| @@ -29,19 +30,16 @@ struct iovec { | |||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #ifndef MSGPACK_VREFBUFFER_REF_SIZE | /**
 | ||||||
| #define MSGPACK_VREFBUFFER_REF_SIZE 32 |  * @defgroup msgpack_vrefbuffer Vectored Referencing buffer | ||||||
| #endif |  * @ingroup msgpack_buffer | ||||||
| 
 |  * @{ | ||||||
| #ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE |  */ | ||||||
| #define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192 |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| struct msgpack_vrefbuffer_chunk; | struct msgpack_vrefbuffer_chunk; | ||||||
| typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk; | typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk; | ||||||
| @@ -64,10 +62,21 @@ typedef struct msgpack_vrefbuffer { | |||||||
| } msgpack_vrefbuffer; | } msgpack_vrefbuffer; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | #ifndef MSGPACK_VREFBUFFER_REF_SIZE | ||||||
|  | #define MSGPACK_VREFBUFFER_REF_SIZE 32 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE | ||||||
|  | #define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf, | bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf, | ||||||
| 		size_t ref_size, size_t chunk_size); | 		size_t ref_size, size_t chunk_size); | ||||||
| void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf); | void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf); | ||||||
| 
 | 
 | ||||||
|  | static inline msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size); | ||||||
|  | static inline void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf); | ||||||
|  | 
 | ||||||
| static inline int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len); | static inline int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len); | ||||||
| 
 | 
 | ||||||
| static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref); | static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref); | ||||||
| @@ -81,6 +90,28 @@ int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf, | |||||||
| 
 | 
 | ||||||
| int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to); | int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to); | ||||||
| 
 | 
 | ||||||
|  | void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vref); | ||||||
|  | 
 | ||||||
|  | /** @} */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size) | ||||||
|  | { | ||||||
|  | 	msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)malloc(sizeof(msgpack_vrefbuffer)); | ||||||
|  | 	if(!msgpack_vrefbuffer_init(vbuf, ref_size, chunk_size)) { | ||||||
|  | 		free(vbuf); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	return vbuf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf) | ||||||
|  | { | ||||||
|  | 	if(vbuf == NULL) { return; } | ||||||
|  | 	msgpack_vrefbuffer_destroy(vbuf); | ||||||
|  | 	free(vbuf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len) | int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len) | ||||||
| { | { | ||||||
| 	msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)data; | 	msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)data; | ||||||
| @@ -102,6 +133,7 @@ size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref) | |||||||
| 	return vref->tail - vref->array; | 	return vref->tail - vref->array; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| @@ -18,7 +18,7 @@ | |||||||
| #ifndef MSGPACK_VREFBUFFER_HPP__ | #ifndef MSGPACK_VREFBUFFER_HPP__ | ||||||
| #define MSGPACK_VREFBUFFER_HPP__ | #define MSGPACK_VREFBUFFER_HPP__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/vrefbuffer.h" | #include "vrefbuffer.h" | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| 
 | 
 | ||||||
| namespace msgpack { | namespace msgpack { | ||||||
| @@ -78,6 +78,11 @@ public: | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void clear() | ||||||
|  | 	{ | ||||||
|  | 		msgpack_vrefbuffer_clear(this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
| 	typedef msgpack_vrefbuffer base; | 	typedef msgpack_vrefbuffer base; | ||||||
| 
 | 
 | ||||||
							
								
								
									
										207
									
								
								cpp/src/msgpack/zbuffer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								cpp/src/msgpack/zbuffer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,207 @@ | |||||||
|  | /* | ||||||
|  |  * MessagePack for C deflate buffer implementation | ||||||
|  |  * | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  | #ifndef MSGPACK_ZBUFFER_H__ | ||||||
|  | #define MSGPACK_ZBUFFER_H__ | ||||||
|  |  | ||||||
|  | #include "sysdep.h" | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <zlib.h> | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @defgroup msgpack_zbuffer Compressed buffer | ||||||
|  |  * @ingroup msgpack_buffer | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | typedef struct msgpack_zbuffer { | ||||||
|  | 	z_stream stream; | ||||||
|  | 	char* data; | ||||||
|  | 	size_t init_size; | ||||||
|  | } msgpack_zbuffer; | ||||||
|  |  | ||||||
|  | #ifndef MSGPACK_ZBUFFER_INIT_SIZE | ||||||
|  | #define MSGPACK_ZBUFFER_INIT_SIZE 8192 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static inline bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf, | ||||||
|  | 		int level, size_t init_size); | ||||||
|  | static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf); | ||||||
|  |  | ||||||
|  | static inline msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size); | ||||||
|  | static inline void msgpack_zbuffer_free(msgpack_zbuffer* zbuf); | ||||||
|  |  | ||||||
|  | static inline char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf); | ||||||
|  |  | ||||||
|  | static inline const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf); | ||||||
|  | static inline size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf); | ||||||
|  |  | ||||||
|  | static inline bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf); | ||||||
|  | static inline void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf); | ||||||
|  | static inline char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef MSGPACK_ZBUFFER_RESERVE_SIZE | ||||||
|  | #define MSGPACK_ZBUFFER_RESERVE_SIZE 512 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static inline int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len); | ||||||
|  |  | ||||||
|  | static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf, | ||||||
|  | 		int level, size_t init_size) | ||||||
|  | { | ||||||
|  | 	memset(zbuf, 0, sizeof(msgpack_zbuffer)); | ||||||
|  | 	zbuf->init_size = init_size; | ||||||
|  | 	if(deflateInit(&zbuf->stream, level) != Z_OK) { | ||||||
|  | 		free(zbuf->data); | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	deflateEnd(&zbuf->stream); | ||||||
|  | 	free(zbuf->data); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size) | ||||||
|  | { | ||||||
|  | 	msgpack_zbuffer* zbuf = (msgpack_zbuffer*)malloc(sizeof(msgpack_zbuffer)); | ||||||
|  | 	if(!msgpack_zbuffer_init(zbuf, level, init_size)) { | ||||||
|  | 		free(zbuf); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	return zbuf; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void msgpack_zbuffer_free(msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	if(zbuf == NULL) { return; } | ||||||
|  | 	msgpack_zbuffer_destroy(zbuf); | ||||||
|  | 	free(zbuf); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	size_t used = (char*)zbuf->stream.next_out - zbuf->data; | ||||||
|  | 	size_t csize = used + zbuf->stream.avail_out; | ||||||
|  | 	size_t nsize = (csize == 0) ? zbuf->init_size : csize * 2; | ||||||
|  |  | ||||||
|  | 	char* tmp = (char*)realloc(zbuf->data, nsize); | ||||||
|  | 	if(tmp == NULL) { | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	zbuf->data = tmp; | ||||||
|  | 	zbuf->stream.next_out  = (Bytef*)(tmp + used); | ||||||
|  | 	zbuf->stream.avail_out = nsize - used; | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len) | ||||||
|  | { | ||||||
|  | 	msgpack_zbuffer* zbuf = (msgpack_zbuffer*)data; | ||||||
|  |  | ||||||
|  | 	zbuf->stream.next_in = (Bytef*)buf; | ||||||
|  | 	zbuf->stream.avail_in = len; | ||||||
|  |  | ||||||
|  | 	do { | ||||||
|  | 		if(zbuf->stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) { | ||||||
|  | 			if(!msgpack_zbuffer_expand(zbuf)) { | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if(deflate(&zbuf->stream, Z_NO_FLUSH) != Z_OK) { | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 	} while(zbuf->stream.avail_in > 0); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	while(true) { | ||||||
|  | 		switch(deflate(&zbuf->stream, Z_FINISH)) { | ||||||
|  | 		case Z_STREAM_END: | ||||||
|  | 			return zbuf->data; | ||||||
|  | 		case Z_OK: | ||||||
|  | 			if(!msgpack_zbuffer_expand(zbuf)) { | ||||||
|  | 				return NULL; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	return zbuf->data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	return (char*)zbuf->stream.next_out - zbuf->data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	zbuf->stream.avail_out += (char*)zbuf->stream.next_out - zbuf->data; | ||||||
|  | 	zbuf->stream.next_out = (Bytef*)zbuf->data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	if(deflateReset(&zbuf->stream) != Z_OK) { | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 	msgpack_zbuffer_reset_buffer(zbuf); | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf) | ||||||
|  | { | ||||||
|  | 	char* tmp = zbuf->data; | ||||||
|  | 	zbuf->data = NULL; | ||||||
|  | 	zbuf->stream.next_out = NULL; | ||||||
|  | 	zbuf->stream.avail_out = 0; | ||||||
|  | 	return tmp; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @} */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif /* msgpack/zbuffer.h */ | ||||||
|  |  | ||||||
							
								
								
									
										100
									
								
								cpp/src/msgpack/zbuffer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								cpp/src/msgpack/zbuffer.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | |||||||
|  | // | ||||||
|  | // MessagePack for C++ deflate buffer implementation | ||||||
|  | // | ||||||
|  | // 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. | ||||||
|  | // | ||||||
|  | #ifndef MSGPACK_ZBUFFER_HPP__ | ||||||
|  | #define MSGPACK_ZBUFFER_HPP__ | ||||||
|  |  | ||||||
|  | #include "zbuffer.h" | ||||||
|  | #include <stdexcept> | ||||||
|  |  | ||||||
|  | namespace msgpack { | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class zbuffer : public msgpack_zbuffer { | ||||||
|  | public: | ||||||
|  | 	zbuffer(int level = Z_DEFAULT_COMPRESSION, | ||||||
|  | 			size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE) | ||||||
|  | 	{ | ||||||
|  | 		msgpack_zbuffer_init(this, level, init_size); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	~zbuffer() | ||||||
|  | 	{ | ||||||
|  | 		msgpack_zbuffer_destroy(this); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | public: | ||||||
|  | 	void write(const char* buf, unsigned int len) | ||||||
|  | 	{ | ||||||
|  | 		if(msgpack_zbuffer_write(this, buf, len) < 0) { | ||||||
|  | 			throw std::bad_alloc(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	char* flush() | ||||||
|  | 	{ | ||||||
|  | 		char* buf = msgpack_zbuffer_flush(this); | ||||||
|  | 		if(!buf) { | ||||||
|  | 			throw std::bad_alloc(); | ||||||
|  | 		} | ||||||
|  | 		return buf; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	char* data() | ||||||
|  | 	{ | ||||||
|  | 		return base::data; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const char* data() const | ||||||
|  | 	{ | ||||||
|  | 		return base::data; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	size_t size() const | ||||||
|  | 	{ | ||||||
|  | 		return msgpack_zbuffer_size(this); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void reset() | ||||||
|  | 	{ | ||||||
|  | 		if(!msgpack_zbuffer_reset(this)) { | ||||||
|  | 			throw std::bad_alloc(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void reset_buffer() | ||||||
|  | 	{ | ||||||
|  | 		msgpack_zbuffer_reset_buffer(this); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	char* release_buffer() | ||||||
|  | 	{ | ||||||
|  | 		return msgpack_zbuffer_release_buffer(this); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	typedef msgpack_zbuffer base; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	zbuffer(const zbuffer&); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | }  // namespace msgpack | ||||||
|  |  | ||||||
|  | #endif /* msgpack/zbuffer.hpp */ | ||||||
|  |  | ||||||
| @@ -18,14 +18,19 @@ | |||||||
| #ifndef MSGPACK_ZONE_H__ | #ifndef MSGPACK_ZONE_H__ | ||||||
| #define MSGPACK_ZONE_H__ | #define MSGPACK_ZONE_H__ | ||||||
| 
 | 
 | ||||||
| #include <stddef.h> | #include "sysdep.h" | ||||||
| #include <stdbool.h> |  | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * @defgroup msgpack_zone Memory zone | ||||||
|  |  * @ingroup msgpack | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| typedef struct msgpack_zone_finalizer { | typedef struct msgpack_zone_finalizer { | ||||||
| 	void (*func)(void* data); | 	void (*func)(void* data); | ||||||
| 	void* data; | 	void* data; | ||||||
| @@ -72,6 +77,7 @@ bool msgpack_zone_is_empty(msgpack_zone* zone); | |||||||
| 
 | 
 | ||||||
| void msgpack_zone_clear(msgpack_zone* zone); | void msgpack_zone_clear(msgpack_zone* zone); | ||||||
| 
 | 
 | ||||||
|  | /** @} */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #ifndef MSGPACK_ZONE_ALIGN | #ifndef MSGPACK_ZONE_ALIGN | ||||||
| @@ -18,8 +18,7 @@ | |||||||
| #ifndef MSGPACK_ZONE_HPP__ | #ifndef MSGPACK_ZONE_HPP__ | ||||||
| #define MSGPACK_ZONE_HPP__ | #define MSGPACK_ZONE_HPP__ | ||||||
| 
 | 
 | ||||||
| #include "msgpack/object.hpp" | #include "zone.h" | ||||||
| #include "msgpack/zone.h" |  | ||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <vector> | #include <vector> | ||||||
| @@ -16,7 +16,6 @@ | |||||||
| //    limitations under the License.
 | //    limitations under the License.
 | ||||||
| //
 | //
 | ||||||
| #include "msgpack/object.hpp" | #include "msgpack/object.hpp" | ||||||
| #include <string.h> |  | ||||||
| 
 | 
 | ||||||
| namespace msgpack { | namespace msgpack { | ||||||
| 
 | 
 | ||||||
| @@ -61,7 +60,6 @@ std::ostream& operator<< (std::ostream& s, const object o) | |||||||
| 		} | 		} | ||||||
| 		s << "]"; | 		s << "]"; | ||||||
| 		break; | 		break; | ||||||
| 		// FIXME loop optimiziation
 |  | ||||||
| 
 | 
 | ||||||
| 	case type::MAP: | 	case type::MAP: | ||||||
| 		s << "{"; | 		s << "{"; | ||||||
| @@ -76,7 +74,6 @@ std::ostream& operator<< (std::ostream& s, const object o) | |||||||
| 		} | 		} | ||||||
| 		s << "}"; | 		s << "}"; | ||||||
| 		break; | 		break; | ||||||
| 		// FIXME loop optimiziation
 |  | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		// FIXME
 | 		// FIXME
 | ||||||
| @@ -86,53 +83,5 @@ std::ostream& operator<< (std::ostream& s, const object o) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| bool operator==(const object x, const object y) |  | ||||||
| { |  | ||||||
| 	if(x.type != y.type) { return false; } |  | ||||||
| 
 |  | ||||||
| 	switch(x.type) { |  | ||||||
| 	case type::NIL: |  | ||||||
| 		return true; |  | ||||||
| 
 |  | ||||||
| 	case type::BOOLEAN: |  | ||||||
| 		return x.via.boolean == y.via.boolean; |  | ||||||
| 
 |  | ||||||
| 	case type::POSITIVE_INTEGER: |  | ||||||
| 		return x.via.u64 == y.via.u64; |  | ||||||
| 
 |  | ||||||
| 	case type::NEGATIVE_INTEGER: |  | ||||||
| 		return x.via.i64 == y.via.i64; |  | ||||||
| 
 |  | ||||||
| 	case type::RAW: |  | ||||||
| 		return x.via.raw.size == y.via.raw.size && |  | ||||||
| 			memcmp(x.via.raw.ptr, y.via.raw.ptr, x.via.raw.size) == 0; |  | ||||||
| 
 |  | ||||||
| 	case type::ARRAY: |  | ||||||
| 		if(x.via.array.size != y.via.array.size) { return false; } |  | ||||||
| 		for(object* px(x.via.array.ptr), |  | ||||||
| 				* const pxend(x.via.array.ptr + x.via.array.size), |  | ||||||
| 				* py(y.via.array.ptr); |  | ||||||
| 				px < pxend; ++px, ++py) { |  | ||||||
| 			if(*px != *py) { return false; } |  | ||||||
| 		} |  | ||||||
| 		return true; |  | ||||||
| 		// FIXME loop optimiziation
 |  | ||||||
| 
 |  | ||||||
| 	case type::MAP: |  | ||||||
| 		if(x.via.map.size != y.via.map.size) { return false; } |  | ||||||
| 		for(object_kv* px(x.via.map.ptr), |  | ||||||
| 				* const pxend(x.via.map.ptr + x.via.map.size), |  | ||||||
| 				* py(y.via.map.ptr); |  | ||||||
| 				px < pxend; ++px, ++py) { |  | ||||||
| 			if(px->key != py->key || px->val != py->val) { return false; } |  | ||||||
| 		} |  | ||||||
| 		return true; |  | ||||||
| 
 |  | ||||||
| 	default: |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| }  // namespace msgpack
 | }  // namespace msgpack
 | ||||||
| 
 | 
 | ||||||
| @@ -18,6 +18,7 @@ | |||||||
| #include "msgpack/object.h" | #include "msgpack/object.h" | ||||||
| #include "msgpack/pack.h" | #include "msgpack/pack.h" | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
| 
 | 
 | ||||||
| #ifndef _MSC_VER | #ifndef _MSC_VER | ||||||
| #include <inttypes.h> | #include <inttypes.h> | ||||||
| @@ -141,7 +142,6 @@ void msgpack_object_print(FILE* out, msgpack_object o) | |||||||
| 		} | 		} | ||||||
| 		fprintf(out, "]"); | 		fprintf(out, "]"); | ||||||
| 		break; | 		break; | ||||||
| 		// FIXME loop optimiziation
 |  | ||||||
| 
 | 
 | ||||||
| 	case MSGPACK_OBJECT_MAP: | 	case MSGPACK_OBJECT_MAP: | ||||||
| 		fprintf(out, "{"); | 		fprintf(out, "{"); | ||||||
| @@ -161,7 +161,6 @@ void msgpack_object_print(FILE* out, msgpack_object o) | |||||||
| 		} | 		} | ||||||
| 		fprintf(out, "}"); | 		fprintf(out, "}"); | ||||||
| 		break; | 		break; | ||||||
| 		// FIXME loop optimiziation
 |  | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		// FIXME
 | 		// FIXME
 | ||||||
| @@ -169,3 +168,70 @@ void msgpack_object_print(FILE* out, msgpack_object o) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool msgpack_object_equal(const msgpack_object x, const msgpack_object y) | ||||||
|  | { | ||||||
|  | 	if(x.type != y.type) { return false; } | ||||||
|  | 
 | ||||||
|  | 	switch(x.type) { | ||||||
|  | 	case MSGPACK_OBJECT_NIL: | ||||||
|  | 		return true; | ||||||
|  | 
 | ||||||
|  | 	case MSGPACK_OBJECT_BOOLEAN: | ||||||
|  | 		return x.via.boolean == y.via.boolean; | ||||||
|  | 
 | ||||||
|  | 	case MSGPACK_OBJECT_POSITIVE_INTEGER: | ||||||
|  | 		return x.via.u64 == y.via.u64; | ||||||
|  | 
 | ||||||
|  | 	case MSGPACK_OBJECT_NEGATIVE_INTEGER: | ||||||
|  | 		return x.via.i64 == y.via.i64; | ||||||
|  | 
 | ||||||
|  | 	case MSGPACK_OBJECT_DOUBLE: | ||||||
|  | 		return x.via.dec == y.via.dec; | ||||||
|  | 
 | ||||||
|  | 	case MSGPACK_OBJECT_RAW: | ||||||
|  | 		return x.via.raw.size == y.via.raw.size && | ||||||
|  | 			memcmp(x.via.raw.ptr, y.via.raw.ptr, x.via.raw.size) == 0; | ||||||
|  | 
 | ||||||
|  | 	case MSGPACK_OBJECT_ARRAY: | ||||||
|  | 		if(x.via.array.size != y.via.array.size) { | ||||||
|  | 			return false; | ||||||
|  | 		} else if(x.via.array.size == 0) { | ||||||
|  | 			return true; | ||||||
|  | 		} else { | ||||||
|  | 			msgpack_object* px = x.via.array.ptr; | ||||||
|  | 			msgpack_object* const pxend = x.via.array.ptr + x.via.array.size; | ||||||
|  | 			msgpack_object* py = y.via.array.ptr; | ||||||
|  | 			do { | ||||||
|  | 				if(!msgpack_object_equal(*px, *py)) { | ||||||
|  | 					return false; | ||||||
|  | 				} | ||||||
|  | 				++px; | ||||||
|  | 				++py; | ||||||
|  | 			} while(px < pxend); | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case MSGPACK_OBJECT_MAP: | ||||||
|  | 		if(x.via.map.size != y.via.map.size) { | ||||||
|  | 			return false; | ||||||
|  | 		} else if(x.via.map.size == 0) { | ||||||
|  | 			return true; | ||||||
|  | 		} else { | ||||||
|  | 			msgpack_object_kv* px = x.via.map.ptr; | ||||||
|  | 			msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size; | ||||||
|  | 			msgpack_object_kv* py = y.via.map.ptr; | ||||||
|  | 			do { | ||||||
|  | 				if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) { | ||||||
|  | 					return false; | ||||||
|  | 				} | ||||||
|  | 				++px; | ||||||
|  | 				++py; | ||||||
|  | 			} while(px < pxend); | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| @@ -52,7 +52,7 @@ static int template_execute(template_context* ctx, | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static inline msgpack_object template_callback_root(unpack_user* u) | static inline msgpack_object template_callback_root(unpack_user* u) | ||||||
| { msgpack_object o; return o; } | { msgpack_object o = {}; return o; } | ||||||
| 
 | 
 | ||||||
| static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_object* o) | static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_object* o) | ||||||
| { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } | { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } | ||||||
| @@ -323,7 +323,7 @@ msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac) | |||||||
| msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac) | msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac) | ||||||
| { | { | ||||||
| 	if(!msgpack_unpacker_flush_zone(mpac)) { | 	if(!msgpack_unpacker_flush_zone(mpac)) { | ||||||
| 		return false; | 		return NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); | 	msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); | ||||||
| @@ -363,28 +363,54 @@ void msgpack_unpacker_reset(msgpack_unpacker* mpac) | |||||||
| 	mpac->parsed = 0; | 	mpac->parsed = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result) | ||||||
|  | { | ||||||
|  | 	if(result->zone != NULL) { | ||||||
|  | 		msgpack_zone_free(result->zone); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	int ret = msgpack_unpacker_execute(mpac); | ||||||
|  | 
 | ||||||
|  | 	if(ret <= 0) { | ||||||
|  | 		result->zone = NULL; | ||||||
|  | 		memset(&result->data, 0, sizeof(msgpack_object)); | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	result->zone = msgpack_unpacker_release_zone(mpac); | ||||||
|  | 	result->data = msgpack_unpacker_data(mpac); | ||||||
|  | 	msgpack_unpacker_reset(mpac); | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| msgpack_unpack_return | msgpack_unpack_return | ||||||
| msgpack_unpack(const char* data, size_t len, size_t* off, | msgpack_unpack(const char* data, size_t len, size_t* off, | ||||||
| 		msgpack_zone* z, msgpack_object* result) | 		msgpack_zone* result_zone, msgpack_object* result) | ||||||
| { | { | ||||||
| 	template_context ctx; |  | ||||||
| 	template_init(&ctx); |  | ||||||
| 
 |  | ||||||
| 	ctx.user.z = z; |  | ||||||
| 	ctx.user.referenced = false; |  | ||||||
| 
 |  | ||||||
| 	size_t noff = 0; | 	size_t noff = 0; | ||||||
| 	if(off != NULL) { noff = *off; } | 	if(off != NULL) { noff = *off; } | ||||||
| 
 | 
 | ||||||
| 	int ret = template_execute(&ctx, data, len, &noff); | 	if(len <= noff) { | ||||||
| 	if(ret < 0) { | 		// FIXME
 | ||||||
|  | 		return MSGPACK_UNPACK_CONTINUE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template_context ctx; | ||||||
|  | 	template_init(&ctx); | ||||||
|  | 
 | ||||||
|  | 	ctx.user.z = result_zone; | ||||||
|  | 	ctx.user.referenced = false; | ||||||
|  | 
 | ||||||
|  | 	int e = template_execute(&ctx, data, len, &noff); | ||||||
|  | 	if(e < 0) { | ||||||
| 		return MSGPACK_UNPACK_PARSE_ERROR; | 		return MSGPACK_UNPACK_PARSE_ERROR; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if(off != NULL) { *off = noff; } | 	if(off != NULL) { *off = noff; } | ||||||
| 
 | 
 | ||||||
| 	if(ret == 0) { | 	if(e == 0) { | ||||||
| 		return MSGPACK_UNPACK_CONTINUE; | 		return MSGPACK_UNPACK_CONTINUE; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @@ -397,3 +423,37 @@ msgpack_unpack(const char* data, size_t len, size_t* off, | |||||||
| 	return MSGPACK_UNPACK_SUCCESS; | 	return MSGPACK_UNPACK_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool msgpack_unpack_next(msgpack_unpacked* result, | ||||||
|  | 		const char* data, size_t len, size_t* off) | ||||||
|  | { | ||||||
|  | 	msgpack_unpacked_destroy(result); | ||||||
|  | 
 | ||||||
|  | 	size_t noff = 0; | ||||||
|  | 	if(off != NULL) { noff = *off; } | ||||||
|  | 
 | ||||||
|  | 	if(len <= noff) { | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); | ||||||
|  | 
 | ||||||
|  | 	template_context ctx; | ||||||
|  | 	template_init(&ctx); | ||||||
|  | 
 | ||||||
|  | 	ctx.user.z = z; | ||||||
|  | 	ctx.user.referenced = false; | ||||||
|  | 
 | ||||||
|  | 	int e = template_execute(&ctx, data, len, &noff); | ||||||
|  | 	if(e <= 0) { | ||||||
|  | 		msgpack_zone_free(z); | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if(off != NULL) { *off = noff; } | ||||||
|  | 
 | ||||||
|  | 	result->zone = z; | ||||||
|  | 	result->data = template_data(&ctx); | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										17
									
								
								cpp/src/version.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								cpp/src/version.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | #include "msgpack.h" | ||||||
|  |  | ||||||
|  | const char* msgpack_version(void) | ||||||
|  | { | ||||||
|  | 	return MSGPACK_VERSION; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int msgpack_version_major(void) | ||||||
|  | { | ||||||
|  | 	return MSGPACK_VERSION_MAJOR; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int msgpack_version_minor(void) | ||||||
|  | { | ||||||
|  | 	return MSGPACK_VERSION_MINOR; | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -30,7 +30,6 @@ bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf, | |||||||
| 	vbuf->chunk_size = chunk_size; | 	vbuf->chunk_size = chunk_size; | ||||||
| 	vbuf->ref_size = ref_size; | 	vbuf->ref_size = ref_size; | ||||||
| 
 | 
 | ||||||
| 	// glibcは72バイト以下のmallocが高速
 |  | ||||||
| 	size_t nfirst = (sizeof(struct iovec) < 72/2) ? | 	size_t nfirst = (sizeof(struct iovec) < 72/2) ? | ||||||
| 			72 / sizeof(struct iovec) : 8; | 			72 / sizeof(struct iovec) : 8; | ||||||
| 
 | 
 | ||||||
| @@ -76,6 +75,25 @@ void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf) | |||||||
| 	free(vbuf->array); | 	free(vbuf->array); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf) | ||||||
|  | { | ||||||
|  | 	msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next; | ||||||
|  | 	msgpack_vrefbuffer_chunk* n; | ||||||
|  | 	while(c != NULL) { | ||||||
|  | 		n = c->next; | ||||||
|  | 		free(c); | ||||||
|  | 		c = n; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; | ||||||
|  | 	msgpack_vrefbuffer_chunk* chunk = ib->head; | ||||||
|  | 	chunk->next = NULL; | ||||||
|  | 	ib->free = vbuf->chunk_size; | ||||||
|  | 	ib->ptr  = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk); | ||||||
|  | 
 | ||||||
|  | 	vbuf->tail = vbuf->array; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf, | int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf, | ||||||
| 		const char* buf, unsigned int len) | 		const char* buf, unsigned int len) | ||||||
| { | { | ||||||
| @@ -104,7 +104,6 @@ static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa) | |||||||
| 
 | 
 | ||||||
| static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa) | static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa) | ||||||
| { | { | ||||||
| 	// 逆順に呼び出し
 |  | ||||||
| 	msgpack_zone_finalizer* fin = fa->tail; | 	msgpack_zone_finalizer* fin = fa->tail; | ||||||
| 	for(; fin != fa->array; --fin) { | 	for(; fin != fa->array; --fin) { | ||||||
| 		(*(fin-1)->func)((fin-1)->data); | 		(*(fin-1)->func)((fin-1)->data); | ||||||
| @@ -132,9 +131,6 @@ bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone, | |||||||
| 
 | 
 | ||||||
| 	size_t nnext; | 	size_t nnext; | ||||||
| 	if(nused == 0) { | 	if(nused == 0) { | ||||||
| 		// 初回の呼び出し:fa->tail == fa->end == fa->array == NULL
 |  | ||||||
| 
 |  | ||||||
| 		// glibcは72バイト以下のmallocが高速
 |  | ||||||
| 		nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ? | 		nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ? | ||||||
| 				72 / sizeof(msgpack_zone_finalizer) : 8; | 				72 / sizeof(msgpack_zone_finalizer) : 8; | ||||||
| 
 | 
 | ||||||
| @@ -208,7 +204,7 @@ msgpack_zone* msgpack_zone_new(size_t chunk_size) | |||||||
| 
 | 
 | ||||||
| 	if(!init_chunk_list(&zone->chunk_list, chunk_size)) { | 	if(!init_chunk_list(&zone->chunk_list, chunk_size)) { | ||||||
| 		free(zone); | 		free(zone); | ||||||
| 		return false; | 		return NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	init_finalizer_array(&zone->finalizer_array); | 	init_finalizer_array(&zone->finalizer_array); | ||||||
| @@ -218,6 +214,7 @@ msgpack_zone* msgpack_zone_new(size_t chunk_size) | |||||||
| 
 | 
 | ||||||
| void msgpack_zone_free(msgpack_zone* zone) | void msgpack_zone_free(msgpack_zone* zone) | ||||||
| { | { | ||||||
|  | 	if(zone == NULL) { return; } | ||||||
| 	msgpack_zone_destroy(zone); | 	msgpack_zone_destroy(zone); | ||||||
| 	free(zone); | 	free(zone); | ||||||
| } | } | ||||||
| @@ -1,9 +0,0 @@ | |||||||
|  |  | ||||||
| CXXFLAGS  += -Wall -g -I. -I.. -O4 |  | ||||||
| LDFLAGS += |  | ||||||
|  |  | ||||||
| all: test |  | ||||||
|  |  | ||||||
| test: test.o unpack.o zone.o object.o pack.hpp unpack.hpp zone.hpp object.hpp |  | ||||||
| 	$(CXX) test.o unpack.o zone.o object.o $(CXXFLAGS) $(LDFLAGS) -o $@ |  | ||||||
|  |  | ||||||
							
								
								
									
										54
									
								
								cpp/test/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								cpp/test/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  |  | ||||||
|  | AM_CPPFLAGS   = -I../src | ||||||
|  | AM_C_CPPFLAGS = -I../src | ||||||
|  | AM_LDFLAGS = ../src/libmsgpack.la -lgtest_main | ||||||
|  |  | ||||||
|  | check_PROGRAMS = \ | ||||||
|  | 		zone \ | ||||||
|  | 		pack_unpack \ | ||||||
|  | 		pack_unpack_c \ | ||||||
|  | 		streaming \ | ||||||
|  | 		streaming_c \ | ||||||
|  | 		object \ | ||||||
|  | 		convert \ | ||||||
|  | 		buffer \ | ||||||
|  | 		cases \ | ||||||
|  | 		fixint \ | ||||||
|  | 		fixint_c \ | ||||||
|  | 		version \ | ||||||
|  | 		msgpackc_test \ | ||||||
|  | 		msgpack_test | ||||||
|  |  | ||||||
|  | TESTS = $(check_PROGRAMS) | ||||||
|  |  | ||||||
|  | zone_SOURCES = zone.cc | ||||||
|  |  | ||||||
|  | pack_unpack_SOURCES = pack_unpack.cc | ||||||
|  |  | ||||||
|  | pack_unpack_c_SOURCES = pack_unpack_c.cc | ||||||
|  |  | ||||||
|  | streaming_SOURCES = streaming.cc | ||||||
|  |  | ||||||
|  | streaming_c_SOURCES = streaming_c.cc | ||||||
|  |  | ||||||
|  | object_SOURCES = object.cc | ||||||
|  |  | ||||||
|  | convert_SOURCES = convert.cc | ||||||
|  |  | ||||||
|  | buffer_SOURCES = buffer.cc | ||||||
|  | buffer_LDADD = -lz | ||||||
|  |  | ||||||
|  | cases_SOURCES = cases.cc | ||||||
|  |  | ||||||
|  | fixint_SOURCES = fixint.cc | ||||||
|  |  | ||||||
|  | fixint_c_SOURCES = fixint_c.cc | ||||||
|  |  | ||||||
|  | version_SOURCES = version.cc | ||||||
|  |  | ||||||
|  | msgpackc_test_SOURCES = msgpackc_test.cpp | ||||||
|  |  | ||||||
|  | msgpack_test_SOURCES = msgpack_test.cpp | ||||||
|  |  | ||||||
|  | EXTRA_DIST = cases.mpac cases_compact.mpac | ||||||
|  |  | ||||||
							
								
								
									
										75
									
								
								cpp/test/buffer.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								cpp/test/buffer.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <msgpack/zbuffer.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | TEST(buffer, sbuffer) | ||||||
|  | { | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	sbuf.write("a", 1); | ||||||
|  | 	sbuf.write("a", 1); | ||||||
|  | 	sbuf.write("a", 1); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(3, sbuf.size()); | ||||||
|  | 	EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); | ||||||
|  |  | ||||||
|  | 	sbuf.clear(); | ||||||
|  | 	sbuf.write("a", 1); | ||||||
|  | 	sbuf.write("a", 1); | ||||||
|  | 	sbuf.write("a", 1); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(3, sbuf.size()); | ||||||
|  | 	EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(buffer, vrefbuffer) | ||||||
|  | { | ||||||
|  | 	msgpack::vrefbuffer vbuf; | ||||||
|  | 	vbuf.write("a", 1); | ||||||
|  | 	vbuf.write("a", 1); | ||||||
|  | 	vbuf.write("a", 1); | ||||||
|  |  | ||||||
|  | 	const struct iovec* vec = vbuf.vector(); | ||||||
|  | 	size_t veclen = vbuf.vector_size(); | ||||||
|  |  | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	for(size_t i=0; i < veclen; ++i) { | ||||||
|  | 		sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(3, sbuf.size()); | ||||||
|  | 	EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	vbuf.clear(); | ||||||
|  | 	vbuf.write("a", 1); | ||||||
|  | 	vbuf.write("a", 1); | ||||||
|  | 	vbuf.write("a", 1); | ||||||
|  |  | ||||||
|  | 	vec = vbuf.vector(); | ||||||
|  | 	veclen = vbuf.vector_size(); | ||||||
|  |  | ||||||
|  | 	sbuf.clear(); | ||||||
|  | 	for(size_t i=0; i < veclen; ++i) { | ||||||
|  | 		sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(3, sbuf.size()); | ||||||
|  | 	EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(buffer, zbuffer) | ||||||
|  | { | ||||||
|  | 	msgpack::zbuffer zbuf; | ||||||
|  | 	zbuf.write("a", 1); | ||||||
|  | 	zbuf.write("a", 1); | ||||||
|  | 	zbuf.write("a", 1); | ||||||
|  |  | ||||||
|  | 	zbuf.flush(); | ||||||
|  |  | ||||||
|  | 	char* data = zbuf.data(); | ||||||
|  | 	size_t size = zbuf.size(); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								cpp/test/cases.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								cpp/test/cases.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <fstream> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  |  | ||||||
|  | static void feed_file(msgpack::unpacker& pac, const char* path) | ||||||
|  | { | ||||||
|  | 	std::ifstream fin(path); | ||||||
|  | 	while(true) { | ||||||
|  | 		pac.reserve_buffer(32*1024); | ||||||
|  | 		fin.read(pac.buffer(), pac.buffer_capacity()); | ||||||
|  | 		if(fin.bad()) { | ||||||
|  | 			throw std::runtime_error("read failed"); | ||||||
|  | 		} | ||||||
|  | 		pac.buffer_consumed(fin.gcount()); | ||||||
|  | 		if(fin.fail()) { | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(cases, format) | ||||||
|  | { | ||||||
|  | 	msgpack::unpacker pac; | ||||||
|  | 	msgpack::unpacker pac_compact; | ||||||
|  |  | ||||||
|  | 	feed_file(pac, "cases.mpac"); | ||||||
|  | 	feed_file(pac_compact, "cases_compact.mpac"); | ||||||
|  |  | ||||||
|  | 	msgpack::unpacked result; | ||||||
|  | 	while(pac.next(&result)) { | ||||||
|  | 		msgpack::unpacked result_compact; | ||||||
|  | 		EXPECT_TRUE( pac_compact.next(&result_compact) ); | ||||||
|  | 		EXPECT_EQ(result_compact.get(), result.get()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	EXPECT_FALSE( pac_compact.next(&result) ); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										74
									
								
								cpp/test/convert.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								cpp/test/convert.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  |  | ||||||
|  | class compatibility { | ||||||
|  | public: | ||||||
|  | 	compatibility() : str1("default"), str2("default") { } | ||||||
|  |  | ||||||
|  | 	std::string str1; | ||||||
|  | 	std::string str2; | ||||||
|  |  | ||||||
|  | 	MSGPACK_DEFINE(str1, str2); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | TEST(convert, compatibility_less) | ||||||
|  | { | ||||||
|  | 	std::vector<std::string> src(1); | ||||||
|  | 	src[0] = "kumofs"; | ||||||
|  |  | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	msgpack::object obj(src, &z); | ||||||
|  |  | ||||||
|  | 	compatibility c; | ||||||
|  | 	EXPECT_NO_THROW( obj.convert(&c) ); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ("kumofs",  c.str1); | ||||||
|  | 	EXPECT_EQ("default", c.str2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(convert, compatibility_more) | ||||||
|  | { | ||||||
|  | 	std::vector<std::string> src(3); | ||||||
|  | 	src[0] = "kumofs"; | ||||||
|  | 	src[1] = "mpio"; | ||||||
|  | 	src[2] = "cloudy"; | ||||||
|  |  | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	msgpack::object obj(src, &z); | ||||||
|  |  | ||||||
|  | 	compatibility to; | ||||||
|  | 	EXPECT_NO_THROW( obj.convert(&to) ); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ("kumofs", to.str1); | ||||||
|  | 	EXPECT_EQ("mpio",   to.str2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class enum_member { | ||||||
|  | public: | ||||||
|  | 	enum_member() : flag(A) { } | ||||||
|  |  | ||||||
|  | 	enum flags_t { | ||||||
|  | 		A = 0, | ||||||
|  | 		B = 1, | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	flags_t flag; | ||||||
|  |  | ||||||
|  | 	MSGPACK_DEFINE((int&)flag); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | TEST(convert, enum_member) | ||||||
|  | { | ||||||
|  | 	enum_member src; | ||||||
|  | 	src.flag = enum_member::B; | ||||||
|  |  | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	msgpack::object obj(src, &z); | ||||||
|  |  | ||||||
|  | 	enum_member to; | ||||||
|  | 	EXPECT_NO_THROW( obj.convert(&to) ); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(enum_member::B, to.flag); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										55
									
								
								cpp/test/fixint.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								cpp/test/fixint.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  |  | ||||||
|  | template <typename T> | ||||||
|  | void check_size(size_t size) { | ||||||
|  | 	T v(0); | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	msgpack::pack(sbuf, v); | ||||||
|  | 	EXPECT_EQ(size, sbuf.size()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(fixint, size) | ||||||
|  | { | ||||||
|  | 	check_size<msgpack::type::fix_int8>(2); | ||||||
|  | 	check_size<msgpack::type::fix_int16>(3); | ||||||
|  | 	check_size<msgpack::type::fix_int32>(5); | ||||||
|  | 	check_size<msgpack::type::fix_int64>(9); | ||||||
|  |  | ||||||
|  | 	check_size<msgpack::type::fix_uint8>(2); | ||||||
|  | 	check_size<msgpack::type::fix_uint16>(3); | ||||||
|  | 	check_size<msgpack::type::fix_uint32>(5); | ||||||
|  | 	check_size<msgpack::type::fix_uint64>(9); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | template <typename T> | ||||||
|  | void check_convert() { | ||||||
|  | 	T v1(-11); | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	msgpack::pack(sbuf, v1); | ||||||
|  |  | ||||||
|  | 	msgpack::unpacked msg; | ||||||
|  | 	msgpack::unpack(&msg, sbuf.data(), sbuf.size()); | ||||||
|  |  | ||||||
|  | 	T v2; | ||||||
|  | 	msg.get().convert(&v2); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(v1.get(), v2.get()); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(msg.get(), msgpack::object(T(v1.get()))); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(fixint, convert) | ||||||
|  | { | ||||||
|  | 	check_convert<msgpack::type::fix_int8>(); | ||||||
|  | 	check_convert<msgpack::type::fix_int16>(); | ||||||
|  | 	check_convert<msgpack::type::fix_int32>(); | ||||||
|  | 	check_convert<msgpack::type::fix_int64>(); | ||||||
|  |  | ||||||
|  | 	check_convert<msgpack::type::fix_uint8>(); | ||||||
|  | 	check_convert<msgpack::type::fix_uint16>(); | ||||||
|  | 	check_convert<msgpack::type::fix_uint32>(); | ||||||
|  | 	check_convert<msgpack::type::fix_uint64>(); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										32
									
								
								cpp/test/fixint_c.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								cpp/test/fixint_c.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  |  | ||||||
|  | TEST(fixint, size) | ||||||
|  | { | ||||||
|  | 	msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); | ||||||
|  | 	msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); | ||||||
|  |  | ||||||
|  | 	size_t sum = 0; | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_fix_int8(pk, 0)); | ||||||
|  | 	EXPECT_EQ(sum+=2, sbuf->size); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_fix_int16(pk, 0)); | ||||||
|  | 	EXPECT_EQ(sum+=3, sbuf->size); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_fix_int32(pk, 0)); | ||||||
|  | 	EXPECT_EQ(sum+=5, sbuf->size); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_fix_int64(pk, 0)); | ||||||
|  | 	EXPECT_EQ(sum+=9, sbuf->size); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_fix_uint8(pk, 0)); | ||||||
|  | 	EXPECT_EQ(sum+=2, sbuf->size); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_fix_uint16(pk, 0)); | ||||||
|  | 	EXPECT_EQ(sum+=3, sbuf->size); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_fix_uint32(pk, 0)); | ||||||
|  | 	EXPECT_EQ(sum+=5, sbuf->size); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_fix_uint64(pk, 0)); | ||||||
|  | 	EXPECT_EQ(sum+=9, sbuf->size); | ||||||
|  |  | ||||||
|  | 	msgpack_sbuffer_free(sbuf); | ||||||
|  | 	msgpack_packer_free(pk); | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -10,6 +10,10 @@ | |||||||
| 
 | 
 | ||||||
| #include <gtest/gtest.h> | #include <gtest/gtest.h> | ||||||
| 
 | 
 | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "config.h" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| using namespace std; | using namespace std; | ||||||
| 
 | 
 | ||||||
| const unsigned int kLoop = 10000; | const unsigned int kLoop = 10000; | ||||||
| @@ -227,6 +231,8 @@ TEST(MSGPACK, simple_buffer_false) | |||||||
| 
 | 
 | ||||||
| //-----------------------------------------------------------------------------
 | //-----------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|  | // STL
 | ||||||
|  | 
 | ||||||
| TEST(MSGPACK_STL, simple_buffer_string) | TEST(MSGPACK_STL, simple_buffer_string) | ||||||
| { | { | ||||||
|   for (unsigned int k = 0; k < kLoop; k++) { |   for (unsigned int k = 0; k < kLoop; k++) { | ||||||
| @@ -365,6 +371,190 @@ TEST(MSGPACK_STL, simple_buffer_pair) | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | TEST(MSGPACK_STL, simple_buffer_multimap) | ||||||
|  | { | ||||||
|  |   for (unsigned int k = 0; k < kLoop; k++) { | ||||||
|  |     multimap<int, int> val1; | ||||||
|  |     for (unsigned int i = 0; i < kElements; i++) { | ||||||
|  |       int i1 = rand(); | ||||||
|  |       val1.insert(make_pair(i1, rand())); | ||||||
|  |       val1.insert(make_pair(i1, rand())); | ||||||
|  |     } | ||||||
|  |     msgpack::sbuffer sbuf; | ||||||
|  |     msgpack::pack(sbuf, val1); | ||||||
|  |     msgpack::zone z; | ||||||
|  |     msgpack::object obj; | ||||||
|  |     msgpack::unpack_return ret = | ||||||
|  |       msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  |     EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); | ||||||
|  |     multimap<int, int> val2; | ||||||
|  |     obj.convert(&val2); | ||||||
|  | 
 | ||||||
|  |     vector<pair<int, int> > v1, v2; | ||||||
|  |     multimap<int, int>::const_iterator it; | ||||||
|  |     for (it = val1.begin(); it != val1.end(); ++it) | ||||||
|  |       v1.push_back(make_pair(it->first, it->second)); | ||||||
|  |     for (it = val2.begin(); it != val2.end(); ++it) | ||||||
|  |       v2.push_back(make_pair(it->first, it->second)); | ||||||
|  |     EXPECT_EQ(val1.size(), val2.size()); | ||||||
|  |     EXPECT_EQ(v1.size(), v2.size()); | ||||||
|  |     sort(v1.begin(), v1.end()); | ||||||
|  |     sort(v2.begin(), v2.end()); | ||||||
|  |     EXPECT_TRUE(v1 == v2); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TEST(MSGPACK_STL, simple_buffer_multiset) | ||||||
|  | { | ||||||
|  |   for (unsigned int k = 0; k < kLoop; k++) { | ||||||
|  |     multiset<int> val1; | ||||||
|  |     for (unsigned int i = 0; i < kElements; i++) | ||||||
|  |       val1.insert(rand()); | ||||||
|  |     msgpack::sbuffer sbuf; | ||||||
|  |     msgpack::pack(sbuf, val1); | ||||||
|  |     msgpack::zone z; | ||||||
|  |     msgpack::object obj; | ||||||
|  |     msgpack::unpack_return ret = | ||||||
|  |       msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  |     EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); | ||||||
|  |     multiset<int> val2; | ||||||
|  |     obj.convert(&val2); | ||||||
|  | 
 | ||||||
|  |     vector<int> v1, v2; | ||||||
|  |     multiset<int>::const_iterator it; | ||||||
|  |     for (it = val1.begin(); it != val1.end(); ++it) | ||||||
|  |       v1.push_back(*it); | ||||||
|  |     for (it = val2.begin(); it != val2.end(); ++it) | ||||||
|  |       v2.push_back(*it); | ||||||
|  |     EXPECT_EQ(val1.size(), val2.size()); | ||||||
|  |     EXPECT_EQ(v1.size(), v2.size()); | ||||||
|  |     sort(v1.begin(), v1.end()); | ||||||
|  |     sort(v2.begin(), v2.end()); | ||||||
|  |     EXPECT_TRUE(v1 == v2); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TR1
 | ||||||
|  | 
 | ||||||
|  | #ifdef HAVE_TR1_UNORDERED_MAP | ||||||
|  | #include <tr1/unordered_map> | ||||||
|  | #include "msgpack/type/tr1/unordered_map.hpp" | ||||||
|  | TEST(MSGPACK_TR1, simple_buffer_unordered_map) | ||||||
|  | { | ||||||
|  |   for (unsigned int k = 0; k < kLoop; k++) { | ||||||
|  |     tr1::unordered_map<int, int> val1; | ||||||
|  |     for (unsigned int i = 0; i < kElements; i++) | ||||||
|  |       val1[rand()] = rand(); | ||||||
|  |     msgpack::sbuffer sbuf; | ||||||
|  |     msgpack::pack(sbuf, val1); | ||||||
|  |     msgpack::zone z; | ||||||
|  |     msgpack::object obj; | ||||||
|  |     msgpack::unpack_return ret = | ||||||
|  |       msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  |     EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); | ||||||
|  |     tr1::unordered_map<int, int> val2; | ||||||
|  |     obj.convert(&val2); | ||||||
|  |     EXPECT_EQ(val1.size(), val2.size()); | ||||||
|  |     tr1::unordered_map<int, int>::const_iterator it; | ||||||
|  |     for (it = val1.begin(); it != val1.end(); ++it) { | ||||||
|  |       EXPECT_TRUE(val2.find(it->first) != val2.end()); | ||||||
|  |       EXPECT_EQ(it->second, val2.find(it->first)->second); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TEST(MSGPACK_TR1, simple_buffer_unordered_multimap) | ||||||
|  | { | ||||||
|  |   for (unsigned int k = 0; k < kLoop; k++) { | ||||||
|  |     tr1::unordered_multimap<int, int> val1; | ||||||
|  |     for (unsigned int i = 0; i < kElements; i++) { | ||||||
|  |       int i1 = rand(); | ||||||
|  |       val1.insert(make_pair(i1, rand())); | ||||||
|  |       val1.insert(make_pair(i1, rand())); | ||||||
|  |     } | ||||||
|  |     msgpack::sbuffer sbuf; | ||||||
|  |     msgpack::pack(sbuf, val1); | ||||||
|  |     msgpack::zone z; | ||||||
|  |     msgpack::object obj; | ||||||
|  |     msgpack::unpack_return ret = | ||||||
|  |       msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  |     EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); | ||||||
|  |     tr1::unordered_multimap<int, int> val2; | ||||||
|  |     obj.convert(&val2); | ||||||
|  | 
 | ||||||
|  |     vector<pair<int, int> > v1, v2; | ||||||
|  |     tr1::unordered_multimap<int, int>::const_iterator it; | ||||||
|  |     for (it = val1.begin(); it != val1.end(); ++it) | ||||||
|  |       v1.push_back(make_pair(it->first, it->second)); | ||||||
|  |     for (it = val2.begin(); it != val2.end(); ++it) | ||||||
|  |       v2.push_back(make_pair(it->first, it->second)); | ||||||
|  |     EXPECT_EQ(val1.size(), val2.size()); | ||||||
|  |     EXPECT_EQ(v1.size(), v2.size()); | ||||||
|  |     sort(v1.begin(), v1.end()); | ||||||
|  |     sort(v2.begin(), v2.end()); | ||||||
|  |     EXPECT_TRUE(v1 == v2); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef HAVE_TR1_UNORDERED_SET | ||||||
|  | #include <tr1/unordered_set> | ||||||
|  | #include "msgpack/type/tr1/unordered_set.hpp" | ||||||
|  | TEST(MSGPACK_TR1, simple_buffer_unordered_set) | ||||||
|  | { | ||||||
|  |   for (unsigned int k = 0; k < kLoop; k++) { | ||||||
|  |     tr1::unordered_set<int> val1; | ||||||
|  |     for (unsigned int i = 0; i < kElements; i++) | ||||||
|  |       val1.insert(rand()); | ||||||
|  |     msgpack::sbuffer sbuf; | ||||||
|  |     msgpack::pack(sbuf, val1); | ||||||
|  |     msgpack::zone z; | ||||||
|  |     msgpack::object obj; | ||||||
|  |     msgpack::unpack_return ret = | ||||||
|  |       msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  |     EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); | ||||||
|  |     tr1::unordered_set<int> val2; | ||||||
|  |     obj.convert(&val2); | ||||||
|  |     EXPECT_EQ(val1.size(), val2.size()); | ||||||
|  |     tr1::unordered_set<int>::const_iterator it; | ||||||
|  |     for (it = val1.begin(); it != val1.end(); ++it) | ||||||
|  |       EXPECT_TRUE(val2.find(*it) != val2.end()); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TEST(MSGPACK_TR1, simple_buffer_unordered_multiset) | ||||||
|  | { | ||||||
|  |   for (unsigned int k = 0; k < kLoop; k++) { | ||||||
|  |     tr1::unordered_multiset<int> val1; | ||||||
|  |     for (unsigned int i = 0; i < kElements; i++) | ||||||
|  |       val1.insert(rand()); | ||||||
|  |     msgpack::sbuffer sbuf; | ||||||
|  |     msgpack::pack(sbuf, val1); | ||||||
|  |     msgpack::zone z; | ||||||
|  |     msgpack::object obj; | ||||||
|  |     msgpack::unpack_return ret = | ||||||
|  |       msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  |     EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); | ||||||
|  |     tr1::unordered_multiset<int> val2; | ||||||
|  |     obj.convert(&val2); | ||||||
|  | 
 | ||||||
|  |     vector<int> v1, v2; | ||||||
|  |     tr1::unordered_multiset<int>::const_iterator it; | ||||||
|  |     for (it = val1.begin(); it != val1.end(); ++it) | ||||||
|  |       v1.push_back(*it); | ||||||
|  |     for (it = val2.begin(); it != val2.end(); ++it) | ||||||
|  |       v2.push_back(*it); | ||||||
|  |     EXPECT_EQ(val1.size(), val2.size()); | ||||||
|  |     EXPECT_EQ(v1.size(), v2.size()); | ||||||
|  |     sort(v1.begin(), v1.end()); | ||||||
|  |     sort(v2.begin(), v2.end()); | ||||||
|  |     EXPECT_TRUE(v1 == v2); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | // User-Defined Structures
 | ||||||
|  | 
 | ||||||
| class TestClass | class TestClass | ||||||
| { | { | ||||||
| public: | public: | ||||||
							
								
								
									
										134
									
								
								cpp/test/object.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								cpp/test/object.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  |  | ||||||
|  | struct myclass { | ||||||
|  | 	myclass() : num(0), str("default") { } | ||||||
|  |  | ||||||
|  | 	myclass(int num, const std::string& str) : | ||||||
|  | 		num(0), str("default") { } | ||||||
|  |  | ||||||
|  | 	~myclass() { } | ||||||
|  |  | ||||||
|  | 	int num; | ||||||
|  | 	std::string str; | ||||||
|  |  | ||||||
|  | 	MSGPACK_DEFINE(num, str); | ||||||
|  |  | ||||||
|  | 	bool operator==(const myclass& o) const | ||||||
|  | 	{ | ||||||
|  | 		return num == o.num && str == o.str; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | std::ostream& operator<<(std::ostream& o, const myclass& m) | ||||||
|  | { | ||||||
|  | 	return o << "myclass("<<m.num<<",\""<<m.str<<"\")"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(object, convert) | ||||||
|  | { | ||||||
|  | 	myclass m1; | ||||||
|  |  | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	msgpack::pack(sbuf, m1); | ||||||
|  |  | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	msgpack::object obj; | ||||||
|  |  | ||||||
|  | 	msgpack::unpack_return ret = | ||||||
|  | 		msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  | 	EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); | ||||||
|  |  | ||||||
|  | 	myclass m2; | ||||||
|  | 	obj.convert(&m2); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(m1, m2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(object, as) | ||||||
|  | { | ||||||
|  | 	myclass m1; | ||||||
|  |  | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	msgpack::pack(sbuf, m1); | ||||||
|  |  | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	msgpack::object obj; | ||||||
|  |  | ||||||
|  | 	msgpack::unpack_return ret = | ||||||
|  | 		msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  | 	EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(m1, obj.as<myclass>()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(object, print) | ||||||
|  | { | ||||||
|  | 	msgpack::object obj; | ||||||
|  | 	std::cout << obj << std::endl; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(object, is_nil) | ||||||
|  | { | ||||||
|  | 	msgpack::object obj; | ||||||
|  | 	EXPECT_TRUE(obj.is_nil()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(object, type_error) | ||||||
|  | { | ||||||
|  | 	msgpack::object obj(1); | ||||||
|  | 	EXPECT_THROW(obj.as<std::string>(), msgpack::type_error); | ||||||
|  | 	EXPECT_THROW(obj.as<std::vector<int> >(), msgpack::type_error); | ||||||
|  | 	EXPECT_EQ(1, obj.as<int>()); | ||||||
|  | 	EXPECT_EQ(1, obj.as<short>()); | ||||||
|  | 	EXPECT_EQ(1u, obj.as<unsigned int>()); | ||||||
|  | 	EXPECT_EQ(1u, obj.as<unsigned long>()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(object, equal_primitive) | ||||||
|  | { | ||||||
|  | 	msgpack::object obj_nil; | ||||||
|  | 	EXPECT_EQ(obj_nil, msgpack::object()); | ||||||
|  |  | ||||||
|  | 	msgpack::object obj_int(1); | ||||||
|  | 	EXPECT_EQ(obj_int, msgpack::object(1)); | ||||||
|  | 	EXPECT_EQ(obj_int, 1); | ||||||
|  |  | ||||||
|  | 	msgpack::object obj_double(1.2); | ||||||
|  | 	EXPECT_EQ(obj_double, msgpack::object(1.2)); | ||||||
|  | 	EXPECT_EQ(obj_double, 1.2); | ||||||
|  |  | ||||||
|  | 	msgpack::object obj_bool(true); | ||||||
|  | 	EXPECT_EQ(obj_bool, msgpack::object(true)); | ||||||
|  | 	EXPECT_EQ(obj_bool, true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(object, construct_primitive) | ||||||
|  | { | ||||||
|  | 	msgpack::object obj_nil; | ||||||
|  | 	EXPECT_EQ(msgpack::type::NIL, obj_nil.type); | ||||||
|  |  | ||||||
|  | 	msgpack::object obj_uint(1); | ||||||
|  | 	EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type); | ||||||
|  | 	EXPECT_EQ(1u, obj_uint.via.u64); | ||||||
|  |  | ||||||
|  | 	msgpack::object obj_int(-1); | ||||||
|  | 	EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type); | ||||||
|  | 	EXPECT_EQ(-1, obj_int.via.i64); | ||||||
|  |  | ||||||
|  | 	msgpack::object obj_double(1.2); | ||||||
|  | 	EXPECT_EQ(msgpack::type::DOUBLE, obj_double.type); | ||||||
|  | 	EXPECT_EQ(1.2, obj_double.via.dec); | ||||||
|  |  | ||||||
|  | 	msgpack::object obj_bool(true); | ||||||
|  | 	EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type); | ||||||
|  | 	EXPECT_EQ(true, obj_bool.via.boolean); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										123
									
								
								cpp/test/pack_unpack.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								cpp/test/pack_unpack.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include <sstream> | ||||||
|  |  | ||||||
|  | TEST(pack, num) | ||||||
|  | { | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	msgpack::pack(sbuf, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(pack, vector) | ||||||
|  | { | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	std::vector<int> vec; | ||||||
|  | 	vec.push_back(1); | ||||||
|  | 	vec.push_back(2); | ||||||
|  | 	vec.push_back(3); | ||||||
|  | 	msgpack::pack(sbuf, vec); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(pack, to_ostream) | ||||||
|  | { | ||||||
|  | 	std::ostringstream stream; | ||||||
|  | 	msgpack::pack(stream, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | struct myclass { | ||||||
|  | 	myclass() : num(0), str("default") { } | ||||||
|  |  | ||||||
|  | 	myclass(int num, const std::string& str) : | ||||||
|  | 		num(0), str("default") { } | ||||||
|  |  | ||||||
|  | 	~myclass() { } | ||||||
|  |  | ||||||
|  | 	int num; | ||||||
|  | 	std::string str; | ||||||
|  |  | ||||||
|  | 	MSGPACK_DEFINE(num, str); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(pack, myclass) | ||||||
|  | { | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	myclass m(1, "msgpack"); | ||||||
|  | 	msgpack::pack(sbuf, m); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(unpack, myclass) | ||||||
|  | { | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	myclass m1(1, "phraser"); | ||||||
|  | 	msgpack::pack(sbuf, m1); | ||||||
|  |  | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	msgpack::object obj; | ||||||
|  |  | ||||||
|  | 	msgpack::unpack_return ret = | ||||||
|  | 		msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); | ||||||
|  |  | ||||||
|  | 	myclass m2 = obj.as<myclass>(); | ||||||
|  | 	EXPECT_EQ(m1.num, m2.num); | ||||||
|  | 	EXPECT_EQ(m1.str, m2.str); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(unpack, sequence) | ||||||
|  | { | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	msgpack::pack(sbuf, 1); | ||||||
|  | 	msgpack::pack(sbuf, 2); | ||||||
|  | 	msgpack::pack(sbuf, 3); | ||||||
|  |  | ||||||
|  | 	size_t offset = 0; | ||||||
|  |  | ||||||
|  | 	msgpack::unpacked msg; | ||||||
|  |  | ||||||
|  | 	msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); | ||||||
|  | 	EXPECT_EQ(1, msg.get().as<int>()); | ||||||
|  |  | ||||||
|  | 	msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); | ||||||
|  | 	EXPECT_EQ(2, msg.get().as<int>()); | ||||||
|  |  | ||||||
|  | 	msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); | ||||||
|  | 	EXPECT_EQ(3, msg.get().as<int>()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(unpack, sequence_compat) | ||||||
|  | { | ||||||
|  | 	msgpack::sbuffer sbuf; | ||||||
|  | 	msgpack::pack(sbuf, 1); | ||||||
|  | 	msgpack::pack(sbuf, 2); | ||||||
|  | 	msgpack::pack(sbuf, 3); | ||||||
|  |  | ||||||
|  | 	size_t offset = 0; | ||||||
|  |  | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	msgpack::object obj; | ||||||
|  | 	msgpack::unpack_return ret; | ||||||
|  |  | ||||||
|  | 	ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); | ||||||
|  | 	EXPECT_TRUE(ret >= 0); | ||||||
|  | 	EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES); | ||||||
|  | 	EXPECT_EQ(1, obj.as<int>()); | ||||||
|  |  | ||||||
|  | 	ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); | ||||||
|  | 	EXPECT_TRUE(ret >= 0); | ||||||
|  | 	EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES); | ||||||
|  | 	EXPECT_EQ(2, obj.as<int>()); | ||||||
|  |  | ||||||
|  | 	ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); | ||||||
|  | 	EXPECT_TRUE(ret >= 0); | ||||||
|  | 	EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); | ||||||
|  | 	EXPECT_EQ(3, obj.as<int>()); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										70
									
								
								cpp/test/pack_unpack_c.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								cpp/test/pack_unpack_c.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | #include <msgpack.h> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | TEST(pack, num) | ||||||
|  | { | ||||||
|  | 	msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); | ||||||
|  | 	msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 1)); | ||||||
|  |  | ||||||
|  | 	msgpack_sbuffer_free(sbuf); | ||||||
|  | 	msgpack_packer_free(pk); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(pack, array) | ||||||
|  | { | ||||||
|  | 	msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); | ||||||
|  | 	msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_array(pk, 3)); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 1)); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 2)); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 3)); | ||||||
|  |  | ||||||
|  | 	msgpack_sbuffer_free(sbuf); | ||||||
|  | 	msgpack_packer_free(pk); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(unpack, sequence) | ||||||
|  | { | ||||||
|  | 	msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); | ||||||
|  | 	msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); | ||||||
|  |  | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 1)); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 2)); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 3)); | ||||||
|  |  | ||||||
|  | 	msgpack_packer_free(pk); | ||||||
|  |  | ||||||
|  | 	bool success; | ||||||
|  | 	size_t offset = 0; | ||||||
|  |  | ||||||
|  | 	msgpack_unpacked msg; | ||||||
|  | 	msgpack_unpacked_init(&msg); | ||||||
|  |  | ||||||
|  | 	success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); | ||||||
|  | 	EXPECT_TRUE(success); | ||||||
|  | 	EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); | ||||||
|  | 	EXPECT_EQ(1, msg.data.via.u64); | ||||||
|  |  | ||||||
|  | 	success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); | ||||||
|  | 	EXPECT_TRUE(success); | ||||||
|  | 	EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); | ||||||
|  | 	EXPECT_EQ(2, msg.data.via.u64); | ||||||
|  |  | ||||||
|  | 	success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); | ||||||
|  | 	EXPECT_TRUE(success); | ||||||
|  | 	EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); | ||||||
|  | 	EXPECT_EQ(3, msg.data.via.u64); | ||||||
|  |  | ||||||
|  | 	success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); | ||||||
|  | 	EXPECT_FALSE(success); | ||||||
|  |  | ||||||
|  | 	msgpack_sbuffer_free(sbuf); | ||||||
|  | 	msgpack_unpacked_destroy(&msg); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										220
									
								
								cpp/test/streaming.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								cpp/test/streaming.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,220 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include <sstream> | ||||||
|  |  | ||||||
|  | TEST(streaming, basic) | ||||||
|  | { | ||||||
|  | 	msgpack::sbuffer buffer; | ||||||
|  |  | ||||||
|  | 	msgpack::packer<msgpack::sbuffer> pk(&buffer); | ||||||
|  | 	pk.pack(1); | ||||||
|  | 	pk.pack(2); | ||||||
|  | 	pk.pack(3); | ||||||
|  |  | ||||||
|  | 	const char* input = buffer.data(); | ||||||
|  | 	const char* const eof = input + buffer.size(); | ||||||
|  |  | ||||||
|  | 	msgpack::unpacker pac; | ||||||
|  | 	msgpack::unpacked result; | ||||||
|  |  | ||||||
|  | 	int count = 0; | ||||||
|  | 	while(count < 3) { | ||||||
|  | 		pac.reserve_buffer(32*1024); | ||||||
|  |  | ||||||
|  | 		// read buffer into pac.buffer() upto | ||||||
|  | 		// pac.buffer_capacity() bytes. | ||||||
|  | 		size_t len = 1; | ||||||
|  | 		memcpy(pac.buffer(), input, len); | ||||||
|  | 		input += len; | ||||||
|  |  | ||||||
|  | 		pac.buffer_consumed(len); | ||||||
|  |  | ||||||
|  | 		while(pac.next(&result)) { | ||||||
|  | 			msgpack::object obj = result.get(); | ||||||
|  | 			switch(count++) { | ||||||
|  | 			case 0: | ||||||
|  | 				EXPECT_EQ(1, obj.as<int>()); | ||||||
|  | 				break; | ||||||
|  | 			case 1: | ||||||
|  | 				EXPECT_EQ(2, obj.as<int>()); | ||||||
|  | 				break; | ||||||
|  | 			case 2: | ||||||
|  | 				EXPECT_EQ(3, obj.as<int>()); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		EXPECT_TRUE(input < eof); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class event_handler { | ||||||
|  | public: | ||||||
|  | 	event_handler(std::istream& input) : input(input) { } | ||||||
|  | 	~event_handler() { } | ||||||
|  |  | ||||||
|  | 	void on_read() | ||||||
|  | 	{ | ||||||
|  | 		while(true) { | ||||||
|  | 			pac.reserve_buffer(32*1024); | ||||||
|  |  | ||||||
|  | 			size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); | ||||||
|  |  | ||||||
|  | 			if(len == 0) { | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			pac.buffer_consumed(len); | ||||||
|  |  | ||||||
|  | 			msgpack::unpacked result; | ||||||
|  | 			while(pac.next(&result)) { | ||||||
|  | 				on_message(result.get(), result.zone()); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if(pac.message_size() > 10*1024*1024) { | ||||||
|  | 				throw std::runtime_error("message is too large"); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void on_message(msgpack::object obj, std::auto_ptr<msgpack::zone> z) | ||||||
|  | 	{ | ||||||
|  | 		EXPECT_EQ(expect, obj.as<int>()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	int expect; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	std::istream& input; | ||||||
|  | 	msgpack::unpacker pac; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | TEST(streaming, event) | ||||||
|  | { | ||||||
|  | 	std::stringstream stream; | ||||||
|  | 	msgpack::packer<std::ostream> pk(&stream); | ||||||
|  |  | ||||||
|  | 	event_handler handler(stream); | ||||||
|  |  | ||||||
|  | 	pk.pack(1); | ||||||
|  | 	handler.expect = 1; | ||||||
|  | 	handler.on_read(); | ||||||
|  |  | ||||||
|  | 	pk.pack(2); | ||||||
|  | 	handler.expect = 2; | ||||||
|  | 	handler.on_read(); | ||||||
|  |  | ||||||
|  | 	pk.pack(3); | ||||||
|  | 	handler.expect = 3; | ||||||
|  | 	handler.on_read(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // backward compatibility | ||||||
|  | TEST(streaming, basic_compat) | ||||||
|  | { | ||||||
|  | 	std::ostringstream stream; | ||||||
|  | 	msgpack::packer<std::ostream> pk(&stream); | ||||||
|  |  | ||||||
|  | 	pk.pack(1); | ||||||
|  | 	pk.pack(2); | ||||||
|  | 	pk.pack(3); | ||||||
|  |  | ||||||
|  | 	std::istringstream input(stream.str()); | ||||||
|  |  | ||||||
|  | 	msgpack::unpacker pac; | ||||||
|  |  | ||||||
|  | 	int count = 0; | ||||||
|  | 	while(count < 3) { | ||||||
|  | 		pac.reserve_buffer(32*1024); | ||||||
|  |  | ||||||
|  | 		size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); | ||||||
|  | 		pac.buffer_consumed(len); | ||||||
|  |  | ||||||
|  | 		while(pac.execute()) { | ||||||
|  | 			std::auto_ptr<msgpack::zone> z(pac.release_zone()); | ||||||
|  | 			msgpack::object obj = pac.data(); | ||||||
|  | 			pac.reset(); | ||||||
|  |  | ||||||
|  | 			switch(count++) { | ||||||
|  | 			case 0: | ||||||
|  | 				EXPECT_EQ(1, obj.as<int>()); | ||||||
|  | 				break; | ||||||
|  | 			case 1: | ||||||
|  | 				EXPECT_EQ(2, obj.as<int>()); | ||||||
|  | 				break; | ||||||
|  | 			case 2: | ||||||
|  | 				EXPECT_EQ(3, obj.as<int>()); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // backward compatibility | ||||||
|  | class event_handler_compat { | ||||||
|  | public: | ||||||
|  | 	event_handler_compat(std::istream& input) : input(input) { } | ||||||
|  | 	~event_handler_compat() { } | ||||||
|  |  | ||||||
|  | 	void on_read() | ||||||
|  | 	{ | ||||||
|  | 		while(true) { | ||||||
|  | 			pac.reserve_buffer(32*1024); | ||||||
|  |  | ||||||
|  | 			size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); | ||||||
|  |  | ||||||
|  | 			if(len == 0) { | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			pac.buffer_consumed(len); | ||||||
|  |  | ||||||
|  | 			while(pac.execute()) { | ||||||
|  | 				std::auto_ptr<msgpack::zone> z(pac.release_zone()); | ||||||
|  | 				msgpack::object obj = pac.data(); | ||||||
|  | 				pac.reset(); | ||||||
|  | 				on_message(obj, z); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if(pac.message_size() > 10*1024*1024) { | ||||||
|  | 				throw std::runtime_error("message is too large"); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void on_message(msgpack::object obj, std::auto_ptr<msgpack::zone> z) | ||||||
|  | 	{ | ||||||
|  | 		EXPECT_EQ(expect, obj.as<int>()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	int expect; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	std::istream& input; | ||||||
|  | 	msgpack::unpacker pac; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | TEST(streaming, event_compat) | ||||||
|  | { | ||||||
|  | 	std::stringstream stream; | ||||||
|  | 	msgpack::packer<std::ostream> pk(&stream); | ||||||
|  |  | ||||||
|  | 	event_handler_compat handler(stream); | ||||||
|  |  | ||||||
|  | 	pk.pack(1); | ||||||
|  | 	handler.expect = 1; | ||||||
|  | 	handler.on_read(); | ||||||
|  |  | ||||||
|  | 	pk.pack(2); | ||||||
|  | 	handler.expect = 2; | ||||||
|  | 	handler.on_read(); | ||||||
|  |  | ||||||
|  | 	pk.pack(3); | ||||||
|  | 	handler.expect = 3; | ||||||
|  | 	handler.on_read(); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										57
									
								
								cpp/test/streaming_c.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								cpp/test/streaming_c.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | #include <msgpack.h> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | TEST(streaming, basic) | ||||||
|  | { | ||||||
|  | 	msgpack_sbuffer* buffer = msgpack_sbuffer_new(); | ||||||
|  |  | ||||||
|  | 	msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 1)); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 2)); | ||||||
|  | 	EXPECT_EQ(0, msgpack_pack_int(pk, 3)); | ||||||
|  | 	msgpack_packer_free(pk); | ||||||
|  |  | ||||||
|  | 	const char* input = buffer->data; | ||||||
|  | 	const char* const eof = input + buffer->size; | ||||||
|  |  | ||||||
|  | 	msgpack_unpacker pac; | ||||||
|  | 	msgpack_unpacker_init(&pac, MSGPACK_UNPACKER_INIT_BUFFER_SIZE); | ||||||
|  |  | ||||||
|  | 	msgpack_unpacked result; | ||||||
|  | 	msgpack_unpacked_init(&result); | ||||||
|  |  | ||||||
|  | 	int count = 0; | ||||||
|  | 	while(count < 3) { | ||||||
|  | 		msgpack_unpacker_reserve_buffer(&pac, 32*1024); | ||||||
|  |  | ||||||
|  | 		/* read buffer into msgpack_unapcker_buffer(&pac) upto | ||||||
|  | 		 * msgpack_unpacker_buffer_capacity(&pac) bytes. */ | ||||||
|  | 		size_t len = 1; | ||||||
|  | 		memcpy(msgpack_unpacker_buffer(&pac), input, len); | ||||||
|  | 		input += len; | ||||||
|  |  | ||||||
|  | 		msgpack_unpacker_buffer_consumed(&pac, len); | ||||||
|  |  | ||||||
|  | 		while(msgpack_unpacker_next(&pac, &result)) { | ||||||
|  | 			msgpack_object obj = result.data; | ||||||
|  | 			switch(count++) { | ||||||
|  | 			case 0: | ||||||
|  | 				EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type); | ||||||
|  | 				EXPECT_EQ(1, result.data.via.u64); | ||||||
|  | 				break; | ||||||
|  | 			case 1: | ||||||
|  | 				EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type); | ||||||
|  | 				EXPECT_EQ(2, result.data.via.u64); | ||||||
|  | 				break; | ||||||
|  | 			case 2: | ||||||
|  | 				EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type); | ||||||
|  | 				EXPECT_EQ(3, result.data.via.u64); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		EXPECT_TRUE(input < eof); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								cpp/test/version.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								cpp/test/version.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  |  | ||||||
|  | TEST(version, print) | ||||||
|  | { | ||||||
|  | 	printf("MSGPACK_VERSION          : %s\n", MSGPACK_VERSION); | ||||||
|  | 	printf("MSGPACK_VERSION_MAJOR    : %d\n", MSGPACK_VERSION_MAJOR); | ||||||
|  | 	printf("MSGPACK_VERSION_MINOR    : %d\n", MSGPACK_VERSION_MINOR); | ||||||
|  | 	printf("msgpack_version()        : %s\n", msgpack_version()); | ||||||
|  | 	printf("msgpack_version_major()  : %d\n", msgpack_version_major()); | ||||||
|  | 	printf("msgpack_version_minor()  : %d\n", msgpack_version_minor()); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										78
									
								
								cpp/test/zone.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								cpp/test/zone.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | #include <msgpack.hpp> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  |  | ||||||
|  | TEST(zone, malloc) | ||||||
|  | { | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	char* buf1 = (char*)z.malloc(4); | ||||||
|  | 	memcpy(buf1, "test", 4); | ||||||
|  | 	char* buf2 = (char*)z.malloc(4); | ||||||
|  | 	memcpy(buf2, "test", 4); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class myclass { | ||||||
|  | public: | ||||||
|  | 	myclass() : num(0), str("default") { } | ||||||
|  |  | ||||||
|  | 	myclass(int num, const std::string& str) : | ||||||
|  | 		num(num), str(str) { } | ||||||
|  |  | ||||||
|  | 	~myclass() { } | ||||||
|  |  | ||||||
|  | 	int num; | ||||||
|  | 	std::string str; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	myclass(const myclass&); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(zone, allocate) | ||||||
|  | { | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	myclass* m = z.allocate<myclass>(); | ||||||
|  | 	EXPECT_EQ(m->num, 0); | ||||||
|  | 	EXPECT_EQ(m->str, "default"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(zone, allocate_constructor) | ||||||
|  | { | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	myclass* m = z.allocate<myclass>(7, "msgpack"); | ||||||
|  | 	EXPECT_EQ(m->num, 7); | ||||||
|  | 	EXPECT_EQ(m->str, "msgpack"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static void custom_finalizer_func(void* user) | ||||||
|  | { | ||||||
|  | 	myclass* m = (myclass*)user; | ||||||
|  | 	delete m; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(zone, push_finalizer) | ||||||
|  | { | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	myclass* m = new myclass(); | ||||||
|  | 	z.push_finalizer(custom_finalizer_func, (void*)m); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(zone, push_finalizer_auto_ptr) | ||||||
|  | { | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	std::auto_ptr<myclass> am(new myclass()); | ||||||
|  | 	z.push_finalizer(am); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST(zone, malloc_no_align) | ||||||
|  | { | ||||||
|  | 	msgpack::zone z; | ||||||
|  | 	char* buf1 = (char*)z.malloc_no_align(4); | ||||||
|  | 	char* buf2 = (char*)z.malloc_no_align(4); | ||||||
|  | 	EXPECT_EQ(buf1+4, buf2); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								cpp/type.hpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								cpp/type.hpp
									
									
									
									
									
								
							| @@ -1,15 +0,0 @@ | |||||||
| #include "msgpack/type/bool.hpp" |  | ||||||
| #include "msgpack/type/float.hpp" |  | ||||||
| #include "msgpack/type/int.hpp" |  | ||||||
| #include "msgpack/type/list.hpp" |  | ||||||
| #include "msgpack/type/deque.hpp" |  | ||||||
| #include "msgpack/type/map.hpp" |  | ||||||
| #include "msgpack/type/nil.hpp" |  | ||||||
| #include "msgpack/type/pair.hpp" |  | ||||||
| #include "msgpack/type/raw.hpp" |  | ||||||
| #include "msgpack/type/set.hpp" |  | ||||||
| #include "msgpack/type/string.hpp" |  | ||||||
| #include "msgpack/type/vector.hpp" |  | ||||||
| #include "msgpack/type/tuple.hpp" |  | ||||||
| #include "msgpack/type/define.hpp" |  | ||||||
|  |  | ||||||
							
								
								
									
										5
									
								
								erlang/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								erlang/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | MANIFEST | ||||||
|  | *.beam | ||||||
|  | .omakedb* | ||||||
|  | *.omc | ||||||
|  | *~ | ||||||
							
								
								
									
										51
									
								
								erlang/OMakefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								erlang/OMakefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | ######################################################################## | ||||||
|  | # Permission is hereby granted, free of charge, to any person | ||||||
|  | # obtaining a copy of this file, to deal in the File without | ||||||
|  | # restriction, including without limitation the rights to use, | ||||||
|  | # copy, modify, merge, publish, distribute, sublicense, and/or | ||||||
|  | # sell copies of the File, and to permit persons to whom the | ||||||
|  | # File is furnished to do so, subject to the following condition: | ||||||
|  | # | ||||||
|  | # THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||||||
|  | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||||
|  | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||||||
|  | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||||
|  | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE FILE OR | ||||||
|  | # THE USE OR OTHER DEALINGS IN THE FILE. | ||||||
|  |  | ||||||
|  | ######################################################################## | ||||||
|  | # The standard OMakefile. | ||||||
|  | # You will usually need to modify this file for your project. | ||||||
|  |  | ||||||
|  | ######################################################################## | ||||||
|  | # Phony targets are scoped, so you probably want to declare them first. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | .PHONY: all clean test edoc dialyzer #install | ||||||
|  |  | ||||||
|  | ######################################################################## | ||||||
|  | # Subdirectories. | ||||||
|  | # You may want to include some subdirectories in this project. | ||||||
|  | # If so, define the subdirectory targets and uncomment this section. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | .DEFAULT: msgpack.beam | ||||||
|  |  | ||||||
|  | msgpack.beam: msgpack.erl | ||||||
|  | 	erlc -Wall +debug_info $< | ||||||
|  |  | ||||||
|  | msgpack.html: msgpack.erl | ||||||
|  | 	erl -noshell -run edoc_run file $< | ||||||
|  |  | ||||||
|  | test: msgpack.beam | ||||||
|  | 	erl -noshell -s msgpack test -s init stop | ||||||
|  |  | ||||||
|  | edoc: msgpack.erl | ||||||
|  | 	erl -noshell -eval 'ok=edoc:files(["msgpack.erl"], [{dir, "edoc"}]).' -s init stop | ||||||
|  |  | ||||||
|  | dialyzer: msgpack.erl | ||||||
|  | 	dialyzer --src $< | ||||||
|  |  | ||||||
|  | clean: | ||||||
|  | 	-rm -f *.beam *.html | ||||||
							
								
								
									
										45
									
								
								erlang/OMakeroot
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								erlang/OMakeroot
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | ######################################################################## | ||||||
|  | # Permission is hereby granted, free of charge, to any person | ||||||
|  | # obtaining a copy of this file, to deal in the File without | ||||||
|  | # restriction, including without limitation the rights to use, | ||||||
|  | # copy, modify, merge, publish, distribute, sublicense, and/or | ||||||
|  | # sell copies of the File, and to permit persons to whom the | ||||||
|  | # File is furnished to do so, subject to the following condition: | ||||||
|  | # | ||||||
|  | # THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||||||
|  | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||||
|  | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||||||
|  | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||||
|  | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE FILE OR | ||||||
|  | # THE USE OR OTHER DEALINGS IN THE FILE. | ||||||
|  |  | ||||||
|  | ######################################################################## | ||||||
|  | # The standard OMakeroot file. | ||||||
|  | # You will not normally need to modify this file. | ||||||
|  | # By default, your changes should be placed in the | ||||||
|  | # OMakefile in this directory. | ||||||
|  | # | ||||||
|  | # If you decide to modify this file, note that it uses exactly | ||||||
|  | # the same syntax as the OMakefile. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | # | ||||||
|  | # Include the standard installed configuration files. | ||||||
|  | # Any of these can be deleted if you are not using them, | ||||||
|  | # but you probably want to keep the Common file. | ||||||
|  | # | ||||||
|  | open build/C | ||||||
|  | open build/OCaml | ||||||
|  | open build/LaTeX | ||||||
|  |  | ||||||
|  | # | ||||||
|  | # The command-line variables are defined *after* the | ||||||
|  | # standard configuration has been loaded. | ||||||
|  | # | ||||||
|  | DefineCommandVars() | ||||||
|  |  | ||||||
|  | # | ||||||
|  | # Include the OMakefile in this directory. | ||||||
|  | # | ||||||
|  | .SUBDIRS: . | ||||||
							
								
								
									
										9
									
								
								erlang/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								erlang/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | MessagePack for Erlang | ||||||
|  | ====================== | ||||||
|  | Binary-based efficient object serialization library. | ||||||
|  |  | ||||||
|  | see wiki ( http://redmine.msgpack.org/projects/msgpack/wiki/QuickStartErlang ) for details | ||||||
|  |  | ||||||
|  | # Status | ||||||
|  |  | ||||||
|  | 0.1.0 released. | ||||||
							
								
								
									
										4
									
								
								erlang/edoc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								erlang/edoc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | *.html | ||||||
|  | *.css | ||||||
|  | *.png | ||||||
|  | edoc-info | ||||||
							
								
								
									
										395
									
								
								erlang/msgpack.erl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								erlang/msgpack.erl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,395 @@ | |||||||
|  | %% | ||||||
|  | %% MessagePack for Erlang | ||||||
|  | %% | ||||||
|  | %% Copyright (C) 2009-2010 UENISHI Kota | ||||||
|  | %% | ||||||
|  | %%    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. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% @doc <a href="http://msgpack.org/">MessagePack</a> codec for Erlang. | ||||||
|  | %% | ||||||
|  | %%      APIs are almost compatible with <a href="http://redmine.msgpack.org/projects/msgpack/wiki/QuickStartC">C API</a> | ||||||
|  | %%      except for buffering functions (both copying and zero-copying), which are unavailable. | ||||||
|  | %% | ||||||
|  | %%   <table border="1"> | ||||||
|  | %%     <caption>Equivalence between Erlang and <a href="http://msgpack.sourceforge.jp/spec">Msgpack type</a> :</caption> | ||||||
|  | %%     <tr><th>    erlang    </th><th>                            msgpack                                      </th></tr> | ||||||
|  | %%     <tr><td> integer()    </td><td> pos_fixnum/neg_fixnum/uint8/uint16/uint32/uint64/int8/int16/int32/int64 </td></tr> | ||||||
|  | %%     <tr><td> float()      </td><td> float/double                                                            </td></tr> | ||||||
|  | %%     <tr><td> nil          </td><td> nil                                                                     </td></tr> | ||||||
|  | %%     <tr><td> boolean()    </td><td> boolean                                                                 </td></tr> | ||||||
|  | %%     <tr><td> binary()     </td><td> fix_raw/raw16/raw32                                                     </td></tr> | ||||||
|  | %%     <tr><td> list()       </td><td> fix_array/array16/array32                                               </td></tr> | ||||||
|  | %%     <tr><td> {proplist()} </td><td> fix_map/map16/map32                                                     </td></tr> | ||||||
|  | %%   </table> | ||||||
|  | %% @end | ||||||
|  |  | ||||||
|  | -module(msgpack). | ||||||
|  | -author('kuenishi+msgpack@gmail.com'). | ||||||
|  |  | ||||||
|  | -export([pack/1, unpack/1, unpack_all/1]). | ||||||
|  |  | ||||||
|  | % @type msgpack_term() = [msgpack_term()] | ||||||
|  | %                      | {[{msgpack_term(),msgpack_term()}]} | ||||||
|  | %                      | integer() | float() | binary(). | ||||||
|  | % Erlang representation of msgpack data. | ||||||
|  | -type msgpack_term() :: [msgpack_term()] | ||||||
|  | 		      | {[{msgpack_term(),msgpack_term()}]} | ||||||
|  | 		      | integer() | float() | binary(). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | % external APIs | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  |  | ||||||
|  | % @doc Encode an erlang term into an msgpack binary. | ||||||
|  | %      Returns {error, {badarg, term()}} if the input is illegal. | ||||||
|  | % @spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}} | ||||||
|  | -spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}. | ||||||
|  | pack(Term)-> | ||||||
|  |     try | ||||||
|  | 	pack_(Term) | ||||||
|  |     catch | ||||||
|  | 	throw:Exception -> | ||||||
|  | 	    {error, Exception} | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  | % @doc Decode an msgpack binary into an erlang term. | ||||||
|  | %      It only decodes the first msgpack packet contained in the binary; the rest is returned as is. | ||||||
|  | %      Returns {error, {badarg, term()}} if the input is corrupted. | ||||||
|  | %      Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again). | ||||||
|  | % @spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}} | ||||||
|  | -spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}. | ||||||
|  | unpack(Bin) when is_binary(Bin) -> | ||||||
|  |     try | ||||||
|  | 	unpack_(Bin) | ||||||
|  |     catch | ||||||
|  | 	throw:Exception -> | ||||||
|  | 	    {error, Exception} | ||||||
|  |     end; | ||||||
|  | unpack(Other) -> | ||||||
|  |     {error, {badarg, Other}}. | ||||||
|  |  | ||||||
|  | % @doc Decode an msgpack binary into an erlang terms. | ||||||
|  | %      It only decodes ALL msgpack packets contained in the binary. No packets should not remain. | ||||||
|  | %      Returns {error, {badarg, term()}} if the input is corrupted. | ||||||
|  | %      Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again). | ||||||
|  | % @spec unpack_all(binary()) -> [msgpack_term()] | {error, incomplete} | {error, {badarg, term()}} | ||||||
|  | -spec unpack_all(binary()) -> [msgpack_term()] | {error, incomplete} | {error, {badarg, term()}}. | ||||||
|  | unpack_all(Data)-> | ||||||
|  |     try | ||||||
|  | 	unpack_all_(Data) | ||||||
|  |     catch | ||||||
|  | 	throw:Exception -> | ||||||
|  | 	    {error, Exception} | ||||||
|  |     end. | ||||||
|  | unpack_all_(Data)-> | ||||||
|  |     case unpack_(Data) of | ||||||
|  | 	{ Term, <<>> } -> | ||||||
|  | 	    [Term]; | ||||||
|  | 	{ Term, Binary } when is_binary(Binary) -> | ||||||
|  | 	    [Term|unpack_all_(Binary)] | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | % internal APIs | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  |  | ||||||
|  | % pack them all | ||||||
|  | -spec pack_(msgpack_term()) -> binary() | no_return(). | ||||||
|  | pack_(I) when is_integer(I) andalso I < 0 -> | ||||||
|  |     pack_int_(I); | ||||||
|  | pack_(I) when is_integer(I) -> | ||||||
|  |     pack_uint_(I); | ||||||
|  | pack_(F) when is_float(F) -> | ||||||
|  |     pack_double(F); | ||||||
|  | pack_(nil) -> | ||||||
|  |     << 16#C0:8 >>; | ||||||
|  | pack_(true) -> | ||||||
|  |     << 16#C3:8 >>; | ||||||
|  | pack_(false) -> | ||||||
|  |     << 16#C2:8 >>; | ||||||
|  | pack_(Bin) when is_binary(Bin) -> | ||||||
|  |     pack_raw(Bin); | ||||||
|  | pack_(List)  when is_list(List) -> | ||||||
|  |     pack_array(List); | ||||||
|  | pack_({Map}) when is_list(Map) -> | ||||||
|  |     pack_map(Map); | ||||||
|  | pack_(Other) -> | ||||||
|  |     throw({badarg, Other}). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | -spec pack_uint_(non_neg_integer()) -> binary(). | ||||||
|  | % positive fixnum | ||||||
|  | pack_uint_(N) when N < 128 -> | ||||||
|  |     << 2#0:1, N:7 >>; | ||||||
|  | % uint 8 | ||||||
|  | pack_uint_(N) when N < 256 -> | ||||||
|  |     << 16#CC:8, N:8 >>; | ||||||
|  | % uint 16 | ||||||
|  | pack_uint_(N) when N < 65536 -> | ||||||
|  |     << 16#CD:8, N:16/big-unsigned-integer-unit:1 >>; | ||||||
|  | % uint 32 | ||||||
|  | pack_uint_(N) when N < 16#FFFFFFFF-> | ||||||
|  |     << 16#CE:8, N:32/big-unsigned-integer-unit:1 >>; | ||||||
|  | % uint 64 | ||||||
|  | pack_uint_(N) -> | ||||||
|  |     << 16#CF:8, N:64/big-unsigned-integer-unit:1 >>. | ||||||
|  |  | ||||||
|  | -spec pack_int_(integer()) -> binary(). | ||||||
|  | % negative fixnum | ||||||
|  | pack_int_(N) when N >= -32-> | ||||||
|  |     << 2#111:3, N:5 >>; | ||||||
|  | % int 8 | ||||||
|  | pack_int_(N) when N > -128 -> | ||||||
|  |     << 16#D0:8, N:8/big-signed-integer-unit:1 >>; | ||||||
|  | % int 16 | ||||||
|  | pack_int_(N) when N > -32768 -> | ||||||
|  |     << 16#D1:8, N:16/big-signed-integer-unit:1 >>; | ||||||
|  | % int 32 | ||||||
|  | pack_int_(N) when N > -16#FFFFFFFF -> | ||||||
|  |     << 16#D2:8, N:32/big-signed-integer-unit:1 >>; | ||||||
|  | % int 64 | ||||||
|  | pack_int_(N) -> | ||||||
|  |     << 16#D3:8, N:64/big-signed-integer-unit:1 >>. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | -spec pack_double(float()) -> binary(). | ||||||
|  | % float : erlang's float is always IEEE 754 64bit format. | ||||||
|  | % pack_float(F) when is_float(F)-> | ||||||
|  | %    << 16#CA:8, F:32/big-float-unit:1 >>. | ||||||
|  | %    pack_double(F). | ||||||
|  | % double | ||||||
|  | pack_double(F) -> | ||||||
|  |     << 16#CB:8, F:64/big-float-unit:1 >>. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | -spec pack_raw(binary()) -> binary(). | ||||||
|  | % raw bytes | ||||||
|  | pack_raw(Bin) -> | ||||||
|  |     case byte_size(Bin) of | ||||||
|  | 	Len when Len < 6-> | ||||||
|  | 	    << 2#101:3, Len:5, Bin/binary >>; | ||||||
|  | 	Len when Len < 16#10000 -> % 65536 | ||||||
|  | 	    << 16#DA:8, Len:16/big-unsigned-integer-unit:1, Bin/binary >>; | ||||||
|  | 	Len -> | ||||||
|  | 	    << 16#DB:8, Len:32/big-unsigned-integer-unit:1, Bin/binary >> | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | -spec pack_array([msgpack_term()]) -> binary() | no_return(). | ||||||
|  | % list | ||||||
|  | pack_array(L) -> | ||||||
|  |     case length(L) of | ||||||
|  |  	Len when Len < 16 -> | ||||||
|  |  	    << 2#1001:4, Len:4/integer-unit:1, (pack_array_(L, <<>>))/binary >>; | ||||||
|  | 	Len when Len < 16#10000 -> % 65536 | ||||||
|  | 	    << 16#DC:8, Len:16/big-unsigned-integer-unit:1, (pack_array_(L, <<>>))/binary >>; | ||||||
|  | 	Len -> | ||||||
|  | 	    << 16#DD:8, Len:32/big-unsigned-integer-unit:1, (pack_array_(L, <<>>))/binary >> | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  | pack_array_([], Acc) -> Acc; | ||||||
|  | pack_array_([Head|Tail], Acc) -> | ||||||
|  |     pack_array_(Tail, <<Acc/binary,  (pack_(Head))/binary>>). | ||||||
|  |  | ||||||
|  | % Users SHOULD NOT send too long list: this uses lists:reverse/1 | ||||||
|  | -spec unpack_array_(binary(), non_neg_integer(), [msgpack_term()]) -> {[msgpack_term()], binary()} | no_return(). | ||||||
|  | unpack_array_(Bin, 0,   Acc) -> {lists:reverse(Acc), Bin}; | ||||||
|  | unpack_array_(Bin, Len, Acc) -> | ||||||
|  |     {Term, Rest} = unpack_(Bin), | ||||||
|  |     unpack_array_(Rest, Len-1, [Term|Acc]). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | -spec pack_map(M::[{msgpack_term(),msgpack_term()}]) -> binary() | no_return(). | ||||||
|  | pack_map(M)-> | ||||||
|  |     case length(M) of | ||||||
|  | 	Len when Len < 16 -> | ||||||
|  | 	    << 2#1000:4, Len:4/integer-unit:1, (pack_map_(M, <<>>))/binary >>; | ||||||
|  | 	Len when Len < 16#10000 -> % 65536 | ||||||
|  | 	    << 16#DE:8, Len:16/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>; | ||||||
|  | 	Len -> | ||||||
|  | 	    << 16#DF:8, Len:32/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >> | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  | pack_map_([], Acc) -> Acc; | ||||||
|  | pack_map_([{Key,Value}|Tail], Acc) -> | ||||||
|  |     pack_map_(Tail, << Acc/binary, (pack_(Key))/binary, (pack_(Value))/binary>>). | ||||||
|  |  | ||||||
|  | % Users SHOULD NOT send too long list: this uses lists:reverse/1 | ||||||
|  | -spec unpack_map_(binary(), non_neg_integer(), [{msgpack_term(), msgpack_term()}]) -> | ||||||
|  | 			 {{[{msgpack_term(), msgpack_term()}]}, binary()} | no_return(). | ||||||
|  | unpack_map_(Bin, 0,   Acc) -> {{lists:reverse(Acc)}, Bin}; | ||||||
|  | unpack_map_(Bin, Len, Acc) -> | ||||||
|  |     {Key, Rest} = unpack_(Bin), | ||||||
|  |     {Value, Rest2} = unpack_(Rest), | ||||||
|  |     unpack_map_(Rest2, Len-1, [{Key,Value}|Acc]). | ||||||
|  |  | ||||||
|  | % unpack them all | ||||||
|  | -spec unpack_(Bin::binary()) -> {msgpack_term(), binary()} | no_return(). | ||||||
|  | unpack_(Bin) -> | ||||||
|  |     case Bin of | ||||||
|  | % ATOMS | ||||||
|  | 	<<16#C0, Rest/binary>> -> {nil, Rest}; | ||||||
|  | 	<<16#C2, Rest/binary>> -> {false, Rest}; | ||||||
|  | 	<<16#C3, Rest/binary>> -> {true, Rest}; | ||||||
|  | % Floats | ||||||
|  | 	<<16#CA, V:32/float-unit:1, Rest/binary>> ->   {V, Rest}; | ||||||
|  | 	<<16#CB, V:64/float-unit:1, Rest/binary>> ->   {V, Rest}; | ||||||
|  | % Unsigned integers | ||||||
|  | 	<<16#CC, V:8/unsigned-integer, Rest/binary>> ->             {V, Rest}; | ||||||
|  | 	<<16#CD, V:16/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest}; | ||||||
|  | 	<<16#CE, V:32/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest}; | ||||||
|  | 	<<16#CF, V:64/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest}; | ||||||
|  | % Signed integers | ||||||
|  | 	<<16#D0, V:8/signed-integer, Rest/binary>> ->             {V, Rest}; | ||||||
|  | 	<<16#D1, V:16/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest}; | ||||||
|  | 	<<16#D2, V:32/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest}; | ||||||
|  | 	<<16#D3, V:64/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest}; | ||||||
|  | % Raw bytes | ||||||
|  | 	<<16#DA, L:16/unsigned-integer-unit:1, V:L/binary, Rest/binary>> -> {V, Rest}; | ||||||
|  | 	<<16#DB, L:32/unsigned-integer-unit:1, V:L/binary, Rest/binary>> -> {V, Rest}; | ||||||
|  | % Arrays | ||||||
|  | 	<<16#DC, L:16/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_array_(Rest, L, []); | ||||||
|  | 	<<16#DD, L:32/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_array_(Rest, L, []); | ||||||
|  | % Maps | ||||||
|  | 	<<16#DE, L:16/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_map_(Rest, L, []); | ||||||
|  | 	<<16#DF, L:32/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_map_(Rest, L, []); | ||||||
|  |  | ||||||
|  | % Tag-encoded lengths (kept last, for speed) | ||||||
|  | 	<<0:1, V:7, Rest/binary>> ->                 {V, Rest};                  % positive int | ||||||
|  | 	<<2#111:3, V:5, Rest/binary>> ->             {V - 2#100000, Rest};       % negative int | ||||||
|  | 	<<2#101:3, L:5, V:L/binary, Rest/binary>> -> {V, Rest};                  % raw bytes | ||||||
|  | 	<<2#1001:4, L:4, Rest/binary>> ->            unpack_array_(Rest, L, []); % array | ||||||
|  | 	<<2#1000:4, L:4, Rest/binary>> ->            unpack_map_(Rest, L, []);   % map | ||||||
|  |  | ||||||
|  | % Invalid data | ||||||
|  | 	<<F, R/binary>> when F==16#C1; | ||||||
|  | 	                     F==16#C4; F==16#C5; F==16#C6; F==16#C7; F==16#C8; F==16#C9; | ||||||
|  | 	                     F==16#D4; F==16#D5; F==16#D6; F==16#D7; F==16#D8; F==16#D9 -> | ||||||
|  | 	    throw({badarg, <<F, R/binary>>}); | ||||||
|  | % Incomplete data (we've covered every complete/invalid case; anything left is incomplete) | ||||||
|  | 	_ -> | ||||||
|  | 	    throw(incomplete) | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | % unit tests | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | -include_lib("eunit/include/eunit.hrl"). | ||||||
|  | -ifdef(EUNIT). | ||||||
|  |  | ||||||
|  | compare_all([], [])-> ok; | ||||||
|  | compare_all([],  R)-> {toomuchrhs, R}; | ||||||
|  | compare_all(L,  [])-> {toomuchlhs, L}; | ||||||
|  | compare_all([LH|LTL], [RH|RTL]) -> | ||||||
|  |     ?assertEqual(LH, RH), | ||||||
|  |     compare_all(LTL, RTL). | ||||||
|  |  | ||||||
|  | port_receive(Port) -> | ||||||
|  |     port_receive(Port, <<>>). | ||||||
|  | port_receive(Port, Acc) -> | ||||||
|  |     receive | ||||||
|  |         {Port, {data, Data}} -> port_receive(Port, <<Acc/binary, Data/binary>>); | ||||||
|  |         {Port, eof} -> Acc | ||||||
|  |     after 1000 -> Acc | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  | test_([]) -> 0; | ||||||
|  | test_([Term|Rest])-> | ||||||
|  |     Pack = msgpack:pack(Term), | ||||||
|  |     ?assertEqual({Term, <<>>}, msgpack:unpack( Pack )), | ||||||
|  |     1+test_(Rest). | ||||||
|  |  | ||||||
|  | test_data()-> | ||||||
|  |     [true, false, nil, | ||||||
|  |      0, 1, 2, 123, 512, 1230, 678908, 16#FFFFFFFFFF, | ||||||
|  |      -1, -23, -512, -1230, -567898, -16#FFFFFFFFFF, | ||||||
|  |      123.123, -234.4355, 1.0e-34, 1.0e64, | ||||||
|  |      [23, 234, 0.23], | ||||||
|  |      <<"hogehoge">>, <<"243546rf7g68h798j", 0, 23, 255>>, | ||||||
|  |      <<"hoasfdafdas][">>, | ||||||
|  |      [0,42, <<"sum">>, [1,2]], [1,42, nil, [3]], | ||||||
|  |      -234, -40000, -16#10000000, -16#100000000, | ||||||
|  |      42 | ||||||
|  |     ]. | ||||||
|  |  | ||||||
|  | basic_test()-> | ||||||
|  |     Tests = test_data(), | ||||||
|  |     Passed = test_(Tests), | ||||||
|  |     Passed = length(Tests). | ||||||
|  |  | ||||||
|  | port_test()-> | ||||||
|  |     Tests = test_data(), | ||||||
|  |     ?assertEqual({[Tests],<<>>}, msgpack:unpack(msgpack:pack([Tests]))), | ||||||
|  |  | ||||||
|  |     Port = open_port({spawn, "ruby ../test/crosslang.rb"}, [binary, eof]), | ||||||
|  |     true = port_command(Port, msgpack:pack(Tests)), | ||||||
|  |     ?assertEqual({Tests, <<>>}, msgpack:unpack(port_receive(Port))), | ||||||
|  |     port_close(Port). | ||||||
|  |  | ||||||
|  | test_p(Len,Term,OrigBin,Len) -> | ||||||
|  |     {Term, <<>>}=msgpack:unpack(OrigBin); | ||||||
|  | test_p(I,_,OrigBin,Len) when I < Len-> | ||||||
|  |     <<Bin:I/binary, _/binary>> = OrigBin, | ||||||
|  |     ?assertEqual({error,incomplete}, msgpack:unpack(Bin)). | ||||||
|  |  | ||||||
|  | partial_test()-> % error handling test. | ||||||
|  |     Term = lists:seq(0, 45), | ||||||
|  |     Bin=msgpack:pack(Term), | ||||||
|  |     BinLen = byte_size(Bin), | ||||||
|  |     [test_p(X, Term, Bin, BinLen) || X <- lists:seq(0,BinLen)]. | ||||||
|  |  | ||||||
|  | long_test()-> | ||||||
|  |     Longer = lists:seq(0, 655), | ||||||
|  |     {Longer, <<>>} = msgpack:unpack(msgpack:pack(Longer)). | ||||||
|  |  | ||||||
|  | map_test()-> | ||||||
|  |     Ints = lists:seq(0, 65), | ||||||
|  |     Map = {[ {X, X*2} || X <- Ints ] ++ [{<<"hage">>, 324}, {43542, [nil, true, false]}]}, | ||||||
|  |     {Map2, <<>>} = msgpack:unpack(msgpack:pack(Map)), | ||||||
|  |     ?assertEqual(Map, Map2), | ||||||
|  |     ok. | ||||||
|  |  | ||||||
|  | unknown_test()-> | ||||||
|  |     Port = open_port({spawn, "ruby testcase_generator.rb"}, [binary, eof]), | ||||||
|  |     Tests = [0, 1, 2, 123, 512, 1230, 678908, | ||||||
|  | 	     -1, -23, -512, -1230, -567898, | ||||||
|  | 	     <<"hogehoge">>, <<"243546rf7g68h798j">>, | ||||||
|  | 	     123.123, | ||||||
|  | 	     -234.4355, 1.0e-34, 1.0e64, | ||||||
|  | 	     [23, 234, 0.23], | ||||||
|  | 	     [0,42,<<"sum">>, [1,2]], [1,42, nil, [3]], | ||||||
|  | 	     {[{1,2},{<<"hoge">>,nil}]}, % map | ||||||
|  | 	     -234, -50000, | ||||||
|  | 	     42 | ||||||
|  | 	    ], | ||||||
|  |     ?assertEqual(ok, compare_all(Tests, msgpack:unpack_all(port_receive(Port)))), | ||||||
|  |     port_close(Port). | ||||||
|  |  | ||||||
|  | other_test()-> | ||||||
|  |     ?assertEqual({error,incomplete},msgpack:unpack(<<>>)). | ||||||
|  |  | ||||||
|  | benchmark_test()-> | ||||||
|  |     Data=[test_data() || _ <- lists:seq(0, 10000)], | ||||||
|  |     S=?debugTime("  serialize", msgpack:pack(Data)), | ||||||
|  |     {Data,<<>>}=?debugTime("deserialize", msgpack:unpack(S)), | ||||||
|  |     ?debugFmt("for ~p KB test data.", [byte_size(S) div 1024]). | ||||||
|  |  | ||||||
|  | error_test()-> | ||||||
|  |     ?assertEqual({error,{badarg, atom}}, msgpack:pack(atom)), | ||||||
|  |     Term = {"hoge", "hage", atom}, | ||||||
|  |     ?assertEqual({error,{badarg, Term}}, msgpack:pack(Term)). | ||||||
|  |  | ||||||
|  | -endif. | ||||||
							
								
								
									
										65
									
								
								erlang/testcase_generator.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								erlang/testcase_generator.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | begin | ||||||
|  | require 'rubygems' | ||||||
|  | rescue LoadError | ||||||
|  | end | ||||||
|  | require 'msgpack' | ||||||
|  |  | ||||||
|  | def usage | ||||||
|  | 	puts <<EOF | ||||||
|  | Usage: #{$0} [out-file] | ||||||
|  |  | ||||||
|  | This tool is for testing of accepting MessagePack random-term. | ||||||
|  | This does following behavior: | ||||||
|  |  | ||||||
|  |   1. serializes the objects in this file, using Ruby implementation | ||||||
|  |      of MessagePack (Note that Ruby implementation is considered valid) | ||||||
|  |   2. Writes the serialized binaries into <out-file> (default: stdout) | ||||||
|  |  | ||||||
|  | EOF | ||||||
|  | 	exit 1 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | code = 1 | ||||||
|  | outio = $stdout | ||||||
|  |  | ||||||
|  | if ARGV.length > 2 | ||||||
|  | 	usage | ||||||
|  | end | ||||||
|  |  | ||||||
|  | if fname = ARGV[0] | ||||||
|  | 	unless fname == "-" | ||||||
|  | 		begin | ||||||
|  | 			outio = File.open(fname, "w") | ||||||
|  | 		rescue | ||||||
|  | 			puts "can't open output file: #{$!}" | ||||||
|  | 			exit 1 | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | objs = [0, 1, 2, 123, 512, 1230, 678908, | ||||||
|  |         -1, -23, -512, -1230, -567898, | ||||||
|  |         "hogehoge", "243546rf7g68h798j", | ||||||
|  |         123.123, | ||||||
|  |        -234.4355, 1.0e-34, 1.0e64, | ||||||
|  |         [23, 234, 0.23], | ||||||
|  |         [0,42,"sum", [1,2]], [1,42, nil, [3]], | ||||||
|  |         { 1 => 2, "hoge" => nil }, | ||||||
|  |         -234, -50000, | ||||||
|  |         42 | ||||||
|  |        ] | ||||||
|  | begin | ||||||
|  |   objs.each do |obj| | ||||||
|  |     outio.write MessagePack.pack(obj) | ||||||
|  |     outio.flush | ||||||
|  |   end | ||||||
|  | rescue EOFError | ||||||
|  |   code=0 | ||||||
|  | rescue | ||||||
|  |   $stderr.puts $! | ||||||
|  |   code=1 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | outio.close | ||||||
|  | exit code | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								haskell/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								haskell/LICENSE
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | Copyright (c) 2009, Hideyuki Tanaka | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |     * Redistributions of source code must retain the above copyright | ||||||
|  |       notice, this list of conditions and the following disclaimer. | ||||||
|  |     * Redistributions in binary form must reproduce the above copyright | ||||||
|  |       notice, this list of conditions and the following disclaimer in the | ||||||
|  |       documentation and/or other materials provided with the distribution. | ||||||
|  |     * Neither the name of the Hideyuki Tanaka nor the | ||||||
|  |       names of its contributors may be used to endorse or promote products | ||||||
|  |       derived from this software without specific prior written permission. | ||||||
|  |  | ||||||
|  | THIS SOFTWARE IS PROVIDED BY Hideyuki Tanaka ''AS IS'' AND ANY | ||||||
|  | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||||
|  | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||||
|  | DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||||||
|  | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||||
|  | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||||
|  | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||||
|  | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||||
|  | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
							
								
								
									
										3
									
								
								haskell/Setup.lhs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								haskell/Setup.lhs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | #!/usr/bin/env runhaskell | ||||||
|  | > import Distribution.Simple | ||||||
|  | > main = defaultMain | ||||||
							
								
								
									
										137
									
								
								haskell/cbits/msgpack.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								haskell/cbits/msgpack.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | |||||||
|  | #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); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										32
									
								
								haskell/msgpack.cabal
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								haskell/msgpack.cabal
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | 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 | ||||||
|  | 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 | ||||||
|  |  | ||||||
|  | library | ||||||
|  |   build-depends:	base>=4 && <5, mtl, bytestring | ||||||
|  |   ghc-options:		-O2 -Wall | ||||||
|  |   hs-source-dirs:	src | ||||||
|  |   extra-libraries:	msgpackc | ||||||
|  |  | ||||||
|  |   Exposed-modules: | ||||||
|  |     Data.MessagePack | ||||||
|  |     Data.MessagePack.Base | ||||||
|  |     Data.MessagePack.Class | ||||||
|  |     Data.MessagePack.Feed | ||||||
|  |     Data.MessagePack.Monad | ||||||
|  |     Data.MessagePack.Stream | ||||||
|  |  | ||||||
|  |   C-Sources: | ||||||
|  |     cbits/msgpack.c | ||||||
							
								
								
									
										63
									
								
								haskell/src/Data/MessagePack.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								haskell/src/Data/MessagePack.hs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | -------------------------------------------------------------------- | ||||||
|  | -- | | ||||||
|  | -- Module    : Data.MessagePack | ||||||
|  | -- Copyright : (c) Hideyuki Tanaka, 2009 | ||||||
|  | -- License   : BSD3 | ||||||
|  | -- | ||||||
|  | -- Maintainer:  tanaka.hideyuki@gmail.com | ||||||
|  | -- Stability :  experimental | ||||||
|  | -- Portability: portable | ||||||
|  | -- | ||||||
|  | -- Simple interface to pack and unpack MessagePack data. | ||||||
|  | -- | ||||||
|  | -------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | module Data.MessagePack( | ||||||
|  |   module Data.MessagePack.Base, | ||||||
|  |   module Data.MessagePack.Class, | ||||||
|  |   module Data.MessagePack.Feed, | ||||||
|  |   module Data.MessagePack.Monad, | ||||||
|  |   module Data.MessagePack.Stream, | ||||||
|  |    | ||||||
|  |   -- * Pack and Unpack | ||||||
|  |   packb, | ||||||
|  |   unpackb, | ||||||
|  |    | ||||||
|  |   -- * Pure version of Pack and Unpack | ||||||
|  |   packb', | ||||||
|  |   unpackb', | ||||||
|  |   ) where | ||||||
|  |  | ||||||
|  | import Data.ByteString (ByteString) | ||||||
|  | import System.IO.Unsafe | ||||||
|  |  | ||||||
|  | import Data.MessagePack.Base | ||||||
|  | import Data.MessagePack.Class | ||||||
|  | import Data.MessagePack.Feed | ||||||
|  | import Data.MessagePack.Monad | ||||||
|  | import Data.MessagePack.Stream | ||||||
|  |  | ||||||
|  | -- | Pack Haskell data to MessagePack string. | ||||||
|  | packb :: OBJECT a => a -> IO ByteString | ||||||
|  | packb dat = do | ||||||
|  |   sb <- newSimpleBuffer | ||||||
|  |   pc <- newPacker sb | ||||||
|  |   pack pc dat | ||||||
|  |   simpleBufferData sb | ||||||
|  |  | ||||||
|  | -- | Unpack MessagePack string to Haskell data. | ||||||
|  | unpackb :: OBJECT a => ByteString -> IO (Result a) | ||||||
|  | unpackb bs = do | ||||||
|  |   withZone $ \z -> do | ||||||
|  |     r <- unpackObject z bs | ||||||
|  |     return $ case r of | ||||||
|  |       Left err -> Left (show err) | ||||||
|  |       Right (_, dat) -> fromObject dat | ||||||
|  |  | ||||||
|  | -- | Pure version of 'packb'. | ||||||
|  | packb' :: OBJECT a => a -> ByteString | ||||||
|  | packb' dat = unsafePerformIO $ packb dat | ||||||
|  |  | ||||||
|  | -- | Pure version of 'unpackb'. | ||||||
|  | unpackb' :: OBJECT a => ByteString -> Result a | ||||||
|  | unpackb' bs = unsafePerformIO $ unpackb bs | ||||||
							
								
								
									
										584
									
								
								haskell/src/Data/MessagePack/Base.hsc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										584
									
								
								haskell/src/Data/MessagePack/Base.hsc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,584 @@ | |||||||
|  | {-# 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 | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user