mochilo 1.2.1 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,21 +4,6 @@ MOAPI mo_value moapi_bytes_new(const char *src, size_t len)
4
4
  return (mo_value)rb_str_new(src, len);
5
5
  }
6
6
 
7
- MOAPI mo_value moapi_sym_new(const char *src, size_t len)
8
- {
9
- char *symbol;
10
-
11
- if (len > 0xFF)
12
- rb_raise(rb_eArgError, "Symbol too long to encode in BananaPack");
13
-
14
- symbol = alloca(len + 1);
15
- memcpy(symbol, src, len);
16
- symbol[len] = '\0';
17
-
18
- return (mo_value)ID2SYM(rb_intern(symbol));
19
- }
20
-
21
- #ifdef HAVE_RUBY_ENCODING_H
22
7
  MOAPI mo_value moapi_str_new(const char *src, size_t len, enum msgpack_enc_t encoding)
23
8
  {
24
9
  int index = 0;
@@ -32,7 +17,6 @@ MOAPI mo_value moapi_str_new(const char *src, size_t len, enum msgpack_enc_t enc
32
17
 
33
18
  return (mo_value)str;
34
19
  }
35
- #endif
36
20
 
37
21
  MOAPI mo_value moapi_array_new(size_t array_size)
38
22
  {
@@ -7,7 +7,7 @@
7
7
 
8
8
  extern VALUE rb_eMochiloPackError;
9
9
 
10
- void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted);
10
+ void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object);
11
11
 
12
12
  void mochilo_pack_fixnum(mochilo_buf *buf, VALUE rb_fixnum)
13
13
  {
@@ -75,14 +75,13 @@ void mochilo_pack_bignum(mochilo_buf *buf, VALUE rb_bignum)
75
75
 
76
76
  struct mochilo_hash_pack {
77
77
  mochilo_buf *buf;
78
- int trusted;
79
78
  };
80
79
 
81
80
  static int hash_callback(VALUE key, VALUE val, VALUE opaque)
82
81
  {
83
82
  struct mochilo_hash_pack *hash_pack = (struct mochilo_hash_pack*)opaque;
84
- mochilo_pack_one(hash_pack->buf, key, hash_pack->trusted);
85
- mochilo_pack_one(hash_pack->buf, val, hash_pack->trusted);
83
+ mochilo_pack_one(hash_pack->buf, key);
84
+ mochilo_pack_one(hash_pack->buf, val);
86
85
  return 0;
87
86
  }
88
87
 
@@ -93,13 +92,12 @@ void mochilo_pack_double(mochilo_buf *buf, VALUE rb_double)
93
92
  mochilo_buf_put64be(buf, &d);
94
93
  }
95
94
 
96
- void mochilo_pack_hash(mochilo_buf *buf, VALUE rb_hash, int trusted)
95
+ void mochilo_pack_hash(mochilo_buf *buf, VALUE rb_hash)
97
96
  {
98
97
  struct mochilo_hash_pack hash_pack;
99
98
  long size = RHASH_SIZE(rb_hash);
100
99
 
101
100
  hash_pack.buf = buf;
102
- hash_pack.trusted = trusted;
103
101
 
104
102
  if (size < 0x10) {
105
103
  uint8_t lead = 0x80 | size;
@@ -124,46 +122,26 @@ void mochilo_pack_bytes(mochilo_buf *buf, VALUE rb_bytes)
124
122
  {
125
123
  long size = RSTRING_LEN(rb_bytes);
126
124
 
127
- if (size < 0x20) {
128
- uint8_t lead = 0xA0 | size;
125
+ if (size < 0x100) {
126
+ uint8_t lead = size;
127
+ mochilo_buf_putc(buf, MSGPACK_T_BIN8);
129
128
  mochilo_buf_putc(buf, lead);
130
- }
131
-
132
- else if (size < 0x10000) {
129
+ } else if (size < 0x10000) {
133
130
  uint16_t lead = size;
134
- mochilo_buf_putc(buf, MSGPACK_T_RAW16);
131
+ mochilo_buf_putc(buf, MSGPACK_T_BIN16);
135
132
  mochilo_buf_put16be(buf, &lead);
136
- }
137
-
138
- else {
139
- mochilo_buf_putc(buf, MSGPACK_T_RAW32);
133
+ } else if (size < 0x100000000) {
134
+ mochilo_buf_putc(buf, MSGPACK_T_BIN32);
140
135
  mochilo_buf_put32be(buf, &size);
141
- }
142
-
143
- mochilo_buf_put(buf, RSTRING_PTR(rb_bytes), size);
144
- }
145
-
146
- void mochilo_pack_symbol(mochilo_buf *buf, VALUE rb_symbol)
147
- {
148
- long size;
149
- const char *name;
150
-
151
- name = rb_id2name(SYM2ID(rb_symbol));
152
- size = strlen(name);
153
-
154
- if (size < 0x100) {
155
- uint8_t lead = size;
156
- mochilo_buf_putc(buf, MSGPACK_T_SYM);
157
- mochilo_buf_putc(buf, lead);
158
136
  } else {
137
+ // there is no bin 64
159
138
  rb_raise(rb_eMochiloPackError,
160
- "Symbol too long: must be under %d bytes, %ld given", 0x100, size);
139
+ "Binary string cannot be larger than %ld bytes", 0x100000000);
161
140
  }
162
141
 
163
- mochilo_buf_put(buf, name, size);
142
+ mochilo_buf_put(buf, RSTRING_PTR(rb_bytes), size);
164
143
  }
165
144
 
166
- #ifdef HAVE_RUBY_ENCODING_H
167
145
  void mochilo_pack_str(mochilo_buf *buf, VALUE rb_str)
168
146
  {
169
147
  long size = RSTRING_LEN(rb_str);
@@ -172,27 +150,57 @@ void mochilo_pack_str(mochilo_buf *buf, VALUE rb_str)
172
150
  const struct mochilo_enc_map *enc2id;
173
151
  const char *enc_name;
174
152
 
175
- if (size < 0x10000) {
176
- uint16_t lead = size;
177
- mochilo_buf_putc(buf, MSGPACK_T_STR16);
178
- mochilo_buf_put16be(buf, &lead);
179
- }
180
-
181
- else {
182
- mochilo_buf_putc(buf, MSGPACK_T_STR32);
183
- mochilo_buf_put32be(buf, &size);
184
- }
185
-
186
153
  encoding = rb_enc_get(rb_str);
187
154
  enc_name = rb_enc_name(encoding);
188
- enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));
189
155
 
190
- mochilo_buf_putc(buf, enc2id ? enc2id->id : 0);
156
+ if (encoding == rb_utf8_encoding()) {
157
+ // use str type from msgpack spec
158
+ if (size < 0x20) {
159
+ uint8_t lead = 0xa0 | size;
160
+ mochilo_buf_putc(buf, lead);
161
+ } else if (size < 0x100) {
162
+ uint8_t lead = size;
163
+ mochilo_buf_putc(buf, MSGPACK_T_STR8);
164
+ mochilo_buf_putc(buf, lead);
165
+ } else if (size < 0x10000) {
166
+ uint16_t lead = size;
167
+ mochilo_buf_putc(buf, MSGPACK_T_STR16);
168
+ mochilo_buf_put16be(buf, &lead);
169
+ } else if (size < 0x100000000) {
170
+ mochilo_buf_putc(buf, MSGPACK_T_STR32);
171
+ mochilo_buf_put32be(buf, &size);
172
+ } else {
173
+ // there is no str 64
174
+ rb_raise(rb_eMochiloPackError,
175
+ "String cannot be larger than %ld bytes", 0x100000000);
176
+ }
177
+ } else {
178
+ // if another encoding is used we need to use our custom types
179
+ if (size < 0x100) {
180
+ uint8_t lead = size;
181
+ mochilo_buf_putc(buf, MSGPACK_T_ENC8);
182
+ mochilo_buf_putc(buf, lead);
183
+ } else if (size < 0x10000) {
184
+ uint16_t lead = size;
185
+ mochilo_buf_putc(buf, MSGPACK_T_ENC16);
186
+ mochilo_buf_put16be(buf, &lead);
187
+ } else if (size < 0x100000000) {
188
+ mochilo_buf_putc(buf, MSGPACK_T_ENC32);
189
+ mochilo_buf_put32be(buf, &size);
190
+ } else {
191
+ // there is no ext 64
192
+ rb_raise(rb_eMochiloPackError,
193
+ "String cannot be larger than %ld bytes", 0x100000000);
194
+ }
195
+
196
+ enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));
197
+ mochilo_buf_putc(buf, enc2id ? enc2id->id : 0);
198
+ }
199
+
191
200
  mochilo_buf_put(buf, RSTRING_PTR(rb_str), size);
192
201
  }
193
- #endif
194
202
 
195
- void mochilo_pack_array(mochilo_buf *buf, VALUE rb_array, int trusted)
203
+ void mochilo_pack_array(mochilo_buf *buf, VALUE rb_array)
196
204
  {
197
205
  long i, size = RARRAY_LEN(rb_array);
198
206
 
@@ -213,11 +221,11 @@ void mochilo_pack_array(mochilo_buf *buf, VALUE rb_array, int trusted)
213
221
  }
214
222
 
215
223
  for (i = 0; i < size; i++) {
216
- mochilo_pack_one(buf, rb_ary_entry(rb_array, i), trusted);
224
+ mochilo_pack_one(buf, rb_ary_entry(rb_array, i));
217
225
  }
218
226
  }
219
227
 
220
- void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted)
228
+ void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object)
221
229
  {
222
230
  switch (rb_type(rb_object)) {
223
231
  case T_NIL:
@@ -236,28 +244,19 @@ void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted)
236
244
  mochilo_pack_fixnum(buf, rb_object);
237
245
  return;
238
246
 
239
- case T_SYMBOL:
240
- if (trusted)
241
- mochilo_pack_symbol(buf, rb_object);
242
- else
243
- mochilo_pack_str(buf, rb_obj_as_string(rb_object));
244
- return;
245
-
246
247
  case T_STRING:
247
- #ifdef HAVE_RUBY_ENCODING_H
248
248
  if (ENCODING_GET(rb_object) != 0)
249
249
  mochilo_pack_str(buf, rb_object);
250
250
  else
251
- #endif
252
251
  mochilo_pack_bytes(buf, rb_object);
253
252
  return;
254
253
 
255
254
  case T_HASH:
256
- mochilo_pack_hash(buf, rb_object, trusted);
255
+ mochilo_pack_hash(buf, rb_object);
257
256
  return;
258
257
 
259
258
  case T_ARRAY:
260
- mochilo_pack_array(buf, rb_object, trusted);
259
+ mochilo_pack_array(buf, rb_object);
261
260
  return;
262
261
 
263
262
  case T_FLOAT:
@@ -269,14 +268,8 @@ void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted)
269
268
  return;
270
269
 
271
270
  default:
272
- if (rb_respond_to(rb_object, rb_intern("to_bpack"))) {
273
- VALUE bpack = rb_funcall(rb_object, rb_intern("to_bpack"), 0);
274
-
275
- mochilo_buf_put(buf, RSTRING_PTR(bpack), RSTRING_LEN(bpack));
276
- } else {
277
- rb_raise(rb_eMochiloPackError,
278
- "Unsupported object type: %s", rb_obj_classname(rb_object));
279
- }
271
+ rb_raise(rb_eMochiloPackError,
272
+ "Unsupported object type: %s", rb_obj_classname(rb_object));
280
273
  return;
281
274
  }
282
275
  }
@@ -159,14 +159,10 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
159
159
  return unpack_hash(_value, (size_t)length, src);
160
160
  }
161
161
 
162
- case MSGPACK_T_SYM:
162
+ case MSGPACK_T_STR8:
163
163
  {
164
164
  uint8_t length;
165
165
  const char *ptr;
166
-
167
- if (!src->trusted) {
168
- return MSGPACK_EUNSAFE;
169
- }
170
166
 
171
167
  SRC_ENSURE_AVAIL(src, 1);
172
168
  mochilo_src_get8be(src, &length);
@@ -174,12 +170,58 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
174
170
  if (!(ptr = mochilo_src_peek(src, length)))
175
171
  return -1;
176
172
 
177
- *_value = moapi_sym_new(ptr, length);
173
+ *_value = moapi_str_new(ptr, length, MSGPACK_ENC_UTF_8);
178
174
  return 0;
179
175
  }
180
176
 
181
- #ifdef HAVE_RUBY_ENCODING_H
182
177
  case MSGPACK_T_STR16:
178
+ {
179
+ uint16_t length;
180
+ const char *ptr;
181
+
182
+ SRC_ENSURE_AVAIL(src, 2 + 1);
183
+ mochilo_src_get16be(src, &length);
184
+
185
+ if (!(ptr = mochilo_src_peek(src, length)))
186
+ return -1;
187
+
188
+ *_value = moapi_str_new(ptr, length, MSGPACK_ENC_UTF_8);
189
+ return 0;
190
+ }
191
+
192
+ case MSGPACK_T_STR32:
193
+ {
194
+ uint32_t length;
195
+ const char *ptr;
196
+
197
+ SRC_ENSURE_AVAIL(src, 4 + 1);
198
+ mochilo_src_get32be(src, &length);
199
+
200
+ if (!(ptr = mochilo_src_peek(src, length)))
201
+ return -1;
202
+
203
+ *_value = moapi_str_new(ptr, length, MSGPACK_ENC_UTF_8);
204
+ return 0;
205
+ }
206
+
207
+ case MSGPACK_T_ENC8:
208
+ {
209
+ uint8_t length;
210
+ uint8_t encoding;
211
+ const char *ptr;
212
+
213
+ SRC_ENSURE_AVAIL(src, 1 + 1);
214
+ mochilo_src_get8be(src, &length);
215
+ mochilo_src_get8be(src, &encoding);
216
+
217
+ if (!(ptr = mochilo_src_peek(src, length)))
218
+ return -1;
219
+
220
+ *_value = moapi_str_new(ptr, length, encoding);
221
+ return 0;
222
+ }
223
+
224
+ case MSGPACK_T_ENC16:
183
225
  {
184
226
  uint16_t length;
185
227
  uint8_t encoding;
@@ -196,7 +238,7 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
196
238
  return 0;
197
239
  }
198
240
 
199
- case MSGPACK_T_STR32:
241
+ case MSGPACK_T_ENC32:
200
242
  {
201
243
  uint32_t length;
202
244
  uint8_t encoding;
@@ -212,9 +254,23 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
212
254
  *_value = moapi_str_new(ptr, length, encoding);
213
255
  return 0;
214
256
  }
215
- #endif
216
257
 
217
- case MSGPACK_T_RAW16:
258
+ case MSGPACK_T_BIN8:
259
+ {
260
+ uint8_t length;
261
+ const char *ptr;
262
+
263
+ SRC_ENSURE_AVAIL(src, 1);
264
+ mochilo_src_get8be(src, &length);
265
+
266
+ if (!(ptr = mochilo_src_peek(src, length)))
267
+ return -1;
268
+
269
+ *_value = moapi_bytes_new(ptr, length);
270
+ return 0;
271
+ }
272
+
273
+ case MSGPACK_T_BIN16:
218
274
  {
219
275
  uint16_t length;
220
276
  const char *ptr;
@@ -229,7 +285,7 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
229
285
  return 0;
230
286
  }
231
287
 
232
- case MSGPACK_T_RAW32:
288
+ case MSGPACK_T_BIN32:
233
289
  {
234
290
  uint32_t length;
235
291
  const char *ptr;
@@ -268,7 +324,7 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
268
324
  if (!(ptr = mochilo_src_peek(src, length)))
269
325
  return -1;
270
326
 
271
- *_value = moapi_bytes_new(ptr, length);
327
+ *_value = moapi_str_new(ptr, length, MSGPACK_ENC_UTF_8);
272
328
  return 0;
273
329
  }
274
330
 
@@ -276,4 +332,3 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
276
332
  }
277
333
  }
278
334
  }
279
-
@@ -1,3 +1,3 @@
1
1
  module Mochilo
2
- VERSION = "1.2.1"
2
+ VERSION = "2.0"
3
3
  end
@@ -13,10 +13,12 @@ Gem::Specification.new do |s|
13
13
  s.require_paths = ["lib"]
14
14
  s.rubygems_version = %q{1.4.2}
15
15
  s.summary = %q{A ruby library for BananaPack}
16
- s.test_files = `git ls-files test`.split("\n")
16
+ s.test_files = `git ls-files spec`.split("\n")
17
17
  s.required_ruby_version = ">= 1.9.3"
18
18
 
19
19
  # tests
20
20
  s.add_development_dependency 'rake-compiler', ">= 0.8.1"
21
21
  s.add_development_dependency 'minitest', ">= 4.1.0"
22
+ # benchmarks
23
+ s.add_development_dependency 'msgpack'
22
24
  end
@@ -12,5 +12,5 @@ cd "$(dirname "$0")/.."
12
12
  if bundle check 1>/dev/null 2>&1; then
13
13
  echo "Gem environment up-to-date"
14
14
  else
15
- exec bundle install --binstubs --path vendor/gems --without benchmark "$@"
15
+ exec bundle install --binstubs --path vendor/gems "$@"
16
16
  fi
@@ -4,7 +4,7 @@ require File.expand_path('../setup', __FILE__)
4
4
  require 'mochilo'
5
5
  require 'stringio'
6
6
 
7
- class MochiloPackTest < MiniTest::Unit::TestCase
7
+ class MochiloPackTest < Minitest::Test
8
8
 
9
9
  OBJECTS = [
10
10
  {"hello" => "world"},
@@ -52,122 +52,222 @@ class MochiloPackTest < MiniTest::Unit::TestCase
52
52
  end
53
53
 
54
54
  def test_pack_positive_fixed
55
- assert_equal "\x15", Mochilo.pack(21)
55
+ [0,127].each do |int|
56
+ assert_equal int.chr, Mochilo.pack(int)
57
+ end
56
58
  end
57
59
 
58
60
  def test_pack_negative_fixed
59
- assert_equal "\xEB", Mochilo.pack(-21)
61
+ assert_equal "\xFF", Mochilo.pack(-1)
62
+ assert_equal "\xE0", Mochilo.pack(-32)
60
63
  end
61
64
 
62
65
  def test_pack_uint8
63
- assert_equal "\xCC\xD6", Mochilo.pack(214)
66
+ [128,255].each do |int|
67
+ assert_equal "\xCC#{int.chr}", Mochilo.pack(int)
68
+ end
64
69
  end
65
70
 
66
71
  def test_pack_uint16
67
- assert_equal "\xCDS\xE2", Mochilo.pack(21474)
72
+ [256,((2**16)-1)].each do |int|
73
+ packed = [int].pack("n")
74
+ assert_equal "\xCD#{packed}", Mochilo.pack(int)
75
+ end
68
76
  end
69
77
 
70
78
  def test_pack_uint32
71
- assert_equal "\xCE\x7F\xFF\xFF\xFF", Mochilo.pack(2147483647)
79
+ [(2**16),((2**32)-1)].each do |int|
80
+ packed = [int].pack("N")
81
+ assert_equal "\xCE#{packed}", Mochilo.pack(int)
82
+ end
72
83
  end
73
84
 
74
85
  def test_pack_uint64
75
- assert_equal "\xCF\x00\x00\x00\x04\xFF\xFF\xFF\xFF", Mochilo.pack(21474836479)
86
+ [(2**32),((2**64)-1)].each do |int|
87
+ packed = [int].pack("Q>")
88
+ assert_equal "\xCF#{packed}", Mochilo.pack(int)
89
+ end
76
90
  end
77
91
 
78
92
  def test_pack_int8
79
- assert_equal "\xD0\xDE", Mochilo.pack(-34)
93
+ assert_equal "\xD0\xDF", Mochilo.pack(-33)
94
+ assert_equal "\xD0\x80", Mochilo.pack(-128)
80
95
  end
81
96
 
82
97
  def test_pack_int16
83
- assert_equal "\xD1\xAC\x1E", Mochilo.pack(-21474)
98
+ assert_equal "\xD1\xFF\x7F", Mochilo.pack(-129)
99
+ assert_equal "\xD1\x80\x00", Mochilo.pack(-32768)
84
100
  end
85
101
 
86
102
  def test_pack_int32
87
- assert_equal "\xD2\x80\x00\x00\x01", Mochilo.pack(-2147483647)
103
+ assert_equal "\xD2\xFF\xFF\x7F\xFF", Mochilo.pack(-32769)
104
+ assert_equal "\xD2\x80\x00\x00\x00", Mochilo.pack(-2147483648)
88
105
  end
89
106
 
90
107
  def test_pack_int64
91
- assert_equal "\xD3\xFF\xFF\xFF\xFB\x00\x00\x00\x01", Mochilo.pack(-21474836479)
108
+ assert_equal "\xD3\xFF\xFF\xFF\xFF\x7F\xFF\xFF\xFF", Mochilo.pack(-2147483649)
109
+ assert_equal "\xD3\x80\x00\x00\x00\x00\x00\x00\x00", Mochilo.pack(-9223372036854775808)
92
110
  end
93
111
 
94
- if defined?(Encoding)
95
- def test_pack_str16
96
- str = "this is a test".force_encoding('UTF-8')
97
- assert_equal "\xD8\x00\x0E\x00#{str}", Mochilo.pack(str)
98
- end
112
+ def test_pack_fixed_str
113
+ str = "a".force_encoding('UTF-8')
114
+ assert_equal "\xA1#{str}", Mochilo.pack(str)
115
+
116
+ str = ("a"*31).force_encoding('UTF-8')
117
+ assert_equal "\xBF#{str}", Mochilo.pack(str)
99
118
  end
100
119
 
101
- def xtest_pack_str32
102
- # TODO: not sure how to test this without making a massive 66k string
120
+ def test_pack_str8
121
+ str = ("a"*32).force_encoding('UTF-8')
122
+ assert_equal "\xD9#{str.bytesize.chr}#{str}", Mochilo.pack(str)
123
+
124
+ str = ("a"*255).force_encoding('UTF-8')
125
+ assert_equal "\xD9#{str.bytesize.chr}#{str}", Mochilo.pack(str)
103
126
  end
104
127
 
105
- def test_pack_fixed_raw
106
- str = "this is a test"
107
- assert_equal "\xAE#{str}", Mochilo.pack(str)
128
+ def test_pack_str16
129
+ str = ("a"*256).force_encoding('UTF-8')
130
+ assert_equal "\xDA\x01\x00#{str}", Mochilo.pack(str)
131
+
132
+ str = ("a"*(2**16-1)).force_encoding('UTF-8')
133
+ assert_equal "\xDA\xFF\xFF#{str}", Mochilo.pack(str)
108
134
  end
109
135
 
110
- def test_pack_raw16
111
- str = ("a"*255)
112
- assert_equal "\xDA\x00\xFF#{str}", Mochilo.pack(str)
136
+ def test_pack_str32
137
+ str = ("a"*(2**16)).force_encoding('UTF-8')
138
+ assert_equal "\xDB\x00\x01\x00\x00#{str}", Mochilo.pack(str)
139
+
140
+ # This will create a 4GB string, so let's just skip that ;)
141
+ # str = ("a"*(2**32-1)).force_encoding('UTF-8')
142
+ # assert_equal "\xDB\x00\x01\x00\x00#{str}", Mochilo.pack(str)
113
143
  end
114
144
 
115
- def xtest_pack_raw32
116
- # TODO: not sure how to test this without making a massive 66k string
145
+ def test_pack_enc8
146
+ str = ("a"*32).force_encoding('ISO-8859-1')
147
+ assert_equal "\xC7#{str.bytesize.chr}\x0C#{str}", Mochilo.pack(str)
148
+
149
+ str = ("a"*255).force_encoding('ISO-8859-1')
150
+ assert_equal "\xC7#{str.bytesize.chr}\x0C#{str}", Mochilo.pack(str)
117
151
  end
118
152
 
119
- def test_pack_fixed_array
120
- assert_equal "\x90", Mochilo.pack([])
121
- assert_equal "\x91\x01", Mochilo.pack([1])
153
+ def test_pack_enc16
154
+ str = ("a"*256).force_encoding('ISO-8859-1')
155
+ assert_equal "\xC8\x01\x00\x0C#{str}", Mochilo.pack(str)
156
+
157
+ str = ("a"*(2**16-1)).force_encoding('ISO-8859-1')
158
+ assert_equal "\xC8\xFF\xFF\x0C#{str}", Mochilo.pack(str)
122
159
  end
123
160
 
124
- def test_pack_array16
125
- bytes = ("a"*34).bytes.to_a
126
- assert_equal "\xDC\x00\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", Mochilo.pack(bytes)
161
+ def test_pack_enc32
162
+ str = ("a"*(2**16)).force_encoding('ISO-8859-1')
163
+ assert_equal "\xC9\x00\x01\x00\x00\x0C#{str}", Mochilo.pack(str)
164
+
165
+ # This would create a 4GB string, so let's just skip that ;)
166
+ # str = ("a"*(2**32-1)).force_encoding('ISO-8859-1')
167
+ # assert_equal "\xC9\x00\x01\x00\x00\x0C#{str}", Mochilo.pack(str)
127
168
  end
128
169
 
129
- def xtest_pack_array32
130
- # TODO: not sure how to test this without making a massive 66k item array
170
+ def test_pack_bin8
171
+ str = ("a"*32).force_encoding('binary')
172
+ assert_equal "\xC4#{str.bytesize.chr}#{str}", Mochilo.pack(str)
173
+
174
+ str = ("a"*255).force_encoding('binary')
175
+ assert_equal "\xC4#{str.bytesize.chr}#{str}", Mochilo.pack(str)
131
176
  end
132
177
 
133
- def test_pack_fixed_map
134
- assert_equal "\x80", Mochilo.pack({})
135
- assert_equal "\x81\x01\x02", Mochilo.pack({1 => 2})
178
+ def test_pack_bin16
179
+ str = ("a"*256).force_encoding('binary')
180
+ assert_equal "\xC5\x01\x00#{str}", Mochilo.pack(str)
181
+
182
+ str = ("a"*(2**16-1)).force_encoding('binary')
183
+ assert_equal "\xC5\xFF\xFF#{str}", Mochilo.pack(str)
136
184
  end
137
185
 
138
- def test_pack_symbol
139
- assert_equal "\xD8\x00\x04\x01test", Mochilo.pack(:test)
140
- assert_equal "\xD4\x04test", Mochilo.pack_unsafe(:test)
186
+ def test_pack_bin32
187
+ str = ("a"*(2**16)).force_encoding('binary')
188
+ assert_equal "\xC6\x00\x01\x00\x00#{str}", Mochilo.pack(str)
189
+
190
+ # This would create a 4GB string, so let's just skip that ;)
191
+ # str = ("a"*(2**32-1)).force_encoding('UTF-8')
192
+ # assert_equal "\xC6\x00\x01\x00\x00#{str}", Mochilo.pack(str)
141
193
  end
142
194
 
143
- def test_pack_symbol_size
144
- too_big = ("a"*0x100).to_sym
145
- fine = ("a"*0xff).to_sym
195
+ def test_pack_fixed_array
196
+ assert_equal "\x90", Mochilo.pack([])
146
197
 
147
- assert_raises Mochilo::PackError do
148
- Mochilo.pack_unsafe(too_big)
149
- end
198
+ arr = (1..15).to_a
199
+ expected = "\x9F"
200
+ arr.each {|i| expected << Mochilo.pack(i)}
201
+ assert_equal expected, Mochilo.pack(arr)
202
+ end
150
203
 
151
- begin
152
- Mochilo.pack_unsafe(fine)
153
- rescue Mochilo::PackError => boom
154
- assert_nil boom, "exception raised, expected nothing"
155
- end
204
+ def test_pack_array16
205
+ arr = (1..16).to_a
206
+ expected = "\xDC\x00\x10"
207
+ arr.each {|i| expected << Mochilo.pack(i)}
208
+ assert_equal expected, Mochilo.pack(arr)
209
+
210
+ arr = (1..2**16-1).to_a
211
+ expected = "\xDC\xFF\xFF"
212
+ arr.each {|i| expected << Mochilo.pack(i)}
213
+ assert_equal expected, Mochilo.pack(arr)
156
214
  end
157
215
 
158
- def test_pack_map16
159
- bytes = ("a"*34).bytes.to_a
160
- assert_equal "\xDC\x00\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", Mochilo.pack(bytes)
216
+ def test_pack_array32
217
+ arr = (1..2**16).to_a
218
+ expected = "\xDD\x00\x01\x00\x00"
219
+ arr.each {|i| expected << Mochilo.pack(i)}
220
+ assert_equal expected, Mochilo.pack(arr)
221
+
222
+ # This would create an array with 4294967295 entries in it, so let's not
223
+ # arr = (1..2**32-1).to_a
224
+ # expected = "\xDD\xFF\xFF\xFF\xFF"
225
+ # arr.each {|i| expected << Mochilo.pack(i)}
226
+ # assert_equal expected, Mochilo.pack(arr)
161
227
  end
162
228
 
163
- def test_pack_map32
164
- # TODO: not sure how to test this without making a massive 66k item hash
229
+ def test_pack_fixed_map
230
+ assert_equal "\x80", Mochilo.pack({})
231
+
232
+ arr = (1..15).to_a
233
+ hash = {}
234
+ arr.each {|i| hash[i] = i }
235
+ expected = "\x8F"
236
+ arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
237
+ assert_equal expected, Mochilo.pack(hash)
165
238
  end
166
239
 
167
- def test_pack_custom_type
168
- obj = CustomType.new("custom")
240
+ def test_pack_map16
241
+ arr = (1..16).to_a
242
+ hash = {}
243
+ arr.each {|i| hash[i] = i }
244
+ expected = "\xDE\x00\x10"
245
+ arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
246
+ assert_equal expected, Mochilo.pack(hash)
247
+
248
+ arr = (1..2**16-1).to_a
249
+ hash = {}
250
+ arr.each {|i| hash[i] = i }
251
+ expected = "\xDE\xFF\xFF"
252
+ arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
253
+ assert_equal expected, Mochilo.pack(hash)
254
+ end
169
255
 
170
- assert_equal "\xA6custom", Mochilo.pack(obj)
256
+ def test_pack_map32
257
+ arr = (1..2**16).to_a
258
+ hash = {}
259
+ arr.each {|i| hash[i] = i }
260
+ expected = "\xDF\x00\x01\x00\x00"
261
+ arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
262
+ assert_equal expected, Mochilo.pack(hash)
263
+
264
+ # This would create a hash with 4294967295 entries in it, so let's not
265
+ # arr = (1..2**32-1).to_a
266
+ # hash = {}
267
+ # arr.each {|i| hash[i] = i }
268
+ # expected = "\xDF\xFF\xFF\xFF\xFF"
269
+ # arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
270
+ # assert_equal expected, Mochilo.pack(hash)
171
271
  end
172
272
 
173
273
  def test_pack_unsupported_type
@@ -175,4 +275,10 @@ class MochiloPackTest < MiniTest::Unit::TestCase
175
275
  Mochilo.pack(Object.new)
176
276
  end
177
277
  end
278
+
279
+ def test_pack_symbol_fails
280
+ assert_raises Mochilo::PackError do
281
+ Mochilo.pack(:symbol)
282
+ end
283
+ end
178
284
  end