stringio 3.0.5 → 3.1.0

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: 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