stringio 3.0.5 → 3.1.0

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: dd5cdd012959f081ba2717eb15a3a6f3ca015ec48bba03ef1bf318686007dac2
4
- data.tar.gz: 57842131091d3f2a38c03abfb8e294c51361c844b0777086126c034a1a904537
3
+ metadata.gz: 67351f85af240c4189d6d1eaf805bfade85b9aae65d930326ec1c6930c5ba9c9
4
+ data.tar.gz: 51016af4762d130788a7f80798fafd346225f67c86096f95e7f3f2f5244d8b17
5
5
  SHA512:
6
- metadata.gz: 2cb53aa9936ad5464a40268c1b4477f06dcde9f4a456107aeb897812c1a1b52859bbe88a90e8d82dd8b30819444cb5c2b05193ab40c2ccb43a04e03002183b2d
7
- data.tar.gz: aefe614e34d66c31b2ddc0c78788e85fba60279c081b65645786cbcaf936e20a42edaa5ef5615dcf4aff6eb10258a1823eee99e89c81f5ed0e01348692bfeb38
6
+ metadata.gz: 6e15df64d01a1592cf7ca5f0024cdd693494c5db5c5cfcf9e7d4662c3f8a8c8cdadf2032e72c80d1baa2110c6310f4e6e0fdc96926eee53095ddf443caab9b5c
7
+ data.tar.gz: 50dafc1b4c0de2e659860b00b6d6e6ef43eedba1cf059956d86acc9f9bb6c28c3924ef5ff3e5b7ba8719afc5366bf1cebf9a0e67b1e1a918a1347aa28f18ea0c
data/README.md CHANGED
@@ -34,7 +34,7 @@ Or install it yourself as:
34
34
 
35
35
  Run `bundle install` to install dependencies and then `bundle exec rake test` to run the tests.
36
36
 
37
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
37
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, author a NEWS.md section, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
38
38
 
39
39
  ## Contributing
40
40
 
@@ -1,4 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
  require 'mkmf'
3
- have_func("rb_io_extract_modeenc", "ruby/io.h")
4
- create_makefile('stringio')
3
+ if RUBY_ENGINE == 'ruby'
4
+ create_makefile('stringio')
5
+ else
6
+ File.write('Makefile', dummy_makefile("").join)
7
+ end
@@ -12,7 +12,8 @@
12
12
 
13
13
  **********************************************************************/
14
14
 
15
- #define STRINGIO_VERSION "3.0.5"
15
+ static const char *const
16
+ STRINGIO_VERSION = "3.1.0";
16
17
 
17
18
  #include "ruby.h"
18
19
  #include "ruby/io.h"
@@ -32,86 +33,6 @@
32
33
  # define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
33
34
  #endif
34
35
 
35
- #ifndef HAVE_RB_IO_EXTRACT_MODEENC
36
- #define rb_io_extract_modeenc strio_extract_modeenc
37
- static void
38
- strio_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
39
- int *oflags_p, int *fmode_p, struct rb_io_enc_t *convconfig_p)
40
- {
41
- VALUE mode = *vmode_p;
42
- VALUE intmode;
43
- int fmode;
44
- int has_enc = 0, has_vmode = 0;
45
-
46
- convconfig_p->enc = convconfig_p->enc2 = 0;
47
-
48
- vmode_handle:
49
- if (NIL_P(mode)) {
50
- fmode = FMODE_READABLE;
51
- }
52
- else if (!NIL_P(intmode = rb_check_to_integer(mode, "to_int"))) {
53
- int flags = NUM2INT(intmode);
54
- fmode = rb_io_oflags_fmode(flags);
55
- }
56
- else {
57
- const char *m = StringValueCStr(mode), *n, *e;
58
- fmode = rb_io_modestr_fmode(m);
59
- n = strchr(m, ':');
60
- if (n) {
61
- long len;
62
- char encname[ENCODING_MAXNAMELEN+1];
63
- has_enc = 1;
64
- if (fmode & FMODE_SETENC_BY_BOM) {
65
- n = strchr(n, '|');
66
- }
67
- e = strchr(++n, ':');
68
- len = e ? e - n : (long)strlen(n);
69
- if (len > 0 && len <= ENCODING_MAXNAMELEN) {
70
- rb_encoding *enc;
71
- if (e) {
72
- memcpy(encname, n, len);
73
- encname[len] = '\0';
74
- n = encname;
75
- }
76
- enc = rb_enc_find(n);
77
- if (e)
78
- convconfig_p->enc2 = enc;
79
- else
80
- convconfig_p->enc = enc;
81
- }
82
- if (e && (len = strlen(++e)) > 0 && len <= ENCODING_MAXNAMELEN) {
83
- convconfig_p->enc = rb_enc_find(e);
84
- }
85
- }
86
- }
87
-
88
- if (!NIL_P(opthash)) {
89
- rb_encoding *extenc = 0, *intenc = 0;
90
- VALUE v;
91
- if (!has_vmode) {
92
- ID id_mode;
93
- CONST_ID(id_mode, "mode");
94
- v = rb_hash_aref(opthash, ID2SYM(id_mode));
95
- if (!NIL_P(v)) {
96
- if (!NIL_P(mode)) {
97
- rb_raise(rb_eArgError, "mode specified twice");
98
- }
99
- has_vmode = 1;
100
- mode = v;
101
- goto vmode_handle;
102
- }
103
- }
104
-
105
- if (rb_io_extract_encoding_option(opthash, &extenc, &intenc, &fmode)) {
106
- if (has_enc) {
107
- rb_raise(rb_eArgError, "encoding specified twice");
108
- }
109
- }
110
- }
111
- *fmode_p = fmode;
112
- }
113
- #endif
114
-
115
36
  struct StringIO {
116
37
  VALUE string;
117
38
  rb_encoding *enc;
@@ -171,7 +92,7 @@ static const rb_data_type_t strio_data_type = {
171
92
  strio_free,
172
93
  strio_memsize,
173
94
  },
174
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
95
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
175
96
  };
176
97
 
177
98
  #define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type))
@@ -356,7 +277,7 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
356
277
  {
357
278
  VALUE string, vmode, opt;
358
279
  int oflags;
359
- struct rb_io_enc_t convconfig;
280
+ rb_io_enc_t convconfig;
360
281
 
361
282
  argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
362
283
  rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
@@ -379,7 +300,7 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
379
300
  if (ptr->flags & FMODE_TRUNC) {
380
301
  rb_str_resize(string, 0);
381
302
  }
382
- ptr->string = string;
303
+ RB_OBJ_WRITE(self, &ptr->string, string);
383
304
  if (argc == 1) {
384
305
  ptr->enc = rb_enc_get(string);
385
306
  }
@@ -397,7 +318,7 @@ static VALUE
397
318
  strio_finalize(VALUE self)
398
319
  {
399
320
  struct StringIO *ptr = StringIO(self);
400
- ptr->string = Qnil;
321
+ RB_OBJ_WRITE(self, &ptr->string, Qnil);
401
322
  ptr->flags &= ~FMODE_READWRITE;
402
323
  return self;
403
324
  }
@@ -563,7 +484,8 @@ strio_set_string(VALUE self, VALUE string)
563
484
  ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
564
485
  ptr->pos = 0;
565
486
  ptr->lineno = 0;
566
- return ptr->string = string;
487
+ RB_OBJ_WRITE(self, &ptr->string, string);
488
+ return string;
567
489
  }
568
490
 
569
491
  /*
@@ -682,11 +604,9 @@ strio_to_read(VALUE self)
682
604
  * eof? -> true or false
683
605
  *
684
606
  * Returns +true+ if positioned at end-of-stream, +false+ otherwise;
685
- * see {Position}[rdoc-ref:File@Position].
607
+ * see {Position}[rdoc-ref:IO@Position].
686
608
  *
687
609
  * Raises IOError if the stream is not opened for reading.
688
- *
689
- * StreamIO#eof is an alias for StreamIO#eof?.
690
610
  */
691
611
  static VALUE
692
612
  strio_eof(VALUE self)
@@ -699,15 +619,19 @@ strio_eof(VALUE self)
699
619
  static VALUE
700
620
  strio_copy(VALUE copy, VALUE orig)
701
621
  {
702
- struct StringIO *ptr;
622
+ struct StringIO *ptr, *old_ptr;
623
+ VALUE old_string = Qundef;
703
624
 
704
625
  orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio");
705
626
  if (copy == orig) return copy;
706
627
  ptr = StringIO(orig);
707
- if (check_strio(copy)) {
708
- strio_free(DATA_PTR(copy));
628
+ old_ptr = check_strio(copy);
629
+ if (old_ptr) {
630
+ old_string = old_ptr->string;
631
+ strio_free(old_ptr);
709
632
  }
710
633
  DATA_PTR(copy) = ptr;
634
+ RB_OBJ_WRITTEN(copy, old_string, ptr->string);
711
635
  RBASIC(copy)->flags &= ~STRIO_READWRITE;
712
636
  RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
713
637
  ++ptr->count;
@@ -808,8 +732,6 @@ strio_reopen(int argc, VALUE *argv, VALUE self)
808
732
  *
809
733
  * Returns the current position (in bytes);
810
734
  * see {Position}[rdoc-ref:IO@Position].
811
- *
812
- * StringIO#tell is an alias for StringIO#pos.
813
735
  */
814
736
  static VALUE
815
737
  strio_get_pos(VALUE self)
@@ -1221,38 +1143,57 @@ struct getline_arg {
1221
1143
  };
1222
1144
 
1223
1145
  static struct getline_arg *
1224
- prepare_getline_args(struct getline_arg *arg, int argc, VALUE *argv)
1146
+ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VALUE *argv)
1225
1147
  {
1226
- VALUE str, lim, opts;
1148
+ VALUE rs, lim, opts;
1227
1149
  long limit = -1;
1228
1150
  int respect_chomp;
1229
1151
 
1230
- argc = rb_scan_args(argc, argv, "02:", &str, &lim, &opts);
1231
- respect_chomp = argc == 0 || !NIL_P(str);
1152
+ argc = rb_scan_args(argc, argv, "02:", &rs, &lim, &opts);
1153
+ respect_chomp = argc == 0 || !NIL_P(rs);
1232
1154
  switch (argc) {
1233
1155
  case 0:
1234
- str = rb_rs;
1156
+ rs = rb_rs;
1235
1157
  break;
1236
1158
 
1237
1159
  case 1:
1238
- if (!NIL_P(str) && !RB_TYPE_P(str, T_STRING)) {
1239
- VALUE tmp = rb_check_string_type(str);
1160
+ if (!NIL_P(rs) && !RB_TYPE_P(rs, T_STRING)) {
1161
+ VALUE tmp = rb_check_string_type(rs);
1240
1162
  if (NIL_P(tmp)) {
1241
- limit = NUM2LONG(str);
1242
- str = rb_rs;
1163
+ limit = NUM2LONG(rs);
1164
+ rs = rb_rs;
1243
1165
  }
1244
1166
  else {
1245
- str = tmp;
1167
+ rs = tmp;
1246
1168
  }
1247
1169
  }
1248
1170
  break;
1249
1171
 
1250
1172
  case 2:
1251
- if (!NIL_P(str)) StringValue(str);
1173
+ if (!NIL_P(rs)) StringValue(rs);
1252
1174
  if (!NIL_P(lim)) limit = NUM2LONG(lim);
1253
1175
  break;
1254
1176
  }
1255
- arg->rs = str;
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
+ }
1195
+ }
1196
+ arg->rs = rs;
1256
1197
  arg->limit = limit;
1257
1198
  arg->chomp = 0;
1258
1199
  if (!NIL_P(opts)) {
@@ -1380,15 +1321,15 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
1380
1321
  static VALUE
1381
1322
  strio_gets(int argc, VALUE *argv, VALUE self)
1382
1323
  {
1324
+ struct StringIO *ptr = readable(self);
1383
1325
  struct getline_arg arg;
1384
1326
  VALUE str;
1385
1327
 
1386
- if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
1387
- struct StringIO *ptr = readable(self);
1328
+ if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
1388
1329
  return rb_enc_str_new(0, 0, get_enc(ptr));
1389
1330
  }
1390
1331
 
1391
- str = strio_getline(&arg, readable(self));
1332
+ str = strio_getline(&arg, ptr);
1392
1333
  rb_lastline_set(str);
1393
1334
  return str;
1394
1335
  }
@@ -1420,23 +1361,21 @@ strio_readline(int argc, VALUE *argv, VALUE self)
1420
1361
  * does nothing if already at end-of-file;
1421
1362
  * returns +self+.
1422
1363
  * See {Line IO}[rdoc-ref:IO@Line+IO].
1423
- *
1424
- * StringIO#each is an alias for StringIO#each_line.
1425
1364
  */
1426
1365
  static VALUE
1427
1366
  strio_each(int argc, VALUE *argv, VALUE self)
1428
1367
  {
1429
1368
  VALUE line;
1369
+ struct StringIO *ptr = readable(self);
1430
1370
  struct getline_arg arg;
1431
1371
 
1432
- StringIO(self);
1433
1372
  RETURN_ENUMERATOR(self, argc, argv);
1434
1373
 
1435
- if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
1374
+ if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
1436
1375
  rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
1437
1376
  }
1438
1377
 
1439
- while (!NIL_P(line = strio_getline(&arg, readable(self)))) {
1378
+ while (!NIL_P(line = strio_getline(&arg, ptr))) {
1440
1379
  rb_yield(line);
1441
1380
  }
1442
1381
  return self;
@@ -1454,15 +1393,15 @@ static VALUE
1454
1393
  strio_readlines(int argc, VALUE *argv, VALUE self)
1455
1394
  {
1456
1395
  VALUE ary, line;
1396
+ struct StringIO *ptr = readable(self);
1457
1397
  struct getline_arg arg;
1458
1398
 
1459
- StringIO(self);
1460
- ary = rb_ary_new();
1461
- if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
1399
+ if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
1462
1400
  rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
1463
1401
  }
1464
1402
 
1465
- while (!NIL_P(line = strio_getline(&arg, readable(self)))) {
1403
+ ary = rb_ary_new();
1404
+ while (!NIL_P(line = strio_getline(&arg, ptr))) {
1466
1405
  rb_ary_push(ary, line);
1467
1406
  }
1468
1407
  return ary;
@@ -1664,6 +1603,55 @@ strio_read(int argc, VALUE *argv, VALUE self)
1664
1603
  return str;
1665
1604
  }
1666
1605
 
1606
+ /*
1607
+ * call-seq:
1608
+ * pread(maxlen, offset) -> string
1609
+ * pread(maxlen, offset, out_string) -> string
1610
+ *
1611
+ * See IO#pread.
1612
+ */
1613
+ static VALUE
1614
+ strio_pread(int argc, VALUE *argv, VALUE self)
1615
+ {
1616
+ VALUE rb_len, rb_offset, rb_buf;
1617
+ rb_scan_args(argc, argv, "21", &rb_len, &rb_offset, &rb_buf);
1618
+ long len = NUM2LONG(rb_len);
1619
+ long offset = NUM2LONG(rb_offset);
1620
+
1621
+ if (len < 0) {
1622
+ rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
1623
+ }
1624
+
1625
+ if (len == 0) {
1626
+ if (NIL_P(rb_buf)) {
1627
+ return rb_str_new("", 0);
1628
+ }
1629
+ return rb_buf;
1630
+ }
1631
+
1632
+ if (offset < 0) {
1633
+ rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
1634
+ }
1635
+
1636
+ struct StringIO *ptr = readable(self);
1637
+
1638
+ if (offset >= RSTRING_LEN(ptr->string)) {
1639
+ rb_eof_error();
1640
+ }
1641
+
1642
+ if (NIL_P(rb_buf)) {
1643
+ return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
1644
+ }
1645
+
1646
+ long rest = RSTRING_LEN(ptr->string) - offset;
1647
+ if (len > rest) len = rest;
1648
+ rb_str_resize(rb_buf, len);
1649
+ rb_enc_associate(rb_buf, rb_ascii8bit_encoding());
1650
+ MEMCPY(RSTRING_PTR(rb_buf), RSTRING_PTR(ptr->string) + offset, char, len);
1651
+ return rb_buf;
1652
+ }
1653
+
1654
+
1667
1655
  /*
1668
1656
  * call-seq:
1669
1657
  * strio.sysread(integer[, outbuf]) -> string
@@ -1824,7 +1812,7 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
1824
1812
  else {
1825
1813
  enc = rb_find_encoding(ext_enc);
1826
1814
  if (!enc) {
1827
- struct rb_io_enc_t convconfig;
1815
+ rb_io_enc_t convconfig;
1828
1816
  int oflags, fmode;
1829
1817
  VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc);
1830
1818
  rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig);
@@ -1924,6 +1912,7 @@ Init_stringio(void)
1924
1912
  rb_define_method(StringIO, "gets", strio_gets, -1);
1925
1913
  rb_define_method(StringIO, "readlines", strio_readlines, -1);
1926
1914
  rb_define_method(StringIO, "read", strio_read, -1);
1915
+ rb_define_method(StringIO, "pread", strio_pread, -1);
1927
1916
 
1928
1917
  rb_define_method(StringIO, "write", strio_write_m, -1);
1929
1918
  rb_define_method(StringIO, "putc", strio_putc, 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.5
4
+ version: 3.1.0
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-02-03 00:00:00.000000000 Z
12
+ date: 2023-11-28 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Pseudo `IO` class from/to `String`.
15
15
  email:
@@ -36,14 +36,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '2.5'
39
+ version: '2.7'
40
40
  required_rubygems_version: !ruby/object:Gem::Requirement
41
41
  requirements:
42
42
  - - ">="
43
43
  - !ruby/object:Gem::Version
44
- version: '2.6'
44
+ version: '0'
45
45
  requirements: []
46
- rubygems_version: 3.4.1
46
+ rubygems_version: 3.4.10
47
47
  signing_key:
48
48
  specification_version: 4
49
49
  summary: Pseudo IO on String