Module: QIO::BaseIO
- Included in:
- QueuedInputIO
- Defined in:
- lib/qio/base_io.rb
Overview
Classes that want to mimic IO can acqire much of its functionality simply by including this module and over-riding the following methods:
close
closed?
eof?
sysread(maxlen, outbuf=nil)
sysseek(offset, whence=IO::SEEK_SET)
syswrite(string)
The following methds are not provided. If you know what you’re doing, and you know that you’re going to need it, you may also over-ride:
autoclose=(bool)
autoclose?
close_on_exec=(bool)
close_on_exec?
close_read
close_write
fcntl(integer_cmd, arg)
fileno
flush
fsync
ioctl(integer_cmd, arg)
pid
reopen(other_io_or_path, mode_str=nil)
stat
sync
sync=(bool)
ungetbyte(string_or_integer)
ungetc(string)
You get all the following for free, but if that’s not good enough for you, and you’re sure you can do better, you may over-ride:
<<(obj)
advise(advice, offset=0, len=0)
binmode #TODO!
binmode? #TODO!
bytes
chars
codepoints
each
each_byte
each_char
each_codepoint
each_line
eof
external_encoding #TODO!
fdatasync
getbyte
getc #TODO!
gets(sep=$/, limit=nil)
internal_encoding #TODO!
isatty
lineno
lineno=(lineno)
lines(sep=$/, limit=nil)
pos
pos=(pos)
print(*args)
printf(format_string, *args)
putc(obj)
puts(*args)
read(length=nil, buffer=nil)
read_nonblock(maxlen, outbuf=nil)
readbyte
reachar
readline(sep=$/, limit=nil)
readlines(sep=$/, limit=nil)
readpartial(maxlen, outbuf=nil)
rewind
seek(amount, whence=IO::SEEK_SET)
set_encoding(ext_enc, int_enc=nil, opt=nil) #TODO!
tell
to_i # if you defined fileno
tty?
write(string)
write_nonblock(string)
Instance Method Summary collapse
-
#<<(obj) ⇒ Object
Implementation relies on: write.
-
#advise(advice, offset = 0, len = 0) ⇒ Object
No-op.
-
#autoclose=(bool) ⇒ Object
NotImplementedError.
-
#autoclose? ⇒ Boolean
NotImplementedError.
-
#binmode ⇒ Object
TODO: Implement binmode.
-
#binmode? ⇒ Boolean
TODO: Implement: binmode?.
-
#bytes ⇒ Object
(also: #each_byte)
Implementation relies on: getbyte.
-
#chars ⇒ Object
(also: #each_char)
Implementation relies on: getc.
-
#close ⇒ Object
Over-ride me!.
-
#close_on_exec=(bool) ⇒ Object
NotImplementedError.
-
#close_on_exec? ⇒ Boolean
NotImplementedError.
-
#close_read ⇒ Object
NotImplementedError.
-
#close_write ⇒ Object
NotImplementedError.
-
#closed? ⇒ Boolean
Over-ride me!.
-
#codepoints ⇒ Object
(also: #each_codepoint)
Implementation relies on: getc.
-
#eof? ⇒ Boolean
(also: #eof)
Over-ride me!.
-
#external_encoding ⇒ Object
TODO: Implement external_encoding.
-
#fcntl(integer_cmd, arg) ⇒ Object
NotImplementedError.
-
#fdatasync ⇒ Object
Implementation relies on: fsync.
-
#fileno ⇒ Object
(also: #to_i)
NotImplementedError.
-
#flush ⇒ Object
NotImplementedError.
-
#fsync ⇒ Object
NotImplementedError.
-
#getbyte ⇒ Object
Implementation relies on: read.
-
#getc ⇒ Object
TODO: Implement getc (probably need to know about encoding conversions first).
-
#gets(sep = $/, limit = nil) ⇒ Object
Implementation relies on: getc TODO: Maybe it should rely on getbyte instead, so we don’t read too many bytes on accident.
-
#internal_encoding ⇒ Object
TODO: Implement internal_encoding.
-
#ioctl(integer_cmd, arg) ⇒ Object
NotImplementedError.
-
#isatty ⇒ Object
(also: #tty?)
Always returns false.
-
#lineno ⇒ Object
Implementation relies on gets to properly keep this up-to-date.
- #lineno=(lineno) ⇒ Object
-
#lines(sep = $/, limit = nil) ⇒ Object
(also: #each, #each_line)
Implementation relies on: gets.
-
#pid ⇒ Object
NotImplementedError.
-
#pos ⇒ Object
(also: #tell)
Subclass is responsible for keeping pos up-to-date!.
-
#pos=(pos) ⇒ Object
Subclass is responsible for keeping pos up-to-date!.
-
#print(*args) ⇒ Object
Implementation relies on write.
-
#printf(format_string, *args) ⇒ Object
Implementation relies on print.
-
#putc(obj) ⇒ Object
Implementation relies on write.
- #puts(*args) ⇒ Object
- #read(length = nil, buffer = nil) ⇒ Object
- #read_nonblock(maxlen, outbuf = nil) ⇒ Object
-
#readbyte ⇒ Object
Implementation relies on getbyte.
-
#readchar ⇒ Object
Implementation relies on: getc.
-
#readline(sep = $/, limit = nil) ⇒ Object
Implementation relies on: gets.
-
#readlines(sep = $/, limit = nil) ⇒ Object
Implementation relies on: gets.
-
#readpartial(maxlen, outbuf = nil) ⇒ Object
Implementation relies on: read_nonblock.
-
#reopen(other_io_or_path, mode_str = nil) ⇒ Object
NotImplementedError.
-
#rewind ⇒ Object
Implementation relies on: seek.
-
#seek(amount, whence = IO::SEEK_SET) ⇒ Object
Implementation relies on: sysseek.
-
#set_encoding(ext_enc, int_enc = nil, opt = nil) ⇒ Object
TODO: Implement set_encoding.
-
#stat ⇒ Object
NotImplementedError.
-
#sync ⇒ Object
NotImplementedError.
-
#sync=(bool) ⇒ Object
NotImplementedError.
-
#sysread(maxlen, outbuf = nil) ⇒ Object
Over-ride me! Remember to count bytes, not chars.
-
#sysseek(offset, whence = IO::SEEK_SET) ⇒ Object
Over-ride me! Remember to count bytes, not chars.
-
#syswrite(string) ⇒ Object
Over-ride me! Remember to count bytes, not chars.
-
#ungetbyte(string_or_integer) ⇒ Object
NotImplementedError.
-
#ungetc(string) ⇒ Object
NotImplementedError.
-
#write(string) ⇒ Object
Implementation relies on: write_nonblock.
-
#write_nonblock(string) ⇒ Object
Implementation relies on: syswrite.
Instance Method Details
#<<(obj) ⇒ Object
Implementation relies on: write
88 89 90 91 |
# File 'lib/qio/base_io.rb', line 88 def <<(obj) write(obj.to_s) self end |
#advise(advice, offset = 0, len = 0) ⇒ Object
No-op
94 |
# File 'lib/qio/base_io.rb', line 94 def advise(advice, offset=0, len=0); end |
#autoclose=(bool) ⇒ Object
NotImplementedError
97 98 99 |
# File 'lib/qio/base_io.rb', line 97 def autoclose=(bool) raise NotImplementedError end |
#autoclose? ⇒ Boolean
NotImplementedError
102 103 104 |
# File 'lib/qio/base_io.rb', line 102 def autoclose? raise NotImplementedError end |
#binmode ⇒ Object
TODO: Implement binmode.
107 108 |
# File 'lib/qio/base_io.rb', line 107 def binmode end |
#binmode? ⇒ Boolean
TODO: Implement: binmode?
111 112 113 |
# File 'lib/qio/base_io.rb', line 111 def binmode? true end |
#bytes ⇒ Object Also known as: each_byte
Implementation relies on: getbyte
116 117 118 119 120 121 |
# File 'lib/qio/base_io.rb', line 116 def bytes return to_enum :bytes unless block_given? while b = getbyte yield b end end |
#chars ⇒ Object Also known as: each_char
Implementation relies on: getc
125 126 127 128 129 130 |
# File 'lib/qio/base_io.rb', line 125 def chars return to_enum :chars unless block_given? while c = getc yield c end end |
#close ⇒ Object
Over-ride me!
134 135 136 |
# File 'lib/qio/base_io.rb', line 134 def close raise NotImplementedError, "Subclass should over-ride!" end |
#close_on_exec=(bool) ⇒ Object
NotImplementedError
139 140 141 |
# File 'lib/qio/base_io.rb', line 139 def close_on_exec=(bool) raise NotImplementedError end |
#close_on_exec? ⇒ Boolean
NotImplementedError
144 145 146 |
# File 'lib/qio/base_io.rb', line 144 def close_on_exec? raise NotImplementedError end |
#close_read ⇒ Object
NotImplementedError
149 150 151 |
# File 'lib/qio/base_io.rb', line 149 def close_read raise NotImplementedError end |
#close_write ⇒ Object
NotImplementedError
154 155 156 |
# File 'lib/qio/base_io.rb', line 154 def close_write raise NotImplementedError end |
#closed? ⇒ Boolean
Over-ride me!
159 160 161 |
# File 'lib/qio/base_io.rb', line 159 def closed? raise NotImplementedError, "Subclass should over-ride!" end |
#codepoints ⇒ Object Also known as: each_codepoint
Implementation relies on: getc
164 165 166 167 168 169 170 171 |
# File 'lib/qio/base_io.rb', line 164 def codepoints return to_enum :codepoints unless block_given? while c = getc c.codepoints.each do |cp| yield cp end end end |
#eof? ⇒ Boolean Also known as: eof
Over-ride me!
175 176 177 |
# File 'lib/qio/base_io.rb', line 175 def eof? raise NotImplementedError, "Subclass should over-ride!" end |
#external_encoding ⇒ Object
TODO: Implement external_encoding
181 182 183 |
# File 'lib/qio/base_io.rb', line 181 def external_encoding raise NotImplementedError end |
#fcntl(integer_cmd, arg) ⇒ Object
NotImplementedError
186 187 188 |
# File 'lib/qio/base_io.rb', line 186 def fcntl(integer_cmd, arg) raise NotImplementedError end |
#fdatasync ⇒ Object
Implementation relies on: fsync
191 192 193 |
# File 'lib/qio/base_io.rb', line 191 def fdatasync fsync end |
#fileno ⇒ Object Also known as: to_i
NotImplementedError
196 197 198 |
# File 'lib/qio/base_io.rb', line 196 def fileno raise NotImplementedError end |
#flush ⇒ Object
NotImplementedError
202 203 204 |
# File 'lib/qio/base_io.rb', line 202 def flush raise NotImplementedError end |
#fsync ⇒ Object
NotImplementedError
207 208 209 |
# File 'lib/qio/base_io.rb', line 207 def fsync raise NotImplementedError end |
#getbyte ⇒ Object
Implementation relies on: read
212 213 214 |
# File 'lib/qio/base_io.rb', line 212 def getbyte read(1) end |
#getc ⇒ Object
TODO: Implement getc (probably need to know about encoding conversions first)
217 218 219 |
# File 'lib/qio/base_io.rb', line 217 def getc raise NotImplementedError end |
#gets(sep = $/, limit = nil) ⇒ Object
Implementation relies on: getc TODO: Maybe it should rely on getbyte instead, so we don’t read too many bytes on accident.
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/qio/base_io.rb', line 223 def gets(sep=$/, limit=nil) return nil if eof? if limit.nil? && sep.is_a?(Integer) #TODO: compare this logic with ::IO#getc limit = sep.to_i sep = $/ end if !limit.nil? && limit < 0 raise ArgumentError, ('negative limit %1d given' % limit) end sep = "\n\n" if sep == "" line = "" while (c = getc) line << c break if !sep.nil? && line.end_with?(sep) break if !limit.nil? && line.bytesize >= limit end if !limit.nil? && limit >= 0 && line.bytesize > limit leftovers = line.byteslice(limit .. -1) #TODO: what should we do with this? line = line.byteslice(0,limit) end $. = (lineno += 1) $_ = line end |
#internal_encoding ⇒ Object
TODO: Implement internal_encoding
248 249 250 |
# File 'lib/qio/base_io.rb', line 248 def internal_encoding raise NotImplementedError end |
#ioctl(integer_cmd, arg) ⇒ Object
NotImplementedError
253 254 255 |
# File 'lib/qio/base_io.rb', line 253 def ioctl(integer_cmd, arg) raise NotImplementedError end |
#isatty ⇒ Object Also known as: tty?
Always returns false
258 259 260 |
# File 'lib/qio/base_io.rb', line 258 def isatty false end |
#lineno ⇒ Object
Implementation relies on gets to properly keep this up-to-date.
264 265 266 |
# File 'lib/qio/base_io.rb', line 264 def lineno @lineno || uninitialized! end |
#lineno=(lineno) ⇒ Object
268 269 270 |
# File 'lib/qio/base_io.rb', line 268 def lineno=(lineno) @lineno = lineno end |
#lines(sep = $/, limit = nil) ⇒ Object Also known as: each, each_line
Implementation relies on: gets
273 274 275 276 277 278 |
# File 'lib/qio/base_io.rb', line 273 def lines(sep=$/, limit=nil) return to_enum :lines unless block_given? while s = gets yield s end end |
#pid ⇒ Object
NotImplementedError
283 284 285 |
# File 'lib/qio/base_io.rb', line 283 def pid raise NotImplementedError end |
#pos ⇒ Object Also known as: tell
Subclass is responsible for keeping pos up-to-date!
288 289 290 |
# File 'lib/qio/base_io.rb', line 288 def pos @pos || uninitialized! end |
#pos=(pos) ⇒ Object
Subclass is responsible for keeping pos up-to-date!
294 295 296 |
# File 'lib/qio/base_io.rb', line 294 def pos=(pos) @pos = pos end |
#print(*args) ⇒ Object
Implementation relies on write.
299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/qio/base_io.rb', line 299 def print(*args) args = [$_] if args.size == 0 first_one = true args.each do |obj| write(obj.to_s) write($,) unless first_one || $,.nil? first_one = false end write($\) unless $\.nil? nil end |
#printf(format_string, *args) ⇒ Object
Implementation relies on print.
312 313 314 |
# File 'lib/qio/base_io.rb', line 312 def printf(format_string, *args) print(Kernel.sprintf(format_string, *args)) end |
#putc(obj) ⇒ Object
Implementation relies on write.
317 318 319 320 321 322 323 |
# File 'lib/qio/base_io.rb', line 317 def putc(obj) if obj.is_a?(Numeric) write((obj.to_i & 0xff).chr) else write(obj.to_s.byteslice(0)) end end |
#puts(*args) ⇒ Object
325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/qio/base_io.rb', line 325 def puts(*args) if args.size == 0 write("\n") else args.flatten.each do |line| line = line.to_s write(line) write("\n") unless line.end_with?("\n") end end nil end |
#read(length = nil, buffer = nil) ⇒ Object
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/qio/base_io.rb', line 338 def read(length=nil, buffer=nil) if !length.nil? && length < 0 raise ArgumentError, ('negative length %1d given' % length) end buffer = buffer.nil? ? "" : buffer.replace("") if length.nil? begin buffer << readpartial until eof? rescue EOFError end # TODO: Apply encoding conversion to buffer. buffer elsif length == 0 buffer else begin while buffer.bytesize < length && !eof? buffer << readpartial(length - buffer.bytesize) # TODO: Code Review - result should be ASCII-8BIT. Is it? end rescue EOFError end buffer.empty? ? nil : buffer end end |
#read_nonblock(maxlen, outbuf = nil) ⇒ Object
365 366 367 368 369 |
# File 'lib/qio/base_io.rb', line 365 def read_nonblock(maxlen, outbuf=nil) nonblock_readable do sysread(maxlen, outbuff) end end |
#readbyte ⇒ Object
Implementation relies on getbyte
372 373 374 |
# File 'lib/qio/base_io.rb', line 372 def readbyte getbyte || raise(EOFError) end |
#readchar ⇒ Object
Implementation relies on: getc
377 378 379 |
# File 'lib/qio/base_io.rb', line 377 def readchar getc || raise(EOFError) end |
#readline(sep = $/, limit = nil) ⇒ Object
Implementation relies on: gets
382 383 384 |
# File 'lib/qio/base_io.rb', line 382 def readline(sep=$/, limit=nil) gets(sep, limit) || raise(EOFError) end |
#readlines(sep = $/, limit = nil) ⇒ Object
Implementation relies on: gets
387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/qio/base_io.rb', line 387 def readlines(sep=$/, limit=nil) result = [] loop do if (line = gets(sep, limit)) break else result << line end end result end |
#readpartial(maxlen, outbuf = nil) ⇒ Object
Implementation relies on: read_nonblock
400 401 402 403 404 405 |
# File 'lib/qio/base_io.rb', line 400 def readpartial(maxlen, outbuf=nil) read_nonblock(maxlen, outbuf) rescue IO::WaitReadable block_until_readable retry end |
#reopen(other_io_or_path, mode_str = nil) ⇒ Object
NotImplementedError
408 409 410 |
# File 'lib/qio/base_io.rb', line 408 def reopen(other_io_or_path, mode_str=nil) raise NotImplementedError end |
#rewind ⇒ Object
Implementation relies on: seek
413 414 415 |
# File 'lib/qio/base_io.rb', line 413 def rewind seek(0) end |
#seek(amount, whence = IO::SEEK_SET) ⇒ Object
Implementation relies on: sysseek
418 419 420 |
# File 'lib/qio/base_io.rb', line 418 def seek(amount, whence=IO::SEEK_SET) sysseek(amount, whence) end |
#set_encoding(ext_enc, int_enc = nil, opt = nil) ⇒ Object
TODO: Implement set_encoding
423 424 425 |
# File 'lib/qio/base_io.rb', line 423 def set_encoding(ext_enc, int_enc=nil, opt=nil) raise NotImplementedError end |
#stat ⇒ Object
NotImplementedError
428 429 430 |
# File 'lib/qio/base_io.rb', line 428 def stat raise NotImplementedError end |
#sync ⇒ Object
NotImplementedError
433 434 435 |
# File 'lib/qio/base_io.rb', line 433 def sync raise NotImplementedError end |
#sync=(bool) ⇒ Object
NotImplementedError
438 439 440 |
# File 'lib/qio/base_io.rb', line 438 def sync=(bool) raise NotImplementedError end |
#sysread(maxlen, outbuf = nil) ⇒ Object
Over-ride me! Remember to count bytes, not chars. Remember to update pos. Remember to use consume_readable to wrap the atomic part of your update.
446 447 448 |
# File 'lib/qio/base_io.rb', line 446 def sysread(maxlen, outbuf=nil) raise NotImplementedError end |
#sysseek(offset, whence = IO::SEEK_SET) ⇒ Object
Over-ride me! Remember to count bytes, not chars. Remember to update pos.
453 454 455 |
# File 'lib/qio/base_io.rb', line 453 def sysseek(offset, whence=IO::SEEK_SET) raise NotImplementedError # TODO: provide best-effort implementation for sysseek end |
#syswrite(string) ⇒ Object
Over-ride me! Remember to count bytes, not chars. Remember to update pos. Remember to use consume_writable to wrap the atomic part of your update.
461 462 463 |
# File 'lib/qio/base_io.rb', line 461 def syswrite(string) raise NotImplementedError end |
#ungetbyte(string_or_integer) ⇒ Object
NotImplementedError
466 467 468 |
# File 'lib/qio/base_io.rb', line 466 def ungetbyte(string_or_integer) raise NotImplementedError end |
#ungetc(string) ⇒ Object
NotImplementedError
471 472 473 |
# File 'lib/qio/base_io.rb', line 471 def ungetc(string) raise NotImplementedError end |
#write(string) ⇒ Object
Implementation relies on: write_nonblock
476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/qio/base_io.rb', line 476 def write(string) written = 0 length = string.bytesize while written < length begin written += write_nonblock(string.byteslice(written, length - written)) rescue IO::WaitWritable, Errno::EINTR block_until_writable retry end end written end |
#write_nonblock(string) ⇒ Object
Implementation relies on: syswrite
491 492 493 494 495 |
# File 'lib/qio/base_io.rb', line 491 def write_nonblock(string) nonblock_writable do syswrite(string) end end |