packsnap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.gitignore +17 -0
  2. data/ChangeLog +29 -0
  3. data/README.rdoc +26 -0
  4. data/Rakefile +150 -0
  5. data/doclib/msgpack.rb +54 -0
  6. data/doclib/packsnap/buffer.rb +177 -0
  7. data/doclib/packsnap/error.rb +14 -0
  8. data/doclib/packsnap/packer.rb +131 -0
  9. data/doclib/packsnap/unpacker.rb +130 -0
  10. data/ext/packsnap/buffer.cc +684 -0
  11. data/ext/packsnap/buffer.hh +439 -0
  12. data/ext/packsnap/buffer_class.cc +490 -0
  13. data/ext/packsnap/buffer_class.hh +32 -0
  14. data/ext/packsnap/compat.h +128 -0
  15. data/ext/packsnap/extconf.rb +94 -0
  16. data/ext/packsnap/packer.cc +137 -0
  17. data/ext/packsnap/packer.h +334 -0
  18. data/ext/packsnap/packer_class.cc +288 -0
  19. data/ext/packsnap/packer_class.hh +32 -0
  20. data/ext/packsnap/packsnap.h +4 -0
  21. data/ext/packsnap/rbinit.cc +52 -0
  22. data/ext/packsnap/rmem.cc +110 -0
  23. data/ext/packsnap/rmem.h +100 -0
  24. data/ext/packsnap/sysdep.h +112 -0
  25. data/ext/packsnap/sysdep_endian.h +50 -0
  26. data/ext/packsnap/sysdep_types.h +46 -0
  27. data/ext/packsnap/unpacker.cc +654 -0
  28. data/ext/packsnap/unpacker.hh +108 -0
  29. data/ext/packsnap/unpacker_class.cc +392 -0
  30. data/ext/packsnap/unpacker_class.hh +32 -0
  31. data/lib/packsnap.rb +12 -0
  32. data/lib/packsnap/version.rb +3 -0
  33. data/packsnap.gemspec +23 -0
  34. data/spec/buffer_io_spec.rb +228 -0
  35. data/spec/buffer_spec.rb +572 -0
  36. data/spec/cases.json +1 -0
  37. data/spec/cases.msg +0 -0
  38. data/spec/cases_compact.msg +0 -0
  39. data/spec/cases_spec.rb +39 -0
  40. data/spec/format_spec.rb +225 -0
  41. data/spec/packer_spec.rb +127 -0
  42. data/spec/random_compat.rb +24 -0
  43. data/spec/spec_helper.rb +21 -0
  44. data/spec/unpacker_spec.rb +128 -0
  45. metadata +183 -0
@@ -0,0 +1,32 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2012 FURUHASHI Sadayuki
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ #ifndef MSGPACK_RUBY_BUFFER_CLASS_H__
19
+ #define MSGPACK_RUBY_BUFFER_CLASS_H__
20
+
21
+ #include "buffer.hh"
22
+
23
+ extern VALUE cMessagePack_Buffer;
24
+
25
+ extern "C" void MessagePack_Buffer_module_init(VALUE mMessagePack);
26
+
27
+ extern "C" VALUE MessagePack_Buffer_wrap(msgpack_buffer_t* b, VALUE owner);
28
+
29
+ void MessagePack_Buffer_initialize(msgpack_buffer_t* b, VALUE io, VALUE options);
30
+
31
+ #endif
32
+
@@ -0,0 +1,128 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2012 FURUHASHI Sadayuki
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ #ifndef MSGPACK_RUBY_COMPAT_H__
19
+ #define MSGPACK_RUBY_COMPAT_H__
20
+
21
+ #include "ruby.h"
22
+
23
+ #if defined(HAVE_RUBY_ST_H)
24
+ #include "ruby/st.h" // ruby hash on Ruby 1.9
25
+ #elif defined(HAVE_ST_H)
26
+ #include "st.h" // ruby hash on Ruby 1.8
27
+ #endif
28
+
29
+ #ifdef HAVE_RUBY_ENCODING_H
30
+ #include "ruby/encoding.h"
31
+ #define COMPAT_HAVE_ENCODING
32
+ extern int s_enc_utf8;
33
+ extern int s_enc_ascii8bit;
34
+ extern int s_enc_usascii;
35
+ extern VALUE s_enc_utf8_value;
36
+ #endif
37
+
38
+
39
+ /* Rubinius and JRuby */
40
+ #if defined(RUBINIUS) || defined(JRUBY)
41
+ #define DISABLE_STR_NEW_MOVE
42
+ #endif
43
+
44
+
45
+ /* MRI 1.9 */
46
+ #if defined(RUBY_VM)
47
+ /* if FL_ALL(str, FL_USER1|FL_USER3) == STR_ASSOC_P(str) returns true, rb_str_dup will copy the string */
48
+ #define STR_DUP_LIKELY_DOES_COPY(str) FL_ALL(str, FL_USER1|FL_USER3)
49
+
50
+ /* Rubinius and JRuby */
51
+ #elif defined(RUBINIUS) || defined(JRUBY)
52
+ #define STR_DUP_LIKELY_DOES_COPY(str) (1)
53
+
54
+ #else
55
+ /* MRI 1.8 */
56
+ #define STR_DUP_LIKELY_DOES_COPY(str) (!FL_TEST(str, ELTS_SHARED))
57
+ #endif
58
+
59
+
60
+ /* MacRuby */
61
+ #if defined(__MACRUBY__)
62
+ #undef COMPAT_HAVE_ENCODING
63
+ #endif
64
+
65
+
66
+ /* MRI 1.8 */
67
+ #ifndef SIZET2NUM
68
+ #define SIZET2NUM(v) ULL2NUM(v)
69
+ #endif
70
+
71
+
72
+ /* MRI 1.9 */
73
+ #if defined(RUBY_VM)
74
+ #define COMPAT_RERAISE rb_exc_raise(rb_errinfo())
75
+
76
+ /* JRuby */
77
+ #elif defined(JRUBY)
78
+ #define COMPAT_RERAISE rb_exc_raise(rb_gv_get("$!"))
79
+
80
+ /* MRI 1.8 and Rubinius */
81
+ #else
82
+ #define COMPAT_RERAISE rb_exc_raise(ruby_errinfo)
83
+ #endif
84
+
85
+
86
+ #ifndef RBIGNUM_POSITIVE_P
87
+
88
+ /* Rubinius */
89
+ #if defined(RUBINIUS)
90
+ #define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue)
91
+
92
+ /* JRuby */
93
+ #elif defined(JRUBY)
94
+ #define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue)
95
+ #define rb_big2ull(b) rb_num2ull(b)
96
+ /*#define rb_big2ll(b) rb_num2ll(b)*/
97
+
98
+ /* MRI 1.8 */
99
+ #else
100
+ #define RBIGNUM_POSITIVE_P(b) (RBIGNUM(b)->sign)
101
+
102
+ #endif
103
+ #endif
104
+
105
+
106
+ /* MRI 1.8.5 */
107
+ #ifndef RSTRING_PTR
108
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
109
+ #endif
110
+
111
+ /* MRI 1.8.5 */
112
+ #ifndef RSTRING_LEN
113
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
114
+ #endif
115
+
116
+ /* MRI 1.8.5 */
117
+ #ifndef RARRAY_PTR
118
+ #define RARRAY_PTR(s) (RARRAY(s)->ptr)
119
+ #endif
120
+
121
+ /* MRI 1.8.5 */
122
+ #ifndef RARRAY_LEN
123
+ #define RARRAY_LEN(s) (RARRAY(s)->len)
124
+ #endif
125
+
126
+
127
+ #endif
128
+
@@ -0,0 +1,94 @@
1
+ require 'mkmf'
2
+ require 'fileutils'
3
+
4
+
5
+ $CFLAGS << %[ -I.. -I. -Wall -O3 -g -std=c99]
6
+
7
+ if warnflags = CONFIG['warnflags']
8
+ warnflags.slice!(/ -Wdeclaration-after-statement/)
9
+ end
10
+
11
+ def try_configure
12
+ return if system "./configure --disable-option-checking --disable-dependency-tracking --disable-gtest --without-gflags"
13
+
14
+ if try_run 'int main(int argc, char** argv){ return __builtin_expect(1, 1) ? 0 : 1; }'
15
+ $defs << '-DHAVE_BUILTIN_EXPECT'
16
+ end
17
+
18
+ if try_run 'int main(int argc, char** argv){ return (__builtin_ctzll(0x100000000LL) == 32) ? 0 : 1; }'
19
+ $defs << '-DHAVE_BUILTIN_CTZ'
20
+ end
21
+
22
+ have_header("ruby/st.h")
23
+ have_header("st.h")
24
+ have_header 'dlfcn.h'
25
+ have_header 'inttypes.h'
26
+ have_header 'memory.h'
27
+ have_header 'stddef.h'
28
+ have_header 'stdint.h'
29
+ have_header 'stdlib.h'
30
+ have_header 'strings.h'
31
+ have_header 'string.h'
32
+ have_header 'sys/byteswap.h'
33
+ have_header 'sys/endian.h'
34
+ have_header 'sys/mman.h'
35
+ have_header 'sys/resource.h'
36
+ have_header 'sys/stat.h'
37
+ have_header 'sys/types.h'
38
+ have_header 'unistd.h'
39
+ have_header 'windows.h'
40
+
41
+ if try_run 'int main(int argc, char** argv){ int i = 1; return *((char*)&i); }'
42
+ $defs << '-DWORDS_BIGENDIAN'
43
+ end
44
+ end
45
+
46
+ unless have_library 'snappy'
47
+ dst = File.dirname File.expand_path __FILE__
48
+
49
+ tar = 'tar'
50
+ tar = 'gnutar' if find_executable 'gnutar'
51
+
52
+ ver = "1.0.4"
53
+ src = "snappy-#{ver}"
54
+
55
+ FileUtils.rm_rf File.join dst, src
56
+ system "curl -s http://snappy.googlecode.com/files/#{src}.tar.gz | #{tar} xz"
57
+
58
+ src = File.join dst, src
59
+
60
+ Dir.chdir src do
61
+ try_configure
62
+ end
63
+
64
+ %w(
65
+ config.h
66
+ snappy-c.cc
67
+ snappy-c.h
68
+ snappy-internal.h
69
+ snappy-sinksource.cc
70
+ snappy-sinksource.h
71
+ snappy-stubs-internal.cc
72
+ snappy-stubs-internal.h
73
+ snappy.cc
74
+ snappy.h
75
+ ).each do |file|
76
+ FileUtils.copy File.join(src, file), File.join(dst, file) if FileTest.exist? File.join(src, file)
77
+ end
78
+
79
+ hdr = File.open(File.join(src, 'snappy-stubs-public.h.in'), 'rb'){ |f| f.read }
80
+ {
81
+ %r'#if @ac_cv_have_stdint_h@' => '#ifdef HAVE_STDINT_H',
82
+ %r'#if @ac_cv_have_stddef_h@' => '#ifdef HAVE_STDDEF_H',
83
+ %r'@SNAPPY_MAJOR@' => '1',
84
+ %r'@SNAPPY_MINOR@' => '0',
85
+ %r'@SNAPPY_PATCHLEVEL@' => '4',
86
+ }.each { |ptn, str| hdr.gsub! ptn, str }
87
+ File.open(File.join(dst, 'snappy-stubs-public.h'), 'wb'){ |f| f.write hdr }
88
+
89
+ FileUtils.touch 'config.h'
90
+ end
91
+
92
+ have_library 'stdc++'
93
+ create_makefile('packsnap/packsnap')
94
+
@@ -0,0 +1,137 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2012 FURUHASHI Sadayuki
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ #include "packer.h"
20
+
21
+ void msgpack_packer_init(msgpack_packer_t* pk)
22
+ {
23
+ memset(pk, 0, sizeof(msgpack_packer_t));
24
+
25
+ msgpack_buffer_init(PACKER_BUFFER_(pk));
26
+
27
+ pk->io = Qnil;
28
+ }
29
+
30
+ void msgpack_packer_destroy(msgpack_packer_t* pk)
31
+ {
32
+ msgpack_buffer_destroy(PACKER_BUFFER_(pk));
33
+ }
34
+
35
+ void msgpack_packer_mark(msgpack_packer_t* pk)
36
+ {
37
+ rb_gc_mark(pk->io);
38
+
39
+ /* See MessagePack_Buffer_wrap */
40
+ /* msgpack_buffer_mark(PACKER_BUFFER_(pk)); */
41
+ rb_gc_mark(pk->buffer_ref);
42
+ }
43
+
44
+ void msgpack_packer_reset(msgpack_packer_t* pk)
45
+ {
46
+ msgpack_buffer_clear(PACKER_BUFFER_(pk));
47
+
48
+ pk->io = Qnil;
49
+ pk->io_write_all_method = 0;
50
+ pk->buffer_ref = Qnil;
51
+ }
52
+
53
+
54
+ void msgpack_packer_write_array_value(msgpack_packer_t* pk, VALUE v)
55
+ {
56
+ size_t len = RARRAY_LEN(v);
57
+ if(len > 0xffffffffUL) {
58
+ // TODO rb_eArgError?
59
+ rb_raise(rb_eArgError, "size of array is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
60
+ }
61
+ unsigned int len32 = (unsigned int)len;
62
+ msgpack_packer_write_array_header(pk, len32);
63
+
64
+ unsigned int i;
65
+ for(i=0; i < len32; ++i) {
66
+ VALUE e = rb_ary_entry(v, i);
67
+ msgpack_packer_write_value(pk, e);
68
+ }
69
+ }
70
+
71
+ static int write_hash_foreach(VALUE key, VALUE value, VALUE pk_value)
72
+ {
73
+ if (key == Qundef) {
74
+ return ST_CONTINUE;
75
+ }
76
+ msgpack_packer_t* pk = (msgpack_packer_t*) pk_value;
77
+ msgpack_packer_write_value(pk, key);
78
+ msgpack_packer_write_value(pk, value);
79
+ return ST_CONTINUE;
80
+ }
81
+
82
+ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v)
83
+ {
84
+ size_t len = RHASH_SIZE(v);
85
+ if(len > 0xffffffffUL) {
86
+ // TODO rb_eArgError?
87
+ rb_raise(rb_eArgError, "size of array is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
88
+ }
89
+ unsigned int len32 = (unsigned int)len;
90
+ msgpack_packer_write_map_header(pk, len32);
91
+
92
+ rb_hash_foreach(v, (int (*)(...))write_hash_foreach, (VALUE) pk);
93
+ }
94
+
95
+ static void _msgpack_packer_write_other_value(msgpack_packer_t* pk, VALUE v)
96
+ {
97
+ rb_funcall(v, pk->to_msgpack_method, 1, pk->to_msgpack_arg);
98
+ }
99
+
100
+ void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v)
101
+ {
102
+ switch(rb_type(v)) {
103
+ case T_NIL:
104
+ msgpack_packer_write_nil(pk);
105
+ break;
106
+ case T_TRUE:
107
+ msgpack_packer_write_true(pk);
108
+ break;
109
+ case T_FALSE:
110
+ msgpack_packer_write_false(pk);
111
+ break;
112
+ case T_FIXNUM:
113
+ msgpack_packer_write_fixnum_value(pk, v);
114
+ break;
115
+ case T_SYMBOL:
116
+ msgpack_packer_write_symbol_value(pk, v);
117
+ break;
118
+ case T_STRING:
119
+ msgpack_packer_write_string_value(pk, v);
120
+ break;
121
+ case T_ARRAY:
122
+ msgpack_packer_write_array_value(pk, v);
123
+ break;
124
+ case T_HASH:
125
+ msgpack_packer_write_hash_value(pk, v);
126
+ break;
127
+ case T_BIGNUM:
128
+ msgpack_packer_write_bignum_value(pk, v);
129
+ break;
130
+ case T_FLOAT:
131
+ msgpack_packer_write_float_value(pk, v);
132
+ break;
133
+ default:
134
+ _msgpack_packer_write_other_value(pk, v);
135
+ }
136
+ }
137
+
@@ -0,0 +1,334 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2012 FURUHASHI Sadayuki
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ #ifndef MSGPACK_RUBY_PACKER_H__
19
+ #define MSGPACK_RUBY_PACKER_H__
20
+
21
+ #include "buffer.hh"
22
+
23
+ #ifndef MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY
24
+ #define MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY (1024)
25
+ #endif
26
+
27
+ struct msgpack_packer_t;
28
+ typedef struct msgpack_packer_t msgpack_packer_t;
29
+
30
+ struct msgpack_packer_t {
31
+ msgpack_buffer_t buffer;
32
+
33
+ VALUE io;
34
+ ID io_write_all_method;
35
+
36
+ ID to_msgpack_method;
37
+ VALUE to_msgpack_arg;
38
+
39
+ VALUE buffer_ref;
40
+ };
41
+
42
+ #define PACKER_BUFFER_(pk) (&(pk)->buffer)
43
+
44
+ void msgpack_packer_init(msgpack_packer_t* pk);
45
+
46
+ void msgpack_packer_destroy(msgpack_packer_t* pk);
47
+
48
+ void msgpack_packer_mark(msgpack_packer_t* pk);
49
+
50
+ static inline void msgpack_packer_set_to_msgpack_method(msgpack_packer_t* pk,
51
+ ID to_msgpack_method, VALUE to_msgpack_arg)
52
+ {
53
+ pk->to_msgpack_method = to_msgpack_method;
54
+ pk->to_msgpack_arg = to_msgpack_arg;
55
+ }
56
+
57
+ static inline void msgpack_packer_set_io(msgpack_packer_t* pk, VALUE io, ID io_write_all_method)
58
+ {
59
+ pk->io = io;
60
+ pk->io_write_all_method = io_write_all_method;
61
+ }
62
+
63
+ void msgpack_packer_reset(msgpack_packer_t* pk);
64
+
65
+
66
+ //void _msgpack_packer_allocate_writable_space(msgpack_packer_t* pk, size_t require);
67
+
68
+ //static inline void _msgpack_packer_ensure_writable(msgpack_packer_t* pk, size_t require)
69
+ //{
70
+ // if(msgpack_buffer_writable_size(PACKER_BUFFER_(pk)) < require) {
71
+ // _msgpack_packer_allocate_writable_space(pk, require);
72
+ // }
73
+ //}
74
+
75
+ static inline void msgpack_packer_write_nil(msgpack_packer_t* pk)
76
+ {
77
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
78
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc0);
79
+ }
80
+
81
+ static inline void msgpack_packer_write_true(msgpack_packer_t* pk)
82
+ {
83
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
84
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc3);
85
+ }
86
+
87
+ static inline void msgpack_packer_write_false(msgpack_packer_t* pk)
88
+ {
89
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
90
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc2);
91
+ }
92
+
93
+ static inline void _msgpack_packer_write_fixint(msgpack_packer_t* pk, int8_t v)
94
+ {
95
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
96
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), v);
97
+ }
98
+
99
+ static inline void _msgpack_packer_write_uint8(msgpack_packer_t* pk, uint8_t v)
100
+ {
101
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 2);
102
+ msgpack_buffer_write_2(PACKER_BUFFER_(pk), 0xcc, v);
103
+ }
104
+
105
+ static inline void _msgpack_packer_write_uint16(msgpack_packer_t* pk, uint16_t v)
106
+ {
107
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
108
+ uint16_t be = _msgpack_be16(v);
109
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcd, (const void*)&be, 2);
110
+ }
111
+
112
+ static inline void _msgpack_packer_write_uint32(msgpack_packer_t* pk, uint32_t v)
113
+ {
114
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
115
+ uint32_t be = _msgpack_be32(v);
116
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xce, (const void*)&be, 4);
117
+ }
118
+
119
+ static inline void _msgpack_packer_write_uint64(msgpack_packer_t* pk, uint64_t v)
120
+ {
121
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
122
+ uint64_t be = _msgpack_be64(v);
123
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcf, (const void*)&be, 8);
124
+ }
125
+
126
+ static inline void _msgpack_packer_write_int8(msgpack_packer_t* pk, int8_t v)
127
+ {
128
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 2);
129
+ msgpack_buffer_write_2(PACKER_BUFFER_(pk), 0xd0, v);
130
+ }
131
+
132
+ static inline void _msgpack_packer_write_int16(msgpack_packer_t* pk, int16_t v)
133
+ {
134
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
135
+ uint16_t be = _msgpack_be16(v);
136
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd1, (const void*)&be, 2);
137
+ }
138
+
139
+ static inline void _msgpack_packer_write_int32(msgpack_packer_t* pk, int32_t v)
140
+ {
141
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
142
+ uint32_t be = _msgpack_be32(v);
143
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd2, (const void*)&be, 4);
144
+ }
145
+
146
+ static inline void _msgpack_packer_write_int64(msgpack_packer_t* pk, int64_t v)
147
+ {
148
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
149
+ uint64_t be = _msgpack_be64(v);
150
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd3, (const void*)&be, 8);
151
+ }
152
+
153
+ static inline void msgpack_packer_write_long(msgpack_packer_t* pk, long v)
154
+ {
155
+ if(v < -0x20L) {
156
+ if(v < -0x8000L) {
157
+ if(v < -0x80000000L) {
158
+ _msgpack_packer_write_int64(pk, (int64_t) v);
159
+ } else {
160
+ _msgpack_packer_write_int32(pk, (int32_t) v);
161
+ }
162
+ } else {
163
+ if(v < -0x80L) {
164
+ _msgpack_packer_write_int16(pk, (int16_t) v);
165
+ } else {
166
+ _msgpack_packer_write_int8(pk, (int8_t) v);
167
+ }
168
+ }
169
+ } else if(v <= 0x7fL) {
170
+ _msgpack_packer_write_fixint(pk, (int8_t) v);
171
+ } else {
172
+ if(v <= 0xffffL) {
173
+ if(v <= 0xffL) {
174
+ _msgpack_packer_write_uint8(pk, (uint8_t) v);
175
+ } else {
176
+ _msgpack_packer_write_uint16(pk, (uint16_t) v);
177
+ }
178
+ } else {
179
+ if(v <= 0xffffffffL) {
180
+ _msgpack_packer_write_uint32(pk, (uint32_t) v);
181
+ } else {
182
+ _msgpack_packer_write_uint64(pk, (uint64_t) v);
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ static inline void msgpack_packer_write_u64(msgpack_packer_t* pk, uint64_t v)
189
+ {
190
+ if(v <= 0xffULL) {
191
+ if(v <= 0x7fULL) {
192
+ _msgpack_packer_write_fixint(pk, (int8_t) v);
193
+ } else {
194
+ _msgpack_packer_write_uint8(pk, (uint8_t) v);
195
+ }
196
+ } else {
197
+ if(v <= 0xffffULL) {
198
+ _msgpack_packer_write_uint16(pk, (uint16_t) v);
199
+ } else if(v <= 0xffffffffULL) {
200
+ _msgpack_packer_write_uint32(pk, (uint32_t) v);
201
+ } else {
202
+ _msgpack_packer_write_uint64(pk, (uint64_t) v);
203
+ }
204
+ }
205
+ }
206
+
207
+ static inline void msgpack_packer_write_double(msgpack_packer_t* pk, double v)
208
+ {
209
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
210
+ union {
211
+ double d;
212
+ uint64_t u64;
213
+ char mem[8];
214
+ } castbuf = { v };
215
+ castbuf.u64 = _msgpack_be_double(castbuf.u64); /* FIXME _msgpack_be_double */
216
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcb, castbuf.mem, 8);
217
+ }
218
+
219
+ static inline void msgpack_packer_write_raw_header(msgpack_packer_t* pk, unsigned int n)
220
+ {
221
+ if(n < 32) {
222
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
223
+ unsigned char h = 0xa0 | (uint8_t) n;
224
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
225
+ } else if(n < 65536) {
226
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
227
+ uint16_t be = _msgpack_be16(n);
228
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xda, (const void*)&be, 2);
229
+ } else {
230
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
231
+ uint32_t be = _msgpack_be32(n);
232
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdb, (const void*)&be, 4);
233
+ }
234
+ }
235
+
236
+ static inline void msgpack_packer_write_array_header(msgpack_packer_t* pk, unsigned int n)
237
+ {
238
+ if(n < 16) {
239
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
240
+ unsigned char h = 0x90 | (uint8_t) n;
241
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
242
+ } else if(n < 65536) {
243
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
244
+ uint16_t be = _msgpack_be16(n);
245
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdc, (const void*)&be, 2);
246
+ } else {
247
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
248
+ uint32_t be = _msgpack_be32(n);
249
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdd, (const void*)&be, 4);
250
+ }
251
+ }
252
+
253
+ static inline void msgpack_packer_write_map_header(msgpack_packer_t* pk, unsigned int n)
254
+ {
255
+ if(n < 16) {
256
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
257
+ unsigned char h = 0x80 | (uint8_t) n;
258
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
259
+ } else if(n < 65536) {
260
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
261
+ uint16_t be = _msgpack_be16(n);
262
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xde, (const void*)&be, 2);
263
+ } else {
264
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
265
+ uint32_t be = _msgpack_be32(n);
266
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdf, (const void*)&be, 4);
267
+ }
268
+ }
269
+
270
+
271
+ void _msgpack_packer_write_string_to_io(msgpack_packer_t* pk, VALUE string);
272
+
273
+ static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
274
+ {
275
+ /* TODO encoding conversion */
276
+ size_t len = RSTRING_LEN(v);
277
+ if(len > 0xffffffffUL) {
278
+ // TODO rb_eArgError?
279
+ rb_raise(rb_eArgError, "size of string is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
280
+ }
281
+ msgpack_packer_write_raw_header(pk, (unsigned int)len);
282
+ msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
283
+ //if(pk->io != Qnil && RSTRING_LEN(v) > MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY) {
284
+ // msgpack_buffer_flush_to_io(PACKER_BUFFER_(pk), pk->io, pk->io_write_all_method);
285
+ // rb_funcall(pk->io, pk->io_write_all_method, 1, v);
286
+ //} else {
287
+ // msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
288
+ //}
289
+ }
290
+
291
+ static inline void msgpack_packer_write_symbol_value(msgpack_packer_t* pk, VALUE v)
292
+ {
293
+ const char* name = rb_id2name(SYM2ID(v));
294
+ size_t len = strlen(name);
295
+ if(len > 0xffffffffUL) {
296
+ // TODO rb_eArgError?
297
+ rb_raise(rb_eArgError, "size of symbol is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
298
+ }
299
+ msgpack_packer_write_raw_header(pk, (unsigned int)len);
300
+ msgpack_buffer_append(PACKER_BUFFER_(pk), name, len);
301
+ }
302
+
303
+ static inline void msgpack_packer_write_fixnum_value(msgpack_packer_t* pk, VALUE v)
304
+ {
305
+ #ifdef JRUBY
306
+ msgpack_packer_write_long(pk, FIXNUM_P(v) ? FIX2LONG(v) : rb_num2ll(v));
307
+ #else
308
+ msgpack_packer_write_long(pk, FIX2LONG(v));
309
+ #endif
310
+ }
311
+
312
+ static inline void msgpack_packer_write_bignum_value(msgpack_packer_t* pk, VALUE v)
313
+ {
314
+ if(RBIGNUM_POSITIVE_P(v)) {
315
+ msgpack_packer_write_u64(pk, rb_big2ull(v));
316
+ } else {
317
+ msgpack_packer_write_long(pk, rb_big2ll(v)); /* FIXME long long? */
318
+ }
319
+ }
320
+
321
+ static inline void msgpack_packer_write_float_value(msgpack_packer_t* pk, VALUE v)
322
+ {
323
+ msgpack_packer_write_double(pk, rb_num2dbl(v));
324
+ }
325
+
326
+ void msgpack_packer_write_array_value(msgpack_packer_t* pk, VALUE v);
327
+
328
+ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v);
329
+
330
+ void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v);
331
+
332
+
333
+ #endif
334
+