stringio 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of stringio might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7fe0c0966c5d325821cf8f32c86b12b8b7def4f6
4
- data.tar.gz: 30143038585ac84c66ee9a5d09305343b2adf36e
2
+ SHA256:
3
+ metadata.gz: 7968119a0c6ab844f6b3ad11ffa51f7b4065af10a2d73ad79ecbee496e8f352a
4
+ data.tar.gz: 11c767a84c56493cf7cd0adf6fddda81f3d6a630ad947c3eddc385b00587311e
5
5
  SHA512:
6
- metadata.gz: a3b0f2a85ceaa075db032b3f6cdced4ec4e4f18532c63b5185253b1f44470c1b0cce55b2b6fcadfdf498c766ea8f3b1f6c784272dccd45efa6cce59efa51456a
7
- data.tar.gz: 9dacd4e043378988e412706b5ac2bac1db90a010598c58c8f3b64c1c09023dac786f336e1c7d5b10b66c6d79dc733d620f3e7cb251534dfc1943f3eff3ef8e9a
6
+ metadata.gz: 69ecd5af25b6334a5dfc7013779f57f6171dec1694f3f0272f05ec51404edc5d4ccac8df78c9f28c8c635bf49afffc2db50dad13ea8a78bf019265390ec0c121
7
+ data.tar.gz: 7ae636d1c423605e568349440f6a2e185a05bb1402569f185456dde23130eeefacd7a37768b6ed64ae99fc578799aabb4aeeede35df4d555b75d6cbbdebd7570
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: false
2
2
  require 'mkmf'
3
+ have_func("rb_io_extract_modeenc", "ruby/io.h")
3
4
  create_makefile('stringio')
@@ -11,6 +11,8 @@
11
11
 
12
12
  **********************************************************************/
13
13
 
14
+ #define STRINGIO_VERSION "0.1.0"
15
+
14
16
  #include "ruby.h"
15
17
  #include "ruby/io.h"
16
18
  #include "ruby/encoding.h"
@@ -24,6 +26,86 @@
24
26
  # define RB_INTEGER_TYPE_P(c) (FIXNUM_P(c) || RB_TYPE_P(c, T_BIGNUM))
25
27
  #endif
26
28
 
29
+ #ifndef RB_PASS_CALLED_KEYWORDS
30
+ # define rb_funcallv_kw(recv, mid, arg, argv, kw_splat) rb_funcallv(recv, mid, arg, argv)
31
+ # define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
32
+ #endif
33
+
34
+ #ifndef HAVE_RB_IO_EXTRACT_MODEENC
35
+ #define rb_io_extract_modeenc strio_extract_modeenc
36
+ static void
37
+ strio_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
38
+ int *oflags_p, int *fmode_p, struct rb_io_enc_t *convconfig_p)
39
+ {
40
+ VALUE mode = *vmode_p;
41
+ VALUE intmode;
42
+ int fmode;
43
+ int has_enc = 0, has_vmode = 0;
44
+
45
+ convconfig_p->enc = convconfig_p->enc2 = 0;
46
+
47
+ vmode_handle:
48
+ if (NIL_P(mode)) {
49
+ fmode = FMODE_READABLE;
50
+ }
51
+ else if (!NIL_P(intmode = rb_check_to_integer(mode, "to_int"))) {
52
+ int flags = NUM2INT(intmode);
53
+ fmode = rb_io_oflags_fmode(flags);
54
+ }
55
+ else {
56
+ const char *m = StringValueCStr(mode), *n, *e;
57
+ fmode = rb_io_modestr_fmode(m);
58
+ n = strchr(m, ':');
59
+ if (n) {
60
+ long len;
61
+ char encname[ENCODING_MAXNAMELEN+1];
62
+ has_enc = 1;
63
+ if (fmode & FMODE_SETENC_BY_BOM) {
64
+ n = strchr(n, '|');
65
+ }
66
+ e = strchr(++n, ':');
67
+ len = e ? e - n : strlen(n);
68
+ if (len > 0 && len <= ENCODING_MAXNAMELEN) {
69
+ if (e) {
70
+ memcpy(encname, n, len);
71
+ encname[len] = '\0';
72
+ n = encname;
73
+ }
74
+ convconfig_p->enc = rb_enc_find(n);
75
+ }
76
+ if (e && (len = strlen(++e)) > 0 && len <= ENCODING_MAXNAMELEN) {
77
+ convconfig_p->enc2 = rb_enc_find(e);
78
+ }
79
+ }
80
+ }
81
+
82
+ if (!NIL_P(opthash)) {
83
+ rb_encoding *extenc = 0, *intenc = 0;
84
+ VALUE v;
85
+ if (!has_vmode) {
86
+ ID id_mode;
87
+ CONST_ID(id_mode, "mode");
88
+ v = rb_hash_aref(opthash, ID2SYM(id_mode));
89
+ if (!NIL_P(v)) {
90
+ if (!NIL_P(mode)) {
91
+ rb_raise(rb_eArgError, "mode specified twice");
92
+ }
93
+ has_vmode = 1;
94
+ mode = v;
95
+ goto vmode_handle;
96
+ }
97
+ }
98
+
99
+ if (rb_io_extract_encoding_option(opthash, &extenc, &intenc, &fmode)) {
100
+ if (has_enc) {
101
+ rb_raise(rb_eArgError, "encoding specified twice");
102
+ }
103
+ }
104
+ }
105
+ *fmode_p = fmode;
106
+ }
107
+ #endif
108
+
27
109
  struct StringIO {
28
110
  VALUE string;
29
111
  rb_encoding *enc;
@@ -185,45 +267,106 @@ strio_initialize(int argc, VALUE *argv, VALUE self)
185
267
  return strio_init(argc, argv, ptr, self);
186
268
  }
187
269
 
188
- static VALUE
189
- strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
270
+ static int
271
+ detect_bom(VALUE str, int *bomlen)
190
272
  {
191
- VALUE string, mode;
192
- int trunc = 0;
273
+ const char *p;
274
+ long len;
193
275
 
194
- switch (rb_scan_args(argc, argv, "02", &string, &mode)) {
195
- case 2:
196
- if (FIXNUM_P(mode)) {
197
- int flags = FIX2INT(mode);
198
- ptr->flags = rb_io_oflags_fmode(flags);
199
- trunc = flags & O_TRUNC;
276
+ RSTRING_GETMEM(str, p, len);
277
+ if (len < 1) return 0;
278
+ switch ((unsigned char)p[0]) {
279
+ case 0xEF:
280
+ if (len < 2) break;
281
+ if ((unsigned char)p[1] == 0xBB && len > 2) {
282
+ if ((unsigned char)p[2] == 0xBF) {
283
+ *bomlen = 3;
284
+ return rb_utf8_encindex();
285
+ }
200
286
  }
201
- else {
202
- const char *m = StringValueCStr(mode);
203
- ptr->flags = rb_io_modestr_fmode(m);
204
- trunc = *m == 'w';
287
+ break;
288
+
289
+ case 0xFE:
290
+ if (len < 2) break;
291
+ if ((unsigned char)p[1] == 0xFF) {
292
+ *bomlen = 2;
293
+ return rb_enc_find_index("UTF-16BE");
205
294
  }
206
- StringValue(string);
207
- if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {
208
- rb_syserr_fail(EACCES, 0);
295
+ break;
296
+
297
+ case 0xFF:
298
+ if (len < 2) break;
299
+ if ((unsigned char)p[1] == 0xFE) {
300
+ if (len >= 4 && (unsigned char)p[2] == 0 && (unsigned char)p[3] == 0) {
301
+ *bomlen = 4;
302
+ return rb_enc_find_index("UTF-32LE");
303
+ }
304
+ *bomlen = 2;
305
+ return rb_enc_find_index("UTF-16LE");
209
306
  }
210
- if (trunc) {
211
- rb_str_resize(string, 0);
307
+ break;
308
+
309
+ case 0:
310
+ if (len < 4) break;
311
+ if ((unsigned char)p[1] == 0 && (unsigned char)p[2] == 0xFE && (unsigned char)p[3] == 0xFF) {
312
+ *bomlen = 4;
313
+ return rb_enc_find_index("UTF-32BE");
212
314
  }
213
315
  break;
214
- case 1:
316
+ }
317
+ return 0;
318
+ }
319
+
320
+ static rb_encoding *
321
+ set_encoding_by_bom(struct StringIO *ptr)
322
+ {
323
+ int bomlen, idx = detect_bom(ptr->string, &bomlen);
324
+ rb_encoding *extenc = NULL;
325
+
326
+ if (idx) {
327
+ extenc = rb_enc_from_index(idx);
328
+ ptr->pos = bomlen;
329
+ if (ptr->flags & FMODE_WRITABLE) {
330
+ rb_enc_associate_index(ptr->string, idx);
331
+ }
332
+ }
333
+ ptr->enc = extenc;
334
+ return extenc;
335
+ }
336
+
337
+ static VALUE
338
+ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
339
+ {
340
+ VALUE string, vmode, opt;
341
+ int oflags;
342
+ struct rb_io_enc_t convconfig;
343
+
344
+ argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
345
+ rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
346
+ if (argc) {
215
347
  StringValue(string);
216
- ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
217
- break;
218
- case 0:
348
+ }
349
+ else {
219
350
  string = rb_enc_str_new("", 0, rb_default_external_encoding());
220
- ptr->flags = FMODE_READWRITE;
221
- break;
351
+ }
352
+ if (OBJ_FROZEN_RAW(string)) {
353
+ if (ptr->flags & FMODE_WRITABLE) {
354
+ rb_syserr_fail(EACCES, 0);
355
+ }
356
+ }
357
+ else {
358
+ if (NIL_P(vmode)) {
359
+ ptr->flags |= FMODE_WRITABLE;
360
+ }
361
+ }
362
+ if (ptr->flags & FMODE_TRUNC) {
363
+ rb_str_resize(string, 0);
222
364
  }
223
365
  ptr->string = string;
224
- ptr->enc = 0;
366
+ ptr->enc = convconfig.enc;
225
367
  ptr->pos = 0;
226
368
  ptr->lineno = 0;
369
+ if (ptr->flags & FMODE_SETENC_BY_BOM) set_encoding_by_bom(ptr);
227
370
  RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);
228
371
  return self;
229
372
  }
@@ -247,7 +390,7 @@ strio_finalize(VALUE self)
247
390
  static VALUE
248
391
  strio_s_open(int argc, VALUE *argv, VALUE klass)
249
392
  {
250
- VALUE obj = rb_class_new_instance(argc, argv, klass);
393
+ VALUE obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
251
394
  if (!rb_block_given_p()) return obj;
252
395
  return rb_ensure(rb_yield, obj, strio_finalize, obj);
253
396
  }
@@ -262,7 +405,7 @@ strio_s_new(int argc, VALUE *argv, VALUE klass)
262
405
  rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
263
406
  cname, cname);
264
407
  }
265
- return rb_class_new_instance(argc, argv, klass);
408
+ return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
266
409
  }
267
410
 
268
411
  /*
@@ -286,7 +429,7 @@ strio_nil(VALUE self)
286
429
  }
287
430
 
288
431
  /*
289
- * Returns *strio* itself. Just for compatibility to IO.
432
+ * Returns an object itself. Just for compatibility to IO.
290
433
  */
291
434
  static VALUE
292
435
  strio_self(VALUE self)
@@ -362,7 +505,7 @@ strio_set_string(VALUE self, VALUE string)
362
505
  * call-seq:
363
506
  * strio.close -> nil
364
507
  *
365
- * Closes strio. The *strio* is unavailable for any further data
508
+ * Closes a StringIO. The stream is unavailable for any further data
366
509
  * operations; an +IOError+ is raised if such an attempt is made.
367
510
  */
368
511
  static VALUE
@@ -378,7 +521,7 @@ strio_close(VALUE self)
378
521
  * strio.close_read -> nil
379
522
  *
380
523
  * Closes the read end of a StringIO. Will raise an +IOError+ if the
381
- * *strio* is not readable.
524
+ * receiver is not readable.
382
525
  */
383
526
  static VALUE
384
527
  strio_close_read(VALUE self)
@@ -396,7 +539,7 @@ strio_close_read(VALUE self)
396
539
  * strio.close_write -> nil
397
540
  *
398
541
  * Closes the write end of a StringIO. Will raise an +IOError+ if the
399
- * *strio* is not writeable.
542
+ * receiver is not writeable.
400
543
  */
401
544
  static VALUE
402
545
  strio_close_write(VALUE self)
@@ -413,7 +556,7 @@ strio_close_write(VALUE self)
413
556
  * call-seq:
414
557
  * strio.closed? -> true or false
415
558
  *
416
- * Returns +true+ if *strio* is completely closed, +false+ otherwise.
559
+ * Returns +true+ if the stream is completely closed, +false+ otherwise.
417
560
  */
418
561
  static VALUE
419
562
  strio_closed(VALUE self)
@@ -427,7 +570,7 @@ strio_closed(VALUE self)
427
570
  * call-seq:
428
571
  * strio.closed_read? -> true or false
429
572
  *
430
- * Returns +true+ if *strio* is not readable, +false+ otherwise.
573
+ * Returns +true+ if the stream is not readable, +false+ otherwise.
431
574
  */
432
575
  static VALUE
433
576
  strio_closed_read(VALUE self)
@@ -441,7 +584,7 @@ strio_closed_read(VALUE self)
441
584
  * call-seq:
442
585
  * strio.closed_write? -> true or false
443
586
  *
444
- * Returns +true+ if *strio* is not writable, +false+ otherwise.
587
+ * Returns +true+ if the stream is not writable, +false+ otherwise.
445
588
  */
446
589
  static VALUE
447
590
  strio_closed_write(VALUE self)
@@ -456,8 +599,8 @@ strio_closed_write(VALUE self)
456
599
  * strio.eof -> true or false
457
600
  * strio.eof? -> true or false
458
601
  *
459
- * Returns true if *strio* is at end of file. The stringio must be
460
- * opened for reading or an +IOError+ will be raised.
602
+ * Returns true if the stream is at the end of the data (underlying string).
603
+ * The stream must be opened for reading or an +IOError+ will be raised.
461
604
  */
462
605
  static VALUE
463
606
  strio_eof(VALUE self)
@@ -480,7 +623,6 @@ strio_copy(VALUE copy, VALUE orig)
480
623
  strio_free(DATA_PTR(copy));
481
624
  }
482
625
  DATA_PTR(copy) = ptr;
483
- OBJ_INFECT(copy, orig);
484
626
  RBASIC(copy)->flags &= ~STRIO_READWRITE;
485
627
  RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
486
628
  ++ptr->count;
@@ -491,7 +633,7 @@ strio_copy(VALUE copy, VALUE orig)
491
633
  * call-seq:
492
634
  * strio.lineno -> integer
493
635
  *
494
- * Returns the current line number in *strio*. The stringio must be
636
+ * Returns the current line number. The stream must be
495
637
  * opened for reading. +lineno+ counts the number of times +gets+ is
496
638
  * called, rather than the number of newlines encountered. The two
497
639
  * values will differ if +gets+ is called with a separator other than
@@ -517,6 +659,13 @@ strio_set_lineno(VALUE self, VALUE lineno)
517
659
  return lineno;
518
660
  }
519
661
 
662
+ /*
663
+ * call-seq:
664
+ * strio.binmode -> stringio
665
+ *
666
+ * Puts stream into binary mode. See IO#binmode.
667
+ *
668
+ */
520
669
  static VALUE
521
670
  strio_binmode(VALUE self)
522
671
  {
@@ -541,7 +690,7 @@ strio_binmode(VALUE self)
541
690
  * strio.reopen(other_StrIO) -> strio
542
691
  * strio.reopen(string, mode) -> strio
543
692
  *
544
- * Reinitializes *strio* with the given <i>other_StrIO</i> or _string_
693
+ * Reinitializes the stream with the given <i>other_StrIO</i> or _string_
545
694
  * and _mode_ (see StringIO#new).
546
695
  */
547
696
  static VALUE
@@ -559,7 +708,7 @@ strio_reopen(int argc, VALUE *argv, VALUE self)
559
708
  * strio.pos -> integer
560
709
  * strio.tell -> integer
561
710
  *
562
- * Returns the current offset (in bytes) of *strio*.
711
+ * Returns the current offset (in bytes).
563
712
  */
564
713
  static VALUE
565
714
  strio_get_pos(VALUE self)
@@ -571,7 +720,7 @@ strio_get_pos(VALUE self)
571
720
  * call-seq:
572
721
  * strio.pos = integer -> integer
573
722
  *
574
- * Seeks to the given position (in bytes) in *strio*.
723
+ * Seeks to the given position (in bytes).
575
724
  */
576
725
  static VALUE
577
726
  strio_set_pos(VALUE self, VALUE pos)
@@ -589,7 +738,7 @@ strio_set_pos(VALUE self, VALUE pos)
589
738
  * call-seq:
590
739
  * strio.rewind -> 0
591
740
  *
592
- * Positions *strio* to the beginning of input, resetting
741
+ * Positions the stream to the beginning of input, resetting
593
742
  * +lineno+ to zero.
594
743
  */
595
744
  static VALUE
@@ -757,7 +906,7 @@ strio_extend(struct StringIO *ptr, long pos, long len)
757
906
  * call-seq:
758
907
  * strio.ungetc(string) -> nil
759
908
  *
760
- * Pushes back one character (passed as a parameter) onto *strio*
909
+ * Pushes back one character (passed as a parameter)
761
910
  * such that a subsequent buffered read will return it. There is no
762
911
  * limitation for multiple pushbacks including pushing back behind the
763
912
  * beginning of the buffer string.
@@ -803,24 +952,25 @@ static VALUE
803
952
  strio_ungetbyte(VALUE self, VALUE c)
804
953
  {
805
954
  struct StringIO *ptr = readable(self);
806
- char buf[1], *cp = buf;
807
- long cl = 1;
808
955
 
809
956
  check_modifiable(ptr);
810
957
  if (NIL_P(c)) return Qnil;
811
- if (FIXNUM_P(c)) {
812
- buf[0] = (char)FIX2INT(c);
813
- return strio_unget_bytes(ptr, buf, 1);
958
+ if (RB_INTEGER_TYPE_P(c)) {
959
+ /* rb_int_and() not visible from exts */
960
+ VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
961
+ const char cc = NUM2INT(v) & 0xFF;
962
+ strio_unget_bytes(ptr, &cc, 1);
814
963
  }
815
964
  else {
965
+ long cl;
816
966
  SafeStringValue(c);
817
- cp = RSTRING_PTR(c);
818
967
  cl = RSTRING_LEN(c);
819
- if (cl == 0) return Qnil;
820
- strio_unget_bytes(ptr, cp, cl);
821
- RB_GC_GUARD(c);
822
- return Qnil;
968
+ if (cl > 0) {
969
+ strio_unget_bytes(ptr, RSTRING_PTR(c), cl);
970
+ RB_GC_GUARD(c);
971
+ }
823
972
  }
973
+ return Qnil;
824
974
  }
825
975
 
826
976
  static VALUE
@@ -863,7 +1013,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
863
1013
  static VALUE
864
1014
  strio_readchar(VALUE self)
865
1015
  {
866
- VALUE c = rb_funcall2(self, rb_intern("getc"), 0, 0);
1016
+ VALUE c = rb_funcallv(self, rb_intern("getc"), 0, 0);
867
1017
  if (NIL_P(c)) rb_eof_error();
868
1018
  return c;
869
1019
  }
@@ -877,7 +1027,7 @@ strio_readchar(VALUE self)
877
1027
  static VALUE
878
1028
  strio_readbyte(VALUE self)
879
1029
  {
880
- VALUE c = rb_funcall2(self, rb_intern("getbyte"), 0, 0);
1030
+ VALUE c = rb_funcallv(self, rb_intern("getbyte"), 0, 0);
881
1031
  if (NIL_P(c)) rb_eof_error();
882
1032
  return c;
883
1033
  }
@@ -903,7 +1053,7 @@ strio_each_char(VALUE self)
903
1053
  }
904
1054
 
905
1055
  /*
906
- * This is a deprecated alias for <code>each_char</code>.
1056
+ * This is a deprecated alias for #each_char.
907
1057
  */
908
1058
  static VALUE
909
1059
  strio_chars(VALUE self)
@@ -947,7 +1097,7 @@ strio_each_codepoint(VALUE self)
947
1097
  }
948
1098
 
949
1099
  /*
950
- * This is a deprecated alias for <code>each_codepoint</code>.
1100
+ * This is a deprecated alias for #each_codepoint.
951
1101
  */
952
1102
  static VALUE
953
1103
  strio_codepoints(VALUE self)
@@ -1137,9 +1287,9 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
1137
1287
 
1138
1288
  /*
1139
1289
  * call-seq:
1140
- * strio.gets(sep=$/) -> string or nil
1141
- * strio.gets(limit) -> string or nil
1142
- * strio.gets(sep, limit) -> string or nil
1290
+ * strio.gets(sep=$/, chomp: false) -> string or nil
1291
+ * strio.gets(limit, chomp: false) -> string or nil
1292
+ * strio.gets(sep, limit, chomp: false) -> string or nil
1143
1293
  *
1144
1294
  * See IO#gets.
1145
1295
  */
@@ -1161,31 +1311,31 @@ strio_gets(int argc, VALUE *argv, VALUE self)
1161
1311
 
1162
1312
  /*
1163
1313
  * call-seq:
1164
- * strio.readline(sep=$/) -> string
1165
- * strio.readline(limit) -> string or nil
1166
- * strio.readline(sep, limit) -> string or nil
1314
+ * strio.readline(sep=$/, chomp: false) -> string
1315
+ * strio.readline(limit, chomp: false) -> string or nil
1316
+ * strio.readline(sep, limit, chomp: false) -> string or nil
1167
1317
  *
1168
1318
  * See IO#readline.
1169
1319
  */
1170
1320
  static VALUE
1171
1321
  strio_readline(int argc, VALUE *argv, VALUE self)
1172
1322
  {
1173
- VALUE line = rb_funcall2(self, rb_intern("gets"), argc, argv);
1323
+ VALUE line = rb_funcallv_kw(self, rb_intern("gets"), argc, argv, RB_PASS_CALLED_KEYWORDS);
1174
1324
  if (NIL_P(line)) rb_eof_error();
1175
1325
  return line;
1176
1326
  }
1177
1327
 
1178
1328
  /*
1179
1329
  * call-seq:
1180
- * strio.each(sep=$/) {|line| block } -> strio
1181
- * strio.each(limit) {|line| block } -> strio
1182
- * strio.each(sep, limit) {|line| block } -> strio
1183
- * strio.each(...) -> anEnumerator
1330
+ * strio.each(sep=$/, chomp: false) {|line| block } -> strio
1331
+ * strio.each(limit, chomp: false) {|line| block } -> strio
1332
+ * strio.each(sep, limit, chomp: false) {|line| block } -> strio
1333
+ * strio.each(...) -> anEnumerator
1184
1334
  *
1185
- * strio.each_line(sep=$/) {|line| block } -> strio
1186
- * strio.each_line(limit) {|line| block } -> strio
1187
- * strio.each_line(sep,limit) {|line| block } -> strio
1188
- * strio.each_line(...) -> anEnumerator
1335
+ * strio.each_line(sep=$/, chomp: false) {|line| block } -> strio
1336
+ * strio.each_line(limit, chomp: false) {|line| block } -> strio
1337
+ * strio.each_line(sep, limit, chomp: false) {|line| block } -> strio
1338
+ * strio.each_line(...) -> anEnumerator
1189
1339
  *
1190
1340
  * See IO#each.
1191
1341
  */
@@ -1209,7 +1359,7 @@ strio_each(int argc, VALUE *argv, VALUE self)
1209
1359
  }
1210
1360
 
1211
1361
  /*
1212
- * This is a deprecated alias for <code>each_line</code>.
1362
+ * This is a deprecated alias for #each_line.
1213
1363
  */
1214
1364
  static VALUE
1215
1365
  strio_lines(int argc, VALUE *argv, VALUE self)
@@ -1222,9 +1372,9 @@ strio_lines(int argc, VALUE *argv, VALUE self)
1222
1372
 
1223
1373
  /*
1224
1374
  * call-seq:
1225
- * strio.readlines(sep=$/) -> array
1226
- * strio.readlines(limit) -> array
1227
- * strio.readlines(sep,limit) -> array
1375
+ * strio.readlines(sep=$/, chomp: false) -> array
1376
+ * strio.readlines(limit, chomp: false) -> array
1377
+ * strio.readlines(sep, limit, chomp: false) -> array
1228
1378
  *
1229
1379
  * See IO#readlines.
1230
1380
  */
@@ -1251,7 +1401,7 @@ strio_readlines(int argc, VALUE *argv, VALUE self)
1251
1401
  * strio.write(string, ...) -> integer
1252
1402
  * strio.syswrite(string) -> integer
1253
1403
  *
1254
- * Appends the given string to the underlying buffer string of *strio*.
1404
+ * Appends the given string to the underlying buffer string.
1255
1405
  * The stream must be opened for writing. If the argument is not a
1256
1406
  * string, it will be converted to a string using <code>to_s</code>.
1257
1407
  * Returns the number of bytes written. See IO#write.
@@ -1292,7 +1442,6 @@ strio_write(VALUE self, VALUE str)
1292
1442
  if (ptr->pos == olen) {
1293
1443
  if (enc == ascii8bit || enc2 == ascii8bit) {
1294
1444
  rb_enc_str_buf_cat(ptr->string, RSTRING_PTR(str), len, enc);
1295
- OBJ_INFECT(ptr->string, str);
1296
1445
  }
1297
1446
  else {
1298
1447
  rb_str_buf_append(ptr->string, str);
@@ -1301,9 +1450,7 @@ strio_write(VALUE self, VALUE str)
1301
1450
  else {
1302
1451
  strio_extend(ptr, ptr->pos, len);
1303
1452
  memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
1304
- OBJ_INFECT(ptr->string, str);
1305
1453
  }
1306
- OBJ_INFECT(ptr->string, self);
1307
1454
  RB_GC_GUARD(str);
1308
1455
  ptr->pos += len;
1309
1456
  return len;
@@ -1406,7 +1553,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
1406
1553
  case 0:
1407
1554
  len = RSTRING_LEN(ptr->string);
1408
1555
  if (len <= ptr->pos) {
1409
- rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
1556
+ rb_encoding *enc = get_enc(ptr);
1410
1557
  if (NIL_P(str)) {
1411
1558
  str = rb_str_new(0, 0);
1412
1559
  }
@@ -1450,7 +1597,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
1450
1597
  static VALUE
1451
1598
  strio_sysread(int argc, VALUE *argv, VALUE self)
1452
1599
  {
1453
- VALUE val = rb_funcall2(self, rb_intern("read"), argc, argv);
1600
+ VALUE val = rb_funcallv_kw(self, rb_intern("read"), argc, argv, RB_PASS_CALLED_KEYWORDS);
1454
1601
  if (NIL_P(val)) {
1455
1602
  rb_eof_error();
1456
1603
  }
@@ -1525,7 +1672,7 @@ strio_size(VALUE self)
1525
1672
  * call-seq:
1526
1673
  * strio.truncate(integer) -> 0
1527
1674
  *
1528
- * Truncates the buffer string to at most _integer_ bytes. The *strio*
1675
+ * Truncates the buffer string to at most _integer_ bytes. The stream
1529
1676
  * must be opened for writing.
1530
1677
  */
1531
1678
  static VALUE
@@ -1549,7 +1696,8 @@ strio_truncate(VALUE self, VALUE len)
1549
1696
  * strio.external_encoding => encoding
1550
1697
  *
1551
1698
  * Returns the Encoding object that represents the encoding of the file.
1552
- * If strio is write mode and no encoding is specified, returns <code>nil</code>.
1699
+ * If the stream is write mode and no encoding is specified, returns
1700
+ * +nil+.
1553
1701
  */
1554
1702
 
1555
1703
  static VALUE
@@ -1564,7 +1712,7 @@ strio_external_encoding(VALUE self)
1564
1712
  * strio.internal_encoding => encoding
1565
1713
  *
1566
1714
  * Returns the Encoding of the internal string if conversion is
1567
- * specified. Otherwise returns nil.
1715
+ * specified. Otherwise returns +nil+.
1568
1716
  */
1569
1717
 
1570
1718
  static VALUE
@@ -1606,18 +1754,37 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
1606
1754
  return self;
1607
1755
  }
1608
1756
 
1757
+ static VALUE
1758
+ strio_set_encoding_by_bom(VALUE self)
1759
+ {
1760
+ struct StringIO *ptr = StringIO(self);
1761
+
1762
+ if (ptr->enc) {
1763
+ rb_raise(rb_eArgError, "encoding conversion is set");
1764
+ }
1765
+ if (!set_encoding_by_bom(ptr)) return Qnil;
1766
+ return rb_enc_from_encoding(ptr->enc);
1767
+ }
1768
+
1609
1769
  /*
1610
- * Pseudo I/O on String object.
1770
+ * Pseudo I/O on String object, with interface corresponding to IO.
1611
1771
  *
1612
- * Commonly used to simulate `$stdio` or `$stderr`
1772
+ * Commonly used to simulate <code>$stdio</code> or <code>$stderr</code>
1613
1773
  *
1614
1774
  * === Examples
1615
1775
  *
1616
1776
  * require 'stringio'
1617
1777
  *
1778
+ * # Writing stream emulation
1618
1779
  * io = StringIO.new
1619
1780
  * io.puts "Hello World"
1620
1781
  * io.string #=> "Hello World\n"
1782
+ *
1783
+ * # Reading stream emulation
1784
+ * io = StringIO.new "first\nsecond\nlast\n"
1785
+ * io.getc #=> "f"
1786
+ * io.gets #=> "irst\n"
1787
+ * io.read #=> "second\nlast\n"
1621
1788
  */
1622
1789
  void
1623
1790
  Init_stringio(void)
@@ -1625,6 +1792,8 @@ Init_stringio(void)
1625
1792
  #undef rb_intern
1626
1793
  VALUE StringIO = rb_define_class("StringIO", rb_cData);
1627
1794
 
1795
+ rb_define_const(StringIO, "VERSION", rb_str_new_cstr(STRINGIO_VERSION));
1796
+
1628
1797
  rb_include_module(StringIO, rb_mEnumerable);
1629
1798
  rb_define_alloc_func(StringIO, strio_s_allocate);
1630
1799
  rb_define_singleton_method(StringIO, "new", strio_s_new, -1);
@@ -1705,6 +1874,7 @@ Init_stringio(void)
1705
1874
  rb_define_method(StringIO, "external_encoding", strio_external_encoding, 0);
1706
1875
  rb_define_method(StringIO, "internal_encoding", strio_internal_encoding, 0);
1707
1876
  rb_define_method(StringIO, "set_encoding", strio_set_encoding, -1);
1877
+ rb_define_method(StringIO, "set_encoding_by_bom", strio_set_encoding_by_bom, 0);
1708
1878
 
1709
1879
  {
1710
1880
  VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stringio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nobu Nakada
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-04 00:00:00.000000000 Z
11
+ date: 2019-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -46,15 +46,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: '2.2'
49
+ version: '2.5'
50
50
  required_rubygems_version: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.6'
55
55
  requirements: []
56
- rubyforge_project:
57
- rubygems_version: 2.6.14.3
56
+ rubygems_version: 3.0.3
58
57
  signing_key:
59
58
  specification_version: 4
60
59
  summary: Pseudo IO on String