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 +5 -5
- data/.travis.yml +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +1 -4
- data/docs/format-spec.md +26 -0
- data/ext/mochilo/buffer.c +14 -11
- data/ext/mochilo/buffer.h +2 -2
- data/ext/mochilo/mochilo.h +2 -0
- data/ext/mochilo/mochilo_api.h +23 -0
- data/ext/mochilo/mochilo_pack.c +59 -1
- data/ext/mochilo/mochilo_unpack.c +36 -0
- data/lib/mochilo/version.rb +1 -1
- data/mochilo.gemspec +0 -2
- data/script/bootstrap +1 -1
- data/test/pack_test.rb +24 -0
- metadata +7 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0b97afc4fd9e2920c58c61e96065c377681018aefe07c15cc072e59922157997
|
4
|
+
data.tar.gz: ab5665e26e73884dd6e6faf2fe4df2ca1ca9ba421283f996d59c9b16dfa9509b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05f5f210fcd4052a278ca9344f37ee1c00a9e9a966ac843843d6deeaacd61aac8d58fbf83886719e241f90d12d9cc852d3a5819b2f3cc10124c105d71d761e5e
|
7
|
+
data.tar.gz: f129d81959c7173d1eb2fa82e14f7271c2cbb585d9f18728fe1fb05cbcaaf3b6fbc10a871139674427c5c252d631ed457d82ce9201039f7495aa6d5e021a9e27
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
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
|
-
|
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
|
-
|
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
|
-
|
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
|
103
|
+
if ((buf->chunk_count * 2) < buf->chunk_count)
|
104
|
+
rb_raise(rb_eArgError, "Too many chunks required to serialize");
|
102
105
|
|
103
|
-
|
104
|
-
if (!
|
105
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
84
|
+
chunk = mochilo_buf_rechunk(b); };
|
85
85
|
|
86
86
|
#define SRC_CHECK_AVAIL(src, bytes) (src->ptr + bytes <= src->end)
|
87
87
|
|
data/ext/mochilo/mochilo.h
CHANGED
@@ -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,
|
data/ext/mochilo/mochilo_api.h
CHANGED
@@ -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
|
{
|
data/ext/mochilo/mochilo_pack.c
CHANGED
@@ -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 (
|
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
|
{
|
data/lib/mochilo/version.rb
CHANGED
data/mochilo.gemspec
CHANGED
data/script/bootstrap
CHANGED
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:
|
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:
|
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
|
-
|
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
|
-
|
114
|
-
|
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:
|