mochilo 1.2 → 1.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 64991c41216b4fb7659230eb433f7cb6c3f4ffff
4
- data.tar.gz: 21e5f81fdf2be02ad17303ca98636020fa2f8f78
2
+ SHA256:
3
+ metadata.gz: 0b97afc4fd9e2920c58c61e96065c377681018aefe07c15cc072e59922157997
4
+ data.tar.gz: ab5665e26e73884dd6e6faf2fe4df2ca1ca9ba421283f996d59c9b16dfa9509b
5
5
  SHA512:
6
- metadata.gz: 8258d48406e1674370d61cf42562db462908a6239f8471f2033a157bc4547fe4e7793d74a516046f6326d4473e73162be9b467b35f4e6fe55f43aa09c763fec7
7
- data.tar.gz: 4e44d9ab0960cadaa4b70c15c1da0b2b10447dfe3790f80189d6ee70f697966b52bdbb9ae9546b446f7bfa860274efb8cd212f80ca26c858ddc1ad8850fc1f66
6
+ metadata.gz: 05f5f210fcd4052a278ca9344f37ee1c00a9e9a966ac843843d6deeaacd61aac8d58fbf83886719e241f90d12d9cc852d3a5819b2f3cc10124c105d71d761e5e
7
+ data.tar.gz: f129d81959c7173d1eb2fa82e14f7271c2cbb585d9f18728fe1fb05cbcaaf3b6fbc10a871139674427c5c252d631ed457d82ce9201039f7495aa6d5e021a9e27
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
  script:
3
3
  - bundle exec rake test
4
+ install: ./script/bootstrap
4
5
  rvm:
5
6
  - 2.3.0
6
7
  - 2.2
data/Gemfile CHANGED
@@ -3,3 +3,7 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  gem "pry"
6
+
7
+ group :benchmark do
8
+ gem "msgpack"
9
+ end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mochilo (1.2)
4
+ mochilo (1.2.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -28,6 +28,3 @@ DEPENDENCIES
28
28
  msgpack
29
29
  pry
30
30
  rake-compiler (>= 0.8.1)
31
-
32
- BUNDLED WITH
33
- 1.11.2
data/docs/format-spec.md CHANGED
@@ -17,6 +17,32 @@ Length is stored in unsigned 8-bit integer.
17
17
  => XXXXXXXX (=N) bytes of raw bytes.
18
18
  ```
19
19
 
20
+ #### Regexp
21
+
22
+ Stores a regular expression, with options and encoding, up to (2^16)-1 bytes long.
23
+
24
+ ```
25
+ +--------+--------+--------+--------+--------+--------+--------+--------+----------
26
+ | 0xd5 |XXXXXXXX|XXXXXXXX|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|ZZZZZZZZ|...N bytes
27
+ +--------+--------+--------+--------+--------+--------+--------+--------+----------
28
+ => XXXXXXXX_XXXXXXXX (=N) bytes of raw bytes.
29
+ => YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY 32-bit int options
30
+ => ZZZZZZZZ encoding flag
31
+ ```
32
+
33
+ #### Time
34
+
35
+ Stores a Ruby time, with usec resolution and UTC offset.
36
+
37
+ ```
38
+ +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
39
+ | 0xd6 |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
40
+ +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
41
+ => XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX 64-bit unsigned seconds since the epoch
42
+ => YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY 64-bit unsigned microseconds
43
+ => ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ 32-bit signed seconds offset from UTC
44
+ ```
45
+
20
46
  #### String16
21
47
 
22
48
  For storing text up to (2^16)-1 bytes.
data/ext/mochilo/buffer.c CHANGED
@@ -19,7 +19,7 @@ static mochilo_buf_chunk *init_cur_chunk(mochilo_buf *buf, size_t chunk_size)
19
19
 
20
20
  buf->last_alloc = chunk->ptr = malloc(chunk_size);
21
21
  if (!chunk->ptr)
22
- return NULL;
22
+ rb_raise(rb_eNoMemError, "Failed to allocate new chunk");
23
23
 
24
24
  chunk->end = chunk->ptr + chunk_size;
25
25
  return chunk;
@@ -38,7 +38,7 @@ static void skip_last_chunk(mochilo_buf *buf)
38
38
 
39
39
  static void free_buf(mochilo_buf *buf)
40
40
  {
41
- uint16_t i;
41
+ uint32_t i;
42
42
 
43
43
  for (i = 0; i < buf->cur_chunk; ++i)
44
44
  free(buf->chunks[i].ptr);
@@ -61,7 +61,7 @@ VALUE mochilo_buf_flush(mochilo_buf *buf)
61
61
  {
62
62
  VALUE rb_str;
63
63
  char *ptr;
64
- uint16_t i;
64
+ uint32_t i;
65
65
 
66
66
  skip_last_chunk(buf);
67
67
 
@@ -95,15 +95,20 @@ VALUE mochilo_buf_flush(mochilo_buf *buf)
95
95
 
96
96
  mochilo_buf_chunk *mochilo_buf_rechunk2(mochilo_buf *buf, size_t chunk_size)
97
97
  {
98
+ mochilo_buf_chunk *chunks;
99
+
98
100
  skip_last_chunk(buf);
99
101
 
100
102
  if (buf->cur_chunk == buf->chunk_count) {
101
- buf->chunk_count *= 2;
103
+ if ((buf->chunk_count * 2) < buf->chunk_count)
104
+ rb_raise(rb_eArgError, "Too many chunks required to serialize");
102
105
 
103
- buf->chunks = realloc(buf->chunks, buf->chunk_count * sizeof(mochilo_buf_chunk));
104
- if (!buf->chunks)
105
- return NULL;
106
+ chunks = realloc(buf->chunks, buf->chunk_count * 2 * sizeof(mochilo_buf_chunk));
107
+ if (!chunks)
108
+ rb_raise(rb_eNoMemError, "Failed to realloc chunks");
106
109
 
110
+ buf->chunks = chunks;
111
+ buf->chunk_count *= 2;
107
112
  }
108
113
 
109
114
  return init_cur_chunk(buf, chunk_size);
@@ -118,10 +123,8 @@ void mochilo_buf_put(mochilo_buf *buf, const char *data, size_t len)
118
123
  {
119
124
  mochilo_buf_chunk *chunk = &buf->chunks[buf->cur_chunk];
120
125
 
121
- if (unlikely(chunk->ptr + len > chunk->end)) {
122
- if (!(chunk = mochilo_buf_rechunk2(buf, len)))
123
- return;
124
- }
126
+ if (unlikely(chunk->ptr + len > chunk->end))
127
+ chunk = mochilo_buf_rechunk2(buf, len);
125
128
 
126
129
  memmove(chunk->ptr, data, len);
127
130
  chunk->ptr += len;
data/ext/mochilo/buffer.h CHANGED
@@ -59,7 +59,7 @@ typedef struct {
59
59
  mochilo_buf_chunk *chunks;
60
60
  char *last_alloc;
61
61
  size_t total_size;
62
- uint16_t chunk_count, cur_chunk;
62
+ uint32_t chunk_count, cur_chunk;
63
63
  } mochilo_buf;
64
64
 
65
65
  typedef struct {
@@ -81,7 +81,7 @@ const char *mochilo_src_peek(mochilo_src *buf, size_t need);
81
81
  #define BUF_ENSURE_AVAIL(b, d) \
82
82
  mochilo_buf_chunk *chunk = &b->chunks[b->cur_chunk]; \
83
83
  if (unlikely(chunk->ptr + (d) > chunk->end)) { \
84
- if ((chunk = mochilo_buf_rechunk(b)) == NULL) return; };
84
+ chunk = mochilo_buf_rechunk(b); };
85
85
 
86
86
  #define SRC_CHECK_AVAIL(src, bytes) (src->ptr + bytes <= src->end)
87
87
 
@@ -28,6 +28,8 @@ enum msgpack_t {
28
28
  MSGPACK_T_INT32 = 0xd2,
29
29
  MSGPACK_T_INT64 = 0xd3,
30
30
  MSGPACK_T_SYM = 0xd4,
31
+ MSGPACK_T_REGEXP = 0xd5,
32
+ MSGPACK_T_TIME = 0xd6,
31
33
  MSGPACK_T_STR16 = 0xd8, /* reserved in the spec */
32
34
  MSGPACK_T_STR32 = 0xd9, /* reserved in the spec */
33
35
  MSGPACK_T_RAW16 = 0xda,
@@ -18,6 +18,29 @@ MOAPI mo_value moapi_sym_new(const char *src, size_t len)
18
18
  return (mo_value)ID2SYM(rb_intern(symbol));
19
19
  }
20
20
 
21
+ #ifdef HAVE_RUBY_ENCODING_H
22
+ MOAPI mo_value moapi_regexp_new(const char *src, size_t len, enum msgpack_enc_t encoding, int reg_options)
23
+ {
24
+ int index = 0;
25
+ VALUE re;
26
+
27
+ if (encoding < sizeof(mochilo_enc_lookup)/sizeof(mochilo_enc_lookup[0]))
28
+ index = rb_enc_find_index(mochilo_enc_lookup[encoding]);
29
+
30
+ re = rb_reg_new(src, len, reg_options);
31
+ rb_enc_set_index(re, index);
32
+
33
+ return (mo_value)re;
34
+ }
35
+ #endif
36
+
37
+ MOAPI mo_value moapi_time_new(uint64_t sec, uint64_t usec, int32_t utc_offset)
38
+ {
39
+ VALUE utc_time = rb_time_new(sec, usec);
40
+ return (mo_value)rb_funcall(utc_time,
41
+ rb_intern("getlocal"), 1, INT2FIX(utc_offset));
42
+ }
43
+
21
44
  #ifdef HAVE_RUBY_ENCODING_H
22
45
  MOAPI mo_value moapi_str_new(const char *src, size_t len, enum msgpack_enc_t encoding)
23
46
  {
@@ -73,6 +73,56 @@ void mochilo_pack_bignum(mochilo_buf *buf, VALUE rb_bignum)
73
73
  }
74
74
  }
75
75
 
76
+ #ifdef HAVE_RUBY_ENCODING_H
77
+ void mochilo_pack_regexp(mochilo_buf *buf, VALUE rb_regexp)
78
+ {
79
+ size_t size;
80
+ rb_encoding *encoding;
81
+ char *enc_name;
82
+ const struct mochilo_enc_map *enc2id;
83
+ uint32_t options;
84
+ const char *regexp;
85
+
86
+ size = RREGEXP_SRC_LEN(rb_regexp);
87
+
88
+ if (size < (1<<16)) {
89
+ uint16_t packed_size = size;
90
+
91
+ encoding = rb_enc_get(rb_regexp);
92
+ enc_name = rb_enc_name(encoding);
93
+ enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));
94
+
95
+ options = rb_reg_options(rb_regexp);
96
+ regexp = RREGEXP_SRC_PTR(rb_regexp);
97
+
98
+ mochilo_buf_putc(buf, MSGPACK_T_REGEXP);
99
+ mochilo_buf_put16be(buf, &packed_size);
100
+ mochilo_buf_put32be(buf, &options);
101
+ mochilo_buf_putc(buf, enc2id ? enc2id->id : 0);
102
+ mochilo_buf_put(buf, regexp, size);
103
+ } else {
104
+ rb_raise(rb_eMochiloPackError,
105
+ "Regexp too long: must be under %d bytes, %ld given", 1<<16, size);
106
+ }
107
+ }
108
+ #endif
109
+
110
+ void mochilo_pack_time(mochilo_buf *buf, VALUE rb_time)
111
+ {
112
+ uint64_t sec;
113
+ uint64_t usec;
114
+ int32_t utc_offset;
115
+
116
+ sec = NUM2ULONG(rb_funcall(rb_time, rb_intern("to_i"), 0));
117
+ usec = NUM2ULONG(rb_funcall(rb_time, rb_intern("usec"), 0));
118
+ utc_offset = NUM2INT(rb_funcall(rb_time, rb_intern("utc_offset"), 0));
119
+
120
+ mochilo_buf_putc(buf, MSGPACK_T_TIME);
121
+ mochilo_buf_put64be(buf, &sec);
122
+ mochilo_buf_put64be(buf, &usec);
123
+ mochilo_buf_put32be(buf, &utc_offset);
124
+ }
125
+
76
126
  struct mochilo_hash_pack {
77
127
  mochilo_buf *buf;
78
128
  int trusted;
@@ -268,8 +318,16 @@ void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted)
268
318
  mochilo_pack_bignum(buf, rb_object);
269
319
  return;
270
320
 
321
+ #ifdef HAVE_RUBY_ENCODING_H
322
+ case T_REGEXP:
323
+ mochilo_pack_regexp(buf, rb_object);
324
+ return;
325
+ #endif
326
+
271
327
  default:
272
- if (rb_respond_to(rb_object, rb_intern("to_bpack"))) {
328
+ if (rb_cTime == rb_obj_class(rb_object)) {
329
+ mochilo_pack_time(buf, rb_object);
330
+ } else if (rb_respond_to(rb_object, rb_intern("to_bpack"))) {
273
331
  VALUE bpack = rb_funcall(rb_object, rb_intern("to_bpack"), 0);
274
332
 
275
333
  mochilo_buf_put(buf, RSTRING_PTR(bpack), RSTRING_LEN(bpack));
@@ -178,6 +178,42 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
178
178
  return 0;
179
179
  }
180
180
 
181
+ #ifdef HAVE_RUBY_ENCODING_H
182
+ case MSGPACK_T_REGEXP:
183
+ {
184
+ uint16_t length;
185
+ uint32_t options;
186
+ uint8_t encoding;
187
+ const char *ptr;
188
+
189
+ SRC_ENSURE_AVAIL(src, 2+4+1);
190
+ mochilo_src_get16be(src, &length);
191
+ mochilo_src_get32be(src, &options);
192
+ mochilo_src_get8be(src, &encoding);
193
+
194
+ if (!(ptr = mochilo_src_peek(src, length)))
195
+ return -1;
196
+
197
+ *_value = moapi_regexp_new(ptr, length, encoding, options);
198
+ return 0;
199
+ }
200
+ #endif
201
+
202
+ case MSGPACK_T_TIME:
203
+ {
204
+ uint64_t sec;
205
+ uint64_t usec;
206
+ int32_t utc_offset;
207
+
208
+ SRC_ENSURE_AVAIL(src, 8+8+4);
209
+ mochilo_src_get64be(src, &sec);
210
+ mochilo_src_get64be(src, &usec);
211
+ mochilo_src_get32be(src, &utc_offset);
212
+
213
+ *_value = moapi_time_new(sec, usec, utc_offset);
214
+ return 0;
215
+ }
216
+
181
217
  #ifdef HAVE_RUBY_ENCODING_H
182
218
  case MSGPACK_T_STR16:
183
219
  {
@@ -1,3 +1,3 @@
1
1
  module Mochilo
2
- VERSION = "1.2"
2
+ VERSION = "1.3.0"
3
3
  end
data/mochilo.gemspec CHANGED
@@ -19,6 +19,4 @@ Gem::Specification.new do |s|
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'
24
22
  end
data/script/bootstrap CHANGED
@@ -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 "$@"
15
+ exec bundle install --binstubs --path vendor/gems --without benchmark "$@"
16
16
  fi
data/test/pack_test.rb CHANGED
@@ -175,4 +175,28 @@ class MochiloPackTest < MiniTest::Unit::TestCase
175
175
  Mochilo.pack(Object.new)
176
176
  end
177
177
  end
178
+
179
+ def test_pack_regexp
180
+ expected = "\xD5\x00\x07\x00\x00\x00\x00\x01pa.tern"
181
+ assert_equal expected, Mochilo.pack(/pa.tern/)
182
+ [
183
+ /pa.tern/,
184
+ /thing/im,
185
+ ].each do |re|
186
+ assert_equal re, Mochilo.unpack(Mochilo.pack(re))
187
+ end
188
+ end
189
+
190
+ def test_time
191
+ offset = -13*60*60 # I don't know if this is possible. There shouldn't be anything with a greater absolute value.
192
+ t = Time.gm(2042, 7, 21, 3, 32, 37, 974010).getlocal(offset)
193
+ expected = "\xD6" +
194
+ "\x00\x00\x00\x00\x88\x77\x66\x55" + # sec
195
+ "\x00\x00\x00\x00\x00\x0E\xDC\xBA" + # usec
196
+ "\xFF\xFF\x49\x30" # utc_offset
197
+ assert_equal expected, Mochilo.pack(t)
198
+ unpacked = Mochilo.unpack(expected)
199
+ assert_equal t, unpacked
200
+ assert_equal t.utc_offset, unpacked.utc_offset
201
+ end
178
202
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mochilo
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.2'
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vicent Martí
8
8
  - Brian Lopez
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-03-02 00:00:00.000000000 Z
12
+ date: 2023-10-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
@@ -39,21 +39,7 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: 4.1.0
42
- - !ruby/object:Gem::Dependency
43
- name: msgpack
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
- description:
42
+ description:
57
43
  email: vicent@github.com seniorlopez@gmail.com
58
44
  executables: []
59
45
  extensions:
@@ -94,7 +80,7 @@ files:
94
80
  homepage: http://github.com/brianmario/mochilo
95
81
  licenses: []
96
82
  metadata: {}
97
- post_install_message:
83
+ post_install_message:
98
84
  rdoc_options:
99
85
  - "--charset=UTF-8"
100
86
  require_paths:
@@ -110,9 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
96
  - !ruby/object:Gem::Version
111
97
  version: '0'
112
98
  requirements: []
113
- rubyforge_project:
114
- rubygems_version: 2.5.1
115
- signing_key:
99
+ rubygems_version: 3.3.10
100
+ signing_key:
116
101
  specification_version: 4
117
102
  summary: A ruby library for BananaPack
118
103
  test_files: