tomlib 0.5.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +7 -6
- data/ext/tomlib/toml.c +48 -35
- data/ext/tomlib/toml.h +1 -1
- data/ext/tomlib/tomlib.c +2 -2
- data/lib/tomlib/dumper.rb +39 -2
- data/lib/tomlib/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02730e4ee5dcfc0fe85a52e1909e42c88163e0d736545a7cf5c967dd11231b54
|
4
|
+
data.tar.gz: e5db101613da4dcd21db1450076df866ddf664338463f5520dbee8782bedae8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95b11c6a6f6af42b4a91710cb82fa192ac9ee1ca6b1487f2970f9694e3deae87ee4afc015947ca9be5d9fea49c32ed02acd852d18ccf98c896bae0690f8c4b01
|
7
|
+
data.tar.gz: 30991beebc111fef5d8c504eb42532d7ee4d7b4b09c094cd16981a28104f09e13283bad8e63a69d44a6aaad42f86d86032973a50933ff6ee5a81437c9d0067c8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## [0.7.0] - 2024-02-10
|
2
|
+
|
3
|
+
- Update tomlc99 to the latest version
|
4
|
+
- Parse very large numbers as Infinity
|
5
|
+
- Add support for Ruby 3.3
|
6
|
+
- Drop support for Ruby 2.7 and 2.7
|
7
|
+
|
8
|
+
## [0.6.0] - 2023-05-05
|
9
|
+
|
10
|
+
- Correctly escape special characters
|
11
|
+
|
1
12
|
## [0.5.0] - 2022-08-16
|
2
13
|
|
3
14
|
- Add support for Ruby 2.6
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Tomlib
|
2
2
|
|
3
|
-
Tomlib is a TOML parser and generator for Ruby. It
|
4
|
-
|
3
|
+
Tomlib is a TOML parser and generator for Ruby. It uses native C extension based on
|
4
|
+
fast and standards-compliant [tomlc99](https://github.com/cktan/tomlc99) parser.
|
5
5
|
|
6
6
|
## Compliance
|
7
7
|
|
@@ -11,7 +11,7 @@ It passes both [BurntSushi/toml-test](https://github.com/BurntSushi/toml-test) a
|
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
|
14
|
-
Tomlib supports Ruby (MRI)
|
14
|
+
Tomlib supports Ruby (MRI) 3.0+
|
15
15
|
|
16
16
|
Add this line to your application's Gemfile:
|
17
17
|
|
@@ -118,10 +118,11 @@ Tomlib.dump(hash, indent: false)
|
|
118
118
|
|
119
119
|
## Performance
|
120
120
|
|
121
|
-
`Tomlib`
|
122
|
-
|
121
|
+
When parsing documents, `Tomlib` is more than 600x (400x with yjit) faster than `toml-rb`,
|
122
|
+
23x (17x with yjit) faster than `Tomlrb` and almost 5x (3.5x with yjit)
|
123
|
+
faster than `perfect_toml` (~5KB TOML document size).
|
123
124
|
|
124
|
-
|
125
|
+
When generating TOML documents, it is about 1.5x (1.7x with yjit) faster than `toml-rb`.
|
125
126
|
|
126
127
|
For full comparison take a look at
|
127
128
|
[benchmarks](https://github.com/kgiszczak/tomlib/tree/master/benchmarks)
|
data/ext/tomlib/toml.c
CHANGED
@@ -45,6 +45,7 @@ void toml_set_memutil(void *(*xxmalloc)(size_t), void (*xxfree)(void *)) {
|
|
45
45
|
ppfree = xxfree;
|
46
46
|
}
|
47
47
|
|
48
|
+
#define ALIGN8(sz) (((sz) + 7) & ~7)
|
48
49
|
#define MALLOC(a) ppmalloc(a)
|
49
50
|
#define FREE(a) ppfree(a)
|
50
51
|
|
@@ -53,7 +54,7 @@ void toml_set_memutil(void *(*xxmalloc)(size_t), void (*xxfree)(void *)) {
|
|
53
54
|
#define calloc(x, y) error - forbidden - use CALLOC instead
|
54
55
|
|
55
56
|
static void *CALLOC(size_t nmemb, size_t sz) {
|
56
|
-
int nb = sz * nmemb;
|
57
|
+
int nb = ALIGN8(sz) * nmemb;
|
57
58
|
void *p = MALLOC(nb);
|
58
59
|
if (p) {
|
59
60
|
memset(p, 0, nb);
|
@@ -220,8 +221,8 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
|
|
220
221
|
110xxxxx 10xxxxxx
|
221
222
|
*/
|
222
223
|
if (code <= 0x000007FF) {
|
223
|
-
buf[0] = (unsigned char)
|
224
|
-
buf[1] = (unsigned char)
|
224
|
+
buf[0] = (unsigned char)(0xc0 | (code >> 6));
|
225
|
+
buf[1] = (unsigned char)(0x80 | (code & 0x3f));
|
225
226
|
return 2;
|
226
227
|
}
|
227
228
|
|
@@ -229,9 +230,9 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
|
|
229
230
|
1110xxxx 10xxxxxx 10xxxxxx
|
230
231
|
*/
|
231
232
|
if (code <= 0x0000FFFF) {
|
232
|
-
buf[0] = (unsigned char)
|
233
|
-
buf[1] = (unsigned char)
|
234
|
-
buf[2] = (unsigned char)
|
233
|
+
buf[0] = (unsigned char)(0xe0 | (code >> 12));
|
234
|
+
buf[1] = (unsigned char)(0x80 | ((code >> 6) & 0x3f));
|
235
|
+
buf[2] = (unsigned char)(0x80 | (code & 0x3f));
|
235
236
|
return 3;
|
236
237
|
}
|
237
238
|
|
@@ -239,10 +240,10 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
|
|
239
240
|
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
240
241
|
*/
|
241
242
|
if (code <= 0x001FFFFF) {
|
242
|
-
buf[0] = (unsigned char)
|
243
|
-
buf[1] = (unsigned char)
|
244
|
-
buf[2] = (unsigned char)
|
245
|
-
buf[3] = (unsigned char)
|
243
|
+
buf[0] = (unsigned char)(0xf0 | (code >> 18));
|
244
|
+
buf[1] = (unsigned char)(0x80 | ((code >> 12) & 0x3f));
|
245
|
+
buf[2] = (unsigned char)(0x80 | ((code >> 6) & 0x3f));
|
246
|
+
buf[3] = (unsigned char)(0x80 | (code & 0x3f));
|
246
247
|
return 4;
|
247
248
|
}
|
248
249
|
|
@@ -250,11 +251,11 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
|
|
250
251
|
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
251
252
|
*/
|
252
253
|
if (code <= 0x03FFFFFF) {
|
253
|
-
buf[0] = (unsigned char)
|
254
|
-
buf[1] = (unsigned char)
|
255
|
-
buf[2] = (unsigned char)
|
256
|
-
buf[3] = (unsigned char)
|
257
|
-
buf[4] = (unsigned char)
|
254
|
+
buf[0] = (unsigned char)(0xf8 | (code >> 24));
|
255
|
+
buf[1] = (unsigned char)(0x80 | ((code >> 18) & 0x3f));
|
256
|
+
buf[2] = (unsigned char)(0x80 | ((code >> 12) & 0x3f));
|
257
|
+
buf[3] = (unsigned char)(0x80 | ((code >> 6) & 0x3f));
|
258
|
+
buf[4] = (unsigned char)(0x80 | (code & 0x3f));
|
258
259
|
return 5;
|
259
260
|
}
|
260
261
|
|
@@ -262,12 +263,12 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
|
|
262
263
|
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
263
264
|
*/
|
264
265
|
if (code <= 0x7FFFFFFF) {
|
265
|
-
buf[0] = (unsigned char)
|
266
|
-
buf[1] = (unsigned char)
|
267
|
-
buf[2] = (unsigned char)
|
268
|
-
buf[3] = (unsigned char)
|
269
|
-
buf[4] = (unsigned char)
|
270
|
-
buf[5] = (unsigned char)
|
266
|
+
buf[0] = (unsigned char)(0xfc | (code >> 30));
|
267
|
+
buf[1] = (unsigned char)(0x80 | ((code >> 24) & 0x3f));
|
268
|
+
buf[2] = (unsigned char)(0x80 | ((code >> 18) & 0x3f));
|
269
|
+
buf[3] = (unsigned char)(0x80 | ((code >> 12) & 0x3f));
|
270
|
+
buf[4] = (unsigned char)(0x80 | ((code >> 6) & 0x3f));
|
271
|
+
buf[5] = (unsigned char)(0x80 | (code & 0x3f));
|
271
272
|
return 6;
|
272
273
|
}
|
273
274
|
|
@@ -411,8 +412,10 @@ static void *expand(void *p, int sz, int newsz) {
|
|
411
412
|
if (!s)
|
412
413
|
return 0;
|
413
414
|
|
414
|
-
|
415
|
-
|
415
|
+
if (p) {
|
416
|
+
memcpy(s, p, sz);
|
417
|
+
FREE(p);
|
418
|
+
}
|
416
419
|
return s;
|
417
420
|
}
|
418
421
|
|
@@ -422,8 +425,10 @@ static void **expand_ptrarr(void **p, int n) {
|
|
422
425
|
return 0;
|
423
426
|
|
424
427
|
s[n] = 0;
|
425
|
-
|
426
|
-
|
428
|
+
if (p) {
|
429
|
+
memcpy(s, p, n * sizeof(void *));
|
430
|
+
FREE(p);
|
431
|
+
}
|
427
432
|
return s;
|
428
433
|
}
|
429
434
|
|
@@ -2198,7 +2203,7 @@ int toml_rtod_ex(toml_raw_t src, double *ret_, char *buf, int buflen) {
|
|
2198
2203
|
}
|
2199
2204
|
|
2200
2205
|
int toml_rtod(toml_raw_t src, double *ret_) {
|
2201
|
-
char buf[
|
2206
|
+
char buf[400];
|
2202
2207
|
return toml_rtod_ex(src, ret_, buf, sizeof(buf));
|
2203
2208
|
}
|
2204
2209
|
|
@@ -2211,6 +2216,7 @@ int toml_rtos(toml_raw_t src, char **ret) {
|
|
2211
2216
|
if (!src)
|
2212
2217
|
return -1;
|
2213
2218
|
|
2219
|
+
// for strings, first char must be a s-quote or d-quote
|
2214
2220
|
int qchar = src[0];
|
2215
2221
|
int srclen = strlen(src);
|
2216
2222
|
if (!(qchar == '\'' || qchar == '"')) {
|
@@ -2219,12 +2225,14 @@ int toml_rtos(toml_raw_t src, char **ret) {
|
|
2219
2225
|
|
2220
2226
|
// triple quotes?
|
2221
2227
|
if (qchar == src[1] && qchar == src[2]) {
|
2222
|
-
multiline = 1;
|
2223
|
-
sp = src + 3;
|
2224
|
-
sq = src + srclen - 3;
|
2225
|
-
|
2226
|
-
if (!(sp <= sq && sq[0] == qchar && sq[1] == qchar && sq[2] == qchar))
|
2228
|
+
multiline = 1; // triple-quote implies multiline
|
2229
|
+
sp = src + 3; // first char after quote
|
2230
|
+
sq = src + srclen - 3; // first char of ending quote
|
2231
|
+
|
2232
|
+
if (!(sp <= sq && sq[0] == qchar && sq[1] == qchar && sq[2] == qchar)) {
|
2233
|
+
// last 3 chars in src must be qchar
|
2227
2234
|
return -1;
|
2235
|
+
}
|
2228
2236
|
|
2229
2237
|
/* skip new line immediate after qchar */
|
2230
2238
|
if (sp[0] == '\n')
|
@@ -2233,13 +2241,18 @@ int toml_rtos(toml_raw_t src, char **ret) {
|
|
2233
2241
|
sp += 2;
|
2234
2242
|
|
2235
2243
|
} else {
|
2236
|
-
sp = src + 1;
|
2237
|
-
sq = src + srclen - 1;
|
2238
|
-
|
2239
|
-
|
2244
|
+
sp = src + 1; // first char after quote
|
2245
|
+
sq = src + srclen - 1; // ending quote
|
2246
|
+
if (!(sp <= sq && *sq == qchar)) {
|
2247
|
+
/* last char in src must be qchar */
|
2240
2248
|
return -1;
|
2249
|
+
}
|
2241
2250
|
}
|
2242
2251
|
|
2252
|
+
// at this point:
|
2253
|
+
// sp points to first valid char after quote.
|
2254
|
+
// sq points to one char beyond last valid char.
|
2255
|
+
// string len is (sq - sp).
|
2243
2256
|
if (qchar == '\'') {
|
2244
2257
|
*ret = norm_lit_str(sp, sq - sp, multiline, 0, 0);
|
2245
2258
|
} else {
|
data/ext/tomlib/toml.h
CHANGED
data/ext/tomlib/tomlib.c
CHANGED
@@ -187,7 +187,7 @@ static VALUE toml_table_key_to_rb_value(const toml_table_t *table, const char *k
|
|
187
187
|
|
188
188
|
datum = toml_double_in(table, key);
|
189
189
|
|
190
|
-
if (datum.ok) {
|
190
|
+
if (datum.ok || datum.u.d == INFINITY || datum.u.d == -INFINITY) {
|
191
191
|
return DBL2NUM(datum.u.d);
|
192
192
|
}
|
193
193
|
|
@@ -320,7 +320,7 @@ static VALUE tomlib_key_type(VALUE self, VALUE rb_key) {
|
|
320
320
|
|
321
321
|
if (str_len == 0) return sym_escape;
|
322
322
|
|
323
|
-
for(long i = 0; i < str_len; i++) {
|
323
|
+
for (long i = 0; i < str_len; i++) {
|
324
324
|
const char c = *(str + i);
|
325
325
|
|
326
326
|
if (c == '\n') {
|
data/lib/tomlib/dumper.rb
CHANGED
@@ -27,6 +27,22 @@ module Tomlib
|
|
27
27
|
# @api private
|
28
28
|
NAN = 'nan'.freeze
|
29
29
|
|
30
|
+
# Regex to match escape chars
|
31
|
+
# @api private
|
32
|
+
ESCAPE_CHARS_REGEX = /[\x00-\x1F\x22\x5C\x7F]/.freeze
|
33
|
+
|
34
|
+
# Escape chars mapping
|
35
|
+
# @api private
|
36
|
+
ESCAPE_CHARS = {
|
37
|
+
"\b" => 'b',
|
38
|
+
"\t" => 't',
|
39
|
+
"\n" => 'n',
|
40
|
+
"\f" => 'f',
|
41
|
+
"\r" => 'r',
|
42
|
+
'"' => '"',
|
43
|
+
'\\' => '\\',
|
44
|
+
}.freeze
|
45
|
+
|
30
46
|
def initialize(use_indent: true)
|
31
47
|
@use_indent = use_indent
|
32
48
|
end
|
@@ -106,7 +122,7 @@ module Tomlib
|
|
106
122
|
|
107
123
|
case key_type(key)
|
108
124
|
when :quoted
|
109
|
-
key
|
125
|
+
escape_string(key)
|
110
126
|
when :escape
|
111
127
|
key.dump.gsub('\n', '\\\\\n')
|
112
128
|
else
|
@@ -138,7 +154,7 @@ module Tomlib
|
|
138
154
|
def to_toml_value(value)
|
139
155
|
case value
|
140
156
|
when String
|
141
|
-
value
|
157
|
+
escape_string(value)
|
142
158
|
when Float, BigDecimal
|
143
159
|
to_toml_float(value)
|
144
160
|
when Time, DateTime
|
@@ -170,5 +186,26 @@ module Tomlib
|
|
170
186
|
|
171
187
|
value.to_s
|
172
188
|
end
|
189
|
+
|
190
|
+
# Escapes TOML special characters
|
191
|
+
#
|
192
|
+
# @param [String] str
|
193
|
+
#
|
194
|
+
# @return [String]
|
195
|
+
#
|
196
|
+
# @api private
|
197
|
+
def escape_string(str)
|
198
|
+
str = str.gsub(ESCAPE_CHARS_REGEX) do |chr|
|
199
|
+
c = ESCAPE_CHARS[chr]
|
200
|
+
|
201
|
+
if c
|
202
|
+
'\\' << c
|
203
|
+
else
|
204
|
+
format('\\u%04X', chr.ord)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
'"' << str << '"'.freeze
|
209
|
+
end
|
173
210
|
end
|
174
211
|
end
|
data/lib/tomlib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tomlib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kamil Giszczak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Fast TOML parser and generator with native extension.
|
14
14
|
email:
|
@@ -54,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
56
|
requirements: []
|
57
|
-
rubygems_version: 3.3
|
57
|
+
rubygems_version: 3.5.3
|
58
58
|
signing_key:
|
59
59
|
specification_version: 4
|
60
60
|
summary: Fast TOML parser and generator with native extension.
|