Class: IO

Inherits:
Object
  • Object
show all
Defined in:
mrbgems/mruby-io/src/io.c,
mrbgems/mruby-io/mrblib/io.rb

Direct Known Subclasses

BasicSocket, File

Constant Summary collapse

SEEK_SET =
0
SEEK_CUR =
1
SEEK_END =
2
BUF_SIZE =
4096

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeObject

15.2.20.5.21 (x)



612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
# File 'mrbgems/mruby-io/src/io.c', line 612

mrb_value
mrb_io_initialize(mrb_state *mrb, mrb_value io)
{
  struct mrb_io *fptr;
  mrb_int fd;
  mrb_value mode, opt;
  int flags;

  mode = opt = mrb_nil_value();

  mrb_get_args(mrb, "i|So", &fd, &mode, &opt);
  if (mrb_nil_p(mode)) {
    mode = mrb_str_new_cstr(mrb, "r");
  }
  if (mrb_nil_p(opt)) {
    opt = mrb_hash_new(mrb);
  }

  flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));

  mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));

  fptr = (struct mrb_io *)DATA_PTR(io);
  if (fptr != NULL) {
    fptr_finalize(mrb, fptr, TRUE);
    mrb_free(mrb, fptr);
  }
  fptr = mrb_io_alloc(mrb);

  DATA_TYPE(io) = &mrb_io_type;
  DATA_PTR(io) = fptr;

  fptr->fd = (int)fd;
  fptr->readable = ((flags & FMODE_READABLE) != 0);
  fptr->writable = ((flags & FMODE_WRITABLE) != 0);
  fptr->sync = 0;
  return io;
}

Class Method Details

.open(*args, &block) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'mrbgems/mruby-io/mrblib/io.rb', line 14

def self.open(*args, &block)
  io = self.new(*args)

  return io unless block

  begin
    yield io
  ensure
    begin
      io.close unless io.closed?
    rescue StandardError
    end
  end
end

.pipe(&block) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'mrbgems/mruby-io/mrblib/io.rb', line 47

def self.pipe(&block)
  if !self.respond_to?(:_pipe)
    raise NotImplementedError, "pipe is not supported on this platform"
  end
  if block
    begin
      r, w = IO._pipe
      yield r, w
    ensure
      r.close unless r.closed?
      w.close unless w.closed?
    end
  else
    IO._pipe
  end
end

.popen(command, mode = 'r', opts = {}, &block) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'mrbgems/mruby-io/mrblib/io.rb', line 29

def self.popen(command, mode = 'r', opts={}, &block)
  if !self.respond_to?(:_popen)
    raise NotImplementedError, "popen is not supported on this platform"
  end
  io = self._popen(command, mode, opts)
  return io unless block

  begin
    yield io
  ensure
    begin
      io.close unless io.closed?
    rescue IOError
      # nothing
    end
  end
end

.read(path, length = nil, offset = nil, opt = nil) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'mrbgems/mruby-io/mrblib/io.rb', line 64

def self.read(path, length=nil, offset=nil, opt=nil)
  if not opt.nil?        # 4 arguments
    offset ||= 0
  elsif not offset.nil?  # 3 arguments
    if offset.is_a? Hash
      opt = offset
      offset = 0
    else
      opt = {}
    end
  elsif not length.nil?  # 2 arguments
    if length.is_a? Hash
      opt = length
      offset = 0
      length = nil
    else
      offset = 0
      opt = {}
    end
  else                   # only 1 argument
    opt = {}
    offset = 0
    length = nil
  end

  str = ""
  fd = -1
  io = nil
  begin
    if path[0] == "|"
      io = IO.popen(path[1..-1], (opt[:mode] || "r"))
    else
      mode = opt[:mode] || "r"
      fd = IO.sysopen(path, mode)
      io = IO.open(fd, mode)
    end
    io.seek(offset) if offset > 0
    str = io.read(length)
  ensure
    if io
      io.close
    elsif fd != -1
      IO._sysclose(fd)
    end
  end
  str
end

Instance Method Details

#<<(str) ⇒ Object



135
136
137
138
# File 'mrbgems/mruby-io/mrblib/io.rb', line 135

def <<(str)
  write(str)
  self
end

#_check_readableObject



714
715
716
717
718
719
720
721
722
# File 'mrbgems/mruby-io/src/io.c', line 714

mrb_value
mrb_io_check_readable(mrb_state *mrb, mrb_value self)
{
  struct mrb_io *fptr = io_get_open_fptr(mrb, self);
  if (! fptr->readable) {
    mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
  }
  return mrb_nil_value();
}

#_read_bufObject



172
173
174
175
176
177
178
179
180
# File 'mrbgems/mruby-io/mrblib/io.rb', line 172

def _read_buf
  return @buf if @buf && @buf.bytesize >= 4 # maximum UTF-8 character is 4 bytes
  @buf ||= ""
  begin
    @buf += sysread(BUF_SIZE)
  rescue EOFError => e
    raise e if @buf.empty?
  end
end

#closeObject

15.2.20.5.1



926
927
928
929
930
931
932
933
# File 'mrbgems/mruby-io/src/io.c', line 926

mrb_value
mrb_io_close(mrb_state *mrb, mrb_value self)
{
  struct mrb_io *fptr;
  fptr = io_get_open_fptr(mrb, self);
  fptr_finalize(mrb, fptr, FALSE);
  return mrb_nil_value();
}

#close_on_exec=Object



1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
# File 'mrbgems/mruby-io/src/io.c', line 1238

mrb_value
mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
{
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
  struct mrb_io *fptr;
  int flag, ret;
  mrb_bool b;

  fptr = io_get_open_fptr(mrb, self);
  mrb_get_args(mrb, "b", &b);
  flag = b ? FD_CLOEXEC : 0;

  if (fptr->fd2 >= 0) {
    if ((ret = fcntl(fptr->fd2, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed");
    if ((ret & FD_CLOEXEC) != flag) {
      ret = (ret & ~FD_CLOEXEC) | flag;
      ret = fcntl(fptr->fd2, F_SETFD, ret);

      if (ret == -1) mrb_sys_fail(mrb, "F_SETFD failed");
    }
  }

  if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed");
  if ((ret & FD_CLOEXEC) != flag) {
    ret = (ret & ~FD_CLOEXEC) | flag;
    ret = fcntl(fptr->fd, F_SETFD, ret);
    if (ret == -1) mrb_sys_fail(mrb, "F_SETFD failed");
  }

  return mrb_bool_value(b);
#else
  mrb_raise(mrb, E_NOTIMP_ERROR, "IO#close_on_exec= is not supported on the platform");
  return mrb_nil_value();
#endif
}

#close_on_exec?Boolean

Returns:

  • (Boolean)


1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
# File 'mrbgems/mruby-io/src/io.c', line 1214

mrb_value
mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
{
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
  struct mrb_io *fptr;
  int ret;

  fptr = io_get_open_fptr(mrb, self);

  if (fptr->fd2 >= 0) {
    if ((ret = fcntl(fptr->fd2, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed");
    if (!(ret & FD_CLOEXEC)) return mrb_false_value();
  }

  if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed");
  if (!(ret & FD_CLOEXEC)) return mrb_false_value();
  return mrb_true_value();

#else
  mrb_raise(mrb, E_NOTIMP_ERROR, "IO#close_on_exec? is not supported on the platform");
  return mrb_false_value();
#endif
}

#close_writeObject

15.2.20.5.1



935
936
937
938
939
940
941
942
943
944
# File 'mrbgems/mruby-io/src/io.c', line 935

mrb_value
mrb_io_close_write(mrb_state *mrb, mrb_value self)
{
  struct mrb_io *fptr;
  fptr = io_get_open_fptr(mrb, self);
  if (close((int)fptr->fd2) == -1) {
    mrb_sys_fail(mrb, "close");
  }
  return mrb_nil_value();
}

#closed?Boolean

15.2.20.5.2

Returns:

  • (Boolean)


946
947
948
949
950
951
952
953
954
955
956
# File 'mrbgems/mruby-io/src/io.c', line 946

mrb_value
mrb_io_closed(mrb_state *mrb, mrb_value io)
{
  struct mrb_io *fptr;
  fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, io, &mrb_io_type);
  if (fptr == NULL || fptr->fd >= 0) {
    return mrb_false_value();
  }

  return mrb_true_value();
}

#each(&block) ⇒ Object Also known as: each_line

15.2.20.5.3



305
306
307
308
309
310
311
312
# File 'mrbgems/mruby-io/mrblib/io.rb', line 305

def each(&block)
  return to_enum unless block

  while line = self.gets
    block.call(line)
  end
  self
end

#each_byte(&block) ⇒ Object Also known as: each_char

15.2.20.5.4



315
316
317
318
319
320
321
322
# File 'mrbgems/mruby-io/mrblib/io.rb', line 315

def each_byte(&block)
  return to_enum(:each_byte) unless block

  while char = self.getc
    block.call(char)
  end
  self
end

#eof?Boolean Also known as: eof

Returns:

  • (Boolean)


140
141
142
143
144
145
146
147
148
# File 'mrbgems/mruby-io/mrblib/io.rb', line 140

def eof?
  _check_readable
  begin
    _read_buf
    return @buf.empty?
  rescue EOFError
    return true
  end
end

#filenoObject Also known as: to_i

15.2.20.5.2



1206
1207
1208
1209
1210
1211
1212
# File 'mrbgems/mruby-io/src/io.c', line 1206

mrb_value
mrb_io_fileno(mrb_state *mrb, mrb_value io)
{
  struct mrb_io *fptr;
  fptr = io_get_open_fptr(mrb, io);
  return mrb_fixnum_value(fptr->fd);
}

#flushObject

Raises:



112
113
114
115
116
# File 'mrbgems/mruby-io/mrblib/io.rb', line 112

def flush
  # mruby-io always writes immediately (no output buffer).
  raise IOError, "closed stream" if self.closed?
  self
end

#getcObject



296
297
298
299
300
301
302
# File 'mrbgems/mruby-io/mrblib/io.rb', line 296

def getc
  begin
    readchar
  rescue EOFError
    nil
  end
end

#gets(*args) ⇒ Object



281
282
283
284
285
286
287
# File 'mrbgems/mruby-io/mrblib/io.rb', line 281

def gets(*args)
  begin
    readline(*args)
  rescue EOFError
    nil
  end
end

#hashObject



118
119
120
121
122
# File 'mrbgems/mruby-io/mrblib/io.rb', line 118

def hash
  # We must define IO#hash here because IO includes Enumerable and
  # Enumerable#hash will call IO#read...
  self.__id__
end

#initialize_copyObject

15.2.20.5.21 (x)



563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'mrbgems/mruby-io/src/io.c', line 563

mrb_value
mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
{
  mrb_value orig;
  mrb_value buf;
  struct mrb_io *fptr_copy;
  struct mrb_io *fptr_orig;
  mrb_bool failed = TRUE;

  mrb_get_args(mrb, "o", &orig);
  fptr_orig = io_get_open_fptr(mrb, orig);
  fptr_copy = (struct mrb_io *)DATA_PTR(copy);
  if (fptr_orig == fptr_copy) return copy;
  if (fptr_copy != NULL) {
    fptr_finalize(mrb, fptr_copy, FALSE);
    mrb_free(mrb, fptr_copy);
  }
  fptr_copy = (struct mrb_io *)mrb_io_alloc(mrb);

  DATA_TYPE(copy) = &mrb_io_type;
  DATA_PTR(copy) = fptr_copy;

  buf = mrb_iv_get(mrb, orig, mrb_intern_cstr(mrb, "@buf"));
  mrb_iv_set(mrb, copy, mrb_intern_cstr(mrb, "@buf"), buf);

  fptr_copy->fd = mrb_dup(mrb, fptr_orig->fd, &failed);
  if (failed) {
    mrb_sys_fail(mrb, 0);
  }
  mrb_fd_cloexec(mrb, fptr_copy->fd);

  if (fptr_orig->fd2 != -1) {
    fptr_copy->fd2 = mrb_dup(mrb, fptr_orig->fd2, &failed);
    if (failed) {
      close(fptr_copy->fd);
      mrb_sys_fail(mrb, 0);
    }
    mrb_fd_cloexec(mrb, fptr_copy->fd2);
  }

  fptr_copy->pid = fptr_orig->pid;
  fptr_copy->readable = fptr_orig->readable;
  fptr_copy->writable = fptr_orig->writable;
  fptr_copy->sync = fptr_orig->sync;
  fptr_copy->is_socket = fptr_orig->is_socket;

  return copy;
}

#isattyObject Also known as: tty?



724
725
726
727
728
729
730
731
732
733
# File 'mrbgems/mruby-io/src/io.c', line 724

mrb_value
mrb_io_isatty(mrb_state *mrb, mrb_value self)
{
  struct mrb_io *fptr;

  fptr = io_get_open_fptr(mrb, self);
  if (isatty(fptr->fd) == 0)
    return mrb_false_value();
  return mrb_true_value();
}

#pidObject

15.2.20.5.2



958
959
960
961
962
963
964
965
966
967
968
969
# File 'mrbgems/mruby-io/src/io.c', line 958

mrb_value
mrb_io_pid(mrb_state *mrb, mrb_value io)
{
  struct mrb_io *fptr;
  fptr = io_get_open_fptr(mrb, io);

  if (fptr->pid > 0) {
    return mrb_fixnum_value(fptr->pid);
  }

  return mrb_nil_value();
}

#posObject Also known as: tell

Raises:



151
152
153
154
# File 'mrbgems/mruby-io/mrblib/io.rb', line 151

def pos
  raise IOError if closed?
  sysseek(0, SEEK_CUR) - @buf.bytesize
end

#pos=(i) ⇒ Object



157
158
159
# File 'mrbgems/mruby-io/mrblib/io.rb', line 157

def pos=(i)
  seek(i, SEEK_SET)
end


350
351
352
353
354
355
356
357
# File 'mrbgems/mruby-io/mrblib/io.rb', line 350

def print(*args)
  i = 0
  len = args.size
  while i < len
    write args[i].to_s
    i += 1
  end
end

#printf(*args) ⇒ Object



359
360
361
362
# File 'mrbgems/mruby-io/mrblib/io.rb', line 359

def printf(*args)
  write sprintf(*args)
  nil
end

#puts(*args) ⇒ Object



337
338
339
340
341
342
343
344
345
346
347
348
# File 'mrbgems/mruby-io/mrblib/io.rb', line 337

def puts(*args)
  i = 0
  len = args.size
  while i < len
    s = args[i].to_s
    write s
    write "\n" if (s[-1] != "\n")
    i += 1
  end
  write "\n" if len == 0
  nil
end

#read(length = nil, outbuf = "") ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'mrbgems/mruby-io/mrblib/io.rb', line 192

def read(length = nil, outbuf = "")
  unless length.nil?
    unless length.is_a? Fixnum
      raise TypeError.new "can't convert #{length.class} into Integer"
    end
    if length < 0
      raise ArgumentError.new "negative length: #{length} given"
    end
    if length == 0
      return ""   # easy case
    end
  end

  array = []
  while 1
    begin
      _read_buf
    rescue EOFError
      array = nil if array.empty? and (not length.nil?) and length != 0
      break
    end

    if length
      consume = (length <= @buf.bytesize) ? length : @buf.bytesize
      array.push IO._bufread(@buf, consume)
      length -= consume
      break if length == 0
    else
      array.push @buf
      @buf = ''
    end
  end

  if array.nil?
    outbuf.replace("")
    nil
  else
    outbuf.replace(array.join)
  end
end

#readcharObject



289
290
291
292
293
294
# File 'mrbgems/mruby-io/mrblib/io.rb', line 289

def readchar
  _read_buf
  c = @buf[0]
  @buf[0] = ""
  c
end

#readline(arg = "\n", limit = nil) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'mrbgems/mruby-io/mrblib/io.rb', line 233

def readline(arg = "\n", limit = nil)
  case arg
  when String
    rs = arg
  when Fixnum
    rs = "\n"
    limit = arg
  else
    raise ArgumentError
  end

  if rs.nil?
    return read
  end

  if rs == ""
    rs = "\n\n"
  end

  array = []
  while 1
    begin
      _read_buf
    rescue EOFError
      array = nil if array.empty?
      break
    end

    if limit && limit <= @buf.size
      array.push @buf[0, limit]
      @buf[0, limit] = ""
      break
    elsif idx = @buf.index(rs)
      len = idx + rs.size
      array.push @buf[0, len]
      @buf[0, len] = ""
      break
    else
      array.push @buf
      @buf = ''
    end
  end

  raise EOFError.new "end of file reached" if array.nil?

  array.join
end

#readlinesObject



329
330
331
332
333
334
335
# File 'mrbgems/mruby-io/mrblib/io.rb', line 329

def readlines
  ary = []
  while (line = gets)
    ary << line
  end
  ary
end

#rewindObject



161
162
163
# File 'mrbgems/mruby-io/mrblib/io.rb', line 161

def rewind
  seek(0, SEEK_SET)
end

#seek(i, whence = SEEK_SET) ⇒ Object

Raises:



165
166
167
168
169
170
# File 'mrbgems/mruby-io/mrblib/io.rb', line 165

def seek(i, whence = SEEK_SET)
  raise IOError if closed?
  sysseek(i, whence)
  @buf = ''
  0
end

#syncObject



1286
1287
1288
1289
1290
1291
1292
# File 'mrbgems/mruby-io/src/io.c', line 1286

mrb_value
mrb_io_sync(mrb_state *mrb, mrb_value self)
{
  struct mrb_io *fptr;
  fptr = io_get_open_fptr(mrb, self);
  return mrb_bool_value(fptr->sync);
}

#sync=Object



1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
# File 'mrbgems/mruby-io/src/io.c', line 1274

mrb_value
mrb_io_set_sync(mrb_state *mrb, mrb_value self)
{
  struct mrb_io *fptr;
  mrb_bool b;

  fptr = io_get_open_fptr(mrb, self);
  mrb_get_args(mrb, "b", &b);
  fptr->sync = b;
  return mrb_bool_value(b);
}

#sysreadObject



818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
# File 'mrbgems/mruby-io/src/io.c', line 818

mrb_value
mrb_io_sysread(mrb_state *mrb, mrb_value io)
{
  struct mrb_io *fptr;
  mrb_value buf = mrb_nil_value();
  mrb_int maxlen;
  int ret;

  mrb_get_args(mrb, "i|S", &maxlen, &buf);
  if (maxlen < 0) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative expanding string size");
  }
  else if (maxlen == 0) {
    return mrb_str_new(mrb, NULL, maxlen);
  }

  if (mrb_nil_p(buf)) {
    buf = mrb_str_new(mrb, NULL, maxlen);
  }

  if (RSTRING_LEN(buf) != maxlen) {
    buf = mrb_str_resize(mrb, buf, maxlen);
  } else {
    mrb_str_modify(mrb, RSTRING(buf));
  }

  fptr = (struct mrb_io *)io_get_open_fptr(mrb, io);
  if (!fptr->readable) {
    mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
  }
  ret = read(fptr->fd, RSTRING_PTR(buf), (fsize_t)maxlen);
  switch (ret) {
    case 0: /* EOF */
      if (maxlen == 0) {
        buf = mrb_str_new_cstr(mrb, "");
      } else {
        mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File");
      }
      break;
    case -1: /* Error */
      mrb_sys_fail(mrb, "sysread failed");
      break;
    default:
      if (RSTRING_LEN(buf) != ret) {
        buf = mrb_str_resize(mrb, buf, ret);
      }
      break;
  }

  return buf;
}

#sysseekObject



870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
# File 'mrbgems/mruby-io/src/io.c', line 870

mrb_value
mrb_io_sysseek(mrb_state *mrb, mrb_value io)
{
  struct mrb_io *fptr;
  off_t pos;
  mrb_int offset, whence = -1;

  mrb_get_args(mrb, "i|i", &offset, &whence);
  if (whence < 0) {
    whence = 0;
  }

  fptr = io_get_open_fptr(mrb, io);
  pos = lseek(fptr->fd, (off_t)offset, (int)whence);
  if (pos == -1) {
    mrb_sys_fail(mrb, "sysseek");
  }
  if (pos > MRB_INT_MAX) {
#ifndef MRB_WITHOUT_FLOAT
    return mrb_float_value(mrb, (mrb_float)pos);
#else
    mrb_raise(mrb, E_IO_ERROR, "sysseek reached too far for MRB_WITHOUT_FLOAT");
#endif
  } else {
    return mrb_fixnum_value(pos);
  }
}

#syswriteObject



898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
# File 'mrbgems/mruby-io/src/io.c', line 898

mrb_value
mrb_io_syswrite(mrb_state *mrb, mrb_value io)
{
  struct mrb_io *fptr;
  mrb_value str, buf;
  int fd, length;

  fptr = io_get_open_fptr(mrb, io);
  if (! fptr->writable) {
    mrb_raise(mrb, E_IO_ERROR, "not opened for writing");
  }

  mrb_get_args(mrb, "S", &str);
  buf = str;

  if (fptr->fd2 == -1) {
    fd = fptr->fd;
  } else {
    fd = fptr->fd2;
  }
  length = write(fd, RSTRING_PTR(buf), (fsize_t)RSTRING_LEN(buf));
  if (length == -1) {
    mrb_sys_fail(mrb, 0);
  }

  return mrb_fixnum_value(length);
}

#ungetc(substr) ⇒ Object



182
183
184
185
186
187
188
189
190
# File 'mrbgems/mruby-io/mrblib/io.rb', line 182

def ungetc(substr)
  raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String)
  if @buf.empty?
    @buf = substr.dup
  else
    @buf = substr + @buf
  end
  nil
end

#write(string) ⇒ Object



124
125
126
127
128
129
130
131
132
133
# File 'mrbgems/mruby-io/mrblib/io.rb', line 124

def write(string)
  str = string.is_a?(String) ? string : string.to_s
  return 0 if str.empty?
  unless @buf.empty?
    # reset real pos ignore buf
    seek(pos, SEEK_SET)
  end
  len = syswrite(str)
  len
end