rubysl-stringio 2.0.0 → 2.1
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 +4 -4
- data/.travis.yml +8 -4
- data/MRI_LICENSE +56 -0
- data/lib/rubysl/stringio.rb +1 -0
- data/lib/rubysl/stringio/version.rb +1 -1
- data/lib/stringio.rb +742 -1
- data/rubysl-stringio.gemspec +1 -0
- data/spec/codepoints_spec.rb +0 -1
- data/spec/each_codepoint_spec.rb +0 -1
- data/spec/external_encoding_spec.rb +0 -1
- data/spec/getc_spec.rb +0 -1
- data/spec/gets_spec.rb +2 -2
- data/spec/internal_encoding_spec.rb +0 -1
- data/spec/putc_spec.rb +0 -1
- data/spec/puts_spec.rb +0 -1
- data/spec/read_spec.rb +0 -1
- data/spec/set_encoding_spec.rb +5 -1
- data/spec/shared/read.rb +8 -8
- data/spec/ungetbyte_spec.rb +0 -1
- metadata +28 -14
- data/lib/rubysl/stringio/stringio.rb +0 -741
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9b77f8e9cdd0225371244cf238863376dbc7340
|
4
|
+
data.tar.gz: 104eda2562feb6b7e27608046b7b2786d86ce8f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c333dea3b14ba64a76d94c934f316f7afb18a2cb3b88112b9d95e205a1df17099821c3631f59e5ffa81791131d2ad91cc9b48ccc36aa9fd553ba229c84f76329
|
7
|
+
data.tar.gz: b686ef987c87441e1a13c1f290f73c4fde5ff8c50f0548448fd06e27cca44b215d1426aa39e6e2efb4d98b26b8a8cbce449ce3fa0c2570fdb3b663a49e4f09b9
|
data/.travis.yml
CHANGED
data/MRI_LICENSE
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the
|
3
|
+
2-clause BSDL (see the file BSDL), or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) give non-standard binaries non-standard names, with
|
21
|
+
instructions on where to get the original software distribution.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or binary form,
|
26
|
+
provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the binaries and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard binaries non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under these terms.
|
43
|
+
|
44
|
+
For the list of those files and their copying conditions, see the
|
45
|
+
file LEGAL.
|
46
|
+
|
47
|
+
5. The scripts and library files supplied as input to or produced as
|
48
|
+
output from the software do not automatically fall under the
|
49
|
+
copyright of the software, but belong to whomever generated them,
|
50
|
+
and may be sold commercially, and may be aggregated with this
|
51
|
+
software.
|
52
|
+
|
53
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
54
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
55
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
56
|
+
PURPOSE.
|
data/lib/rubysl/stringio.rb
CHANGED
data/lib/stringio.rb
CHANGED
@@ -1 +1,742 @@
|
|
1
|
-
|
1
|
+
class IO
|
2
|
+
module Writable
|
3
|
+
end
|
4
|
+
module Readable
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class StringIO
|
9
|
+
|
10
|
+
include Enumerable
|
11
|
+
include IO::Writable
|
12
|
+
include IO::Readable
|
13
|
+
|
14
|
+
DEFAULT_RECORD_SEPARATOR = "\n" unless defined?(::DEFAULT_RECORD_SEPARATOR)
|
15
|
+
|
16
|
+
# This is why we need undefined in Ruby
|
17
|
+
Undefined = Object.new
|
18
|
+
|
19
|
+
class Data
|
20
|
+
attr_accessor :string, :pos, :lineno, :encoding
|
21
|
+
|
22
|
+
def initialize(string)
|
23
|
+
@string = string
|
24
|
+
@encoding = string.encoding
|
25
|
+
@pos = @lineno = 0
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.open(*args)
|
30
|
+
io = new(*args)
|
31
|
+
return io unless block_given?
|
32
|
+
|
33
|
+
begin
|
34
|
+
yield io
|
35
|
+
ensure
|
36
|
+
io.close
|
37
|
+
io.__data__.string = nil
|
38
|
+
self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :__data__
|
43
|
+
|
44
|
+
def initialize(string=nil, mode=nil)
|
45
|
+
if string.nil?
|
46
|
+
@__data__ = Data.new ""
|
47
|
+
set_encoding(nil)
|
48
|
+
mode = IO::RDWR
|
49
|
+
else
|
50
|
+
string = Rubinius::Type.coerce_to string, String, :to_str
|
51
|
+
@__data__ = Data.new string
|
52
|
+
end
|
53
|
+
|
54
|
+
if mode
|
55
|
+
if mode.is_a?(Integer)
|
56
|
+
mode_from_integer(mode)
|
57
|
+
else
|
58
|
+
mode = StringValue(mode)
|
59
|
+
mode_from_string(mode)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
mode_from_string(string.frozen? ? "r" : "r+")
|
63
|
+
end
|
64
|
+
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def initialize_copy(from)
|
69
|
+
from = Rubinius::Type.coerce_to(from, StringIO, :to_strio)
|
70
|
+
|
71
|
+
taint if from.tainted?
|
72
|
+
|
73
|
+
@append = from.instance_variable_get(:@append)
|
74
|
+
@readable = from.instance_variable_get(:@readable)
|
75
|
+
@writable = from.instance_variable_get(:@writable)
|
76
|
+
@__data__ = from.instance_variable_get(:@__data__)
|
77
|
+
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
def check_readable
|
82
|
+
raise IOError, "not opened for reading" unless @readable
|
83
|
+
end
|
84
|
+
|
85
|
+
private :check_readable
|
86
|
+
|
87
|
+
def check_writable
|
88
|
+
raise IOError, "not opened for writing" unless @writable
|
89
|
+
raise IOError, "unable to modify data" if @__data__.string.frozen?
|
90
|
+
end
|
91
|
+
|
92
|
+
private :check_writable
|
93
|
+
|
94
|
+
def set_encoding(external, internal=nil, options=nil)
|
95
|
+
encoding = external || Encoding.default_external
|
96
|
+
@__data__.encoding = encoding
|
97
|
+
@__data__.string.force_encoding(encoding)
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
def external_encoding
|
102
|
+
@__data__.encoding
|
103
|
+
end
|
104
|
+
|
105
|
+
def internal_encoding
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
|
109
|
+
def each_byte
|
110
|
+
return to_enum :each_byte unless block_given?
|
111
|
+
check_readable
|
112
|
+
|
113
|
+
d = @__data__
|
114
|
+
string = d.string
|
115
|
+
|
116
|
+
while d.pos < string.length
|
117
|
+
byte = string.getbyte d.pos
|
118
|
+
d.pos += 1
|
119
|
+
yield byte
|
120
|
+
end
|
121
|
+
|
122
|
+
self
|
123
|
+
end
|
124
|
+
|
125
|
+
alias_method :bytes, :each_byte
|
126
|
+
|
127
|
+
def each_char
|
128
|
+
return to_enum :each_char unless block_given?
|
129
|
+
while s = getc
|
130
|
+
yield s
|
131
|
+
end
|
132
|
+
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
alias_method :chars, :each_char
|
137
|
+
|
138
|
+
def each_codepoint(&block)
|
139
|
+
return to_enum :each_codepoint unless block_given?
|
140
|
+
check_readable
|
141
|
+
|
142
|
+
d = @__data__
|
143
|
+
string = d.string
|
144
|
+
|
145
|
+
while d.pos < string.bytesize
|
146
|
+
char = string.chr_at d.pos
|
147
|
+
|
148
|
+
unless char
|
149
|
+
raise ArgumentError, "invalid byte sequence in #{d.encoding}"
|
150
|
+
end
|
151
|
+
|
152
|
+
d.pos += char.bytesize
|
153
|
+
yield char.ord
|
154
|
+
end
|
155
|
+
|
156
|
+
self
|
157
|
+
end
|
158
|
+
|
159
|
+
alias_method :codepoints, :each_codepoint
|
160
|
+
|
161
|
+
def each(sep=$/, limit=Undefined)
|
162
|
+
return to_enum :each, sep, limit unless block_given?
|
163
|
+
check_readable
|
164
|
+
|
165
|
+
while line = getline(true, sep, limit)
|
166
|
+
yield line
|
167
|
+
end
|
168
|
+
|
169
|
+
self
|
170
|
+
end
|
171
|
+
|
172
|
+
alias_method :each_line, :each
|
173
|
+
alias_method :lines, :each
|
174
|
+
|
175
|
+
def <<(str)
|
176
|
+
write(str)
|
177
|
+
self
|
178
|
+
end
|
179
|
+
|
180
|
+
def binmode
|
181
|
+
self
|
182
|
+
end
|
183
|
+
|
184
|
+
def write(str)
|
185
|
+
check_writable
|
186
|
+
|
187
|
+
str = String(str)
|
188
|
+
return 0 if str.empty?
|
189
|
+
|
190
|
+
d = @__data__
|
191
|
+
pos = d.pos
|
192
|
+
string = d.string
|
193
|
+
|
194
|
+
if @append || pos == string.bytesize
|
195
|
+
string.byte_append str
|
196
|
+
d.pos = string.bytesize
|
197
|
+
elsif pos > string.bytesize
|
198
|
+
m = Rubinius::Mirror.reflect string
|
199
|
+
m.splice string.bytesize, 0, "\000" * (pos - string.bytesize)
|
200
|
+
string.byte_append str
|
201
|
+
d.pos = string.bytesize
|
202
|
+
else
|
203
|
+
stop = string.bytesize - pos
|
204
|
+
if str.bytesize < stop
|
205
|
+
stop = str.bytesize
|
206
|
+
end
|
207
|
+
m = Rubinius::Mirror.reflect string
|
208
|
+
m.splice pos, stop, str
|
209
|
+
d.pos += str.bytesize
|
210
|
+
string.taint if str.tainted?
|
211
|
+
end
|
212
|
+
|
213
|
+
str.bytesize
|
214
|
+
end
|
215
|
+
alias_method :syswrite, :write
|
216
|
+
alias_method :write_nonblock, :write
|
217
|
+
|
218
|
+
def close
|
219
|
+
raise IOError, "closed stream" if closed?
|
220
|
+
@readable = @writable = nil
|
221
|
+
end
|
222
|
+
|
223
|
+
def closed?
|
224
|
+
!@readable && !@writable
|
225
|
+
end
|
226
|
+
|
227
|
+
def close_read
|
228
|
+
check_readable
|
229
|
+
@readable = nil
|
230
|
+
end
|
231
|
+
|
232
|
+
def closed_read?
|
233
|
+
!@readable
|
234
|
+
end
|
235
|
+
|
236
|
+
def close_write
|
237
|
+
check_writable
|
238
|
+
@writable = nil
|
239
|
+
end
|
240
|
+
|
241
|
+
def closed_write?
|
242
|
+
!@writable
|
243
|
+
end
|
244
|
+
|
245
|
+
def eof?
|
246
|
+
d = @__data__
|
247
|
+
d.pos >= d.string.bytesize
|
248
|
+
end
|
249
|
+
alias_method :eof, :eof?
|
250
|
+
|
251
|
+
def fcntl
|
252
|
+
raise NotImplementedError, "StringIO#fcntl is not implemented"
|
253
|
+
end
|
254
|
+
|
255
|
+
def fileno
|
256
|
+
nil
|
257
|
+
end
|
258
|
+
|
259
|
+
def flush
|
260
|
+
self
|
261
|
+
end
|
262
|
+
|
263
|
+
def fsync
|
264
|
+
0
|
265
|
+
end
|
266
|
+
|
267
|
+
def getc
|
268
|
+
check_readable
|
269
|
+
d = @__data__
|
270
|
+
|
271
|
+
return nil if eof?
|
272
|
+
|
273
|
+
char = d.string.find_character(d.pos)
|
274
|
+
d.pos += char.bytesize
|
275
|
+
char
|
276
|
+
end
|
277
|
+
|
278
|
+
def getbyte
|
279
|
+
check_readable
|
280
|
+
d = @__data__
|
281
|
+
|
282
|
+
return nil if eof?
|
283
|
+
|
284
|
+
byte = d.string.getbyte(d.pos)
|
285
|
+
d.pos += 1
|
286
|
+
byte
|
287
|
+
end
|
288
|
+
|
289
|
+
def gets(sep=$/, limit=Undefined)
|
290
|
+
check_readable
|
291
|
+
|
292
|
+
$_ = getline(false, sep, limit)
|
293
|
+
end
|
294
|
+
|
295
|
+
def isatty
|
296
|
+
false
|
297
|
+
end
|
298
|
+
alias_method :tty?, :isatty
|
299
|
+
|
300
|
+
def lineno
|
301
|
+
@__data__.lineno
|
302
|
+
end
|
303
|
+
|
304
|
+
def lineno=(line)
|
305
|
+
@__data__.lineno = line
|
306
|
+
end
|
307
|
+
|
308
|
+
def pid
|
309
|
+
nil
|
310
|
+
end
|
311
|
+
|
312
|
+
def pos
|
313
|
+
@__data__.pos
|
314
|
+
end
|
315
|
+
|
316
|
+
def pos=(pos)
|
317
|
+
raise Errno::EINVAL if pos < 0
|
318
|
+
@__data__.pos = pos
|
319
|
+
end
|
320
|
+
|
321
|
+
def print(*args)
|
322
|
+
check_writable
|
323
|
+
args << $_ if args.empty?
|
324
|
+
write((args << $\).flatten.join)
|
325
|
+
nil
|
326
|
+
end
|
327
|
+
|
328
|
+
def printf(*args)
|
329
|
+
check_writable
|
330
|
+
|
331
|
+
if args.size > 1
|
332
|
+
write(args.shift % args)
|
333
|
+
else
|
334
|
+
write(args.first)
|
335
|
+
end
|
336
|
+
|
337
|
+
nil
|
338
|
+
end
|
339
|
+
|
340
|
+
def putc(obj)
|
341
|
+
check_writable
|
342
|
+
|
343
|
+
if obj.is_a?(String)
|
344
|
+
char = obj[0]
|
345
|
+
else
|
346
|
+
c = Rubinius::Type.coerce_to obj, Integer, :to_int
|
347
|
+
char = (c & 0xff).chr
|
348
|
+
end
|
349
|
+
|
350
|
+
d = @__data__
|
351
|
+
pos = d.pos
|
352
|
+
string = d.string
|
353
|
+
|
354
|
+
if @append || pos == string.bytesize
|
355
|
+
string.byte_append char
|
356
|
+
d.pos = string.bytesize
|
357
|
+
elsif pos > string.bytesize
|
358
|
+
m = Rubinius::Mirror.reflect string
|
359
|
+
m.splice string.bytesize, 0, "\000" * (pos - string.bytesize)
|
360
|
+
string.byte_append char
|
361
|
+
d.pos = string.bytesize
|
362
|
+
else
|
363
|
+
m = Rubinius::Mirror.reflect string
|
364
|
+
m.splice pos, char.bytesize, char
|
365
|
+
d.pos += char.bytesize
|
366
|
+
end
|
367
|
+
|
368
|
+
obj
|
369
|
+
end
|
370
|
+
|
371
|
+
def puts(*args)
|
372
|
+
if args.empty?
|
373
|
+
write(DEFAULT_RECORD_SEPARATOR)
|
374
|
+
else
|
375
|
+
args.each do |arg|
|
376
|
+
if arg.nil?
|
377
|
+
line = ""
|
378
|
+
elsif Thread.guarding? arg
|
379
|
+
line = "[...]"
|
380
|
+
else
|
381
|
+
begin
|
382
|
+
arg = Rubinius::Type.coerce_to(arg, Array, :to_ary)
|
383
|
+
Thread.recursion_guard arg do
|
384
|
+
arg.each { |a| puts a }
|
385
|
+
end
|
386
|
+
next
|
387
|
+
rescue
|
388
|
+
line = arg.to_s
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
write(line)
|
393
|
+
write(DEFAULT_RECORD_SEPARATOR) unless line[-1] == ?\n
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
nil
|
398
|
+
end
|
399
|
+
|
400
|
+
def read(length=nil, buffer=nil)
|
401
|
+
check_readable
|
402
|
+
d = @__data__
|
403
|
+
pos = d.pos
|
404
|
+
string = d.string
|
405
|
+
|
406
|
+
if length
|
407
|
+
length = Rubinius::Type.coerce_to length, Integer, :to_int
|
408
|
+
raise ArgumentError if length < 0
|
409
|
+
|
410
|
+
buffer = StringValue(buffer) if buffer
|
411
|
+
|
412
|
+
if eof?
|
413
|
+
buffer.clear if buffer
|
414
|
+
if length == 0
|
415
|
+
return "".force_encoding(Encoding::ASCII_8BIT)
|
416
|
+
else
|
417
|
+
return nil
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
str = string.byteslice(pos, length)
|
422
|
+
str.force_encoding Encoding::ASCII_8BIT
|
423
|
+
|
424
|
+
str = buffer.replace(str) if buffer
|
425
|
+
else
|
426
|
+
if eof?
|
427
|
+
buffer.clear if buffer
|
428
|
+
return "".force_encoding(Encoding::ASCII_8BIT)
|
429
|
+
end
|
430
|
+
|
431
|
+
str = string.byteslice(pos..-1)
|
432
|
+
buffer.replace str if buffer
|
433
|
+
end
|
434
|
+
|
435
|
+
d.pos += str.length
|
436
|
+
return str
|
437
|
+
end
|
438
|
+
|
439
|
+
def readchar
|
440
|
+
raise IO::EOFError, "end of file reached" if eof?
|
441
|
+
getc
|
442
|
+
end
|
443
|
+
|
444
|
+
def readbyte
|
445
|
+
readchar.getbyte(0)
|
446
|
+
end
|
447
|
+
|
448
|
+
def readline(sep=$/, limit=Undefined)
|
449
|
+
check_readable
|
450
|
+
raise IO::EOFError, "end of file reached" if eof?
|
451
|
+
|
452
|
+
$_ = getline(true, sep, limit)
|
453
|
+
end
|
454
|
+
|
455
|
+
def readlines(sep=$/, limit=Undefined)
|
456
|
+
check_readable
|
457
|
+
|
458
|
+
ary = []
|
459
|
+
while line = getline(true, sep, limit)
|
460
|
+
ary << line
|
461
|
+
end
|
462
|
+
|
463
|
+
ary
|
464
|
+
end
|
465
|
+
|
466
|
+
def reopen(string=nil, mode=Undefined)
|
467
|
+
if string and not string.kind_of? String and mode.equal? Undefined
|
468
|
+
stringio = Rubinius::Type.coerce_to(string, StringIO, :to_strio)
|
469
|
+
|
470
|
+
taint if stringio.tainted?
|
471
|
+
initialize_copy stringio
|
472
|
+
else
|
473
|
+
mode = nil if mode.equal? Undefined
|
474
|
+
string = "" unless string
|
475
|
+
|
476
|
+
initialize string, mode
|
477
|
+
end
|
478
|
+
|
479
|
+
self
|
480
|
+
end
|
481
|
+
|
482
|
+
def rewind
|
483
|
+
d = @__data__
|
484
|
+
d.pos = d.lineno = 0
|
485
|
+
end
|
486
|
+
|
487
|
+
def seek(to, whence = IO::SEEK_SET)
|
488
|
+
raise IOError, "closed stream" if self.closed?
|
489
|
+
to = Rubinius::Type.coerce_to to, Integer, :to_int
|
490
|
+
|
491
|
+
case whence
|
492
|
+
when IO::SEEK_CUR
|
493
|
+
to += @__data__.pos
|
494
|
+
when IO::SEEK_END
|
495
|
+
to += @__data__.string.bytesize
|
496
|
+
when IO::SEEK_SET, nil
|
497
|
+
else
|
498
|
+
raise Errno::EINVAL, "invalid whence"
|
499
|
+
end
|
500
|
+
|
501
|
+
raise Errno::EINVAL if to < 0
|
502
|
+
|
503
|
+
@__data__.pos = to
|
504
|
+
|
505
|
+
return 0
|
506
|
+
end
|
507
|
+
|
508
|
+
def size
|
509
|
+
@__data__.string.bytesize
|
510
|
+
end
|
511
|
+
alias_method :length, :size
|
512
|
+
|
513
|
+
def string
|
514
|
+
@__data__.string
|
515
|
+
end
|
516
|
+
|
517
|
+
def string=(string)
|
518
|
+
d = @__data__
|
519
|
+
d.string = StringValue(string)
|
520
|
+
d.pos = 0
|
521
|
+
d.lineno = 0
|
522
|
+
end
|
523
|
+
|
524
|
+
def sync
|
525
|
+
true
|
526
|
+
end
|
527
|
+
|
528
|
+
def sync=(val)
|
529
|
+
val
|
530
|
+
end
|
531
|
+
|
532
|
+
def sysread(length=nil, buffer="")
|
533
|
+
str = read(length, buffer)
|
534
|
+
|
535
|
+
if str.nil?
|
536
|
+
buffer.clear
|
537
|
+
raise IO::EOFError, "end of file reached"
|
538
|
+
end
|
539
|
+
|
540
|
+
str
|
541
|
+
end
|
542
|
+
|
543
|
+
alias_method :readpartial, :sysread
|
544
|
+
alias_method :read_nonblock, :sysread
|
545
|
+
|
546
|
+
def tell
|
547
|
+
@__data__.pos
|
548
|
+
end
|
549
|
+
|
550
|
+
def truncate(length)
|
551
|
+
check_writable
|
552
|
+
len = Rubinius::Type.coerce_to length, Integer, :to_int
|
553
|
+
raise Errno::EINVAL, "negative length" if len < 0
|
554
|
+
string = @__data__.string
|
555
|
+
|
556
|
+
if len < string.bytesize
|
557
|
+
string[len..string.bytesize] = ""
|
558
|
+
else
|
559
|
+
string << "\000" * (len - string.bytesize)
|
560
|
+
end
|
561
|
+
return length
|
562
|
+
end
|
563
|
+
|
564
|
+
def ungetc(char)
|
565
|
+
check_readable
|
566
|
+
|
567
|
+
d = @__data__
|
568
|
+
pos = d.pos
|
569
|
+
string = d.string
|
570
|
+
|
571
|
+
if char.kind_of? Integer
|
572
|
+
char = Rubinius::Type.coerce_to char, String, :chr
|
573
|
+
else
|
574
|
+
char = Rubinius::Type.coerce_to char, String, :to_str
|
575
|
+
end
|
576
|
+
|
577
|
+
if pos > string.bytesize
|
578
|
+
string[string.bytesize..pos] = "\000" * (pos - string.bytesize)
|
579
|
+
d.pos -= 1
|
580
|
+
string[d.pos] = char
|
581
|
+
elsif pos > 0
|
582
|
+
d.pos -= 1
|
583
|
+
string[d.pos] = char
|
584
|
+
end
|
585
|
+
|
586
|
+
nil
|
587
|
+
end
|
588
|
+
|
589
|
+
def ungetbyte(bytes)
|
590
|
+
check_readable
|
591
|
+
|
592
|
+
return unless bytes
|
593
|
+
|
594
|
+
if bytes.kind_of? Fixnum
|
595
|
+
bytes = "" << bytes
|
596
|
+
else
|
597
|
+
bytes = StringValue(bytes)
|
598
|
+
return if bytes.bytesize == 0
|
599
|
+
end
|
600
|
+
|
601
|
+
d = @__data__
|
602
|
+
pos = d.pos
|
603
|
+
string = d.string
|
604
|
+
|
605
|
+
enc = string.encoding
|
606
|
+
|
607
|
+
if d.pos == 0
|
608
|
+
d.string = "#{bytes}#{string}"
|
609
|
+
else
|
610
|
+
size = bytes.bytesize
|
611
|
+
a = string.byteslice(0, pos - size) if size < pos
|
612
|
+
b = string.byteslice(pos..-1)
|
613
|
+
d.string = "#{a}#{bytes}#{b}"
|
614
|
+
d.pos = pos > size ? pos - size : 0
|
615
|
+
end
|
616
|
+
|
617
|
+
d.string.force_encoding enc
|
618
|
+
nil
|
619
|
+
end
|
620
|
+
|
621
|
+
def encode_with(coder)
|
622
|
+
end
|
623
|
+
|
624
|
+
def init_with(coder)
|
625
|
+
@__data__ = Data.new("")
|
626
|
+
end
|
627
|
+
|
628
|
+
def to_yaml_properties
|
629
|
+
[]
|
630
|
+
end
|
631
|
+
|
632
|
+
def yaml_initialize(type, val)
|
633
|
+
@__data__ = Data.new("")
|
634
|
+
end
|
635
|
+
|
636
|
+
protected
|
637
|
+
|
638
|
+
def mode_from_string(mode)
|
639
|
+
@append = truncate = false
|
640
|
+
|
641
|
+
if mode[0] == ?r
|
642
|
+
@readable = true
|
643
|
+
@writable = mode[-1] == ?+ ? true : false
|
644
|
+
end
|
645
|
+
|
646
|
+
if mode[0] == ?w
|
647
|
+
@writable = truncate = true
|
648
|
+
@readable = mode[-1] == ?+ ? true : false
|
649
|
+
end
|
650
|
+
|
651
|
+
if mode[0] == ?a
|
652
|
+
@append = @writable = true
|
653
|
+
@readable = mode[-1] == ?+ ? true : false
|
654
|
+
end
|
655
|
+
|
656
|
+
d = @__data__
|
657
|
+
raise Errno::EACCES, "Permission denied" if @writable && d.string.frozen?
|
658
|
+
d.string.replace("") if truncate
|
659
|
+
end
|
660
|
+
|
661
|
+
def mode_from_integer(mode)
|
662
|
+
@readable = @writable = @append = false
|
663
|
+
d = @__data__
|
664
|
+
|
665
|
+
if mode == 0 or mode & IO::RDWR != 0
|
666
|
+
@readable = true
|
667
|
+
end
|
668
|
+
|
669
|
+
if mode & (IO::WRONLY | IO::RDWR) != 0
|
670
|
+
raise Errno::EACCES, "Permission denied" if d.string.frozen?
|
671
|
+
@writable = true
|
672
|
+
end
|
673
|
+
|
674
|
+
@append = true if (mode & IO::APPEND) != 0
|
675
|
+
d.string.replace("") if (mode & IO::TRUNC) != 0
|
676
|
+
end
|
677
|
+
|
678
|
+
def getline(arg_error, sep, limit)
|
679
|
+
if limit != Undefined
|
680
|
+
limit = Rubinius::Type.coerce_to limit, Fixnum, :to_int if limit
|
681
|
+
sep = Rubinius::Type.coerce_to sep, String, :to_str if sep
|
682
|
+
else
|
683
|
+
limit = nil
|
684
|
+
|
685
|
+
unless sep == $/ or sep.nil?
|
686
|
+
osep = sep
|
687
|
+
sep = Rubinius::Type.check_convert_type sep, String, :to_str
|
688
|
+
limit = Rubinius::Type.coerce_to osep, Fixnum, :to_int unless sep
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
raise ArgumentError if arg_error and limit == 0
|
693
|
+
|
694
|
+
return nil if eof?
|
695
|
+
|
696
|
+
d = @__data__
|
697
|
+
pos = d.pos
|
698
|
+
string = d.string
|
699
|
+
|
700
|
+
if sep.nil?
|
701
|
+
if limit
|
702
|
+
line = string.byteslice(pos, limit)
|
703
|
+
else
|
704
|
+
line = string.byteslice(pos, string.bytesize - pos)
|
705
|
+
end
|
706
|
+
d.pos += line.bytesize
|
707
|
+
elsif sep.empty?
|
708
|
+
if stop = string.find_string("\n\n", pos)
|
709
|
+
stop += 2
|
710
|
+
line = string.byteslice(pos, stop - pos)
|
711
|
+
while string.getbyte(stop) == 10
|
712
|
+
stop += 1
|
713
|
+
end
|
714
|
+
d.pos = stop
|
715
|
+
else
|
716
|
+
line = string.byteslice(pos, string.bytesize - pos)
|
717
|
+
d.pos = string.bytesize
|
718
|
+
end
|
719
|
+
else
|
720
|
+
if stop = string.find_string(sep, pos)
|
721
|
+
if limit && stop - pos >= limit
|
722
|
+
stop = pos + limit
|
723
|
+
else
|
724
|
+
stop += sep.bytesize
|
725
|
+
end
|
726
|
+
line = string.byteslice(pos, stop - pos)
|
727
|
+
d.pos = stop
|
728
|
+
else
|
729
|
+
if limit
|
730
|
+
line = string.byteslice(pos, limit)
|
731
|
+
else
|
732
|
+
line = string.byteslice(pos, string.bytesize - pos)
|
733
|
+
end
|
734
|
+
d.pos += line.bytesize
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|
738
|
+
d.lineno += 1
|
739
|
+
|
740
|
+
return line
|
741
|
+
end
|
742
|
+
end
|