tomlib 0.5.0 → 0.7.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 +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.
|