mochilo 1.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: