stringio 3.0.9 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c756222b86fbf0eb9e39360a3541b2877a85da13658be6119fa5582205a103e
4
- data.tar.gz: 82da787881d2e0a49e134202f68ec0bba3e23976227bdfac04a58813dd20d7db
3
+ metadata.gz: 0f8291051ef78bfdd817200ff02c25db3e2fa495d9b4a164c9737511d6eadb38
4
+ data.tar.gz: 8593995f8dbb66e6a3dc9f2755f97d0cc05e2d363e6cd027cc15a7d46deaf60f
5
5
  SHA512:
6
- metadata.gz: f49902b5785864fbd00c4e12b3f62b1ab0d4595943f256af7e7b4bf23647d4ef9e98d3637bd20eb89cd7030c1dcb8e1995d2b299904d4b33cb5b1d78326f5a18
7
- data.tar.gz: '08a58465652dbdf23df245db28129c5d2416ae6fc91d00376894754a896b526736d964d466630e62427b4b56dc07e9ca9242e1f49b1648d2eb0e4f8df09a4b66'
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]
@@ -1,3 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
  require 'mkmf'
3
- create_makefile('stringio')
3
+ if RUBY_ENGINE == 'ruby'
4
+ create_makefile('stringio')
5
+ else
6
+ File.write('Makefile', dummy_makefile("").join)
7
+ end
@@ -13,7 +13,9 @@
13
13
  **********************************************************************/
14
14
 
15
15
  static const char *const
16
- STRINGIO_VERSION = "3.0.9";
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.0.9
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-08 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