stringio 0.0.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of stringio might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +34 -0
- data/{extconf.rb → ext/stringio/extconf.rb} +1 -0
- data/{stringio.c → ext/stringio/stringio.c} +273 -141
- metadata +23 -11
- data/depend +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41c6ce121bb7eb707f594272b5665080732c7eb7d5ae868f95bb633dc83711ae
|
4
|
+
data.tar.gz: d7c1e9260fa0095a95a31e7170264d0d40b4e0093b6bccd0ee84fc80e3c4f005
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c19e3fa54ab666fe1ac76a398637e7181ca7e5948bb3576a2504e3a79253ab995dbf515bbaa52f01a6aec112f28102c002353038eced204ddeba0b15ea930544
|
7
|
+
data.tar.gz: 3d67ea8a7975013bdf361bf8ab80cd208187b6f4396a118fd16f1d6e9134ab0b596d4b7453b5bdaa0a7f232e08c0103ae3da638258f98baf2e4bd5bcaf5e35f8
|
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# StringIO
|
2
2
|
|
3
|
+
![ubuntu](https://github.com/ruby/stringio/workflows/ubuntu/badge.svg?branch=master&event=push)
|
4
|
+
![macos](https://github.com/ruby/stringio/workflows/macos/badge.svg?branch=master&event=push)
|
5
|
+
![windows](https://github.com/ruby/stringio/workflows/windows/badge.svg?branch=master&event=push)
|
6
|
+
|
3
7
|
Pseudo `IO` class from/to `String`.
|
4
8
|
|
5
9
|
This library is based on MoonWolf version written in Ruby. Thanks a lot.
|
@@ -8,3 +12,33 @@ This library is based on MoonWolf version written in Ruby. Thanks a lot.
|
|
8
12
|
|
9
13
|
* `fileno` raises `NotImplementedError`.
|
10
14
|
* encoding conversion is not implemented, and ignored silently.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'stringio'
|
22
|
+
```
|
23
|
+
|
24
|
+
And then execute:
|
25
|
+
|
26
|
+
$ bundle
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install stringio
|
31
|
+
|
32
|
+
## Development
|
33
|
+
|
34
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
35
|
+
|
36
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/stringio.
|
41
|
+
|
42
|
+
## License
|
43
|
+
|
44
|
+
The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
|
@@ -11,6 +11,8 @@
|
|
11
11
|
|
12
12
|
**********************************************************************/
|
13
13
|
|
14
|
+
#define STRINGIO_VERSION "3.0.0"
|
15
|
+
|
14
16
|
#include "ruby.h"
|
15
17
|
#include "ruby/io.h"
|
16
18
|
#include "ruby/encoding.h"
|
@@ -24,6 +26,86 @@
|
|
24
26
|
# define RB_INTEGER_TYPE_P(c) (FIXNUM_P(c) || RB_TYPE_P(c, T_BIGNUM))
|
25
27
|
#endif
|
26
28
|
|
29
|
+
#ifndef RB_PASS_CALLED_KEYWORDS
|
30
|
+
# define rb_funcallv_kw(recv, mid, arg, argv, kw_splat) rb_funcallv(recv, mid, arg, argv)
|
31
|
+
# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
|
32
|
+
#endif
|
33
|
+
|
34
|
+
#ifndef HAVE_RB_IO_EXTRACT_MODEENC
|
35
|
+
#define rb_io_extract_modeenc strio_extract_modeenc
|
36
|
+
static void
|
37
|
+
strio_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
|
38
|
+
int *oflags_p, int *fmode_p, struct rb_io_enc_t *convconfig_p)
|
39
|
+
{
|
40
|
+
VALUE mode = *vmode_p;
|
41
|
+
VALUE intmode;
|
42
|
+
int fmode;
|
43
|
+
int has_enc = 0, has_vmode = 0;
|
44
|
+
|
45
|
+
convconfig_p->enc = convconfig_p->enc2 = 0;
|
46
|
+
|
47
|
+
vmode_handle:
|
48
|
+
if (NIL_P(mode)) {
|
49
|
+
fmode = FMODE_READABLE;
|
50
|
+
}
|
51
|
+
else if (!NIL_P(intmode = rb_check_to_integer(mode, "to_int"))) {
|
52
|
+
int flags = NUM2INT(intmode);
|
53
|
+
fmode = rb_io_oflags_fmode(flags);
|
54
|
+
}
|
55
|
+
else {
|
56
|
+
const char *m = StringValueCStr(mode), *n, *e;
|
57
|
+
fmode = rb_io_modestr_fmode(m);
|
58
|
+
n = strchr(m, ':');
|
59
|
+
if (n) {
|
60
|
+
long len;
|
61
|
+
char encname[ENCODING_MAXNAMELEN+1];
|
62
|
+
has_enc = 1;
|
63
|
+
if (fmode & FMODE_SETENC_BY_BOM) {
|
64
|
+
n = strchr(n, '|');
|
65
|
+
}
|
66
|
+
e = strchr(++n, ':');
|
67
|
+
len = e ? e - n : strlen(n);
|
68
|
+
if (len > 0 && len <= ENCODING_MAXNAMELEN) {
|
69
|
+
if (e) {
|
70
|
+
memcpy(encname, n, len);
|
71
|
+
encname[len] = '\0';
|
72
|
+
n = encname;
|
73
|
+
}
|
74
|
+
convconfig_p->enc = rb_enc_find(n);
|
75
|
+
}
|
76
|
+
if (e && (len = strlen(++e)) > 0 && len <= ENCODING_MAXNAMELEN) {
|
77
|
+
convconfig_p->enc2 = rb_enc_find(e);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
if (!NIL_P(opthash)) {
|
83
|
+
rb_encoding *extenc = 0, *intenc = 0;
|
84
|
+
VALUE v;
|
85
|
+
if (!has_vmode) {
|
86
|
+
ID id_mode;
|
87
|
+
CONST_ID(id_mode, "mode");
|
88
|
+
v = rb_hash_aref(opthash, ID2SYM(id_mode));
|
89
|
+
if (!NIL_P(v)) {
|
90
|
+
if (!NIL_P(mode)) {
|
91
|
+
rb_raise(rb_eArgError, "mode specified twice");
|
92
|
+
}
|
93
|
+
has_vmode = 1;
|
94
|
+
mode = v;
|
95
|
+
goto vmode_handle;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
if (rb_io_extract_encoding_option(opthash, &extenc, &intenc, &fmode)) {
|
100
|
+
if (has_enc) {
|
101
|
+
rb_raise(rb_eArgError, "encoding specified twice");
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
*fmode_p = fmode;
|
106
|
+
}
|
107
|
+
#endif
|
108
|
+
|
27
109
|
struct StringIO {
|
28
110
|
VALUE string;
|
29
111
|
rb_encoding *enc;
|
@@ -185,45 +267,111 @@ strio_initialize(int argc, VALUE *argv, VALUE self)
|
|
185
267
|
return strio_init(argc, argv, ptr, self);
|
186
268
|
}
|
187
269
|
|
188
|
-
static
|
189
|
-
|
270
|
+
static int
|
271
|
+
detect_bom(VALUE str, int *bomlen)
|
190
272
|
{
|
191
|
-
|
192
|
-
|
273
|
+
const char *p;
|
274
|
+
long len;
|
193
275
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
276
|
+
RSTRING_GETMEM(str, p, len);
|
277
|
+
if (len < 1) return 0;
|
278
|
+
switch ((unsigned char)p[0]) {
|
279
|
+
case 0xEF:
|
280
|
+
if (len < 2) break;
|
281
|
+
if ((unsigned char)p[1] == 0xBB && len > 2) {
|
282
|
+
if ((unsigned char)p[2] == 0xBF) {
|
283
|
+
*bomlen = 3;
|
284
|
+
return rb_utf8_encindex();
|
285
|
+
}
|
200
286
|
}
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
287
|
+
break;
|
288
|
+
|
289
|
+
case 0xFE:
|
290
|
+
if (len < 2) break;
|
291
|
+
if ((unsigned char)p[1] == 0xFF) {
|
292
|
+
*bomlen = 2;
|
293
|
+
return rb_enc_find_index("UTF-16BE");
|
205
294
|
}
|
206
|
-
|
207
|
-
|
208
|
-
|
295
|
+
break;
|
296
|
+
|
297
|
+
case 0xFF:
|
298
|
+
if (len < 2) break;
|
299
|
+
if ((unsigned char)p[1] == 0xFE) {
|
300
|
+
if (len >= 4 && (unsigned char)p[2] == 0 && (unsigned char)p[3] == 0) {
|
301
|
+
*bomlen = 4;
|
302
|
+
return rb_enc_find_index("UTF-32LE");
|
303
|
+
}
|
304
|
+
*bomlen = 2;
|
305
|
+
return rb_enc_find_index("UTF-16LE");
|
209
306
|
}
|
210
|
-
|
211
|
-
|
307
|
+
break;
|
308
|
+
|
309
|
+
case 0:
|
310
|
+
if (len < 4) break;
|
311
|
+
if ((unsigned char)p[1] == 0 && (unsigned char)p[2] == 0xFE && (unsigned char)p[3] == 0xFF) {
|
312
|
+
*bomlen = 4;
|
313
|
+
return rb_enc_find_index("UTF-32BE");
|
212
314
|
}
|
213
315
|
break;
|
214
|
-
|
316
|
+
}
|
317
|
+
return 0;
|
318
|
+
}
|
319
|
+
|
320
|
+
static rb_encoding *
|
321
|
+
set_encoding_by_bom(struct StringIO *ptr)
|
322
|
+
{
|
323
|
+
int bomlen, idx = detect_bom(ptr->string, &bomlen);
|
324
|
+
rb_encoding *extenc = NULL;
|
325
|
+
|
326
|
+
if (idx) {
|
327
|
+
extenc = rb_enc_from_index(idx);
|
328
|
+
ptr->pos = bomlen;
|
329
|
+
if (ptr->flags & FMODE_WRITABLE) {
|
330
|
+
rb_enc_associate_index(ptr->string, idx);
|
331
|
+
}
|
332
|
+
}
|
333
|
+
ptr->enc = extenc;
|
334
|
+
return extenc;
|
335
|
+
}
|
336
|
+
|
337
|
+
static VALUE
|
338
|
+
strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
|
339
|
+
{
|
340
|
+
VALUE string, vmode, opt;
|
341
|
+
int oflags;
|
342
|
+
struct rb_io_enc_t convconfig;
|
343
|
+
|
344
|
+
argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
|
345
|
+
rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
|
346
|
+
if (argc) {
|
215
347
|
StringValue(string);
|
216
|
-
|
217
|
-
|
218
|
-
case 0:
|
348
|
+
}
|
349
|
+
else {
|
219
350
|
string = rb_enc_str_new("", 0, rb_default_external_encoding());
|
220
|
-
|
221
|
-
|
351
|
+
}
|
352
|
+
if (OBJ_FROZEN_RAW(string)) {
|
353
|
+
if (ptr->flags & FMODE_WRITABLE) {
|
354
|
+
rb_syserr_fail(EACCES, 0);
|
355
|
+
}
|
356
|
+
}
|
357
|
+
else {
|
358
|
+
if (NIL_P(vmode)) {
|
359
|
+
ptr->flags |= FMODE_WRITABLE;
|
360
|
+
}
|
361
|
+
}
|
362
|
+
if (ptr->flags & FMODE_TRUNC) {
|
363
|
+
rb_str_resize(string, 0);
|
222
364
|
}
|
223
365
|
ptr->string = string;
|
224
|
-
|
366
|
+
if (argc == 1) {
|
367
|
+
ptr->enc = rb_enc_get(string);
|
368
|
+
}
|
369
|
+
else {
|
370
|
+
ptr->enc = convconfig.enc;
|
371
|
+
}
|
225
372
|
ptr->pos = 0;
|
226
373
|
ptr->lineno = 0;
|
374
|
+
if (ptr->flags & FMODE_SETENC_BY_BOM) set_encoding_by_bom(ptr);
|
227
375
|
RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);
|
228
376
|
return self;
|
229
377
|
}
|
@@ -247,7 +395,7 @@ strio_finalize(VALUE self)
|
|
247
395
|
static VALUE
|
248
396
|
strio_s_open(int argc, VALUE *argv, VALUE klass)
|
249
397
|
{
|
250
|
-
VALUE obj =
|
398
|
+
VALUE obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
|
251
399
|
if (!rb_block_given_p()) return obj;
|
252
400
|
return rb_ensure(rb_yield, obj, strio_finalize, obj);
|
253
401
|
}
|
@@ -262,7 +410,7 @@ strio_s_new(int argc, VALUE *argv, VALUE klass)
|
|
262
410
|
rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
|
263
411
|
cname, cname);
|
264
412
|
}
|
265
|
-
return
|
413
|
+
return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
|
266
414
|
}
|
267
415
|
|
268
416
|
/*
|
@@ -286,7 +434,7 @@ strio_nil(VALUE self)
|
|
286
434
|
}
|
287
435
|
|
288
436
|
/*
|
289
|
-
* Returns
|
437
|
+
* Returns an object itself. Just for compatibility to IO.
|
290
438
|
*/
|
291
439
|
static VALUE
|
292
440
|
strio_self(VALUE self)
|
@@ -362,7 +510,7 @@ strio_set_string(VALUE self, VALUE string)
|
|
362
510
|
* call-seq:
|
363
511
|
* strio.close -> nil
|
364
512
|
*
|
365
|
-
* Closes
|
513
|
+
* Closes a StringIO. The stream is unavailable for any further data
|
366
514
|
* operations; an +IOError+ is raised if such an attempt is made.
|
367
515
|
*/
|
368
516
|
static VALUE
|
@@ -378,7 +526,7 @@ strio_close(VALUE self)
|
|
378
526
|
* strio.close_read -> nil
|
379
527
|
*
|
380
528
|
* Closes the read end of a StringIO. Will raise an +IOError+ if the
|
381
|
-
*
|
529
|
+
* receiver is not readable.
|
382
530
|
*/
|
383
531
|
static VALUE
|
384
532
|
strio_close_read(VALUE self)
|
@@ -396,7 +544,7 @@ strio_close_read(VALUE self)
|
|
396
544
|
* strio.close_write -> nil
|
397
545
|
*
|
398
546
|
* Closes the write end of a StringIO. Will raise an +IOError+ if the
|
399
|
-
*
|
547
|
+
* receiver is not writeable.
|
400
548
|
*/
|
401
549
|
static VALUE
|
402
550
|
strio_close_write(VALUE self)
|
@@ -413,7 +561,7 @@ strio_close_write(VALUE self)
|
|
413
561
|
* call-seq:
|
414
562
|
* strio.closed? -> true or false
|
415
563
|
*
|
416
|
-
* Returns +true+ if
|
564
|
+
* Returns +true+ if the stream is completely closed, +false+ otherwise.
|
417
565
|
*/
|
418
566
|
static VALUE
|
419
567
|
strio_closed(VALUE self)
|
@@ -427,7 +575,7 @@ strio_closed(VALUE self)
|
|
427
575
|
* call-seq:
|
428
576
|
* strio.closed_read? -> true or false
|
429
577
|
*
|
430
|
-
* Returns +true+ if
|
578
|
+
* Returns +true+ if the stream is not readable, +false+ otherwise.
|
431
579
|
*/
|
432
580
|
static VALUE
|
433
581
|
strio_closed_read(VALUE self)
|
@@ -441,7 +589,7 @@ strio_closed_read(VALUE self)
|
|
441
589
|
* call-seq:
|
442
590
|
* strio.closed_write? -> true or false
|
443
591
|
*
|
444
|
-
* Returns +true+ if
|
592
|
+
* Returns +true+ if the stream is not writable, +false+ otherwise.
|
445
593
|
*/
|
446
594
|
static VALUE
|
447
595
|
strio_closed_write(VALUE self)
|
@@ -456,8 +604,8 @@ strio_closed_write(VALUE self)
|
|
456
604
|
* strio.eof -> true or false
|
457
605
|
* strio.eof? -> true or false
|
458
606
|
*
|
459
|
-
* Returns true if
|
460
|
-
* opened for reading or an +IOError+ will be raised.
|
607
|
+
* Returns true if the stream is at the end of the data (underlying string).
|
608
|
+
* The stream must be opened for reading or an +IOError+ will be raised.
|
461
609
|
*/
|
462
610
|
static VALUE
|
463
611
|
strio_eof(VALUE self)
|
@@ -480,7 +628,6 @@ strio_copy(VALUE copy, VALUE orig)
|
|
480
628
|
strio_free(DATA_PTR(copy));
|
481
629
|
}
|
482
630
|
DATA_PTR(copy) = ptr;
|
483
|
-
OBJ_INFECT(copy, orig);
|
484
631
|
RBASIC(copy)->flags &= ~STRIO_READWRITE;
|
485
632
|
RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
|
486
633
|
++ptr->count;
|
@@ -491,7 +638,7 @@ strio_copy(VALUE copy, VALUE orig)
|
|
491
638
|
* call-seq:
|
492
639
|
* strio.lineno -> integer
|
493
640
|
*
|
494
|
-
* Returns the current line number
|
641
|
+
* Returns the current line number. The stream must be
|
495
642
|
* opened for reading. +lineno+ counts the number of times +gets+ is
|
496
643
|
* called, rather than the number of newlines encountered. The two
|
497
644
|
* values will differ if +gets+ is called with a separator other than
|
@@ -517,6 +664,13 @@ strio_set_lineno(VALUE self, VALUE lineno)
|
|
517
664
|
return lineno;
|
518
665
|
}
|
519
666
|
|
667
|
+
/*
|
668
|
+
* call-seq:
|
669
|
+
* strio.binmode -> stringio
|
670
|
+
*
|
671
|
+
* Puts stream into binary mode. See IO#binmode.
|
672
|
+
*
|
673
|
+
*/
|
520
674
|
static VALUE
|
521
675
|
strio_binmode(VALUE self)
|
522
676
|
{
|
@@ -541,7 +695,7 @@ strio_binmode(VALUE self)
|
|
541
695
|
* strio.reopen(other_StrIO) -> strio
|
542
696
|
* strio.reopen(string, mode) -> strio
|
543
697
|
*
|
544
|
-
* Reinitializes
|
698
|
+
* Reinitializes the stream with the given <i>other_StrIO</i> or _string_
|
545
699
|
* and _mode_ (see StringIO#new).
|
546
700
|
*/
|
547
701
|
static VALUE
|
@@ -559,7 +713,7 @@ strio_reopen(int argc, VALUE *argv, VALUE self)
|
|
559
713
|
* strio.pos -> integer
|
560
714
|
* strio.tell -> integer
|
561
715
|
*
|
562
|
-
* Returns the current offset (in bytes)
|
716
|
+
* Returns the current offset (in bytes).
|
563
717
|
*/
|
564
718
|
static VALUE
|
565
719
|
strio_get_pos(VALUE self)
|
@@ -571,7 +725,7 @@ strio_get_pos(VALUE self)
|
|
571
725
|
* call-seq:
|
572
726
|
* strio.pos = integer -> integer
|
573
727
|
*
|
574
|
-
* Seeks to the given position (in bytes)
|
728
|
+
* Seeks to the given position (in bytes).
|
575
729
|
*/
|
576
730
|
static VALUE
|
577
731
|
strio_set_pos(VALUE self, VALUE pos)
|
@@ -589,7 +743,7 @@ strio_set_pos(VALUE self, VALUE pos)
|
|
589
743
|
* call-seq:
|
590
744
|
* strio.rewind -> 0
|
591
745
|
*
|
592
|
-
* Positions
|
746
|
+
* Positions the stream to the beginning of input, resetting
|
593
747
|
* +lineno+ to zero.
|
594
748
|
*/
|
595
749
|
static VALUE
|
@@ -678,18 +832,6 @@ strio_each_byte(VALUE self)
|
|
678
832
|
return self;
|
679
833
|
}
|
680
834
|
|
681
|
-
/*
|
682
|
-
* This is a deprecated alias for #each_byte.
|
683
|
-
*/
|
684
|
-
static VALUE
|
685
|
-
strio_bytes(VALUE self)
|
686
|
-
{
|
687
|
-
rb_warn("StringIO#bytes is deprecated; use #each_byte instead");
|
688
|
-
if (!rb_block_given_p())
|
689
|
-
return rb_enumeratorize(self, ID2SYM(rb_intern("each_byte")), 0, 0);
|
690
|
-
return strio_each_byte(self);
|
691
|
-
}
|
692
|
-
|
693
835
|
/*
|
694
836
|
* call-seq:
|
695
837
|
* strio.getc -> string or nil
|
@@ -757,7 +899,7 @@ strio_extend(struct StringIO *ptr, long pos, long len)
|
|
757
899
|
* call-seq:
|
758
900
|
* strio.ungetc(string) -> nil
|
759
901
|
*
|
760
|
-
* Pushes back one character (passed as a parameter)
|
902
|
+
* Pushes back one character (passed as a parameter)
|
761
903
|
* such that a subsequent buffered read will return it. There is no
|
762
904
|
* limitation for multiple pushbacks including pushing back behind the
|
763
905
|
* beginning of the buffer string.
|
@@ -803,24 +945,25 @@ static VALUE
|
|
803
945
|
strio_ungetbyte(VALUE self, VALUE c)
|
804
946
|
{
|
805
947
|
struct StringIO *ptr = readable(self);
|
806
|
-
char buf[1], *cp = buf;
|
807
|
-
long cl = 1;
|
808
948
|
|
809
949
|
check_modifiable(ptr);
|
810
950
|
if (NIL_P(c)) return Qnil;
|
811
|
-
if (
|
812
|
-
|
813
|
-
|
951
|
+
if (RB_INTEGER_TYPE_P(c)) {
|
952
|
+
/* rb_int_and() not visible from exts */
|
953
|
+
VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
|
954
|
+
const char cc = NUM2INT(v) & 0xFF;
|
955
|
+
strio_unget_bytes(ptr, &cc, 1);
|
814
956
|
}
|
815
957
|
else {
|
958
|
+
long cl;
|
816
959
|
SafeStringValue(c);
|
817
|
-
cp = RSTRING_PTR(c);
|
818
960
|
cl = RSTRING_LEN(c);
|
819
|
-
if (cl
|
820
|
-
|
821
|
-
|
822
|
-
|
961
|
+
if (cl > 0) {
|
962
|
+
strio_unget_bytes(ptr, RSTRING_PTR(c), cl);
|
963
|
+
RB_GC_GUARD(c);
|
964
|
+
}
|
823
965
|
}
|
966
|
+
return Qnil;
|
824
967
|
}
|
825
968
|
|
826
969
|
static VALUE
|
@@ -863,7 +1006,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
|
|
863
1006
|
static VALUE
|
864
1007
|
strio_readchar(VALUE self)
|
865
1008
|
{
|
866
|
-
VALUE c =
|
1009
|
+
VALUE c = rb_funcallv(self, rb_intern("getc"), 0, 0);
|
867
1010
|
if (NIL_P(c)) rb_eof_error();
|
868
1011
|
return c;
|
869
1012
|
}
|
@@ -877,7 +1020,7 @@ strio_readchar(VALUE self)
|
|
877
1020
|
static VALUE
|
878
1021
|
strio_readbyte(VALUE self)
|
879
1022
|
{
|
880
|
-
VALUE c =
|
1023
|
+
VALUE c = rb_funcallv(self, rb_intern("getbyte"), 0, 0);
|
881
1024
|
if (NIL_P(c)) rb_eof_error();
|
882
1025
|
return c;
|
883
1026
|
}
|
@@ -902,18 +1045,6 @@ strio_each_char(VALUE self)
|
|
902
1045
|
return self;
|
903
1046
|
}
|
904
1047
|
|
905
|
-
/*
|
906
|
-
* This is a deprecated alias for <code>each_char</code>.
|
907
|
-
*/
|
908
|
-
static VALUE
|
909
|
-
strio_chars(VALUE self)
|
910
|
-
{
|
911
|
-
rb_warn("StringIO#chars is deprecated; use #each_char instead");
|
912
|
-
if (!rb_block_given_p())
|
913
|
-
return rb_enumeratorize(self, ID2SYM(rb_intern("each_char")), 0, 0);
|
914
|
-
return strio_each_char(self);
|
915
|
-
}
|
916
|
-
|
917
1048
|
/*
|
918
1049
|
* call-seq:
|
919
1050
|
* strio.each_codepoint {|c| block } -> strio
|
@@ -940,24 +1071,12 @@ strio_each_codepoint(VALUE self)
|
|
940
1071
|
|
941
1072
|
c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
|
942
1073
|
RSTRING_END(ptr->string), &n, enc);
|
943
|
-
rb_yield(UINT2NUM(c));
|
944
1074
|
ptr->pos += n;
|
1075
|
+
rb_yield(UINT2NUM(c));
|
945
1076
|
}
|
946
1077
|
return self;
|
947
1078
|
}
|
948
1079
|
|
949
|
-
/*
|
950
|
-
* This is a deprecated alias for <code>each_codepoint</code>.
|
951
|
-
*/
|
952
|
-
static VALUE
|
953
|
-
strio_codepoints(VALUE self)
|
954
|
-
{
|
955
|
-
rb_warn("StringIO#codepoints is deprecated; use #each_codepoint instead");
|
956
|
-
if (!rb_block_given_p())
|
957
|
-
return rb_enumeratorize(self, ID2SYM(rb_intern("each_codepoint")), 0, 0);
|
958
|
-
return strio_each_codepoint(self);
|
959
|
-
}
|
960
|
-
|
961
1080
|
/* Boyer-Moore search: copied from regex.c */
|
962
1081
|
static void
|
963
1082
|
bm_init_skip(long *skip, const char *pat, long m)
|
@@ -1137,9 +1256,9 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
|
|
1137
1256
|
|
1138
1257
|
/*
|
1139
1258
|
* call-seq:
|
1140
|
-
* strio.gets(sep
|
1141
|
-
* strio.gets(limit) -> string or nil
|
1142
|
-
* strio.gets(sep, limit) -> string or nil
|
1259
|
+
* strio.gets(sep=$/, chomp: false) -> string or nil
|
1260
|
+
* strio.gets(limit, chomp: false) -> string or nil
|
1261
|
+
* strio.gets(sep, limit, chomp: false) -> string or nil
|
1143
1262
|
*
|
1144
1263
|
* See IO#gets.
|
1145
1264
|
*/
|
@@ -1161,31 +1280,31 @@ strio_gets(int argc, VALUE *argv, VALUE self)
|
|
1161
1280
|
|
1162
1281
|
/*
|
1163
1282
|
* call-seq:
|
1164
|
-
* strio.readline(sep
|
1165
|
-
* strio.readline(limit) -> string or nil
|
1166
|
-
* strio.readline(sep, limit) -> string or nil
|
1283
|
+
* strio.readline(sep=$/, chomp: false) -> string
|
1284
|
+
* strio.readline(limit, chomp: false) -> string or nil
|
1285
|
+
* strio.readline(sep, limit, chomp: false) -> string or nil
|
1167
1286
|
*
|
1168
1287
|
* See IO#readline.
|
1169
1288
|
*/
|
1170
1289
|
static VALUE
|
1171
1290
|
strio_readline(int argc, VALUE *argv, VALUE self)
|
1172
1291
|
{
|
1173
|
-
VALUE line =
|
1292
|
+
VALUE line = rb_funcallv_kw(self, rb_intern("gets"), argc, argv, RB_PASS_CALLED_KEYWORDS);
|
1174
1293
|
if (NIL_P(line)) rb_eof_error();
|
1175
1294
|
return line;
|
1176
1295
|
}
|
1177
1296
|
|
1178
1297
|
/*
|
1179
1298
|
* call-seq:
|
1180
|
-
* strio.each(sep
|
1181
|
-
* strio.each(limit) {|line| block } -> strio
|
1182
|
-
* strio.each(sep, limit) {|line| block } -> strio
|
1183
|
-
* strio.each(...)
|
1299
|
+
* strio.each(sep=$/, chomp: false) {|line| block } -> strio
|
1300
|
+
* strio.each(limit, chomp: false) {|line| block } -> strio
|
1301
|
+
* strio.each(sep, limit, chomp: false) {|line| block } -> strio
|
1302
|
+
* strio.each(...) -> anEnumerator
|
1184
1303
|
*
|
1185
|
-
* strio.each_line(sep
|
1186
|
-
* strio.each_line(limit) {|line| block }
|
1187
|
-
* strio.each_line(sep,limit) {|line| block } -> strio
|
1188
|
-
* strio.each_line(...)
|
1304
|
+
* strio.each_line(sep=$/, chomp: false) {|line| block } -> strio
|
1305
|
+
* strio.each_line(limit, chomp: false) {|line| block } -> strio
|
1306
|
+
* strio.each_line(sep, limit, chomp: false) {|line| block } -> strio
|
1307
|
+
* strio.each_line(...) -> anEnumerator
|
1189
1308
|
*
|
1190
1309
|
* See IO#each.
|
1191
1310
|
*/
|
@@ -1208,23 +1327,11 @@ strio_each(int argc, VALUE *argv, VALUE self)
|
|
1208
1327
|
return self;
|
1209
1328
|
}
|
1210
1329
|
|
1211
|
-
/*
|
1212
|
-
* This is a deprecated alias for <code>each_line</code>.
|
1213
|
-
*/
|
1214
|
-
static VALUE
|
1215
|
-
strio_lines(int argc, VALUE *argv, VALUE self)
|
1216
|
-
{
|
1217
|
-
rb_warn("StringIO#lines is deprecated; use #each_line instead");
|
1218
|
-
if (!rb_block_given_p())
|
1219
|
-
return rb_enumeratorize(self, ID2SYM(rb_intern("each_line")), argc, argv);
|
1220
|
-
return strio_each(argc, argv, self);
|
1221
|
-
}
|
1222
|
-
|
1223
1330
|
/*
|
1224
1331
|
* call-seq:
|
1225
|
-
* strio.readlines(sep
|
1226
|
-
* strio.readlines(limit)
|
1227
|
-
* strio.readlines(sep,limit) -> array
|
1332
|
+
* strio.readlines(sep=$/, chomp: false) -> array
|
1333
|
+
* strio.readlines(limit, chomp: false) -> array
|
1334
|
+
* strio.readlines(sep, limit, chomp: false) -> array
|
1228
1335
|
*
|
1229
1336
|
* See IO#readlines.
|
1230
1337
|
*/
|
@@ -1251,7 +1358,7 @@ strio_readlines(int argc, VALUE *argv, VALUE self)
|
|
1251
1358
|
* strio.write(string, ...) -> integer
|
1252
1359
|
* strio.syswrite(string) -> integer
|
1253
1360
|
*
|
1254
|
-
* Appends the given string to the underlying buffer string
|
1361
|
+
* Appends the given string to the underlying buffer string.
|
1255
1362
|
* The stream must be opened for writing. If the argument is not a
|
1256
1363
|
* string, it will be converted to a string using <code>to_s</code>.
|
1257
1364
|
* Returns the number of bytes written. See IO#write.
|
@@ -1274,13 +1381,18 @@ strio_write(VALUE self, VALUE str)
|
|
1274
1381
|
long len, olen;
|
1275
1382
|
rb_encoding *enc, *enc2;
|
1276
1383
|
rb_encoding *const ascii8bit = rb_ascii8bit_encoding();
|
1384
|
+
rb_encoding *usascii = 0;
|
1277
1385
|
|
1278
1386
|
if (!RB_TYPE_P(str, T_STRING))
|
1279
1387
|
str = rb_obj_as_string(str);
|
1280
1388
|
enc = get_enc(ptr);
|
1281
1389
|
enc2 = rb_enc_get(str);
|
1282
|
-
if (enc != enc2 && enc != ascii8bit) {
|
1283
|
-
|
1390
|
+
if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding())) {
|
1391
|
+
VALUE converted = rb_str_conv_enc(str, enc2, enc);
|
1392
|
+
if (converted == str && enc2 != ascii8bit && enc2 != usascii) { /* conversion failed */
|
1393
|
+
rb_enc_check(rb_enc_from_encoding(enc), str);
|
1394
|
+
}
|
1395
|
+
str = converted;
|
1284
1396
|
}
|
1285
1397
|
len = RSTRING_LEN(str);
|
1286
1398
|
if (len == 0) return 0;
|
@@ -1292,7 +1404,6 @@ strio_write(VALUE self, VALUE str)
|
|
1292
1404
|
if (ptr->pos == olen) {
|
1293
1405
|
if (enc == ascii8bit || enc2 == ascii8bit) {
|
1294
1406
|
rb_enc_str_buf_cat(ptr->string, RSTRING_PTR(str), len, enc);
|
1295
|
-
OBJ_INFECT(ptr->string, str);
|
1296
1407
|
}
|
1297
1408
|
else {
|
1298
1409
|
rb_str_buf_append(ptr->string, str);
|
@@ -1301,9 +1412,7 @@ strio_write(VALUE self, VALUE str)
|
|
1301
1412
|
else {
|
1302
1413
|
strio_extend(ptr, ptr->pos, len);
|
1303
1414
|
memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
|
1304
|
-
OBJ_INFECT(ptr->string, str);
|
1305
1415
|
}
|
1306
|
-
OBJ_INFECT(ptr->string, self);
|
1307
1416
|
RB_GC_GUARD(str);
|
1308
1417
|
ptr->pos += len;
|
1309
1418
|
return len;
|
@@ -1380,7 +1489,6 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
1380
1489
|
long len;
|
1381
1490
|
int binary = 0;
|
1382
1491
|
|
1383
|
-
rb_check_arity(argc, 0, 2);
|
1384
1492
|
switch (argc) {
|
1385
1493
|
case 2:
|
1386
1494
|
str = argv[1];
|
@@ -1406,7 +1514,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
1406
1514
|
case 0:
|
1407
1515
|
len = RSTRING_LEN(ptr->string);
|
1408
1516
|
if (len <= ptr->pos) {
|
1409
|
-
rb_encoding *enc =
|
1517
|
+
rb_encoding *enc = get_enc(ptr);
|
1410
1518
|
if (NIL_P(str)) {
|
1411
1519
|
str = rb_str_new(0, 0);
|
1412
1520
|
}
|
@@ -1420,6 +1528,8 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
1420
1528
|
len -= ptr->pos;
|
1421
1529
|
}
|
1422
1530
|
break;
|
1531
|
+
default:
|
1532
|
+
rb_error_arity(argc, 0, 2);
|
1423
1533
|
}
|
1424
1534
|
if (NIL_P(str)) {
|
1425
1535
|
rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
|
@@ -1450,7 +1560,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
1450
1560
|
static VALUE
|
1451
1561
|
strio_sysread(int argc, VALUE *argv, VALUE self)
|
1452
1562
|
{
|
1453
|
-
VALUE val =
|
1563
|
+
VALUE val = rb_funcallv_kw(self, rb_intern("read"), argc, argv, RB_PASS_CALLED_KEYWORDS);
|
1454
1564
|
if (NIL_P(val)) {
|
1455
1565
|
rb_eof_error();
|
1456
1566
|
}
|
@@ -1525,7 +1635,7 @@ strio_size(VALUE self)
|
|
1525
1635
|
* call-seq:
|
1526
1636
|
* strio.truncate(integer) -> 0
|
1527
1637
|
*
|
1528
|
-
* Truncates the buffer string to at most _integer_ bytes. The
|
1638
|
+
* Truncates the buffer string to at most _integer_ bytes. The stream
|
1529
1639
|
* must be opened for writing.
|
1530
1640
|
*/
|
1531
1641
|
static VALUE
|
@@ -1549,7 +1659,8 @@ strio_truncate(VALUE self, VALUE len)
|
|
1549
1659
|
* strio.external_encoding => encoding
|
1550
1660
|
*
|
1551
1661
|
* Returns the Encoding object that represents the encoding of the file.
|
1552
|
-
* If
|
1662
|
+
* If the stream is write mode and no encoding is specified, returns
|
1663
|
+
* +nil+.
|
1553
1664
|
*/
|
1554
1665
|
|
1555
1666
|
static VALUE
|
@@ -1564,7 +1675,7 @@ strio_external_encoding(VALUE self)
|
|
1564
1675
|
* strio.internal_encoding => encoding
|
1565
1676
|
*
|
1566
1677
|
* Returns the Encoding of the internal string if conversion is
|
1567
|
-
* specified. Otherwise returns nil
|
1678
|
+
* specified. Otherwise returns +nil+.
|
1568
1679
|
*/
|
1569
1680
|
|
1570
1681
|
static VALUE
|
@@ -1606,24 +1717,48 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
|
|
1606
1717
|
return self;
|
1607
1718
|
}
|
1608
1719
|
|
1720
|
+
static VALUE
|
1721
|
+
strio_set_encoding_by_bom(VALUE self)
|
1722
|
+
{
|
1723
|
+
struct StringIO *ptr = StringIO(self);
|
1724
|
+
|
1725
|
+
if (!set_encoding_by_bom(ptr)) return Qnil;
|
1726
|
+
return rb_enc_from_encoding(ptr->enc);
|
1727
|
+
}
|
1728
|
+
|
1609
1729
|
/*
|
1610
|
-
* Pseudo I/O on String object.
|
1730
|
+
* Pseudo I/O on String object, with interface corresponding to IO.
|
1611
1731
|
*
|
1612
|
-
* Commonly used to simulate
|
1732
|
+
* Commonly used to simulate <code>$stdio</code> or <code>$stderr</code>
|
1613
1733
|
*
|
1614
1734
|
* === Examples
|
1615
1735
|
*
|
1616
1736
|
* require 'stringio'
|
1617
1737
|
*
|
1738
|
+
* # Writing stream emulation
|
1618
1739
|
* io = StringIO.new
|
1619
1740
|
* io.puts "Hello World"
|
1620
1741
|
* io.string #=> "Hello World\n"
|
1742
|
+
*
|
1743
|
+
* # Reading stream emulation
|
1744
|
+
* io = StringIO.new "first\nsecond\nlast\n"
|
1745
|
+
* io.getc #=> "f"
|
1746
|
+
* io.gets #=> "irst\n"
|
1747
|
+
* io.read #=> "second\nlast\n"
|
1621
1748
|
*/
|
1622
1749
|
void
|
1623
1750
|
Init_stringio(void)
|
1624
1751
|
{
|
1752
|
+
#undef rb_intern
|
1753
|
+
|
1754
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
1755
|
+
rb_ext_ractor_safe(true);
|
1756
|
+
#endif
|
1757
|
+
|
1625
1758
|
VALUE StringIO = rb_define_class("StringIO", rb_cData);
|
1626
1759
|
|
1760
|
+
rb_define_const(StringIO, "VERSION", rb_str_new_cstr(STRINGIO_VERSION));
|
1761
|
+
|
1627
1762
|
rb_include_module(StringIO, rb_mEnumerable);
|
1628
1763
|
rb_define_alloc_func(StringIO, strio_s_allocate);
|
1629
1764
|
rb_define_singleton_method(StringIO, "new", strio_s_new, -1);
|
@@ -1665,13 +1800,9 @@ Init_stringio(void)
|
|
1665
1800
|
|
1666
1801
|
rb_define_method(StringIO, "each", strio_each, -1);
|
1667
1802
|
rb_define_method(StringIO, "each_line", strio_each, -1);
|
1668
|
-
rb_define_method(StringIO, "lines", strio_lines, -1);
|
1669
1803
|
rb_define_method(StringIO, "each_byte", strio_each_byte, 0);
|
1670
|
-
rb_define_method(StringIO, "bytes", strio_bytes, 0);
|
1671
1804
|
rb_define_method(StringIO, "each_char", strio_each_char, 0);
|
1672
|
-
rb_define_method(StringIO, "chars", strio_chars, 0);
|
1673
1805
|
rb_define_method(StringIO, "each_codepoint", strio_each_codepoint, 0);
|
1674
|
-
rb_define_method(StringIO, "codepoints", strio_codepoints, 0);
|
1675
1806
|
rb_define_method(StringIO, "getc", strio_getc, 0);
|
1676
1807
|
rb_define_method(StringIO, "ungetc", strio_ungetc, 1);
|
1677
1808
|
rb_define_method(StringIO, "ungetbyte", strio_ungetbyte, 1);
|
@@ -1704,6 +1835,7 @@ Init_stringio(void)
|
|
1704
1835
|
rb_define_method(StringIO, "external_encoding", strio_external_encoding, 0);
|
1705
1836
|
rb_define_method(StringIO, "internal_encoding", strio_internal_encoding, 0);
|
1706
1837
|
rb_define_method(StringIO, "set_encoding", strio_set_encoding, -1);
|
1838
|
+
rb_define_method(StringIO, "set_encoding_by_bom", strio_set_encoding_by_bom, 0);
|
1707
1839
|
|
1708
1840
|
{
|
1709
1841
|
VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stringio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nobu Nakada
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
-
|
12
|
-
date: 2016-06-09 00:00:00.000000000 Z
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-12-18 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake-compiler
|
@@ -25,19 +24,33 @@ dependencies:
|
|
25
24
|
- - ">="
|
26
25
|
- !ruby/object:Gem::Version
|
27
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: test-unit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
28
41
|
description: Pseudo `IO` class from/to `String`.
|
29
42
|
email: nobu@ruby-lang.org
|
30
43
|
executables: []
|
31
44
|
extensions:
|
32
|
-
- extconf.rb
|
45
|
+
- ext/stringio/extconf.rb
|
33
46
|
extra_rdoc_files: []
|
34
47
|
files:
|
35
48
|
- README.md
|
36
|
-
-
|
37
|
-
-
|
38
|
-
- stringio.c
|
49
|
+
- ext/stringio/extconf.rb
|
50
|
+
- ext/stringio/stringio.c
|
39
51
|
homepage: https://github.com/ruby/stringio
|
40
52
|
licenses:
|
53
|
+
- Ruby
|
41
54
|
- BSD-2-Clause
|
42
55
|
metadata: {}
|
43
56
|
post_install_message:
|
@@ -48,15 +61,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
48
61
|
requirements:
|
49
62
|
- - ">="
|
50
63
|
- !ruby/object:Gem::Version
|
51
|
-
version: '2.
|
64
|
+
version: '2.5'
|
52
65
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
66
|
requirements:
|
54
67
|
- - ">="
|
55
68
|
- !ruby/object:Gem::Version
|
56
69
|
version: '2.6'
|
57
70
|
requirements: []
|
58
|
-
|
59
|
-
rubygems_version: 2.7.6
|
71
|
+
rubygems_version: 3.1.4
|
60
72
|
signing_key:
|
61
73
|
specification_version: 4
|
62
74
|
summary: Pseudo IO on String
|
data/depend
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# AUTOGENERATED DEPENDENCIES START
|
2
|
-
stringio.o: $(RUBY_EXTCONF_H)
|
3
|
-
stringio.o: $(arch_hdrdir)/ruby/config.h
|
4
|
-
stringio.o: $(hdrdir)/ruby/backward.h
|
5
|
-
stringio.o: $(hdrdir)/ruby/defines.h
|
6
|
-
stringio.o: $(hdrdir)/ruby/encoding.h
|
7
|
-
stringio.o: $(hdrdir)/ruby/intern.h
|
8
|
-
stringio.o: $(hdrdir)/ruby/io.h
|
9
|
-
stringio.o: $(hdrdir)/ruby/missing.h
|
10
|
-
stringio.o: $(hdrdir)/ruby/onigmo.h
|
11
|
-
stringio.o: $(hdrdir)/ruby/oniguruma.h
|
12
|
-
stringio.o: $(hdrdir)/ruby/ruby.h
|
13
|
-
stringio.o: $(hdrdir)/ruby/st.h
|
14
|
-
stringio.o: $(hdrdir)/ruby/subst.h
|
15
|
-
stringio.o: $(top_srcdir)/include/ruby.h
|
16
|
-
stringio.o: stringio.c
|
17
|
-
# AUTOGENERATED DEPENDENCIES END
|