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.
- data/.gitignore +17 -0
- data/ChangeLog +29 -0
- data/README.rdoc +26 -0
- data/Rakefile +150 -0
- data/doclib/msgpack.rb +54 -0
- data/doclib/packsnap/buffer.rb +177 -0
- data/doclib/packsnap/error.rb +14 -0
- data/doclib/packsnap/packer.rb +131 -0
- data/doclib/packsnap/unpacker.rb +130 -0
- data/ext/packsnap/buffer.cc +684 -0
- data/ext/packsnap/buffer.hh +439 -0
- data/ext/packsnap/buffer_class.cc +490 -0
- data/ext/packsnap/buffer_class.hh +32 -0
- data/ext/packsnap/compat.h +128 -0
- data/ext/packsnap/extconf.rb +94 -0
- data/ext/packsnap/packer.cc +137 -0
- data/ext/packsnap/packer.h +334 -0
- data/ext/packsnap/packer_class.cc +288 -0
- data/ext/packsnap/packer_class.hh +32 -0
- data/ext/packsnap/packsnap.h +4 -0
- data/ext/packsnap/rbinit.cc +52 -0
- data/ext/packsnap/rmem.cc +110 -0
- data/ext/packsnap/rmem.h +100 -0
- data/ext/packsnap/sysdep.h +112 -0
- data/ext/packsnap/sysdep_endian.h +50 -0
- data/ext/packsnap/sysdep_types.h +46 -0
- data/ext/packsnap/unpacker.cc +654 -0
- data/ext/packsnap/unpacker.hh +108 -0
- data/ext/packsnap/unpacker_class.cc +392 -0
- data/ext/packsnap/unpacker_class.hh +32 -0
- data/lib/packsnap.rb +12 -0
- data/lib/packsnap/version.rb +3 -0
- data/packsnap.gemspec +23 -0
- data/spec/buffer_io_spec.rb +228 -0
- data/spec/buffer_spec.rb +572 -0
- data/spec/cases.json +1 -0
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +39 -0
- data/spec/format_spec.rb +225 -0
- data/spec/packer_spec.rb +127 -0
- data/spec/random_compat.rb +24 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/unpacker_spec.rb +128 -0
- 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
|
+
|