packsnap 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+