Skip to content

Commit 7df6016

Browse files
committedJul 29, 2013
Initial StringIO implementation
1 parent 7e69a43 commit 7df6016

File tree

4 files changed

+215
-0
lines changed

4 files changed

+215
-0
lines changed
 

Diff for: ‎corelib/opal.rb

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
require 'opal/time'
1919
require 'opal/struct'
2020
require 'opal/native'
21+
require 'opal/io'
2122

2223
# regexp matches
2324
$& = $~ = $` = $' = nil
@@ -27,6 +28,7 @@
2728

2829
# split lines
2930
$/ = "\n"
31+
$, = " "
3032

3133
# native global
3234
$$ = $global = Native(`Opal.global`)

Diff for: ‎corelib/opal/error.rb

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class IndexError < StandardError; end
4343
class StopIteration < IndexError; end
4444
class KeyError < IndexError; end
4545
class RangeError < StandardError; end
46+
class IOError < StandardError; end
4647

4748
class ScriptError < Exception; end
4849
class SyntaxError < ScriptError; end

Diff for: ‎corelib/opal/io.rb

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class IO
2+
SEEK_SET = 0
3+
SEEK_CUR = 1
4+
SEEK_END = 2
5+
6+
module Writable
7+
def <<(string)
8+
write(string)
9+
10+
self
11+
end
12+
13+
def print(*args)
14+
write args.map { |arg| String(arg) }.join($,)
15+
end
16+
17+
def puts(*args)
18+
write args.map { |arg| String(arg) }.join($/)
19+
end
20+
end
21+
22+
module Readable
23+
def readbyte
24+
getbyte
25+
end
26+
27+
def readchar
28+
getc
29+
end
30+
31+
def readline(sep = $/)
32+
raise NotImplementedError
33+
end
34+
35+
def readpartial(integer, outbuf = nil)
36+
raise NotImplementedError
37+
end
38+
end
39+
end

Diff for: ‎stdlib/stringio.rb

+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
class StringIO < IO
2+
include IO::Readable
3+
include IO::Writable
4+
5+
def self.open(string = "", mode = nil, &block)
6+
io = new(string, mode)
7+
res = block.call(io)
8+
io.close
9+
10+
res
11+
end
12+
13+
attr_accessor :string
14+
15+
def initialize(string = "", mode = 'rw')
16+
@string = string
17+
@position = string.length
18+
19+
if mode.include?('r') and not mode.include?('w')
20+
@closed = :write
21+
elsif mode.include?('w') and not mode.include?('r')
22+
@closed = :read
23+
end
24+
end
25+
26+
def eof?
27+
check_readable
28+
29+
@position == @string.length
30+
end
31+
32+
alias eof eof?
33+
34+
def seek(pos, whence = IO::SEEK_SET)
35+
case whence
36+
when IO::SEEK_SET
37+
@position = pos
38+
39+
when IO::SEEK_CUR
40+
if @position + pos > @string.length
41+
@position = @string.length
42+
else
43+
@position += pos
44+
end
45+
46+
when IO::SEEK_END
47+
if pos > @string.length
48+
@position = 0
49+
else
50+
@position -= pos
51+
end
52+
end
53+
54+
0
55+
end
56+
57+
def tell
58+
@position
59+
end
60+
61+
alias pos tell
62+
63+
alias pos= seek
64+
65+
def rewind
66+
seek 0
67+
end
68+
69+
def each_byte(&block)
70+
return enum_for :each_byte unless block
71+
72+
check_readable
73+
74+
i = @position
75+
until eof?
76+
block.call(@string[i].ord)
77+
i += 1
78+
end
79+
80+
self
81+
end
82+
83+
def each_char(&block)
84+
return enum_for :each_char unless block
85+
86+
check_readable
87+
88+
i = @position
89+
until eof?
90+
block.call(@string[i])
91+
i += 1
92+
end
93+
94+
self
95+
end
96+
97+
def write(string)
98+
check_writable
99+
100+
string = String(string)
101+
102+
if @string.length == @position
103+
@string += string
104+
else
105+
before = @string[0 .. @position - 1]
106+
after = @string[@position + string.length .. -1]
107+
108+
@string = before + string + after
109+
end
110+
end
111+
112+
def read(length = nil, outbuf = nil)
113+
check_readable
114+
115+
return if eof?
116+
117+
string = if length
118+
@string[@position, length]
119+
else
120+
@string[@position .. -1]
121+
end
122+
123+
if outbuf
124+
outbuf.write(string)
125+
else
126+
string
127+
end
128+
end
129+
130+
def close
131+
@closed = :both
132+
end
133+
134+
def close_read
135+
if @closed == :write
136+
@closed = :both
137+
else
138+
@closed = :read
139+
end
140+
end
141+
142+
def close_write
143+
if @closed == :read
144+
@closed = :both
145+
else
146+
@closed = :write
147+
end
148+
end
149+
150+
def closed?
151+
@closed == :both
152+
end
153+
154+
def closed_read?
155+
@closed == :read || @closed == :both
156+
end
157+
158+
def closed_write?
159+
@closed == :write || @closed == :both
160+
end
161+
162+
def check_writable
163+
if closed_write?
164+
raise IOError, "not opened for writing"
165+
end
166+
end
167+
168+
def check_readable
169+
if closed_read?
170+
raise IOError, "not opened for reading"
171+
end
172+
end
173+
end

0 commit comments

Comments
 (0)
Please sign in to comment.