msgpack 1.4.2 → 1.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +89 -0
  3. data/README.md +73 -13
  4. data/ext/java/org/msgpack/jruby/Buffer.java +26 -19
  5. data/ext/java/org/msgpack/jruby/Decoder.java +29 -21
  6. data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
  7. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +43 -64
  8. data/ext/java/org/msgpack/jruby/ExtensionValue.java +6 -9
  9. data/ext/java/org/msgpack/jruby/Factory.java +43 -42
  10. data/ext/java/org/msgpack/jruby/Packer.java +37 -40
  11. data/ext/java/org/msgpack/jruby/Unpacker.java +80 -73
  12. data/ext/msgpack/buffer.c +54 -74
  13. data/ext/msgpack/buffer.h +21 -18
  14. data/ext/msgpack/buffer_class.c +161 -52
  15. data/ext/msgpack/buffer_class.h +1 -0
  16. data/ext/msgpack/compat.h +0 -99
  17. data/ext/msgpack/extconf.rb +25 -46
  18. data/ext/msgpack/factory_class.c +143 -87
  19. data/ext/msgpack/packer.c +66 -43
  20. data/ext/msgpack/packer.h +25 -20
  21. data/ext/msgpack/packer_class.c +102 -130
  22. data/ext/msgpack/packer_class.h +11 -0
  23. data/ext/msgpack/packer_ext_registry.c +35 -40
  24. data/ext/msgpack/packer_ext_registry.h +41 -38
  25. data/ext/msgpack/rbinit.c +1 -1
  26. data/ext/msgpack/rmem.c +3 -4
  27. data/ext/msgpack/sysdep.h +5 -2
  28. data/ext/msgpack/unpacker.c +136 -111
  29. data/ext/msgpack/unpacker.h +16 -13
  30. data/ext/msgpack/unpacker_class.c +86 -126
  31. data/ext/msgpack/unpacker_class.h +11 -0
  32. data/ext/msgpack/unpacker_ext_registry.c +40 -28
  33. data/ext/msgpack/unpacker_ext_registry.h +21 -18
  34. data/lib/msgpack/bigint.rb +69 -0
  35. data/lib/msgpack/buffer.rb +9 -0
  36. data/lib/msgpack/factory.rb +140 -10
  37. data/lib/msgpack/packer.rb +10 -1
  38. data/lib/msgpack/symbol.rb +21 -4
  39. data/lib/msgpack/time.rb +1 -1
  40. data/lib/msgpack/unpacker.rb +14 -1
  41. data/lib/msgpack/version.rb +1 -1
  42. data/lib/msgpack.rb +6 -7
  43. data/msgpack.gemspec +8 -5
  44. metadata +37 -82
  45. data/.gitignore +0 -23
  46. data/.rubocop.yml +0 -36
  47. data/.travis.yml +0 -39
  48. data/Gemfile +0 -9
  49. data/Rakefile +0 -71
  50. data/appveyor.yml +0 -18
  51. data/bench/pack.rb +0 -23
  52. data/bench/pack_log.rb +0 -33
  53. data/bench/pack_log_long.rb +0 -65
  54. data/bench/pack_symbols.rb +0 -28
  55. data/bench/run.sh +0 -14
  56. data/bench/run_long.sh +0 -35
  57. data/bench/run_symbols.sh +0 -26
  58. data/bench/unpack.rb +0 -21
  59. data/bench/unpack_log.rb +0 -34
  60. data/bench/unpack_log_long.rb +0 -67
  61. data/doclib/msgpack/buffer.rb +0 -193
  62. data/doclib/msgpack/core_ext.rb +0 -101
  63. data/doclib/msgpack/error.rb +0 -19
  64. data/doclib/msgpack/extension_value.rb +0 -9
  65. data/doclib/msgpack/factory.rb +0 -101
  66. data/doclib/msgpack/packer.rb +0 -208
  67. data/doclib/msgpack/time.rb +0 -22
  68. data/doclib/msgpack/timestamp.rb +0 -44
  69. data/doclib/msgpack/unpacker.rb +0 -183
  70. data/doclib/msgpack.rb +0 -87
  71. data/msgpack.org.md +0 -46
  72. data/spec/cases.json +0 -1
  73. data/spec/cases.msg +0 -0
  74. data/spec/cases_compact.msg +0 -0
  75. data/spec/cases_spec.rb +0 -39
  76. data/spec/cruby/buffer_io_spec.rb +0 -255
  77. data/spec/cruby/buffer_packer.rb +0 -29
  78. data/spec/cruby/buffer_spec.rb +0 -575
  79. data/spec/cruby/buffer_unpacker.rb +0 -19
  80. data/spec/cruby/unpacker_spec.rb +0 -70
  81. data/spec/ext_value_spec.rb +0 -99
  82. data/spec/exttypes.rb +0 -51
  83. data/spec/factory_spec.rb +0 -367
  84. data/spec/format_spec.rb +0 -301
  85. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  86. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  87. data/spec/jruby/unpacker_spec.rb +0 -186
  88. data/spec/msgpack_spec.rb +0 -214
  89. data/spec/pack_spec.rb +0 -61
  90. data/spec/packer_spec.rb +0 -557
  91. data/spec/random_compat.rb +0 -24
  92. data/spec/spec_helper.rb +0 -55
  93. data/spec/timestamp_spec.rb +0 -121
  94. data/spec/unpack_spec.rb +0 -57
  95. data/spec/unpacker_spec.rb +0 -819
data/ext/msgpack/buffer.c CHANGED
@@ -19,21 +19,15 @@
19
19
  #include "buffer.h"
20
20
  #include "rmem.h"
21
21
 
22
- #ifndef HAVE_RB_STR_REPLACE
23
- static ID s_replace;
24
- #endif
25
-
26
22
  int msgpack_rb_encindex_utf8;
27
23
  int msgpack_rb_encindex_usascii;
28
24
  int msgpack_rb_encindex_ascii8bit;
29
25
 
30
26
  ID s_uminus;
31
27
 
32
- #ifndef DISABLE_RMEM
33
28
  static msgpack_rmem_t s_rmem;
34
- #endif
35
29
 
36
- void msgpack_buffer_static_init()
30
+ void msgpack_buffer_static_init(void)
37
31
  {
38
32
  s_uminus = rb_intern("-@");
39
33
 
@@ -41,20 +35,12 @@ void msgpack_buffer_static_init()
41
35
  msgpack_rb_encindex_usascii = rb_usascii_encindex();
42
36
  msgpack_rb_encindex_ascii8bit = rb_ascii8bit_encindex();
43
37
 
44
- #ifndef DISABLE_RMEM
45
38
  msgpack_rmem_init(&s_rmem);
46
- #endif
47
-
48
- #ifndef HAVE_RB_STR_REPLACE
49
- s_replace = rb_intern("replace");
50
- #endif
51
39
  }
52
40
 
53
- void msgpack_buffer_static_destroy()
41
+ void msgpack_buffer_static_destroy(void)
54
42
  {
55
- #ifndef DISABLE_RMEM
56
43
  msgpack_rmem_destroy(&s_rmem);
57
- #endif
58
44
  }
59
45
 
60
46
  void msgpack_buffer_init(msgpack_buffer_t* b)
@@ -72,16 +58,16 @@ void msgpack_buffer_init(msgpack_buffer_t* b)
72
58
  static void _msgpack_buffer_chunk_destroy(msgpack_buffer_chunk_t* c)
73
59
  {
74
60
  if(c->mem != NULL) {
75
- #ifndef DISABLE_RMEM
76
- if(!msgpack_rmem_free(&s_rmem, c->mem)) {
61
+ if(c->rmem) {
62
+ if(!msgpack_rmem_free(&s_rmem, c->mem)) {
63
+ rb_bug("Failed to free an rmem pointer, memory leak?");
64
+ }
65
+ } else {
77
66
  xfree(c->mem);
78
67
  }
79
68
  /* no needs to update rmem_owner because chunks will not be
80
69
  * free()ed (left in free_list) and thus *rmem_owner is
81
70
  * always valid. */
82
- #else
83
- xfree(c->mem);
84
- #endif
85
71
  }
86
72
  c->first = NULL;
87
73
  c->last = NULL;
@@ -108,8 +94,25 @@ void msgpack_buffer_destroy(msgpack_buffer_t* b)
108
94
  }
109
95
  }
110
96
 
111
- void msgpack_buffer_mark(msgpack_buffer_t* b)
97
+ size_t msgpack_buffer_memsize(const msgpack_buffer_t* b)
98
+ {
99
+ size_t memsize = 0;
100
+ msgpack_buffer_chunk_t* c = b->head;
101
+
102
+ while(c) {
103
+ memsize += sizeof(msgpack_buffer_chunk_t);
104
+ if(c->mapped_string != NO_MAPPED_STRING) {
105
+ memsize += (c->last - c->first);
106
+ }
107
+ c = c->next;
108
+ }
109
+
110
+ return memsize;
111
+ }
112
+
113
+ void msgpack_buffer_mark(void *ptr)
112
114
  {
115
+ msgpack_buffer_t* b = ptr;
113
116
  /* head is always available */
114
117
  msgpack_buffer_chunk_t* c = b->head;
115
118
  while(c != &b->tail) {
@@ -120,8 +123,6 @@ void msgpack_buffer_mark(msgpack_buffer_t* b)
120
123
 
121
124
  rb_gc_mark(b->io);
122
125
  rb_gc_mark(b->io_buffer);
123
-
124
- rb_gc_mark(b->owner);
125
126
  }
126
127
 
127
128
  bool _msgpack_buffer_shift_chunk(msgpack_buffer_t* b)
@@ -158,24 +159,17 @@ size_t msgpack_buffer_read_to_string_nonblock(msgpack_buffer_t* b, VALUE string,
158
159
  {
159
160
  size_t avail = msgpack_buffer_top_readable_size(b);
160
161
 
161
- #ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE
162
162
  /* optimize */
163
163
  if(length <= avail && RSTRING_LEN(string) == 0 &&
164
164
  b->head->mapped_string != NO_MAPPED_STRING &&
165
165
  length >= b->read_reference_threshold) {
166
166
  VALUE s = _msgpack_buffer_refer_head_mapped_string(b, length);
167
- #ifndef HAVE_RB_STR_REPLACE
168
- /* TODO MRI 1.8 */
169
- rb_funcall(string, s_replace, 1, s);
170
- #else
171
167
  rb_str_replace(string, s);
172
- #endif
173
168
  /* here doesn't have to call ENCODING_SET because
174
169
  * encoding of s is always ASCII-8BIT */
175
170
  _msgpack_buffer_consumed(b, length);
176
171
  return length;
177
172
  }
178
- #endif
179
173
 
180
174
  size_t const length_orig = length;
181
175
 
@@ -257,12 +251,14 @@ bool _msgpack_buffer_read_all2(msgpack_buffer_t* b, char* buffer, size_t length)
257
251
 
258
252
  static inline msgpack_buffer_chunk_t* _msgpack_buffer_alloc_new_chunk(msgpack_buffer_t* b)
259
253
  {
260
- msgpack_buffer_chunk_t* reuse = b->free_list;
261
- if(reuse == NULL) {
262
- return xmalloc(sizeof(msgpack_buffer_chunk_t));
254
+ msgpack_buffer_chunk_t* chunk = b->free_list;
255
+ if (chunk) {
256
+ b->free_list = b->free_list->next;
257
+ } else {
258
+ chunk = xmalloc(sizeof(msgpack_buffer_chunk_t));
263
259
  }
264
- b->free_list = b->free_list->next;
265
- return reuse;
260
+ memset(chunk, 0, sizeof(msgpack_buffer_chunk_t));
261
+ return chunk;
266
262
  }
267
263
 
268
264
  static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
@@ -288,15 +284,11 @@ static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
288
284
 
289
285
  msgpack_buffer_chunk_t* nc = _msgpack_buffer_alloc_new_chunk(b);
290
286
 
291
- #ifndef DISABLE_RMEM
292
- #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT
293
287
  if(b->rmem_last == b->tail_buffer_end) {
294
288
  /* reuse unused rmem space */
295
289
  size_t unused = b->tail_buffer_end - b->tail.last;
296
290
  b->rmem_last -= unused;
297
291
  }
298
- #endif
299
- #endif
300
292
 
301
293
  /* rebuild tail */
302
294
  *nc = b->tail;
@@ -307,8 +299,13 @@ static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
307
299
 
308
300
  static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE string)
309
301
  {
310
- VALUE mapped_string = rb_str_dup(string);
311
- ENCODING_SET(mapped_string, msgpack_rb_encindex_ascii8bit);
302
+ VALUE mapped_string;
303
+ if(ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit && RTEST(rb_obj_frozen_p(string))) {
304
+ mapped_string = string;
305
+ } else {
306
+ mapped_string = rb_str_dup(string);
307
+ ENCODING_SET(mapped_string, msgpack_rb_encindex_ascii8bit);
308
+ }
312
309
 
313
310
  _msgpack_buffer_add_new_chunk(b);
314
311
 
@@ -331,24 +328,15 @@ static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE s
331
328
 
332
329
  void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
333
330
  {
334
- size_t length = RSTRING_LEN(string);
335
-
336
331
  if(b->io != Qnil) {
337
332
  msgpack_buffer_flush(b);
338
333
  if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
339
334
  rb_funcall(b->io, b->io_write_all_method, 1, string);
340
- } else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
341
- VALUE s = rb_str_dup(string);
342
- ENCODING_SET(s, msgpack_rb_encindex_ascii8bit);
343
- rb_funcall(b->io, b->io_write_all_method, 1, s);
344
335
  } else {
345
- msgpack_buffer_append(b, RSTRING_PTR(string), length);
336
+ msgpack_buffer_append(b, RSTRING_PTR(string), RSTRING_LEN(string));
346
337
  }
347
- } else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
348
- _msgpack_buffer_append_reference(b, string);
349
-
350
338
  } else {
351
- msgpack_buffer_append(b, RSTRING_PTR(string), length);
339
+ _msgpack_buffer_append_reference(b, string);
352
340
  }
353
341
  }
354
342
 
@@ -356,11 +344,10 @@ static inline void* _msgpack_buffer_chunk_malloc(
356
344
  msgpack_buffer_t* b, msgpack_buffer_chunk_t* c,
357
345
  size_t required_size, size_t* allocated_size)
358
346
  {
359
- #ifndef DISABLE_RMEM
360
347
  if(required_size <= MSGPACK_RMEM_PAGE_SIZE) {
361
- #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT
348
+ c->rmem = true;
349
+
362
350
  if((size_t)(b->rmem_end - b->rmem_last) < required_size) {
363
- #endif
364
351
  /* alloc new rmem page */
365
352
  *allocated_size = MSGPACK_RMEM_PAGE_SIZE;
366
353
  char* buffer = msgpack_rmem_alloc(&s_rmem);
@@ -371,8 +358,6 @@ static inline void* _msgpack_buffer_chunk_malloc(
371
358
  b->rmem_last = b->rmem_end = buffer + MSGPACK_RMEM_PAGE_SIZE;
372
359
 
373
360
  return buffer;
374
-
375
- #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT
376
361
  } else {
377
362
  /* reuse unused rmem */
378
363
  *allocated_size = (size_t)(b->rmem_end - b->rmem_last);
@@ -386,18 +371,13 @@ static inline void* _msgpack_buffer_chunk_malloc(
386
371
 
387
372
  return buffer;
388
373
  }
389
- #endif
390
374
  }
391
- #else
392
- if(required_size < 72) {
393
- required_size = 72;
394
- }
395
- #endif
396
375
 
397
376
  // TODO alignment?
398
377
  *allocated_size = required_size;
399
378
  void* mem = xmalloc(required_size);
400
379
  c->mem = mem;
380
+ c->rmem = false;
401
381
  return mem;
402
382
  }
403
383
 
@@ -447,11 +427,7 @@ void _msgpack_buffer_expand(msgpack_buffer_t* b, const char* data, size_t length
447
427
  size_t capacity = b->tail.last - b->tail.first;
448
428
 
449
429
  /* can't realloc mapped chunk or rmem page */
450
- if(b->tail.mapped_string != NO_MAPPED_STRING
451
- #ifndef DISABLE_RMEM
452
- || capacity <= MSGPACK_RMEM_PAGE_SIZE
453
- #endif
454
- ) {
430
+ if(b->tail.mapped_string != NO_MAPPED_STRING || capacity <= MSGPACK_RMEM_PAGE_SIZE) {
455
431
  /* allocate new chunk */
456
432
  _msgpack_buffer_add_new_chunk(b);
457
433
 
@@ -624,13 +600,13 @@ size_t msgpack_buffer_flush_to_io(msgpack_buffer_t* b, VALUE io, ID write_method
624
600
  size_t _msgpack_buffer_feed_from_io(msgpack_buffer_t* b)
625
601
  {
626
602
  if(b->io_buffer == Qnil) {
627
- b->io_buffer = rb_funcall(b->io, b->io_partial_read_method, 1, LONG2NUM(b->io_buffer_size));
603
+ b->io_buffer = rb_funcall(b->io, b->io_partial_read_method, 1, SIZET2NUM(b->io_buffer_size));
628
604
  if(b->io_buffer == Qnil) {
629
605
  rb_raise(rb_eEOFError, "IO reached end of file");
630
606
  }
631
607
  StringValue(b->io_buffer);
632
608
  } else {
633
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(b->io_buffer_size), b->io_buffer);
609
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(b->io_buffer_size), b->io_buffer);
634
610
  if(ret == Qnil) {
635
611
  rb_raise(rb_eEOFError, "IO reached end of file");
636
612
  }
@@ -649,9 +625,11 @@ size_t _msgpack_buffer_feed_from_io(msgpack_buffer_t* b)
649
625
 
650
626
  size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string, size_t length)
651
627
  {
628
+ #define MIN(x, y) (((x) < (y)) ? (x) : (y))
629
+
652
630
  if(RSTRING_LEN(string) == 0) {
653
631
  /* direct read */
654
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), string);
632
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(MIN(b->io_buffer_size, length)), string);
655
633
  if(ret == Qnil) {
656
634
  return 0;
657
635
  }
@@ -663,7 +641,7 @@ size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string,
663
641
  b->io_buffer = rb_str_buf_new(0);
664
642
  }
665
643
 
666
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), b->io_buffer);
644
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(MIN(b->io_buffer_size, length)), b->io_buffer);
667
645
  if(ret == Qnil) {
668
646
  return 0;
669
647
  }
@@ -671,6 +649,8 @@ size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string,
671
649
 
672
650
  rb_str_buf_cat(string, (const void*)RSTRING_PTR(b->io_buffer), rl);
673
651
  return rl;
652
+
653
+ #undef MIN
674
654
  }
675
655
 
676
656
  size_t _msgpack_buffer_skip_from_io(msgpack_buffer_t* b, size_t length)
@@ -679,7 +659,7 @@ size_t _msgpack_buffer_skip_from_io(msgpack_buffer_t* b, size_t length)
679
659
  b->io_buffer = rb_str_buf_new(0);
680
660
  }
681
661
 
682
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), b->io_buffer);
662
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(length), b->io_buffer);
683
663
  if(ret == Qnil) {
684
664
  return 0;
685
665
  }
data/ext/msgpack/buffer.h CHANGED
@@ -49,6 +49,10 @@
49
49
 
50
50
  #define NO_MAPPED_STRING ((VALUE)0)
51
51
 
52
+ #ifndef RB_ENC_INTERNED_STR_NULL_CHECK
53
+ #define RB_ENC_INTERNED_STR_NULL_CHECK 0
54
+ #endif
55
+
52
56
  extern int msgpack_rb_encindex_utf8;
53
57
  extern int msgpack_rb_encindex_usascii;
54
58
  extern int msgpack_rb_encindex_ascii8bit;
@@ -74,6 +78,7 @@ struct msgpack_buffer_chunk_t {
74
78
  void* mem;
75
79
  msgpack_buffer_chunk_t* next;
76
80
  VALUE mapped_string; /* RBString or NO_MAPPED_STRING */
81
+ bool rmem;
77
82
  };
78
83
 
79
84
  union msgpack_buffer_cast_block_t {
@@ -98,11 +103,9 @@ struct msgpack_buffer_t {
98
103
  msgpack_buffer_chunk_t* head;
99
104
  msgpack_buffer_chunk_t* free_list;
100
105
 
101
- #ifndef DISABLE_RMEM
102
106
  char* rmem_last;
103
107
  char* rmem_end;
104
108
  void** rmem_owner;
105
- #endif
106
109
 
107
110
  union msgpack_buffer_cast_block_t cast_block;
108
111
 
@@ -114,25 +117,25 @@ struct msgpack_buffer_t {
114
117
  size_t write_reference_threshold;
115
118
  size_t read_reference_threshold;
116
119
  size_t io_buffer_size;
117
-
118
- VALUE owner;
119
120
  };
120
121
 
121
122
  /*
122
123
  * initialization functions
123
124
  */
124
- void msgpack_buffer_static_init();
125
+ void msgpack_buffer_static_init(void);
125
126
 
126
- void msgpack_buffer_static_destroy();
127
+ void msgpack_buffer_static_destroy(void);
127
128
 
128
129
  void msgpack_buffer_init(msgpack_buffer_t* b);
129
130
 
130
131
  void msgpack_buffer_destroy(msgpack_buffer_t* b);
131
132
 
132
- void msgpack_buffer_mark(msgpack_buffer_t* b);
133
+ void msgpack_buffer_mark(void* b);
133
134
 
134
135
  void msgpack_buffer_clear(msgpack_buffer_t* b);
135
136
 
137
+ size_t msgpack_buffer_memsize(const msgpack_buffer_t* b);
138
+
136
139
  static inline void msgpack_buffer_set_write_reference_threshold(msgpack_buffer_t* b, size_t length)
137
140
  {
138
141
  if(length < MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) {
@@ -265,14 +268,9 @@ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE str
265
268
  static inline size_t msgpack_buffer_append_string_reference(msgpack_buffer_t* b, VALUE string)
266
269
  {
267
270
  size_t length = RSTRING_LEN(string);
268
-
269
- if(length > MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) {
271
+ if (length > 0) {
270
272
  _msgpack_buffer_append_long_string(b, string);
271
-
272
- } else {
273
- msgpack_buffer_append(b, RSTRING_PTR(string), length);
274
273
  }
275
-
276
274
  return length;
277
275
  }
278
276
 
@@ -440,7 +438,6 @@ static inline VALUE _msgpack_buffer_refer_head_mapped_string(msgpack_buffer_t* b
440
438
 
441
439
  static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_t length, bool will_be_frozen, bool utf8)
442
440
  {
443
- #ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE
444
441
  /* optimize */
445
442
  if(!will_be_frozen &&
446
443
  b->head->mapped_string != NO_MAPPED_STRING &&
@@ -450,13 +447,16 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
450
447
  _msgpack_buffer_consumed(b, length);
451
448
  return result;
452
449
  }
453
- #endif
454
450
 
455
451
  VALUE result;
456
452
 
457
453
  #ifdef HAVE_RB_ENC_INTERNED_STR
458
454
  if (will_be_frozen) {
459
- result = rb_enc_interned_str(b->read_buffer, length, utf8 ? rb_utf8_encoding() : rb_ascii8bit_encoding());
455
+ if (RB_ENC_INTERNED_STR_NULL_CHECK && length == 0) {
456
+ result = rb_enc_interned_str("", length, utf8 ? rb_utf8_encoding() : rb_ascii8bit_encoding());
457
+ } else {
458
+ result = rb_enc_interned_str(b->read_buffer, length, utf8 ? rb_utf8_encoding() : rb_ascii8bit_encoding());
459
+ }
460
460
  } else {
461
461
  if (utf8) {
462
462
  result = rb_utf8_str_new(b->read_buffer, length);
@@ -475,7 +475,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
475
475
  result = rb_str_new(b->read_buffer, length);
476
476
  }
477
477
 
478
- #if STR_UMINUS_DEDUPE
479
478
  if (will_be_frozen) {
480
479
  #if STR_UMINUS_DEDUPE_FROZEN
481
480
  // Starting from MRI 2.8 it is preferable to freeze the string
@@ -487,11 +486,15 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
487
486
  // frozen.
488
487
  result = rb_funcall(result, s_uminus, 0);
489
488
  }
490
- #endif // STR_UMINUS_DEDUPE
491
489
  _msgpack_buffer_consumed(b, length);
492
490
  return result;
493
491
 
494
492
  #endif // HAVE_RB_ENC_INTERNED_STR
495
493
  }
496
494
 
495
+ static inline VALUE msgpack_buffer_read_top_as_symbol(msgpack_buffer_t* b, size_t length, bool utf8)
496
+ {
497
+ return rb_str_intern(msgpack_buffer_read_top_as_string(b, length, true, utf8));
498
+ }
499
+
497
500
  #endif