stringio 3.1.0 → 3.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67351f85af240c4189d6d1eaf805bfade85b9aae65d930326ec1c6930c5ba9c9
4
- data.tar.gz: 51016af4762d130788a7f80798fafd346225f67c86096f95e7f3f2f5244d8b17
3
+ metadata.gz: 0f8291051ef78bfdd817200ff02c25db3e2fa495d9b4a164c9737511d6eadb38
4
+ data.tar.gz: 8593995f8dbb66e6a3dc9f2755f97d0cc05e2d363e6cd027cc15a7d46deaf60f
5
5
  SHA512:
6
- metadata.gz: 6e15df64d01a1592cf7ca5f0024cdd693494c5db5c5cfcf9e7d4662c3f8a8c8cdadf2032e72c80d1baa2110c6310f4e6e0fdc96926eee53095ddf443caab9b5c
7
- data.tar.gz: 50dafc1b4c0de2e659860b00b6d6e6ef43eedba1cf059956d86acc9f9bb6c28c3924ef5ff3e5b7ba8719afc5366bf1cebf9a0e67b1e1a918a1347aa28f18ea0c
6
+ metadata.gz: 5060643c29e66ccc88df7a7ab4c19943d89ce3779641b9be7e0cfc61ce79db7c53af06367875b1892b80f31d98be32d10da2590445cb86425b7d89f285a30b5f
7
+ data.tar.gz: 1a6dcf694eaa38dd0d939b8db9cb4f29cc96db93ac545f5f06d6354ad5e75f92fb9807f529f54ae6801a3f791e7139db7ad371bf8efd6b7ca34f45f61fb10429
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ COPYING
2
+ *.md
3
+ *.txt
4
+ docs/
5
+ ext/stringio/
data/.rdoc_options ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ main_page: README.md
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,166 @@
1
+ # News
2
+
3
+ ## 3.1.1 - 2024-06-13
4
+
5
+ ### Improvements
6
+
7
+ * JRuby: Improved.
8
+ * GH-83
9
+ * GH-84
10
+ * GH-85
11
+
12
+ * Added `StringIO::MAX_LENGTH`.
13
+
14
+ * Added support for NULL `StringIO` by `StringIO.new(nil)`.
15
+
16
+ * Improved IO compatibility for partial read.
17
+ * GH-95
18
+ * https://bugs.ruby-lang.org/issues/20418
19
+
20
+ ### Fixes
21
+
22
+ * Fixed a bug that coderange isn't updated after overwrite.
23
+ * Reported by Tiago Cardoso.
24
+ * https://bugs.ruby-lang.org/issues/20185
25
+ * GH-77
26
+ * GH-79
27
+
28
+ ### Thanks
29
+
30
+ * Tiago Cardoso
31
+
32
+ ## 3.1.0 - 2023-11-28
33
+
34
+ ### Fixes
35
+
36
+ * TruffleRuby: Do not compile the C extension
37
+
38
+ GH-71
39
+
40
+ ## 3.0.9 - 2023-11-08
41
+
42
+ ### Improvements
43
+
44
+ * JRuby: Aligned `StringIO#gets` behavior with the C implementation.
45
+
46
+ GH-61
47
+
48
+ ### Fixes
49
+
50
+ * CRuby: Fixed `StringIO#pread` with the length 0.
51
+
52
+ Patch by Jean byroot Boussier.
53
+
54
+ GH-67
55
+
56
+ * CRuby: Fixed a bug that `StringIO#gets` with non ASCII compatible
57
+ encoding such as UTF-16 doesn't detect correct new line characters.
58
+
59
+ Reported by IWAMOTO Kouichi.
60
+
61
+ GH-68
62
+
63
+ ### Thanks
64
+
65
+ * Jean byroot Boussier
66
+
67
+ * IWAMOTO Kouichi
68
+
69
+ ## 3.0.8 - 2023-08-10
70
+
71
+ ### Improvements
72
+
73
+ * Added `StringIO#pread`.
74
+
75
+ Patch by Jean byroot Boussier.
76
+
77
+ GH-56
78
+
79
+ * JRuby: Added `StringIO::VERSION`.
80
+
81
+ GH-57 GH-59
82
+
83
+ ### Thanks
84
+
85
+ * Jean byroot Boussier
86
+
87
+ ## 3.0.7 - 2023-06-02
88
+
89
+ * CRuby: Avoid direct struct usage. This change is for supporting
90
+ Ruby 3.3.
91
+
92
+ GH-54
93
+
94
+ ## 3.0.6 - 2023-04-14
95
+
96
+ ### Improvements
97
+
98
+ * CRuby: Added support for write barrier.
99
+
100
+ * JRuby: Added missing arty-checking.
101
+
102
+ GH-48
103
+
104
+ * JRuby: Added support for `StringIO.new(encoding:)`.
105
+
106
+ GH-45
107
+
108
+ ## 3.0.5 - 2023-02-02
109
+
110
+ ### Improvements
111
+
112
+ ### Fixes
113
+
114
+ * Fixed a bug that `StringIO#gets("2+ character", chomp: true)` did not
115
+ remove the separator at the end.
116
+ [[Bug #19389](https://bugs.ruby-lang.org/issues/19389)]
117
+
118
+ ## 3.0.4 - 2022-12-09
119
+
120
+ ### Improvements
121
+
122
+ * JRuby: Changed to use flag registry.
123
+ [[GitHub#33](https://github.com/ruby/stringio/pull/26)]
124
+
125
+ ## 3.0.3 - 2022-12-08
126
+
127
+ ### Improvements
128
+
129
+ * Improved documents.
130
+ [[GitHub#33](https://github.com/ruby/stringio/pull/33)]
131
+ [[GitHub#34](https://github.com/ruby/stringio/pull/34)]
132
+ [[GitHub#35](https://github.com/ruby/stringio/pull/35)]
133
+ [[GitHub#36](https://github.com/ruby/stringio/pull/36)]
134
+ [[GitHub#37](https://github.com/ruby/stringio/pull/37)]
135
+ [Patch by Burdette Lamar]
136
+
137
+ ### Fixes
138
+
139
+ * Fixed a bug that large `StringIO#ungetc`/`StringIO#ungetbyte`
140
+ break internal buffer.
141
+
142
+ * Fixed a bug that `StringIO#each("2+ character", chomp: true)` cause
143
+ infinite loop.
144
+ [[Bug #18769](https://bugs.ruby-lang.org/issues/18769)]
145
+
146
+ * Fixed a bug that `StringIO#each(nil, chomp: true)` chomps.
147
+ [[Bug #18770](https://bugs.ruby-lang.org/issues/18770)]
148
+
149
+ * Fixed a bug that `StringIO#each("", chomp: true)` isn't compatible
150
+ with `IO#each("", chomp: true)`.
151
+ [[Bug #18768](https://bugs.ruby-lang.org/issues/18768)]
152
+
153
+ * Fixed a bug that `StringIO#set_encoding` doesn't accept external
154
+ and internal encodings pairo.
155
+ [[GitHub#16](https://github.com/ruby/stringio/issues/16)]
156
+ [Reported by Kenta Murata]
157
+
158
+ * Fixed a bug that `StringIO#truncate` isn't compatible with
159
+ `File#truncate`.
160
+
161
+ ### Thanks
162
+
163
+ * Kenta Murata
164
+
165
+ * Burdette Lamar
166
+
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,8 @@
1
+ # :stopdoc:
2
+ class IO
3
+ module generic_readable
4
+ end
5
+ module generic_writable
6
+ end
7
+ end
8
+ # :startdoc:
@@ -0,0 +1 @@
1
+ *.[ch]
@@ -13,7 +13,9 @@
13
13
  **********************************************************************/
14
14
 
15
15
  static const char *const
16
- STRINGIO_VERSION = "3.1.0";
16
+ STRINGIO_VERSION = "3.1.1";
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 (OBJ_FROZEN(ptr->string)) {
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 (argc) {
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
- if (OBJ_FROZEN_RAW(string)) {
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 = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
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,9 +928,6 @@ 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
- else {
919
- rb_str_modify(ptr->string);
920
- }
921
931
  }
922
932
 
923
933
  /*
@@ -934,6 +944,7 @@ strio_ungetc(VALUE self, VALUE c)
934
944
  rb_encoding *enc, *enc2;
935
945
 
936
946
  check_modifiable(ptr);
947
+ if (NIL_P(ptr->string)) return Qnil;
937
948
  if (NIL_P(c)) return Qnil;
938
949
  if (RB_INTEGER_TYPE_P(c)) {
939
950
  int len, cc = NUM2INT(c);
@@ -971,12 +982,13 @@ strio_ungetbyte(VALUE self, VALUE c)
971
982
  struct StringIO *ptr = readable(self);
972
983
 
973
984
  check_modifiable(ptr);
985
+ if (NIL_P(ptr->string)) return Qnil;
974
986
  if (NIL_P(c)) return Qnil;
975
987
  if (RB_INTEGER_TYPE_P(c)) {
976
- /* rb_int_and() not visible from exts */
977
- VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
978
- const char cc = NUM2INT(v) & 0xFF;
979
- strio_unget_bytes(ptr, &cc, 1);
988
+ /* rb_int_and() not visible from exts */
989
+ VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
990
+ const char cc = NUM2INT(v) & 0xFF;
991
+ strio_unget_bytes(ptr, &cc, 1);
980
992
  }
981
993
  else {
982
994
  long cl;
@@ -1157,41 +1169,41 @@ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VA
1157
1169
  break;
1158
1170
 
1159
1171
  case 1:
1160
- if (!NIL_P(rs) && !RB_TYPE_P(rs, T_STRING)) {
1161
- VALUE tmp = rb_check_string_type(rs);
1172
+ if (!NIL_P(rs) && !RB_TYPE_P(rs, T_STRING)) {
1173
+ VALUE tmp = rb_check_string_type(rs);
1162
1174
  if (NIL_P(tmp)) {
1163
- limit = NUM2LONG(rs);
1164
- rs = rb_rs;
1175
+ limit = NUM2LONG(rs);
1176
+ rs = rb_rs;
1165
1177
  }
1166
1178
  else {
1167
- rs = tmp;
1179
+ rs = tmp;
1168
1180
  }
1169
1181
  }
1170
1182
  break;
1171
1183
 
1172
1184
  case 2:
1173
- if (!NIL_P(rs)) StringValue(rs);
1185
+ if (!NIL_P(rs)) StringValue(rs);
1174
1186
  if (!NIL_P(lim)) limit = NUM2LONG(lim);
1175
1187
  break;
1176
1188
  }
1177
- if (!NIL_P(rs)) {
1178
- rb_encoding *enc_rs, *enc_io;
1179
- enc_rs = rb_enc_get(rs);
1180
- enc_io = get_enc(ptr);
1181
- if (enc_rs != enc_io &&
1182
- (rb_enc_str_coderange(rs) != ENC_CODERANGE_7BIT ||
1183
- (RSTRING_LEN(rs) > 0 && !rb_enc_asciicompat(enc_io)))) {
1184
- if (rs == rb_rs) {
1185
- rs = rb_enc_str_new(0, 0, enc_io);
1186
- rb_str_buf_cat_ascii(rs, "\n");
1187
- rs = rs;
1188
- }
1189
- else {
1190
- rb_raise(rb_eArgError, "encoding mismatch: %s IO with %s RS",
1191
- rb_enc_name(enc_io),
1192
- rb_enc_name(enc_rs));
1193
- }
1194
- }
1189
+ if (!NIL_P(ptr->string) && !NIL_P(rs)) {
1190
+ rb_encoding *enc_rs, *enc_io;
1191
+ enc_rs = rb_enc_get(rs);
1192
+ enc_io = get_enc(ptr);
1193
+ if (enc_rs != enc_io &&
1194
+ (rb_enc_str_coderange(rs) != ENC_CODERANGE_7BIT ||
1195
+ (RSTRING_LEN(rs) > 0 && !rb_enc_asciicompat(enc_io)))) {
1196
+ if (rs == rb_rs) {
1197
+ rs = rb_enc_str_new(0, 0, enc_io);
1198
+ rb_str_buf_cat_ascii(rs, "\n");
1199
+ rs = rs;
1200
+ }
1201
+ else {
1202
+ rb_raise(rb_eArgError, "encoding mismatch: %s IO with %s RS",
1203
+ rb_enc_name(enc_io),
1204
+ rb_enc_name(enc_rs));
1205
+ }
1206
+ }
1195
1207
  }
1196
1208
  arg->rs = rs;
1197
1209
  arg->limit = limit;
@@ -1203,9 +1215,9 @@ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VA
1203
1215
  keywords[0] = rb_intern_const("chomp");
1204
1216
  }
1205
1217
  rb_get_kwargs(opts, keywords, 0, 1, &vchomp);
1206
- if (respect_chomp) {
1218
+ if (respect_chomp) {
1207
1219
  arg->chomp = (vchomp != Qundef) && RTEST(vchomp);
1208
- }
1220
+ }
1209
1221
  }
1210
1222
  return arg;
1211
1223
  }
@@ -1229,7 +1241,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
1229
1241
  long w = 0;
1230
1242
  rb_encoding *enc = get_enc(ptr);
1231
1243
 
1232
- if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
1244
+ if (NIL_P(ptr->string) || ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
1233
1245
  return Qnil;
1234
1246
  }
1235
1247
  s = RSTRING_PTR(ptr->string);
@@ -1245,7 +1257,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
1245
1257
  str = strio_substr(ptr, ptr->pos, e - s - w, enc);
1246
1258
  }
1247
1259
  else if ((n = RSTRING_LEN(str)) == 0) {
1248
- const char *paragraph_end = NULL;
1260
+ const char *paragraph_end = NULL;
1249
1261
  p = s;
1250
1262
  while (p[(p + 1 < e) && (*p == '\r') && 0] == '\n') {
1251
1263
  p += *p == '\r';
@@ -1255,18 +1267,18 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
1255
1267
  }
1256
1268
  s = p;
1257
1269
  while ((p = memchr(p, '\n', e - p)) && (p != e)) {
1258
- p++;
1259
- if (!((p < e && *p == '\n') ||
1260
- (p + 1 < e && *p == '\r' && *(p+1) == '\n'))) {
1261
- continue;
1262
- }
1263
- paragraph_end = p - ((*(p-2) == '\r') ? 2 : 1);
1264
- while ((p < e && *p == '\n') ||
1265
- (p + 1 < e && *p == '\r' && *(p+1) == '\n')) {
1266
- p += (*p == '\r') ? 2 : 1;
1267
- }
1268
- e = p;
1269
- break;
1270
+ p++;
1271
+ if (!((p < e && *p == '\n') ||
1272
+ (p + 1 < e && *p == '\r' && *(p+1) == '\n'))) {
1273
+ continue;
1274
+ }
1275
+ paragraph_end = p - ((*(p-2) == '\r') ? 2 : 1);
1276
+ while ((p < e && *p == '\n') ||
1277
+ (p + 1 < e && *p == '\r' && *(p+1) == '\n')) {
1278
+ p += (*p == '\r') ? 2 : 1;
1279
+ }
1280
+ e = p;
1281
+ break;
1270
1282
  }
1271
1283
  if (arg->chomp && paragraph_end) {
1272
1284
  w = e - paragraph_end;
@@ -1326,6 +1338,7 @@ strio_gets(int argc, VALUE *argv, VALUE self)
1326
1338
  VALUE str;
1327
1339
 
1328
1340
  if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
1341
+ if (NIL_P(ptr->string)) return Qnil;
1329
1342
  return rb_enc_str_new(0, 0, get_enc(ptr));
1330
1343
  }
1331
1344
 
@@ -1440,6 +1453,7 @@ strio_write(VALUE self, VALUE str)
1440
1453
  if (!RB_TYPE_P(str, T_STRING))
1441
1454
  str = rb_obj_as_string(str);
1442
1455
  enc = get_enc(ptr);
1456
+ if (!enc) return 0;
1443
1457
  enc2 = rb_enc_get(str);
1444
1458
  if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding())) {
1445
1459
  VALUE converted = rb_str_conv_enc(str, enc2, enc);
@@ -1465,6 +1479,7 @@ strio_write(VALUE self, VALUE str)
1465
1479
  }
1466
1480
  else {
1467
1481
  strio_extend(ptr, ptr->pos, len);
1482
+ rb_str_modify(ptr->string);
1468
1483
  memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
1469
1484
  }
1470
1485
  RB_GC_GUARD(str);
@@ -1511,10 +1526,12 @@ strio_putc(VALUE self, VALUE ch)
1511
1526
 
1512
1527
  check_modifiable(ptr);
1513
1528
  if (RB_TYPE_P(ch, T_STRING)) {
1529
+ if (NIL_P(ptr->string)) return ch;
1514
1530
  str = rb_str_substr(ch, 0, 1);
1515
1531
  }
1516
1532
  else {
1517
1533
  char c = NUM2CHR(ch);
1534
+ if (NIL_P(ptr->string)) return ch;
1518
1535
  str = rb_str_new(&c, 1);
1519
1536
  }
1520
1537
  strio_write(self, str);
@@ -1557,7 +1574,8 @@ strio_read(int argc, VALUE *argv, VALUE self)
1557
1574
  if (len < 0) {
1558
1575
  rb_raise(rb_eArgError, "negative length %ld given", len);
1559
1576
  }
1560
- if (len > 0 && ptr->pos >= RSTRING_LEN(ptr->string)) {
1577
+ if (len > 0 &&
1578
+ (NIL_P(ptr->string) || ptr->pos >= RSTRING_LEN(ptr->string))) {
1561
1579
  if (!NIL_P(str)) rb_str_resize(str, 0);
1562
1580
  return Qnil;
1563
1581
  }
@@ -1566,6 +1584,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
1566
1584
  }
1567
1585
  /* fall through */
1568
1586
  case 0:
1587
+ if (NIL_P(ptr->string)) return Qnil;
1569
1588
  len = RSTRING_LEN(ptr->string);
1570
1589
  if (len <= ptr->pos) {
1571
1590
  rb_encoding *enc = get_enc(ptr);
@@ -1583,7 +1602,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
1583
1602
  }
1584
1603
  break;
1585
1604
  default:
1586
- rb_error_arity(argc, 0, 2);
1605
+ rb_error_arity(argc, 0, 2);
1587
1606
  }
1588
1607
  if (NIL_P(str)) {
1589
1608
  rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
@@ -1594,10 +1613,9 @@ strio_read(int argc, VALUE *argv, VALUE self)
1594
1613
  if (len > rest) len = rest;
1595
1614
  rb_str_resize(str, len);
1596
1615
  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
1616
+ if (!binary) {
1600
1617
  rb_enc_copy(str, ptr->string);
1618
+ }
1601
1619
  }
1602
1620
  ptr->pos += RSTRING_LEN(str);
1603
1621
  return str;
@@ -1619,28 +1637,28 @@ strio_pread(int argc, VALUE *argv, VALUE self)
1619
1637
  long offset = NUM2LONG(rb_offset);
1620
1638
 
1621
1639
  if (len < 0) {
1622
- rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
1640
+ rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
1623
1641
  }
1624
1642
 
1625
1643
  if (len == 0) {
1626
- if (NIL_P(rb_buf)) {
1627
- return rb_str_new("", 0);
1628
- }
1629
- return rb_buf;
1644
+ if (NIL_P(rb_buf)) {
1645
+ return rb_str_new("", 0);
1646
+ }
1647
+ return rb_buf;
1630
1648
  }
1631
1649
 
1632
1650
  if (offset < 0) {
1633
- rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
1651
+ rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
1634
1652
  }
1635
1653
 
1636
1654
  struct StringIO *ptr = readable(self);
1637
1655
 
1638
1656
  if (offset >= RSTRING_LEN(ptr->string)) {
1639
- rb_eof_error();
1657
+ rb_eof_error();
1640
1658
  }
1641
1659
 
1642
1660
  if (NIL_P(rb_buf)) {
1643
- return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
1661
+ return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
1644
1662
  }
1645
1663
 
1646
1664
  long rest = RSTRING_LEN(ptr->string) - offset;
@@ -1700,8 +1718,14 @@ strio_read_nonblock(int argc, VALUE *argv, VALUE self)
1700
1718
  return val;
1701
1719
  }
1702
1720
 
1721
+ /*
1722
+ * See IO#write
1723
+ */
1703
1724
  #define strio_syswrite rb_io_write
1704
1725
 
1726
+ /*
1727
+ * See IO#write_nonblock
1728
+ */
1705
1729
  static VALUE
1706
1730
  strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self)
1707
1731
  {
@@ -1729,7 +1753,7 @@ strio_size(VALUE self)
1729
1753
  {
1730
1754
  VALUE string = StringIO(self)->string;
1731
1755
  if (NIL_P(string)) {
1732
- rb_raise(rb_eIOError, "not opened");
1756
+ return INT2FIX(0);
1733
1757
  }
1734
1758
  return ULONG2NUM(RSTRING_LEN(string));
1735
1759
  }
@@ -1746,10 +1770,12 @@ strio_truncate(VALUE self, VALUE len)
1746
1770
  {
1747
1771
  VALUE string = writable(self)->string;
1748
1772
  long l = NUM2LONG(len);
1749
- long plen = RSTRING_LEN(string);
1773
+ long plen;
1750
1774
  if (l < 0) {
1751
1775
  error_inval("negative length");
1752
1776
  }
1777
+ if (NIL_P(string)) return 0;
1778
+ plen = RSTRING_LEN(string);
1753
1779
  rb_str_resize(string, l);
1754
1780
  if (plen < l) {
1755
1781
  MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
@@ -1820,13 +1846,22 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
1820
1846
  }
1821
1847
  }
1822
1848
  ptr->enc = enc;
1823
- if (WRITABLE(self)) {
1849
+ if (!NIL_P(ptr->string) && WRITABLE(self)) {
1824
1850
  rb_enc_associate(ptr->string, enc);
1825
1851
  }
1826
1852
 
1827
1853
  return self;
1828
1854
  }
1829
1855
 
1856
+ /*
1857
+ * call-seq:
1858
+ * strio.set_encoding_by_bom => strio or nil
1859
+ *
1860
+ * Sets the encoding according to the BOM (Byte Order Mark) in the
1861
+ * string.
1862
+ *
1863
+ * Returns +self+ if the BOM is found, otherwise +nil.
1864
+ */
1830
1865
  static VALUE
1831
1866
  strio_set_encoding_by_bom(VALUE self)
1832
1867
  {
@@ -1859,10 +1894,15 @@ Init_stringio(void)
1859
1894
 
1860
1895
  VALUE StringIO = rb_define_class("StringIO", rb_cObject);
1861
1896
 
1897
+ /* The version string */
1862
1898
  rb_define_const(StringIO, "VERSION", rb_str_new_cstr(STRINGIO_VERSION));
1863
1899
 
1864
1900
  rb_include_module(StringIO, rb_mEnumerable);
1865
1901
  rb_define_alloc_func(StringIO, strio_s_allocate);
1902
+
1903
+ /* Maximum length that a StringIO instance can hold */
1904
+ rb_define_const(StringIO, "MAX_LENGTH", LONG2NUM(LONG_MAX));
1905
+
1866
1906
  rb_define_singleton_method(StringIO, "new", strio_s_new, -1);
1867
1907
  rb_define_singleton_method(StringIO, "open", strio_s_open, -1);
1868
1908
  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.0
4
+ version: 3.1.1
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: 2023-11-28 00:00:00.000000000 Z
12
+ date: 2024-06-13 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.4.10
61
+ rubygems_version: 3.5.11
47
62
  signing_key:
48
63
  specification_version: 4
49
64
  summary: Pseudo IO on String