stringio 3.1.0 → 3.1.7
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 +243 -0
- data/README.md +1 -1
- data/docs/io.rb +8 -0
- data/ext/stringio/.document +1 -0
- data/ext/stringio/extconf.rb +2 -0
- data/ext/stringio/stringio.c +145 -87
- metadata +21 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d32a3b9eb5ecb12a5c78c7a79418ed351272fe49a2fc1bbde837880a8e6a2a53
|
4
|
+
data.tar.gz: 8f965cb4f731147e7d6da44db5acbeda3a08ac51df419445d8001f35b17a1dc9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c3f11fa1dee2b8e00269cad5e99db7014ecdc7b1b7d99f5086d15fb3f04d17105dabd838887e5f87af817851e2a8a59260c7c7af26a5ea40f2ce103ad830775
|
7
|
+
data.tar.gz: c9e2afe1c8104c27591454cfeefdc71926c76196d3afc343f76052b9e465566f62df19ae25baaa1217839684910b0c94e4d05b7b08723f1960065f0c2d0844df
|
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,243 @@
|
|
1
|
+
# News
|
2
|
+
|
3
|
+
## 3.1.7 - 2025-04-21
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* CRuby: Added support for `rb_io_mode_t` that will be introduced in
|
8
|
+
Ruby 3.5 or later.
|
9
|
+
* GH-129
|
10
|
+
* Patch by Samuel Williams
|
11
|
+
|
12
|
+
### Thanks
|
13
|
+
|
14
|
+
* Samuel Williams
|
15
|
+
|
16
|
+
## 3.1.6 - 2025-03-25
|
17
|
+
|
18
|
+
### Fixes
|
19
|
+
|
20
|
+
* CRuby: Fix SEGV at unget to a null device StringIO
|
21
|
+
* JRuby:
|
22
|
+
* Fix NullPointerException at unget to a null device StringIO
|
23
|
+
* Use proper checkEncoding signature
|
24
|
+
* Update strioWrite logic to match CRuby
|
25
|
+
* GH-124
|
26
|
+
|
27
|
+
## 3.1.5 - 2025-02-21
|
28
|
+
|
29
|
+
### Improvements
|
30
|
+
|
31
|
+
* JRuby: Improved compatibility with CRuby for `StringIO#seek` with
|
32
|
+
frozen string.
|
33
|
+
* GH-119
|
34
|
+
* GH-121
|
35
|
+
|
36
|
+
## 3.1.4 - 2025-02-20
|
37
|
+
|
38
|
+
### Improvements
|
39
|
+
|
40
|
+
* JRuby: Improved compatibility with CRuby.
|
41
|
+
* GH-116
|
42
|
+
|
43
|
+
### Fixes
|
44
|
+
|
45
|
+
* CRuby: Fixed a bug that `StringIO` may mutate a shared string.
|
46
|
+
* GH-117
|
47
|
+
|
48
|
+
## 3.1.3 - 2025-02-14
|
49
|
+
|
50
|
+
### Fixes
|
51
|
+
|
52
|
+
* JRuby: Fixed a bug that JRuby may not be able to be started
|
53
|
+
* GH-112
|
54
|
+
* GH-113
|
55
|
+
* Reported by Karol Bucek
|
56
|
+
|
57
|
+
### Thanks
|
58
|
+
|
59
|
+
* Karol Bucek
|
60
|
+
|
61
|
+
## 3.1.2 - 2024-11-07
|
62
|
+
|
63
|
+
### Improvements
|
64
|
+
|
65
|
+
* JRuby: Added support for detecting encoding by BOM.
|
66
|
+
* GH-100
|
67
|
+
* GH-101
|
68
|
+
|
69
|
+
### Fixes
|
70
|
+
|
71
|
+
* CRuby: Fixed a bug that unknown memory may be used by
|
72
|
+
`StringIO#ungetc`/`StringIO#ungetbyte`.
|
73
|
+
* https://hackerone.com/reports/2805165
|
74
|
+
* Reported by manun.
|
75
|
+
|
76
|
+
### Thanks
|
77
|
+
|
78
|
+
* manun
|
79
|
+
|
80
|
+
## 3.1.1 - 2024-06-13
|
81
|
+
|
82
|
+
### Improvements
|
83
|
+
|
84
|
+
* JRuby: Improved.
|
85
|
+
* GH-83
|
86
|
+
* GH-84
|
87
|
+
* GH-85
|
88
|
+
|
89
|
+
* Added `StringIO::MAX_LENGTH`.
|
90
|
+
|
91
|
+
* Added support for NULL `StringIO` by `StringIO.new(nil)`.
|
92
|
+
|
93
|
+
* Improved IO compatibility for partial read.
|
94
|
+
* GH-95
|
95
|
+
* https://bugs.ruby-lang.org/issues/20418
|
96
|
+
|
97
|
+
### Fixes
|
98
|
+
|
99
|
+
* Fixed a bug that coderange isn't updated after overwrite.
|
100
|
+
* Reported by Tiago Cardoso.
|
101
|
+
* https://bugs.ruby-lang.org/issues/20185
|
102
|
+
* GH-77
|
103
|
+
* GH-79
|
104
|
+
|
105
|
+
### Thanks
|
106
|
+
|
107
|
+
* Tiago Cardoso
|
108
|
+
|
109
|
+
## 3.1.0 - 2023-11-28
|
110
|
+
|
111
|
+
### Fixes
|
112
|
+
|
113
|
+
* TruffleRuby: Do not compile the C extension
|
114
|
+
|
115
|
+
GH-71
|
116
|
+
|
117
|
+
## 3.0.9 - 2023-11-08
|
118
|
+
|
119
|
+
### Improvements
|
120
|
+
|
121
|
+
* JRuby: Aligned `StringIO#gets` behavior with the C implementation.
|
122
|
+
|
123
|
+
GH-61
|
124
|
+
|
125
|
+
### Fixes
|
126
|
+
|
127
|
+
* CRuby: Fixed `StringIO#pread` with the length 0.
|
128
|
+
|
129
|
+
Patch by Jean byroot Boussier.
|
130
|
+
|
131
|
+
GH-67
|
132
|
+
|
133
|
+
* CRuby: Fixed a bug that `StringIO#gets` with non ASCII compatible
|
134
|
+
encoding such as UTF-16 doesn't detect correct new line characters.
|
135
|
+
|
136
|
+
Reported by IWAMOTO Kouichi.
|
137
|
+
|
138
|
+
GH-68
|
139
|
+
|
140
|
+
### Thanks
|
141
|
+
|
142
|
+
* Jean byroot Boussier
|
143
|
+
|
144
|
+
* IWAMOTO Kouichi
|
145
|
+
|
146
|
+
## 3.0.8 - 2023-08-10
|
147
|
+
|
148
|
+
### Improvements
|
149
|
+
|
150
|
+
* Added `StringIO#pread`.
|
151
|
+
|
152
|
+
Patch by Jean byroot Boussier.
|
153
|
+
|
154
|
+
GH-56
|
155
|
+
|
156
|
+
* JRuby: Added `StringIO::VERSION`.
|
157
|
+
|
158
|
+
GH-57 GH-59
|
159
|
+
|
160
|
+
### Thanks
|
161
|
+
|
162
|
+
* Jean byroot Boussier
|
163
|
+
|
164
|
+
## 3.0.7 - 2023-06-02
|
165
|
+
|
166
|
+
* CRuby: Avoid direct struct usage. This change is for supporting
|
167
|
+
Ruby 3.3.
|
168
|
+
|
169
|
+
GH-54
|
170
|
+
|
171
|
+
## 3.0.6 - 2023-04-14
|
172
|
+
|
173
|
+
### Improvements
|
174
|
+
|
175
|
+
* CRuby: Added support for write barrier.
|
176
|
+
|
177
|
+
* JRuby: Added missing arty-checking.
|
178
|
+
|
179
|
+
GH-48
|
180
|
+
|
181
|
+
* JRuby: Added support for `StringIO.new(encoding:)`.
|
182
|
+
|
183
|
+
GH-45
|
184
|
+
|
185
|
+
## 3.0.5 - 2023-02-02
|
186
|
+
|
187
|
+
### Improvements
|
188
|
+
|
189
|
+
### Fixes
|
190
|
+
|
191
|
+
* Fixed a bug that `StringIO#gets("2+ character", chomp: true)` did not
|
192
|
+
remove the separator at the end.
|
193
|
+
[[Bug #19389](https://bugs.ruby-lang.org/issues/19389)]
|
194
|
+
|
195
|
+
## 3.0.4 - 2022-12-09
|
196
|
+
|
197
|
+
### Improvements
|
198
|
+
|
199
|
+
* JRuby: Changed to use flag registry.
|
200
|
+
[[GitHub#33](https://github.com/ruby/stringio/pull/26)]
|
201
|
+
|
202
|
+
## 3.0.3 - 2022-12-08
|
203
|
+
|
204
|
+
### Improvements
|
205
|
+
|
206
|
+
* Improved documents.
|
207
|
+
[[GitHub#33](https://github.com/ruby/stringio/pull/33)]
|
208
|
+
[[GitHub#34](https://github.com/ruby/stringio/pull/34)]
|
209
|
+
[[GitHub#35](https://github.com/ruby/stringio/pull/35)]
|
210
|
+
[[GitHub#36](https://github.com/ruby/stringio/pull/36)]
|
211
|
+
[[GitHub#37](https://github.com/ruby/stringio/pull/37)]
|
212
|
+
[Patch by Burdette Lamar]
|
213
|
+
|
214
|
+
### Fixes
|
215
|
+
|
216
|
+
* Fixed a bug that large `StringIO#ungetc`/`StringIO#ungetbyte`
|
217
|
+
break internal buffer.
|
218
|
+
|
219
|
+
* Fixed a bug that `StringIO#each("2+ character", chomp: true)` cause
|
220
|
+
infinite loop.
|
221
|
+
[[Bug #18769](https://bugs.ruby-lang.org/issues/18769)]
|
222
|
+
|
223
|
+
* Fixed a bug that `StringIO#each(nil, chomp: true)` chomps.
|
224
|
+
[[Bug #18770](https://bugs.ruby-lang.org/issues/18770)]
|
225
|
+
|
226
|
+
* Fixed a bug that `StringIO#each("", chomp: true)` isn't compatible
|
227
|
+
with `IO#each("", chomp: true)`.
|
228
|
+
[[Bug #18768](https://bugs.ruby-lang.org/issues/18768)]
|
229
|
+
|
230
|
+
* Fixed a bug that `StringIO#set_encoding` doesn't accept external
|
231
|
+
and internal encodings pairo.
|
232
|
+
[[GitHub#16](https://github.com/ruby/stringio/issues/16)]
|
233
|
+
[Reported by Kenta Murata]
|
234
|
+
|
235
|
+
* Fixed a bug that `StringIO#truncate` isn't compatible with
|
236
|
+
`File#truncate`.
|
237
|
+
|
238
|
+
### Thanks
|
239
|
+
|
240
|
+
* Kenta Murata
|
241
|
+
|
242
|
+
* Burdette Lamar
|
243
|
+
|
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/extconf.rb
CHANGED
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.7";
|
17
|
+
|
18
|
+
#include <stdbool.h>
|
17
19
|
|
18
20
|
#include "ruby.h"
|
19
21
|
#include "ruby/io.h"
|
@@ -33,12 +35,16 @@ STRINGIO_VERSION = "3.1.0";
|
|
33
35
|
# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
|
34
36
|
#endif
|
35
37
|
|
38
|
+
#ifndef HAVE_TYPE_RB_IO_MODE_T
|
39
|
+
typedef int rb_io_mode_t;
|
40
|
+
#endif
|
41
|
+
|
36
42
|
struct StringIO {
|
37
43
|
VALUE string;
|
38
44
|
rb_encoding *enc;
|
39
45
|
long pos;
|
40
46
|
long lineno;
|
41
|
-
|
47
|
+
rb_io_mode_t flags;
|
42
48
|
int count;
|
43
49
|
};
|
44
50
|
|
@@ -48,7 +54,13 @@ static long strio_write(VALUE self, VALUE str);
|
|
48
54
|
|
49
55
|
#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
|
50
56
|
#define error_inval(msg) (rb_syserr_fail(EINVAL, msg))
|
51
|
-
#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string))
|
57
|
+
#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : !NIL_P((ptr)->string) ? rb_enc_get((ptr)->string) : NULL)
|
58
|
+
|
59
|
+
static bool
|
60
|
+
readonly_string_p(VALUE string)
|
61
|
+
{
|
62
|
+
return OBJ_FROZEN_RAW(string);
|
63
|
+
}
|
52
64
|
|
53
65
|
static struct StringIO *
|
54
66
|
strio_alloc(void)
|
@@ -166,9 +178,15 @@ writable(VALUE strio)
|
|
166
178
|
static void
|
167
179
|
check_modifiable(struct StringIO *ptr)
|
168
180
|
{
|
169
|
-
if (
|
181
|
+
if (NIL_P(ptr->string)) {
|
182
|
+
/* Null device StringIO */
|
183
|
+
}
|
184
|
+
else if (OBJ_FROZEN_RAW(ptr->string)) {
|
170
185
|
rb_raise(rb_eIOError, "not modifiable string");
|
171
186
|
}
|
187
|
+
else {
|
188
|
+
rb_str_modify(ptr->string);
|
189
|
+
}
|
172
190
|
}
|
173
191
|
|
174
192
|
static VALUE
|
@@ -281,13 +299,14 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
|
|
281
299
|
|
282
300
|
argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
|
283
301
|
rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
|
284
|
-
if (
|
302
|
+
if (!NIL_P(string)) {
|
285
303
|
StringValue(string);
|
286
304
|
}
|
287
|
-
else {
|
305
|
+
else if (!argc) {
|
288
306
|
string = rb_enc_str_new("", 0, rb_default_external_encoding());
|
289
307
|
}
|
290
|
-
|
308
|
+
|
309
|
+
if (!NIL_P(string) && readonly_string_p(string)) {
|
291
310
|
if (ptr->flags & FMODE_WRITABLE) {
|
292
311
|
rb_syserr_fail(EACCES, 0);
|
293
312
|
}
|
@@ -297,11 +316,11 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
|
|
297
316
|
ptr->flags |= FMODE_WRITABLE;
|
298
317
|
}
|
299
318
|
}
|
300
|
-
if (ptr->flags & FMODE_TRUNC) {
|
319
|
+
if (!NIL_P(string) && (ptr->flags & FMODE_TRUNC)) {
|
301
320
|
rb_str_resize(string, 0);
|
302
321
|
}
|
303
322
|
RB_OBJ_WRITE(self, &ptr->string, string);
|
304
|
-
if (argc == 1) {
|
323
|
+
if (argc == 1 && !NIL_P(string)) {
|
305
324
|
ptr->enc = rb_enc_get(string);
|
306
325
|
}
|
307
326
|
else {
|
@@ -481,7 +500,7 @@ strio_set_string(VALUE self, VALUE string)
|
|
481
500
|
rb_io_taint_check(self);
|
482
501
|
ptr->flags &= ~FMODE_READWRITE;
|
483
502
|
StringValue(string);
|
484
|
-
ptr->flags =
|
503
|
+
ptr->flags = readonly_string_p(string) ? FMODE_READABLE : FMODE_READWRITE;
|
485
504
|
ptr->pos = 0;
|
486
505
|
ptr->lineno = 0;
|
487
506
|
RB_OBJ_WRITE(self, &ptr->string, string);
|
@@ -595,6 +614,7 @@ static struct StringIO *
|
|
595
614
|
strio_to_read(VALUE self)
|
596
615
|
{
|
597
616
|
struct StringIO *ptr = readable(self);
|
617
|
+
if (NIL_P(ptr->string)) return NULL;
|
598
618
|
if (ptr->pos < RSTRING_LEN(ptr->string)) return ptr;
|
599
619
|
return NULL;
|
600
620
|
}
|
@@ -872,7 +892,7 @@ strio_getc(VALUE self)
|
|
872
892
|
int len;
|
873
893
|
char *p;
|
874
894
|
|
875
|
-
if (pos >= RSTRING_LEN(str)) {
|
895
|
+
if (NIL_P(str) || pos >= RSTRING_LEN(str)) {
|
876
896
|
return Qnil;
|
877
897
|
}
|
878
898
|
p = RSTRING_PTR(str)+pos;
|
@@ -893,7 +913,7 @@ strio_getbyte(VALUE self)
|
|
893
913
|
{
|
894
914
|
struct StringIO *ptr = readable(self);
|
895
915
|
int c;
|
896
|
-
if (ptr->pos >= RSTRING_LEN(ptr->string)) {
|
916
|
+
if (NIL_P(ptr->string) || ptr->pos >= RSTRING_LEN(ptr->string)) {
|
897
917
|
return Qnil;
|
898
918
|
}
|
899
919
|
c = RSTRING_PTR(ptr->string)[ptr->pos++];
|
@@ -915,8 +935,17 @@ strio_extend(struct StringIO *ptr, long pos, long len)
|
|
915
935
|
if (pos > olen)
|
916
936
|
MEMZERO(RSTRING_PTR(ptr->string) + olen, char, pos - olen);
|
917
937
|
}
|
918
|
-
|
919
|
-
|
938
|
+
}
|
939
|
+
|
940
|
+
static void
|
941
|
+
strio_unget_string(struct StringIO *ptr, VALUE c)
|
942
|
+
{
|
943
|
+
const char *cp = NULL;
|
944
|
+
long cl = RSTRING_LEN(c);
|
945
|
+
if (cl > 0) {
|
946
|
+
if (c != ptr->string) cp = RSTRING_PTR(c);
|
947
|
+
strio_unget_bytes(ptr, cp, cl);
|
948
|
+
RB_GC_GUARD(c);
|
920
949
|
}
|
921
950
|
}
|
922
951
|
|
@@ -934,6 +963,7 @@ strio_ungetc(VALUE self, VALUE c)
|
|
934
963
|
rb_encoding *enc, *enc2;
|
935
964
|
|
936
965
|
check_modifiable(ptr);
|
966
|
+
if (NIL_P(ptr->string)) return Qnil;
|
937
967
|
if (NIL_P(c)) return Qnil;
|
938
968
|
if (RB_INTEGER_TYPE_P(c)) {
|
939
969
|
int len, cc = NUM2INT(c);
|
@@ -941,19 +971,22 @@ strio_ungetc(VALUE self, VALUE c)
|
|
941
971
|
|
942
972
|
enc = rb_enc_get(ptr->string);
|
943
973
|
len = rb_enc_codelen(cc, enc);
|
944
|
-
if (len <= 0)
|
974
|
+
if (len <= 0) {
|
975
|
+
rb_enc_uint_chr(cc, enc); /* to raise an exception */
|
976
|
+
UNREACHABLE;
|
977
|
+
}
|
945
978
|
rb_enc_mbcput(cc, buf, enc);
|
946
979
|
return strio_unget_bytes(ptr, buf, len);
|
947
980
|
}
|
948
981
|
else {
|
949
|
-
|
982
|
+
StringValue(c);
|
983
|
+
if (RSTRING_LEN(c) == 0) return Qnil;
|
950
984
|
enc = rb_enc_get(ptr->string);
|
951
985
|
enc2 = rb_enc_get(c);
|
952
986
|
if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
|
953
987
|
c = rb_str_conv_enc(c, enc2, enc);
|
954
988
|
}
|
955
|
-
|
956
|
-
RB_GC_GUARD(c);
|
989
|
+
strio_unget_string(ptr, c);
|
957
990
|
return Qnil;
|
958
991
|
}
|
959
992
|
}
|
@@ -971,21 +1004,17 @@ strio_ungetbyte(VALUE self, VALUE c)
|
|
971
1004
|
struct StringIO *ptr = readable(self);
|
972
1005
|
|
973
1006
|
check_modifiable(ptr);
|
1007
|
+
if (NIL_P(ptr->string)) return Qnil;
|
974
1008
|
if (NIL_P(c)) return Qnil;
|
975
1009
|
if (RB_INTEGER_TYPE_P(c)) {
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
1010
|
+
/* rb_int_and() not visible from exts */
|
1011
|
+
VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
|
1012
|
+
const char cc = NUM2INT(v) & 0xFF;
|
1013
|
+
strio_unget_bytes(ptr, &cc, 1);
|
980
1014
|
}
|
981
1015
|
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
|
-
}
|
1016
|
+
StringValue(c);
|
1017
|
+
strio_unget_string(ptr, c);
|
989
1018
|
}
|
990
1019
|
return Qnil;
|
991
1020
|
}
|
@@ -1016,7 +1045,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
|
|
1016
1045
|
if (rest > cl) memset(s + len, 0, rest - cl);
|
1017
1046
|
pos -= cl;
|
1018
1047
|
}
|
1019
|
-
memcpy(s + pos, cp, cl);
|
1048
|
+
memcpy(s + pos, (cp ? cp : s), cl);
|
1020
1049
|
ptr->pos = pos;
|
1021
1050
|
return Qnil;
|
1022
1051
|
}
|
@@ -1157,41 +1186,41 @@ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VA
|
|
1157
1186
|
break;
|
1158
1187
|
|
1159
1188
|
case 1:
|
1160
|
-
|
1161
|
-
|
1189
|
+
if (!NIL_P(rs) && !RB_TYPE_P(rs, T_STRING)) {
|
1190
|
+
VALUE tmp = rb_check_string_type(rs);
|
1162
1191
|
if (NIL_P(tmp)) {
|
1163
|
-
|
1164
|
-
|
1192
|
+
limit = NUM2LONG(rs);
|
1193
|
+
rs = rb_rs;
|
1165
1194
|
}
|
1166
1195
|
else {
|
1167
|
-
|
1196
|
+
rs = tmp;
|
1168
1197
|
}
|
1169
1198
|
}
|
1170
1199
|
break;
|
1171
1200
|
|
1172
1201
|
case 2:
|
1173
|
-
|
1202
|
+
if (!NIL_P(rs)) StringValue(rs);
|
1174
1203
|
if (!NIL_P(lim)) limit = NUM2LONG(lim);
|
1175
1204
|
break;
|
1176
1205
|
}
|
1177
|
-
if (!NIL_P(rs)) {
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1206
|
+
if (!NIL_P(ptr->string) && !NIL_P(rs)) {
|
1207
|
+
rb_encoding *enc_rs, *enc_io;
|
1208
|
+
enc_rs = rb_enc_get(rs);
|
1209
|
+
enc_io = get_enc(ptr);
|
1210
|
+
if (enc_rs != enc_io &&
|
1211
|
+
(rb_enc_str_coderange(rs) != ENC_CODERANGE_7BIT ||
|
1212
|
+
(RSTRING_LEN(rs) > 0 && !rb_enc_asciicompat(enc_io)))) {
|
1213
|
+
if (rs == rb_rs) {
|
1214
|
+
rs = rb_enc_str_new(0, 0, enc_io);
|
1215
|
+
rb_str_buf_cat_ascii(rs, "\n");
|
1216
|
+
rs = rs;
|
1217
|
+
}
|
1218
|
+
else {
|
1219
|
+
rb_raise(rb_eArgError, "encoding mismatch: %s IO with %s RS",
|
1220
|
+
rb_enc_name(enc_io),
|
1221
|
+
rb_enc_name(enc_rs));
|
1222
|
+
}
|
1223
|
+
}
|
1195
1224
|
}
|
1196
1225
|
arg->rs = rs;
|
1197
1226
|
arg->limit = limit;
|
@@ -1203,9 +1232,9 @@ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VA
|
|
1203
1232
|
keywords[0] = rb_intern_const("chomp");
|
1204
1233
|
}
|
1205
1234
|
rb_get_kwargs(opts, keywords, 0, 1, &vchomp);
|
1206
|
-
|
1235
|
+
if (respect_chomp) {
|
1207
1236
|
arg->chomp = (vchomp != Qundef) && RTEST(vchomp);
|
1208
|
-
|
1237
|
+
}
|
1209
1238
|
}
|
1210
1239
|
return arg;
|
1211
1240
|
}
|
@@ -1229,7 +1258,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
|
|
1229
1258
|
long w = 0;
|
1230
1259
|
rb_encoding *enc = get_enc(ptr);
|
1231
1260
|
|
1232
|
-
if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
|
1261
|
+
if (NIL_P(ptr->string) || ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
|
1233
1262
|
return Qnil;
|
1234
1263
|
}
|
1235
1264
|
s = RSTRING_PTR(ptr->string);
|
@@ -1245,7 +1274,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
|
|
1245
1274
|
str = strio_substr(ptr, ptr->pos, e - s - w, enc);
|
1246
1275
|
}
|
1247
1276
|
else if ((n = RSTRING_LEN(str)) == 0) {
|
1248
|
-
|
1277
|
+
const char *paragraph_end = NULL;
|
1249
1278
|
p = s;
|
1250
1279
|
while (p[(p + 1 < e) && (*p == '\r') && 0] == '\n') {
|
1251
1280
|
p += *p == '\r';
|
@@ -1255,18 +1284,18 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
|
|
1255
1284
|
}
|
1256
1285
|
s = p;
|
1257
1286
|
while ((p = memchr(p, '\n', e - p)) && (p != e)) {
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1287
|
+
p++;
|
1288
|
+
if (!((p < e && *p == '\n') ||
|
1289
|
+
(p + 1 < e && *p == '\r' && *(p+1) == '\n'))) {
|
1290
|
+
continue;
|
1291
|
+
}
|
1292
|
+
paragraph_end = p - ((*(p-2) == '\r') ? 2 : 1);
|
1293
|
+
while ((p < e && *p == '\n') ||
|
1294
|
+
(p + 1 < e && *p == '\r' && *(p+1) == '\n')) {
|
1295
|
+
p += (*p == '\r') ? 2 : 1;
|
1296
|
+
}
|
1297
|
+
e = p;
|
1298
|
+
break;
|
1270
1299
|
}
|
1271
1300
|
if (arg->chomp && paragraph_end) {
|
1272
1301
|
w = e - paragraph_end;
|
@@ -1326,6 +1355,7 @@ strio_gets(int argc, VALUE *argv, VALUE self)
|
|
1326
1355
|
VALUE str;
|
1327
1356
|
|
1328
1357
|
if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
|
1358
|
+
if (NIL_P(ptr->string)) return Qnil;
|
1329
1359
|
return rb_enc_str_new(0, 0, get_enc(ptr));
|
1330
1360
|
}
|
1331
1361
|
|
@@ -1440,6 +1470,7 @@ strio_write(VALUE self, VALUE str)
|
|
1440
1470
|
if (!RB_TYPE_P(str, T_STRING))
|
1441
1471
|
str = rb_obj_as_string(str);
|
1442
1472
|
enc = get_enc(ptr);
|
1473
|
+
if (!enc) return 0;
|
1443
1474
|
enc2 = rb_enc_get(str);
|
1444
1475
|
if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding())) {
|
1445
1476
|
VALUE converted = rb_str_conv_enc(str, enc2, enc);
|
@@ -1465,6 +1496,7 @@ strio_write(VALUE self, VALUE str)
|
|
1465
1496
|
}
|
1466
1497
|
else {
|
1467
1498
|
strio_extend(ptr, ptr->pos, len);
|
1499
|
+
rb_str_modify(ptr->string);
|
1468
1500
|
memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
|
1469
1501
|
}
|
1470
1502
|
RB_GC_GUARD(str);
|
@@ -1511,10 +1543,12 @@ strio_putc(VALUE self, VALUE ch)
|
|
1511
1543
|
|
1512
1544
|
check_modifiable(ptr);
|
1513
1545
|
if (RB_TYPE_P(ch, T_STRING)) {
|
1546
|
+
if (NIL_P(ptr->string)) return ch;
|
1514
1547
|
str = rb_str_substr(ch, 0, 1);
|
1515
1548
|
}
|
1516
1549
|
else {
|
1517
1550
|
char c = NUM2CHR(ch);
|
1551
|
+
if (NIL_P(ptr->string)) return ch;
|
1518
1552
|
str = rb_str_new(&c, 1);
|
1519
1553
|
}
|
1520
1554
|
strio_write(self, str);
|
@@ -1557,7 +1591,8 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
1557
1591
|
if (len < 0) {
|
1558
1592
|
rb_raise(rb_eArgError, "negative length %ld given", len);
|
1559
1593
|
}
|
1560
|
-
if (len > 0 &&
|
1594
|
+
if (len > 0 &&
|
1595
|
+
(NIL_P(ptr->string) || ptr->pos >= RSTRING_LEN(ptr->string))) {
|
1561
1596
|
if (!NIL_P(str)) rb_str_resize(str, 0);
|
1562
1597
|
return Qnil;
|
1563
1598
|
}
|
@@ -1566,6 +1601,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
1566
1601
|
}
|
1567
1602
|
/* fall through */
|
1568
1603
|
case 0:
|
1604
|
+
if (NIL_P(ptr->string)) return Qnil;
|
1569
1605
|
len = RSTRING_LEN(ptr->string);
|
1570
1606
|
if (len <= ptr->pos) {
|
1571
1607
|
rb_encoding *enc = get_enc(ptr);
|
@@ -1583,7 +1619,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
1583
1619
|
}
|
1584
1620
|
break;
|
1585
1621
|
default:
|
1586
|
-
|
1622
|
+
rb_error_arity(argc, 0, 2);
|
1587
1623
|
}
|
1588
1624
|
if (NIL_P(str)) {
|
1589
1625
|
rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
|
@@ -1594,10 +1630,9 @@ strio_read(int argc, VALUE *argv, VALUE self)
|
|
1594
1630
|
if (len > rest) len = rest;
|
1595
1631
|
rb_str_resize(str, len);
|
1596
1632
|
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
|
1633
|
+
if (!binary) {
|
1600
1634
|
rb_enc_copy(str, ptr->string);
|
1635
|
+
}
|
1601
1636
|
}
|
1602
1637
|
ptr->pos += RSTRING_LEN(str);
|
1603
1638
|
return str;
|
@@ -1619,28 +1654,28 @@ strio_pread(int argc, VALUE *argv, VALUE self)
|
|
1619
1654
|
long offset = NUM2LONG(rb_offset);
|
1620
1655
|
|
1621
1656
|
if (len < 0) {
|
1622
|
-
|
1657
|
+
rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
|
1623
1658
|
}
|
1624
1659
|
|
1625
1660
|
if (len == 0) {
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1661
|
+
if (NIL_P(rb_buf)) {
|
1662
|
+
return rb_str_new("", 0);
|
1663
|
+
}
|
1664
|
+
return rb_buf;
|
1630
1665
|
}
|
1631
1666
|
|
1632
1667
|
if (offset < 0) {
|
1633
|
-
|
1668
|
+
rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
|
1634
1669
|
}
|
1635
1670
|
|
1636
1671
|
struct StringIO *ptr = readable(self);
|
1637
1672
|
|
1638
1673
|
if (offset >= RSTRING_LEN(ptr->string)) {
|
1639
|
-
|
1674
|
+
rb_eof_error();
|
1640
1675
|
}
|
1641
1676
|
|
1642
1677
|
if (NIL_P(rb_buf)) {
|
1643
|
-
|
1678
|
+
return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
|
1644
1679
|
}
|
1645
1680
|
|
1646
1681
|
long rest = RSTRING_LEN(ptr->string) - offset;
|
@@ -1700,8 +1735,14 @@ strio_read_nonblock(int argc, VALUE *argv, VALUE self)
|
|
1700
1735
|
return val;
|
1701
1736
|
}
|
1702
1737
|
|
1738
|
+
/*
|
1739
|
+
* See IO#write
|
1740
|
+
*/
|
1703
1741
|
#define strio_syswrite rb_io_write
|
1704
1742
|
|
1743
|
+
/*
|
1744
|
+
* See IO#write_nonblock
|
1745
|
+
*/
|
1705
1746
|
static VALUE
|
1706
1747
|
strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self)
|
1707
1748
|
{
|
@@ -1729,7 +1770,7 @@ strio_size(VALUE self)
|
|
1729
1770
|
{
|
1730
1771
|
VALUE string = StringIO(self)->string;
|
1731
1772
|
if (NIL_P(string)) {
|
1732
|
-
|
1773
|
+
return INT2FIX(0);
|
1733
1774
|
}
|
1734
1775
|
return ULONG2NUM(RSTRING_LEN(string));
|
1735
1776
|
}
|
@@ -1746,10 +1787,12 @@ strio_truncate(VALUE self, VALUE len)
|
|
1746
1787
|
{
|
1747
1788
|
VALUE string = writable(self)->string;
|
1748
1789
|
long l = NUM2LONG(len);
|
1749
|
-
long plen
|
1790
|
+
long plen;
|
1750
1791
|
if (l < 0) {
|
1751
1792
|
error_inval("negative length");
|
1752
1793
|
}
|
1794
|
+
if (NIL_P(string)) return 0;
|
1795
|
+
plen = RSTRING_LEN(string);
|
1753
1796
|
rb_str_resize(string, l);
|
1754
1797
|
if (plen < l) {
|
1755
1798
|
MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
|
@@ -1813,20 +1856,30 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
|
|
1813
1856
|
enc = rb_find_encoding(ext_enc);
|
1814
1857
|
if (!enc) {
|
1815
1858
|
rb_io_enc_t convconfig;
|
1816
|
-
int oflags
|
1859
|
+
int oflags;
|
1860
|
+
rb_io_mode_t fmode;
|
1817
1861
|
VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc);
|
1818
1862
|
rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig);
|
1819
1863
|
enc = convconfig.enc2;
|
1820
1864
|
}
|
1821
1865
|
}
|
1822
1866
|
ptr->enc = enc;
|
1823
|
-
if (WRITABLE(self)) {
|
1867
|
+
if (!NIL_P(ptr->string) && WRITABLE(self)) {
|
1824
1868
|
rb_enc_associate(ptr->string, enc);
|
1825
1869
|
}
|
1826
1870
|
|
1827
1871
|
return self;
|
1828
1872
|
}
|
1829
1873
|
|
1874
|
+
/*
|
1875
|
+
* call-seq:
|
1876
|
+
* strio.set_encoding_by_bom => strio or nil
|
1877
|
+
*
|
1878
|
+
* Sets the encoding according to the BOM (Byte Order Mark) in the
|
1879
|
+
* string.
|
1880
|
+
*
|
1881
|
+
* Returns +self+ if the BOM is found, otherwise +nil.
|
1882
|
+
*/
|
1830
1883
|
static VALUE
|
1831
1884
|
strio_set_encoding_by_bom(VALUE self)
|
1832
1885
|
{
|
@@ -1859,10 +1912,15 @@ Init_stringio(void)
|
|
1859
1912
|
|
1860
1913
|
VALUE StringIO = rb_define_class("StringIO", rb_cObject);
|
1861
1914
|
|
1915
|
+
/* The version string */
|
1862
1916
|
rb_define_const(StringIO, "VERSION", rb_str_new_cstr(STRINGIO_VERSION));
|
1863
1917
|
|
1864
1918
|
rb_include_module(StringIO, rb_mEnumerable);
|
1865
1919
|
rb_define_alloc_func(StringIO, strio_s_allocate);
|
1920
|
+
|
1921
|
+
/* Maximum length that a StringIO instance can hold */
|
1922
|
+
rb_define_const(StringIO, "MAX_LENGTH", LONG2NUM(LONG_MAX));
|
1923
|
+
|
1866
1924
|
rb_define_singleton_method(StringIO, "new", strio_s_new, -1);
|
1867
1925
|
rb_define_singleton_method(StringIO, "open", strio_s_open, -1);
|
1868
1926
|
rb_define_method(StringIO, "initialize", strio_initialize, -1);
|
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: 3.1.
|
4
|
+
version: 3.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nobu Nakada
|
8
8
|
- Charles Oliver Nutter
|
9
|
-
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2025-04-21 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
13
|
description: Pseudo `IO` class from/to `String`.
|
15
14
|
email:
|
@@ -18,17 +17,32 @@ email:
|
|
18
17
|
executables: []
|
19
18
|
extensions:
|
20
19
|
- ext/stringio/extconf.rb
|
21
|
-
extra_rdoc_files:
|
20
|
+
extra_rdoc_files:
|
21
|
+
- ".document"
|
22
|
+
- ".rdoc_options"
|
23
|
+
- COPYING
|
24
|
+
- LICENSE.txt
|
25
|
+
- NEWS.md
|
26
|
+
- README.md
|
27
|
+
- docs/io.rb
|
28
|
+
- ext/stringio/.document
|
22
29
|
files:
|
30
|
+
- ".document"
|
31
|
+
- ".rdoc_options"
|
32
|
+
- COPYING
|
33
|
+
- LICENSE.txt
|
34
|
+
- NEWS.md
|
23
35
|
- README.md
|
36
|
+
- docs/io.rb
|
37
|
+
- ext/stringio/.document
|
24
38
|
- ext/stringio/extconf.rb
|
25
39
|
- ext/stringio/stringio.c
|
26
40
|
homepage: https://github.com/ruby/stringio
|
27
41
|
licenses:
|
28
42
|
- Ruby
|
29
43
|
- BSD-2-Clause
|
30
|
-
metadata:
|
31
|
-
|
44
|
+
metadata:
|
45
|
+
changelog_uri: https://github.com/ruby/stringio/releases/tag/v3.1.7
|
32
46
|
rdoc_options: []
|
33
47
|
require_paths:
|
34
48
|
- lib
|
@@ -43,8 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
57
|
- !ruby/object:Gem::Version
|
44
58
|
version: '0'
|
45
59
|
requirements: []
|
46
|
-
rubygems_version: 3.
|
47
|
-
signing_key:
|
60
|
+
rubygems_version: 3.6.7
|
48
61
|
specification_version: 4
|
49
62
|
summary: Pseudo IO on String
|
50
63
|
test_files: []
|