stringio 3.1.0 → 3.1.2
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/.document +5 -0
- data/.rdoc_options +2 -0
- data/COPYING +56 -0
- data/LICENSE.txt +22 -0
- data/NEWS.md +185 -0
- data/README.md +1 -1
- data/docs/io.rb +8 -0
- data/ext/stringio/.document +1 -0
- data/ext/stringio/stringio.c +135 -85
- metadata +19 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 89f7a19f0a8689e3fa7ceae8a0139eab614a14f64f2d1f5831c0d012d3b49dac
|
|
4
|
+
data.tar.gz: 71b2022cc337d594566c0dfcb215bc1f3d4949747c97ffb984ea0613f67d58aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e6aa9ba1567fe2ea15f973a81ef8ae215be4ea7b88013dd9a4d9e8cbd8d1d0381dd70980ffb049d8b4283e0b1e6e586ef840618c8f129f1182c71bfa95847824
|
|
7
|
+
data.tar.gz: ed2fd455cbe0f072ef020f2b6a114ae192a8a86509cebcb927fb4c7b9754551bdda8519ebc7aa21b6cbf2b3c0cab4170e5017c0468ad4431ea4b9eaf9c473825
|
data/.rdoc_options
ADDED
data/COPYING
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
|
|
2
|
+
You can redistribute it and/or modify it under either the terms of the
|
|
3
|
+
2-clause BSDL (see the file BSDL), or the conditions below:
|
|
4
|
+
|
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
|
6
|
+
software without restriction, provided that you duplicate all of the
|
|
7
|
+
original copyright notices and associated disclaimers.
|
|
8
|
+
|
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
|
10
|
+
you do at least ONE of the following:
|
|
11
|
+
|
|
12
|
+
a. place your modifications in the Public Domain or otherwise
|
|
13
|
+
make them Freely Available, such as by posting said
|
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
|
15
|
+
the author to include your modifications in the software.
|
|
16
|
+
|
|
17
|
+
b. use the modified software only within your corporation or
|
|
18
|
+
organization.
|
|
19
|
+
|
|
20
|
+
c. give non-standard binaries non-standard names, with
|
|
21
|
+
instructions on where to get the original software distribution.
|
|
22
|
+
|
|
23
|
+
d. make other distribution arrangements with the author.
|
|
24
|
+
|
|
25
|
+
3. You may distribute the software in object code or binary form,
|
|
26
|
+
provided that you do at least ONE of the following:
|
|
27
|
+
|
|
28
|
+
a. distribute the binaries and library files of the software,
|
|
29
|
+
together with instructions (in the manual page or equivalent)
|
|
30
|
+
on where to get the original distribution.
|
|
31
|
+
|
|
32
|
+
b. accompany the distribution with the machine-readable source of
|
|
33
|
+
the software.
|
|
34
|
+
|
|
35
|
+
c. give non-standard binaries non-standard names, with
|
|
36
|
+
instructions on where to get the original software distribution.
|
|
37
|
+
|
|
38
|
+
d. make other distribution arrangements with the author.
|
|
39
|
+
|
|
40
|
+
4. You may modify and include the part of the software into any other
|
|
41
|
+
software (possibly commercial). But some files in the distribution
|
|
42
|
+
are not written by the author, so that they are not under these terms.
|
|
43
|
+
|
|
44
|
+
For the list of those files and their copying conditions, see the
|
|
45
|
+
file LEGAL.
|
|
46
|
+
|
|
47
|
+
5. The scripts and library files supplied as input to or produced as
|
|
48
|
+
output from the software do not automatically fall under the
|
|
49
|
+
copyright of the software, but belong to whomever generated them,
|
|
50
|
+
and may be sold commercially, and may be aggregated with this
|
|
51
|
+
software.
|
|
52
|
+
|
|
53
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
|
54
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
55
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
56
|
+
PURPOSE.
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
|
4
|
+
modification, are permitted provided that the following conditions
|
|
5
|
+
are met:
|
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
|
10
|
+
documentation and/or other materials provided with the distribution.
|
|
11
|
+
|
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
22
|
+
SUCH DAMAGE.
|
data/NEWS.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# News
|
|
2
|
+
|
|
3
|
+
## 3.1.2 - 2024-11-07
|
|
4
|
+
|
|
5
|
+
### Improvements
|
|
6
|
+
|
|
7
|
+
* JRuby: Added support for detecting encoding by BOM.
|
|
8
|
+
* GH-100
|
|
9
|
+
* GH-101
|
|
10
|
+
|
|
11
|
+
### Fixes
|
|
12
|
+
|
|
13
|
+
* CRuby: Fixed a bug that unknown memory may be used by
|
|
14
|
+
`StringIO#ungetc`/`StringIO#ungetbyte`.
|
|
15
|
+
* https://hackerone.com/reports/2805165
|
|
16
|
+
* Reported by manun.
|
|
17
|
+
|
|
18
|
+
### Thanks
|
|
19
|
+
|
|
20
|
+
* manun
|
|
21
|
+
|
|
22
|
+
## 3.1.1 - 2024-06-13
|
|
23
|
+
|
|
24
|
+
### Improvements
|
|
25
|
+
|
|
26
|
+
* JRuby: Improved.
|
|
27
|
+
* GH-83
|
|
28
|
+
* GH-84
|
|
29
|
+
* GH-85
|
|
30
|
+
|
|
31
|
+
* Added `StringIO::MAX_LENGTH`.
|
|
32
|
+
|
|
33
|
+
* Added support for NULL `StringIO` by `StringIO.new(nil)`.
|
|
34
|
+
|
|
35
|
+
* Improved IO compatibility for partial read.
|
|
36
|
+
* GH-95
|
|
37
|
+
* https://bugs.ruby-lang.org/issues/20418
|
|
38
|
+
|
|
39
|
+
### Fixes
|
|
40
|
+
|
|
41
|
+
* Fixed a bug that coderange isn't updated after overwrite.
|
|
42
|
+
* Reported by Tiago Cardoso.
|
|
43
|
+
* https://bugs.ruby-lang.org/issues/20185
|
|
44
|
+
* GH-77
|
|
45
|
+
* GH-79
|
|
46
|
+
|
|
47
|
+
### Thanks
|
|
48
|
+
|
|
49
|
+
* Tiago Cardoso
|
|
50
|
+
|
|
51
|
+
## 3.1.0 - 2023-11-28
|
|
52
|
+
|
|
53
|
+
### Fixes
|
|
54
|
+
|
|
55
|
+
* TruffleRuby: Do not compile the C extension
|
|
56
|
+
|
|
57
|
+
GH-71
|
|
58
|
+
|
|
59
|
+
## 3.0.9 - 2023-11-08
|
|
60
|
+
|
|
61
|
+
### Improvements
|
|
62
|
+
|
|
63
|
+
* JRuby: Aligned `StringIO#gets` behavior with the C implementation.
|
|
64
|
+
|
|
65
|
+
GH-61
|
|
66
|
+
|
|
67
|
+
### Fixes
|
|
68
|
+
|
|
69
|
+
* CRuby: Fixed `StringIO#pread` with the length 0.
|
|
70
|
+
|
|
71
|
+
Patch by Jean byroot Boussier.
|
|
72
|
+
|
|
73
|
+
GH-67
|
|
74
|
+
|
|
75
|
+
* CRuby: Fixed a bug that `StringIO#gets` with non ASCII compatible
|
|
76
|
+
encoding such as UTF-16 doesn't detect correct new line characters.
|
|
77
|
+
|
|
78
|
+
Reported by IWAMOTO Kouichi.
|
|
79
|
+
|
|
80
|
+
GH-68
|
|
81
|
+
|
|
82
|
+
### Thanks
|
|
83
|
+
|
|
84
|
+
* Jean byroot Boussier
|
|
85
|
+
|
|
86
|
+
* IWAMOTO Kouichi
|
|
87
|
+
|
|
88
|
+
## 3.0.8 - 2023-08-10
|
|
89
|
+
|
|
90
|
+
### Improvements
|
|
91
|
+
|
|
92
|
+
* Added `StringIO#pread`.
|
|
93
|
+
|
|
94
|
+
Patch by Jean byroot Boussier.
|
|
95
|
+
|
|
96
|
+
GH-56
|
|
97
|
+
|
|
98
|
+
* JRuby: Added `StringIO::VERSION`.
|
|
99
|
+
|
|
100
|
+
GH-57 GH-59
|
|
101
|
+
|
|
102
|
+
### Thanks
|
|
103
|
+
|
|
104
|
+
* Jean byroot Boussier
|
|
105
|
+
|
|
106
|
+
## 3.0.7 - 2023-06-02
|
|
107
|
+
|
|
108
|
+
* CRuby: Avoid direct struct usage. This change is for supporting
|
|
109
|
+
Ruby 3.3.
|
|
110
|
+
|
|
111
|
+
GH-54
|
|
112
|
+
|
|
113
|
+
## 3.0.6 - 2023-04-14
|
|
114
|
+
|
|
115
|
+
### Improvements
|
|
116
|
+
|
|
117
|
+
* CRuby: Added support for write barrier.
|
|
118
|
+
|
|
119
|
+
* JRuby: Added missing arty-checking.
|
|
120
|
+
|
|
121
|
+
GH-48
|
|
122
|
+
|
|
123
|
+
* JRuby: Added support for `StringIO.new(encoding:)`.
|
|
124
|
+
|
|
125
|
+
GH-45
|
|
126
|
+
|
|
127
|
+
## 3.0.5 - 2023-02-02
|
|
128
|
+
|
|
129
|
+
### Improvements
|
|
130
|
+
|
|
131
|
+
### Fixes
|
|
132
|
+
|
|
133
|
+
* Fixed a bug that `StringIO#gets("2+ character", chomp: true)` did not
|
|
134
|
+
remove the separator at the end.
|
|
135
|
+
[[Bug #19389](https://bugs.ruby-lang.org/issues/19389)]
|
|
136
|
+
|
|
137
|
+
## 3.0.4 - 2022-12-09
|
|
138
|
+
|
|
139
|
+
### Improvements
|
|
140
|
+
|
|
141
|
+
* JRuby: Changed to use flag registry.
|
|
142
|
+
[[GitHub#33](https://github.com/ruby/stringio/pull/26)]
|
|
143
|
+
|
|
144
|
+
## 3.0.3 - 2022-12-08
|
|
145
|
+
|
|
146
|
+
### Improvements
|
|
147
|
+
|
|
148
|
+
* Improved documents.
|
|
149
|
+
[[GitHub#33](https://github.com/ruby/stringio/pull/33)]
|
|
150
|
+
[[GitHub#34](https://github.com/ruby/stringio/pull/34)]
|
|
151
|
+
[[GitHub#35](https://github.com/ruby/stringio/pull/35)]
|
|
152
|
+
[[GitHub#36](https://github.com/ruby/stringio/pull/36)]
|
|
153
|
+
[[GitHub#37](https://github.com/ruby/stringio/pull/37)]
|
|
154
|
+
[Patch by Burdette Lamar]
|
|
155
|
+
|
|
156
|
+
### Fixes
|
|
157
|
+
|
|
158
|
+
* Fixed a bug that large `StringIO#ungetc`/`StringIO#ungetbyte`
|
|
159
|
+
break internal buffer.
|
|
160
|
+
|
|
161
|
+
* Fixed a bug that `StringIO#each("2+ character", chomp: true)` cause
|
|
162
|
+
infinite loop.
|
|
163
|
+
[[Bug #18769](https://bugs.ruby-lang.org/issues/18769)]
|
|
164
|
+
|
|
165
|
+
* Fixed a bug that `StringIO#each(nil, chomp: true)` chomps.
|
|
166
|
+
[[Bug #18770](https://bugs.ruby-lang.org/issues/18770)]
|
|
167
|
+
|
|
168
|
+
* Fixed a bug that `StringIO#each("", chomp: true)` isn't compatible
|
|
169
|
+
with `IO#each("", chomp: true)`.
|
|
170
|
+
[[Bug #18768](https://bugs.ruby-lang.org/issues/18768)]
|
|
171
|
+
|
|
172
|
+
* Fixed a bug that `StringIO#set_encoding` doesn't accept external
|
|
173
|
+
and internal encodings pairo.
|
|
174
|
+
[[GitHub#16](https://github.com/ruby/stringio/issues/16)]
|
|
175
|
+
[Reported by Kenta Murata]
|
|
176
|
+
|
|
177
|
+
* Fixed a bug that `StringIO#truncate` isn't compatible with
|
|
178
|
+
`File#truncate`.
|
|
179
|
+
|
|
180
|
+
### Thanks
|
|
181
|
+
|
|
182
|
+
* Kenta Murata
|
|
183
|
+
|
|
184
|
+
* Burdette Lamar
|
|
185
|
+
|
data/README.md
CHANGED
|
@@ -12,7 +12,7 @@ This library is based on MoonWolf version written in Ruby. Thanks a lot.
|
|
|
12
12
|
|
|
13
13
|
* `fileno` raises `NotImplementedError`.
|
|
14
14
|
* encoding conversion is not implemented, and ignored silently.
|
|
15
|
-
* there is no `#to_io` method because this is not an `IO
|
|
15
|
+
* there is no `#to_io` method because this is not an `IO`.
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
data/docs/io.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.[ch]
|
data/ext/stringio/stringio.c
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
**********************************************************************/
|
|
14
14
|
|
|
15
15
|
static const char *const
|
|
16
|
-
STRINGIO_VERSION = "3.1.
|
|
16
|
+
STRINGIO_VERSION = "3.1.2";
|
|
17
|
+
|
|
18
|
+
#include <stdbool.h>
|
|
17
19
|
|
|
18
20
|
#include "ruby.h"
|
|
19
21
|
#include "ruby/io.h"
|
|
@@ -48,7 +50,13 @@ static long strio_write(VALUE self, VALUE str);
|
|
|
48
50
|
|
|
49
51
|
#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
|
|
50
52
|
#define error_inval(msg) (rb_syserr_fail(EINVAL, msg))
|
|
51
|
-
#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string))
|
|
53
|
+
#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : !NIL_P((ptr)->string) ? rb_enc_get((ptr)->string) : NULL)
|
|
54
|
+
|
|
55
|
+
static bool
|
|
56
|
+
readonly_string_p(VALUE string)
|
|
57
|
+
{
|
|
58
|
+
return OBJ_FROZEN_RAW(string);
|
|
59
|
+
}
|
|
52
60
|
|
|
53
61
|
static struct StringIO *
|
|
54
62
|
strio_alloc(void)
|
|
@@ -166,7 +174,10 @@ writable(VALUE strio)
|
|
|
166
174
|
static void
|
|
167
175
|
check_modifiable(struct StringIO *ptr)
|
|
168
176
|
{
|
|
169
|
-
if (
|
|
177
|
+
if (NIL_P(ptr->string)) {
|
|
178
|
+
/* Null device StringIO */
|
|
179
|
+
}
|
|
180
|
+
else if (OBJ_FROZEN_RAW(ptr->string)) {
|
|
170
181
|
rb_raise(rb_eIOError, "not modifiable string");
|
|
171
182
|
}
|
|
172
183
|
}
|
|
@@ -281,13 +292,14 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
|
|
|
281
292
|
|
|
282
293
|
argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
|
|
283
294
|
rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
|
|
284
|
-
if (
|
|
295
|
+
if (!NIL_P(string)) {
|
|
285
296
|
StringValue(string);
|
|
286
297
|
}
|
|
287
|
-
else {
|
|
298
|
+
else if (!argc) {
|
|
288
299
|
string = rb_enc_str_new("", 0, rb_default_external_encoding());
|
|
289
300
|
}
|
|
290
|
-
|
|
301
|
+
|
|
302
|
+
if (!NIL_P(string) && readonly_string_p(string)) {
|
|
291
303
|
if (ptr->flags & FMODE_WRITABLE) {
|
|
292
304
|
rb_syserr_fail(EACCES, 0);
|
|
293
305
|
}
|
|
@@ -297,11 +309,11 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
|
|
|
297
309
|
ptr->flags |= FMODE_WRITABLE;
|
|
298
310
|
}
|
|
299
311
|
}
|
|
300
|
-
if (ptr->flags & FMODE_TRUNC) {
|
|
312
|
+
if (!NIL_P(string) && (ptr->flags & FMODE_TRUNC)) {
|
|
301
313
|
rb_str_resize(string, 0);
|
|
302
314
|
}
|
|
303
315
|
RB_OBJ_WRITE(self, &ptr->string, string);
|
|
304
|
-
if (argc == 1) {
|
|
316
|
+
if (argc == 1 && !NIL_P(string)) {
|
|
305
317
|
ptr->enc = rb_enc_get(string);
|
|
306
318
|
}
|
|
307
319
|
else {
|
|
@@ -481,7 +493,7 @@ strio_set_string(VALUE self, VALUE string)
|
|
|
481
493
|
rb_io_taint_check(self);
|
|
482
494
|
ptr->flags &= ~FMODE_READWRITE;
|
|
483
495
|
StringValue(string);
|
|
484
|
-
ptr->flags =
|
|
496
|
+
ptr->flags = readonly_string_p(string) ? FMODE_READABLE : FMODE_READWRITE;
|
|
485
497
|
ptr->pos = 0;
|
|
486
498
|
ptr->lineno = 0;
|
|
487
499
|
RB_OBJ_WRITE(self, &ptr->string, string);
|
|
@@ -595,6 +607,7 @@ static struct StringIO *
|
|
|
595
607
|
strio_to_read(VALUE self)
|
|
596
608
|
{
|
|
597
609
|
struct StringIO *ptr = readable(self);
|
|
610
|
+
if (NIL_P(ptr->string)) return NULL;
|
|
598
611
|
if (ptr->pos < RSTRING_LEN(ptr->string)) return ptr;
|
|
599
612
|
return NULL;
|
|
600
613
|
}
|
|
@@ -872,7 +885,7 @@ strio_getc(VALUE self)
|
|
|
872
885
|
int len;
|
|
873
886
|
char *p;
|
|
874
887
|
|
|
875
|
-
if (pos >= RSTRING_LEN(str)) {
|
|
888
|
+
if (NIL_P(str) || pos >= RSTRING_LEN(str)) {
|
|
876
889
|
return Qnil;
|
|
877
890
|
}
|
|
878
891
|
p = RSTRING_PTR(str)+pos;
|
|
@@ -893,7 +906,7 @@ strio_getbyte(VALUE self)
|
|
|
893
906
|
{
|
|
894
907
|
struct StringIO *ptr = readable(self);
|
|
895
908
|
int c;
|
|
896
|
-
if (ptr->pos >= RSTRING_LEN(ptr->string)) {
|
|
909
|
+
if (NIL_P(ptr->string) || ptr->pos >= RSTRING_LEN(ptr->string)) {
|
|
897
910
|
return Qnil;
|
|
898
911
|
}
|
|
899
912
|
c = RSTRING_PTR(ptr->string)[ptr->pos++];
|
|
@@ -915,8 +928,17 @@ strio_extend(struct StringIO *ptr, long pos, long len)
|
|
|
915
928
|
if (pos > olen)
|
|
916
929
|
MEMZERO(RSTRING_PTR(ptr->string) + olen, char, pos - olen);
|
|
917
930
|
}
|
|
918
|
-
|
|
919
|
-
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
static void
|
|
934
|
+
strio_unget_string(struct StringIO *ptr, VALUE c)
|
|
935
|
+
{
|
|
936
|
+
const char *cp = NULL;
|
|
937
|
+
long cl = RSTRING_LEN(c);
|
|
938
|
+
if (cl > 0) {
|
|
939
|
+
if (c != ptr->string) cp = RSTRING_PTR(c);
|
|
940
|
+
strio_unget_bytes(ptr, cp, cl);
|
|
941
|
+
RB_GC_GUARD(c);
|
|
920
942
|
}
|
|
921
943
|
}
|
|
922
944
|
|
|
@@ -934,6 +956,7 @@ strio_ungetc(VALUE self, VALUE c)
|
|
|
934
956
|
rb_encoding *enc, *enc2;
|
|
935
957
|
|
|
936
958
|
check_modifiable(ptr);
|
|
959
|
+
if (NIL_P(ptr->string)) return Qnil;
|
|
937
960
|
if (NIL_P(c)) return Qnil;
|
|
938
961
|
if (RB_INTEGER_TYPE_P(c)) {
|
|
939
962
|
int len, cc = NUM2INT(c);
|
|
@@ -941,19 +964,22 @@ strio_ungetc(VALUE self, VALUE c)
|
|
|
941
964
|
|
|
942
965
|
enc = rb_enc_get(ptr->string);
|
|
943
966
|
len = rb_enc_codelen(cc, enc);
|
|
944
|
-
if (len <= 0)
|
|
967
|
+
if (len <= 0) {
|
|
968
|
+
rb_enc_uint_chr(cc, enc); /* to raise an exception */
|
|
969
|
+
UNREACHABLE;
|
|
970
|
+
}
|
|
945
971
|
rb_enc_mbcput(cc, buf, enc);
|
|
946
972
|
return strio_unget_bytes(ptr, buf, len);
|
|
947
973
|
}
|
|
948
974
|
else {
|
|
949
|
-
|
|
975
|
+
StringValue(c);
|
|
976
|
+
if (RSTRING_LEN(c) == 0) return Qnil;
|
|
950
977
|
enc = rb_enc_get(ptr->string);
|
|
951
978
|
enc2 = rb_enc_get(c);
|
|
952
979
|
if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
|
|
953
980
|
c = rb_str_conv_enc(c, enc2, enc);
|
|
954
981
|
}
|
|
955
|
-
|
|
956
|
-
RB_GC_GUARD(c);
|
|
982
|
+
strio_unget_string(ptr, c);
|
|
957
983
|
return Qnil;
|
|
958
984
|
}
|
|
959
985
|
}
|
|
@@ -971,21 +997,17 @@ strio_ungetbyte(VALUE self, VALUE c)
|
|
|
971
997
|
struct StringIO *ptr = readable(self);
|
|
972
998
|
|
|
973
999
|
check_modifiable(ptr);
|
|
1000
|
+
if (NIL_P(ptr->string)) return Qnil;
|
|
974
1001
|
if (NIL_P(c)) return Qnil;
|
|
975
1002
|
if (RB_INTEGER_TYPE_P(c)) {
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1003
|
+
/* rb_int_and() not visible from exts */
|
|
1004
|
+
VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
|
|
1005
|
+
const char cc = NUM2INT(v) & 0xFF;
|
|
1006
|
+
strio_unget_bytes(ptr, &cc, 1);
|
|
980
1007
|
}
|
|
981
1008
|
else {
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
cl = RSTRING_LEN(c);
|
|
985
|
-
if (cl > 0) {
|
|
986
|
-
strio_unget_bytes(ptr, RSTRING_PTR(c), cl);
|
|
987
|
-
RB_GC_GUARD(c);
|
|
988
|
-
}
|
|
1009
|
+
StringValue(c);
|
|
1010
|
+
strio_unget_string(ptr, c);
|
|
989
1011
|
}
|
|
990
1012
|
return Qnil;
|
|
991
1013
|
}
|
|
@@ -1016,7 +1038,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
|
|
|
1016
1038
|
if (rest > cl) memset(s + len, 0, rest - cl);
|
|
1017
1039
|
pos -= cl;
|
|
1018
1040
|
}
|
|
1019
|
-
memcpy(s + pos, cp, cl);
|
|
1041
|
+
memcpy(s + pos, (cp ? cp : s), cl);
|
|
1020
1042
|
ptr->pos = pos;
|
|
1021
1043
|
return Qnil;
|
|
1022
1044
|
}
|
|
@@ -1157,41 +1179,41 @@ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VA
|
|
|
1157
1179
|
break;
|
|
1158
1180
|
|
|
1159
1181
|
case 1:
|
|
1160
|
-
|
|
1161
|
-
|
|
1182
|
+
if (!NIL_P(rs) && !RB_TYPE_P(rs, T_STRING)) {
|
|
1183
|
+
VALUE tmp = rb_check_string_type(rs);
|
|
1162
1184
|
if (NIL_P(tmp)) {
|
|
1163
|
-
|
|
1164
|
-
|
|
1185
|
+
limit = NUM2LONG(rs);
|
|
1186
|
+
rs = rb_rs;
|
|
1165
1187
|
}
|
|
1166
1188
|
else {
|
|
1167
|
-
|
|
1189
|
+
rs = tmp;
|
|
1168
1190
|
}
|
|
1169
1191
|
}
|
|
1170
1192
|
break;
|
|
1171
1193
|
|
|
1172
1194
|
case 2:
|
|
1173
|
-
|
|
1195
|
+
if (!NIL_P(rs)) StringValue(rs);
|
|
1174
1196
|
if (!NIL_P(lim)) limit = NUM2LONG(lim);
|
|
1175
1197
|
break;
|
|
1176
1198
|
}
|
|
1177
|
-
if (!NIL_P(rs)) {
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1199
|
+
if (!NIL_P(ptr->string) && !NIL_P(rs)) {
|
|
1200
|
+
rb_encoding *enc_rs, *enc_io;
|
|
1201
|
+
enc_rs = rb_enc_get(rs);
|
|
1202
|
+
enc_io = get_enc(ptr);
|
|
1203
|
+
if (enc_rs != enc_io &&
|
|
1204
|
+
(rb_enc_str_coderange(rs) != ENC_CODERANGE_7BIT ||
|
|
1205
|
+
(RSTRING_LEN(rs) > 0 && !rb_enc_asciicompat(enc_io)))) {
|
|
1206
|
+
if (rs == rb_rs) {
|
|
1207
|
+
rs = rb_enc_str_new(0, 0, enc_io);
|
|
1208
|
+
rb_str_buf_cat_ascii(rs, "\n");
|
|
1209
|
+
rs = rs;
|
|
1210
|
+
}
|
|
1211
|
+
else {
|
|
1212
|
+
rb_raise(rb_eArgError, "encoding mismatch: %s IO with %s RS",
|
|
1213
|
+
rb_enc_name(enc_io),
|
|
1214
|
+
rb_enc_name(enc_rs));
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1195
1217
|
}
|
|
1196
1218
|
arg->rs = rs;
|
|
1197
1219
|
arg->limit = limit;
|
|
@@ -1203,9 +1225,9 @@ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VA
|
|
|
1203
1225
|
keywords[0] = rb_intern_const("chomp");
|
|
1204
1226
|
}
|
|
1205
1227
|
rb_get_kwargs(opts, keywords, 0, 1, &vchomp);
|
|
1206
|
-
|
|
1228
|
+
if (respect_chomp) {
|
|
1207
1229
|
arg->chomp = (vchomp != Qundef) && RTEST(vchomp);
|
|
1208
|
-
|
|
1230
|
+
}
|
|
1209
1231
|
}
|
|
1210
1232
|
return arg;
|
|
1211
1233
|
}
|
|
@@ -1229,7 +1251,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
|
|
|
1229
1251
|
long w = 0;
|
|
1230
1252
|
rb_encoding *enc = get_enc(ptr);
|
|
1231
1253
|
|
|
1232
|
-
if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
|
|
1254
|
+
if (NIL_P(ptr->string) || ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
|
|
1233
1255
|
return Qnil;
|
|
1234
1256
|
}
|
|
1235
1257
|
s = RSTRING_PTR(ptr->string);
|
|
@@ -1245,7 +1267,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
|
|
|
1245
1267
|
str = strio_substr(ptr, ptr->pos, e - s - w, enc);
|
|
1246
1268
|
}
|
|
1247
1269
|
else if ((n = RSTRING_LEN(str)) == 0) {
|
|
1248
|
-
|
|
1270
|
+
const char *paragraph_end = NULL;
|
|
1249
1271
|
p = s;
|
|
1250
1272
|
while (p[(p + 1 < e) && (*p == '\r') && 0] == '\n') {
|
|
1251
1273
|
p += *p == '\r';
|
|
@@ -1255,18 +1277,18 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
|
|
|
1255
1277
|
}
|
|
1256
1278
|
s = p;
|
|
1257
1279
|
while ((p = memchr(p, '\n', e - p)) && (p != e)) {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1280
|
+
p++;
|
|
1281
|
+
if (!((p < e && *p == '\n') ||
|
|
1282
|
+
(p + 1 < e && *p == '\r' && *(p+1) == '\n'))) {
|
|
1283
|
+
continue;
|
|
1284
|
+
}
|
|
1285
|
+
paragraph_end = p - ((*(p-2) == '\r') ? 2 : 1);
|
|
1286
|
+
while ((p < e && *p == '\n') ||
|
|
1287
|
+
(p + 1 < e && *p == '\r' && *(p+1) == '\n')) {
|
|
1288
|
+
p += (*p == '\r') ? 2 : 1;
|
|
1289
|
+
}
|
|
1290
|
+
e = p;
|
|
1291
|
+
break;
|
|
1270
1292
|
}
|
|
1271
1293
|
if (arg->chomp && paragraph_end) {
|
|
1272
1294
|
w = e - paragraph_end;
|
|
@@ -1326,6 +1348,7 @@ strio_gets(int argc, VALUE *argv, VALUE self)
|
|
|
1326
1348
|
VALUE str;
|
|
1327
1349
|
|
|
1328
1350
|
if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
|
|
1351
|
+
if (NIL_P(ptr->string)) return Qnil;
|
|
1329
1352
|
return rb_enc_str_new(0, 0, get_enc(ptr));
|
|
1330
1353
|
}
|
|
1331
1354
|
|
|
@@ -1440,6 +1463,7 @@ strio_write(VALUE self, VALUE str)
|
|
|
1440
1463
|
if (!RB_TYPE_P(str, T_STRING))
|
|
1441
1464
|
str = rb_obj_as_string(str);
|
|
1442
1465
|
enc = get_enc(ptr);
|
|
1466
|
+
if (!enc) return 0;
|
|
1443
1467
|
enc2 = rb_enc_get(str);
|
|
1444
1468
|
if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding())) {
|
|
1445
1469
|
VALUE converted = rb_str_conv_enc(str, enc2, enc);
|
|
@@ -1465,6 +1489,7 @@ strio_write(VALUE self, VALUE str)
|
|
|
1465
1489
|
}
|
|
1466
1490
|
else {
|
|
1467
1491
|
strio_extend(ptr, ptr->pos, len);
|
|
1492
|
+
rb_str_modify(ptr->string);
|
|
1468
1493
|
memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
|
|
1469
1494
|
}
|
|
1470
1495
|
RB_GC_GUARD(str);
|
|
@@ -1511,10 +1536,12 @@ strio_putc(VALUE self, VALUE ch)
|
|
|
1511
1536
|
|
|
1512
1537
|
check_modifiable(ptr);
|
|
1513
1538
|
if (RB_TYPE_P(ch, T_STRING)) {
|
|
1539
|
+
if (NIL_P(ptr->string)) return ch;
|
|
1514
1540
|
str = rb_str_substr(ch, 0, 1);
|
|
1515
1541
|
}
|
|
1516
1542
|
else {
|
|
1517
1543
|
char c = NUM2CHR(ch);
|
|
1544
|
+
if (NIL_P(ptr->string)) return ch;
|
|
1518
1545
|
str = rb_str_new(&c, 1);
|
|
1519
1546
|
}
|
|
1520
1547
|
strio_write(self, str);
|
|
@@ -1557,7 +1584,8 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
|
1557
1584
|
if (len < 0) {
|
|
1558
1585
|
rb_raise(rb_eArgError, "negative length %ld given", len);
|
|
1559
1586
|
}
|
|
1560
|
-
if (len > 0 &&
|
|
1587
|
+
if (len > 0 &&
|
|
1588
|
+
(NIL_P(ptr->string) || ptr->pos >= RSTRING_LEN(ptr->string))) {
|
|
1561
1589
|
if (!NIL_P(str)) rb_str_resize(str, 0);
|
|
1562
1590
|
return Qnil;
|
|
1563
1591
|
}
|
|
@@ -1566,6 +1594,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
|
1566
1594
|
}
|
|
1567
1595
|
/* fall through */
|
|
1568
1596
|
case 0:
|
|
1597
|
+
if (NIL_P(ptr->string)) return Qnil;
|
|
1569
1598
|
len = RSTRING_LEN(ptr->string);
|
|
1570
1599
|
if (len <= ptr->pos) {
|
|
1571
1600
|
rb_encoding *enc = get_enc(ptr);
|
|
@@ -1583,7 +1612,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
|
1583
1612
|
}
|
|
1584
1613
|
break;
|
|
1585
1614
|
default:
|
|
1586
|
-
|
|
1615
|
+
rb_error_arity(argc, 0, 2);
|
|
1587
1616
|
}
|
|
1588
1617
|
if (NIL_P(str)) {
|
|
1589
1618
|
rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
|
|
@@ -1594,10 +1623,9 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
|
1594
1623
|
if (len > rest) len = rest;
|
|
1595
1624
|
rb_str_resize(str, len);
|
|
1596
1625
|
MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len);
|
|
1597
|
-
if (binary)
|
|
1598
|
-
rb_enc_associate(str, rb_ascii8bit_encoding());
|
|
1599
|
-
else
|
|
1626
|
+
if (!binary) {
|
|
1600
1627
|
rb_enc_copy(str, ptr->string);
|
|
1628
|
+
}
|
|
1601
1629
|
}
|
|
1602
1630
|
ptr->pos += RSTRING_LEN(str);
|
|
1603
1631
|
return str;
|
|
@@ -1619,28 +1647,28 @@ strio_pread(int argc, VALUE *argv, VALUE self)
|
|
|
1619
1647
|
long offset = NUM2LONG(rb_offset);
|
|
1620
1648
|
|
|
1621
1649
|
if (len < 0) {
|
|
1622
|
-
|
|
1650
|
+
rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
|
|
1623
1651
|
}
|
|
1624
1652
|
|
|
1625
1653
|
if (len == 0) {
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1654
|
+
if (NIL_P(rb_buf)) {
|
|
1655
|
+
return rb_str_new("", 0);
|
|
1656
|
+
}
|
|
1657
|
+
return rb_buf;
|
|
1630
1658
|
}
|
|
1631
1659
|
|
|
1632
1660
|
if (offset < 0) {
|
|
1633
|
-
|
|
1661
|
+
rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
|
|
1634
1662
|
}
|
|
1635
1663
|
|
|
1636
1664
|
struct StringIO *ptr = readable(self);
|
|
1637
1665
|
|
|
1638
1666
|
if (offset >= RSTRING_LEN(ptr->string)) {
|
|
1639
|
-
|
|
1667
|
+
rb_eof_error();
|
|
1640
1668
|
}
|
|
1641
1669
|
|
|
1642
1670
|
if (NIL_P(rb_buf)) {
|
|
1643
|
-
|
|
1671
|
+
return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
|
|
1644
1672
|
}
|
|
1645
1673
|
|
|
1646
1674
|
long rest = RSTRING_LEN(ptr->string) - offset;
|
|
@@ -1700,8 +1728,14 @@ strio_read_nonblock(int argc, VALUE *argv, VALUE self)
|
|
|
1700
1728
|
return val;
|
|
1701
1729
|
}
|
|
1702
1730
|
|
|
1731
|
+
/*
|
|
1732
|
+
* See IO#write
|
|
1733
|
+
*/
|
|
1703
1734
|
#define strio_syswrite rb_io_write
|
|
1704
1735
|
|
|
1736
|
+
/*
|
|
1737
|
+
* See IO#write_nonblock
|
|
1738
|
+
*/
|
|
1705
1739
|
static VALUE
|
|
1706
1740
|
strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self)
|
|
1707
1741
|
{
|
|
@@ -1729,7 +1763,7 @@ strio_size(VALUE self)
|
|
|
1729
1763
|
{
|
|
1730
1764
|
VALUE string = StringIO(self)->string;
|
|
1731
1765
|
if (NIL_P(string)) {
|
|
1732
|
-
|
|
1766
|
+
return INT2FIX(0);
|
|
1733
1767
|
}
|
|
1734
1768
|
return ULONG2NUM(RSTRING_LEN(string));
|
|
1735
1769
|
}
|
|
@@ -1746,10 +1780,12 @@ strio_truncate(VALUE self, VALUE len)
|
|
|
1746
1780
|
{
|
|
1747
1781
|
VALUE string = writable(self)->string;
|
|
1748
1782
|
long l = NUM2LONG(len);
|
|
1749
|
-
long plen
|
|
1783
|
+
long plen;
|
|
1750
1784
|
if (l < 0) {
|
|
1751
1785
|
error_inval("negative length");
|
|
1752
1786
|
}
|
|
1787
|
+
if (NIL_P(string)) return 0;
|
|
1788
|
+
plen = RSTRING_LEN(string);
|
|
1753
1789
|
rb_str_resize(string, l);
|
|
1754
1790
|
if (plen < l) {
|
|
1755
1791
|
MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
|
|
@@ -1820,13 +1856,22 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
|
|
|
1820
1856
|
}
|
|
1821
1857
|
}
|
|
1822
1858
|
ptr->enc = enc;
|
|
1823
|
-
if (WRITABLE(self)) {
|
|
1859
|
+
if (!NIL_P(ptr->string) && WRITABLE(self)) {
|
|
1824
1860
|
rb_enc_associate(ptr->string, enc);
|
|
1825
1861
|
}
|
|
1826
1862
|
|
|
1827
1863
|
return self;
|
|
1828
1864
|
}
|
|
1829
1865
|
|
|
1866
|
+
/*
|
|
1867
|
+
* call-seq:
|
|
1868
|
+
* strio.set_encoding_by_bom => strio or nil
|
|
1869
|
+
*
|
|
1870
|
+
* Sets the encoding according to the BOM (Byte Order Mark) in the
|
|
1871
|
+
* string.
|
|
1872
|
+
*
|
|
1873
|
+
* Returns +self+ if the BOM is found, otherwise +nil.
|
|
1874
|
+
*/
|
|
1830
1875
|
static VALUE
|
|
1831
1876
|
strio_set_encoding_by_bom(VALUE self)
|
|
1832
1877
|
{
|
|
@@ -1859,10 +1904,15 @@ Init_stringio(void)
|
|
|
1859
1904
|
|
|
1860
1905
|
VALUE StringIO = rb_define_class("StringIO", rb_cObject);
|
|
1861
1906
|
|
|
1907
|
+
/* The version string */
|
|
1862
1908
|
rb_define_const(StringIO, "VERSION", rb_str_new_cstr(STRINGIO_VERSION));
|
|
1863
1909
|
|
|
1864
1910
|
rb_include_module(StringIO, rb_mEnumerable);
|
|
1865
1911
|
rb_define_alloc_func(StringIO, strio_s_allocate);
|
|
1912
|
+
|
|
1913
|
+
/* Maximum length that a StringIO instance can hold */
|
|
1914
|
+
rb_define_const(StringIO, "MAX_LENGTH", LONG2NUM(LONG_MAX));
|
|
1915
|
+
|
|
1866
1916
|
rb_define_singleton_method(StringIO, "new", strio_s_new, -1);
|
|
1867
1917
|
rb_define_singleton_method(StringIO, "open", strio_s_open, -1);
|
|
1868
1918
|
rb_define_method(StringIO, "initialize", strio_initialize, -1);
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stringio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nobu Nakada
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2024-11-07 00:00:00.000000000 Z
|
|
13
13
|
dependencies: []
|
|
14
14
|
description: Pseudo `IO` class from/to `String`.
|
|
15
15
|
email:
|
|
@@ -18,9 +18,24 @@ email:
|
|
|
18
18
|
executables: []
|
|
19
19
|
extensions:
|
|
20
20
|
- ext/stringio/extconf.rb
|
|
21
|
-
extra_rdoc_files:
|
|
21
|
+
extra_rdoc_files:
|
|
22
|
+
- ".document"
|
|
23
|
+
- ".rdoc_options"
|
|
24
|
+
- COPYING
|
|
25
|
+
- LICENSE.txt
|
|
26
|
+
- NEWS.md
|
|
27
|
+
- README.md
|
|
28
|
+
- docs/io.rb
|
|
29
|
+
- ext/stringio/.document
|
|
22
30
|
files:
|
|
31
|
+
- ".document"
|
|
32
|
+
- ".rdoc_options"
|
|
33
|
+
- COPYING
|
|
34
|
+
- LICENSE.txt
|
|
35
|
+
- NEWS.md
|
|
23
36
|
- README.md
|
|
37
|
+
- docs/io.rb
|
|
38
|
+
- ext/stringio/.document
|
|
24
39
|
- ext/stringio/extconf.rb
|
|
25
40
|
- ext/stringio/stringio.c
|
|
26
41
|
homepage: https://github.com/ruby/stringio
|
|
@@ -43,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
43
58
|
- !ruby/object:Gem::Version
|
|
44
59
|
version: '0'
|
|
45
60
|
requirements: []
|
|
46
|
-
rubygems_version: 3.
|
|
61
|
+
rubygems_version: 3.5.22
|
|
47
62
|
signing_key:
|
|
48
63
|
specification_version: 4
|
|
49
64
|
summary: Pseudo IO on String
|