cursor 0.6 → 0.8
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.
- data/cursor.rb +626 -1143
- data/cursor/buffered.rb +89 -0
- data/cursor/circular.rb +245 -0
- data/cursor/circular/indexed.rb +51 -0
- data/cursor/circular/linked.rb +98 -0
- data/cursor/circular/position.rb +105 -0
- data/cursor/circular/shifting.rb +48 -0
- data/cursor/circular/split.rb +106 -0
- data/cursor/indexed.rb +52 -0
- data/cursor/io.rb +342 -0
- data/cursor/lined.rb +49 -0
- data/cursor/linked.rb +62 -0
- data/cursor/position.rb +145 -0
- data/cursor/reversed.rb +122 -0
- data/cursor/shifting.rb +40 -0
- data/cursor/split.rb +45 -0
- data/cursor/test.rb +519 -0
- data/cursor/test_circulars.rb +87 -0
- data/cursor/test_cursors.rb +112 -0
- data/cursor/usedeleteinsert.rb +150 -0
- data/cursor/usenext.rb +145 -0
- data/cursor/usenext/position.rb +71 -0
- data/cursor/useposition.rb +42 -0
- data/cursor/usereadwrite.rb +126 -0
- data/duck.rb +31 -0
- data/regexp_cursor.rb +50 -0
- data/weakrefset.rb +130 -0
- metadata +35 -7
@@ -0,0 +1,105 @@
|
|
1
|
+
# $Id: position.rb,v 1.2 2005/07/18 14:46:28 eric_mahurin Exp $
|
2
|
+
|
3
|
+
require 'cursor/circular'
|
4
|
+
|
5
|
+
class Cursor
|
6
|
+
class Circular
|
7
|
+
class Position < Cursor::Position # :nodoc:
|
8
|
+
def initialize(parent,reverse=false)
|
9
|
+
@parent = parent
|
10
|
+
@anchor_after = reverse
|
11
|
+
@pos = @parent.__send__(:_pos)
|
12
|
+
if @anchor_after
|
13
|
+
if @pos==@parent.size
|
14
|
+
if @pos.zero?
|
15
|
+
@anchor_after = false
|
16
|
+
else
|
17
|
+
@pos = 0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
else
|
21
|
+
@pos = @parent.size if @pos.zero?
|
22
|
+
end
|
23
|
+
prop(nil,@parent.prop)
|
24
|
+
end
|
25
|
+
def position=(p)
|
26
|
+
self._pos = p.__send__(:_pos,nil)
|
27
|
+
self.prop(nil,p.prop)
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
def pos(reverse=false)
|
31
|
+
reverse ? -0.0 : 0
|
32
|
+
end
|
33
|
+
def pos=(p)
|
34
|
+
skip(p)
|
35
|
+
p
|
36
|
+
end
|
37
|
+
protected
|
38
|
+
def _pos(reverse=false)
|
39
|
+
if reverse.nil? ? @anchor_after : reverse
|
40
|
+
(@pos.to_i-@parent.size).nonzero? || -0.0
|
41
|
+
else
|
42
|
+
@pos
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def _pos=(p)
|
46
|
+
if (p.nonzero?||1.0/p)<0
|
47
|
+
@anchor_after = true
|
48
|
+
@pos = p.to_i
|
49
|
+
if @pos.zero?
|
50
|
+
@anchor_after = false if @parent.size.zero?
|
51
|
+
else
|
52
|
+
@pos += @parent.size
|
53
|
+
end
|
54
|
+
else
|
55
|
+
@anchor_after = false
|
56
|
+
@pos = p.nonzero? || @parent.size
|
57
|
+
end
|
58
|
+
p
|
59
|
+
end
|
60
|
+
def _deletion(pos,len=1,reverse=false,size=nil)
|
61
|
+
if @pos==pos
|
62
|
+
@anchor_after = false
|
63
|
+
@pos = (size ||= @parent.size) if @pos.zero?
|
64
|
+
elsif @pos>pos
|
65
|
+
@pos -= len
|
66
|
+
if @pos<pos
|
67
|
+
@pos = pos
|
68
|
+
if @anchor_after==reverse
|
69
|
+
@anchor_after = !reverse
|
70
|
+
if @anchor_after
|
71
|
+
if @pos==(size ||= @parent.size)
|
72
|
+
if @pos.zero?
|
73
|
+
@anchor_after = false
|
74
|
+
else
|
75
|
+
@pos = 0
|
76
|
+
end
|
77
|
+
end
|
78
|
+
else
|
79
|
+
@pos = (size ||= @parent.size) if @pos.zero?
|
80
|
+
end
|
81
|
+
end
|
82
|
+
elsif @pos==pos && !@anchor_after
|
83
|
+
@anchor_after = true
|
84
|
+
if @pos==(size ||= @parent.size)
|
85
|
+
if @pos.zero?
|
86
|
+
@anchor_after = false
|
87
|
+
else
|
88
|
+
@pos = 0
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
size
|
94
|
+
end
|
95
|
+
def _insertion(pos,len=1,dummy=nil)
|
96
|
+
if @pos>=pos+((@anchor_after||@pos.zero?) ? 0 : 1)
|
97
|
+
@pos += len
|
98
|
+
end
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# $Id: shifting.rb,v 1.4 2005/07/21 15:15:38 eric_mahurin Exp $
|
2
|
+
|
3
|
+
require 'cursor/circular'
|
4
|
+
require 'cursor/usedeleteinsert'
|
5
|
+
|
6
|
+
class Cursor
|
7
|
+
class Circular
|
8
|
+
# This Cursor class puts a cursor at the ends of an Array/String (or something
|
9
|
+
# like those). Assuming insertions/deletions are efficient at both ends of that
|
10
|
+
# structure, all insertions/deletions at the cursor will be also.
|
11
|
+
class Shifting < Circular
|
12
|
+
include UseDeleteInsert
|
13
|
+
def initialize(data=[],pos0=0)
|
14
|
+
@data = data
|
15
|
+
@pos0 = pos0
|
16
|
+
end
|
17
|
+
# :stopdoc:
|
18
|
+
def new_data
|
19
|
+
@data.class.new
|
20
|
+
end
|
21
|
+
protected
|
22
|
+
def _delete1after?
|
23
|
+
@pos0 = (@data.size.nonzero?||return) if @pos0.zero?
|
24
|
+
@pos0 -= 1
|
25
|
+
@data.slice!(0)
|
26
|
+
end
|
27
|
+
def _delete1before?
|
28
|
+
@pos0 = 0 if @pos0==@data.size
|
29
|
+
@data.slice!(-1)
|
30
|
+
end
|
31
|
+
def _insert1before(v)
|
32
|
+
@data << v
|
33
|
+
true
|
34
|
+
end
|
35
|
+
def _insert1after(v)
|
36
|
+
@data[0,0] = (@data.class.new << v)
|
37
|
+
@pos0 += 1
|
38
|
+
true
|
39
|
+
end
|
40
|
+
def _pos(reverse=false)
|
41
|
+
reverse ? -(@pos0.nonzero?||0.0) : @data.size-@pos0
|
42
|
+
end
|
43
|
+
# :startdoc:
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# $Id: split.rb,v 1.3 2005/07/18 14:46:28 eric_mahurin Exp $
|
2
|
+
|
3
|
+
require 'cursor/circular'
|
4
|
+
require 'cursor/usedeleteinsert'
|
5
|
+
|
6
|
+
class Cursor
|
7
|
+
class Circular
|
8
|
+
# This Cursor class uses an Array/String for data before the cursor
|
9
|
+
# and another one for data after the cursor. The result of this is that
|
10
|
+
# data is only deleted/inserted at the end of these 2. Because of that
|
11
|
+
# most operations have similar expense and are linear with respect to the
|
12
|
+
# number of elements being moved, inserted, deleted, replaced, etc.
|
13
|
+
class Split < Circular
|
14
|
+
include UseDeleteInsert
|
15
|
+
def initialize(before=[],after=before.class.new)
|
16
|
+
@before = before
|
17
|
+
@after = after
|
18
|
+
@middle = before.class.new
|
19
|
+
@middle_start = nil
|
20
|
+
@middle_before = false
|
21
|
+
@size = @before.size+@after.size
|
22
|
+
@pos0 = @after.size
|
23
|
+
end
|
24
|
+
# :stopdoc:
|
25
|
+
def new_data
|
26
|
+
@before.class.new
|
27
|
+
end
|
28
|
+
protected
|
29
|
+
def _delete1after?
|
30
|
+
@pos0 = (@size.nonzero?||return) if @pos0.zero?
|
31
|
+
@pos0 -= 1
|
32
|
+
@size -= 1
|
33
|
+
v = @after.slice!(-1)
|
34
|
+
if v.nil?
|
35
|
+
if !@middle_start
|
36
|
+
@before,@middle = @middle,@before
|
37
|
+
@middle_before = true
|
38
|
+
@middle_start = 0
|
39
|
+
end
|
40
|
+
if @middle_before
|
41
|
+
v = @middle[@middle_start]
|
42
|
+
@middle_start += 1
|
43
|
+
else
|
44
|
+
v = @middle.slice!(-1)
|
45
|
+
end
|
46
|
+
if @middle_start>=@middle.size
|
47
|
+
@middle.replace(@middle.class.new)
|
48
|
+
@middle_start = nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
v
|
52
|
+
end
|
53
|
+
def _delete1before?
|
54
|
+
if @pos0==@size
|
55
|
+
return if @size.zero?
|
56
|
+
@pos0 = 0
|
57
|
+
end
|
58
|
+
@size -= 1
|
59
|
+
v = @before.slice!(-1)
|
60
|
+
if v.nil?
|
61
|
+
if !@middle_start
|
62
|
+
@after,@middle = @middle,@after
|
63
|
+
@middle_before = false
|
64
|
+
@middle_start = 0
|
65
|
+
end
|
66
|
+
if !@middle_before
|
67
|
+
v = @middle[@middle_start]
|
68
|
+
@middle_start += 1
|
69
|
+
else
|
70
|
+
v = @middle.slice!(-1)
|
71
|
+
end
|
72
|
+
if @middle_start>=@middle.size
|
73
|
+
@middle.replace(@middle.class.new)
|
74
|
+
@middle_start = nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
v
|
78
|
+
end
|
79
|
+
def _insert1before(v)
|
80
|
+
@size += 1
|
81
|
+
if !@middle_before and @middle_start and @middle_start.nonzero?
|
82
|
+
@middle[@middle_start -= 1] = v
|
83
|
+
else
|
84
|
+
@before << v
|
85
|
+
end
|
86
|
+
true
|
87
|
+
end
|
88
|
+
def _insert1after(v)
|
89
|
+
@pos0 += 1
|
90
|
+
@size += 1
|
91
|
+
if @middle_before and @middle_start and @middle_start.nonzero?
|
92
|
+
@middle[@middle_start -= 1] = v
|
93
|
+
else
|
94
|
+
@after << v
|
95
|
+
end
|
96
|
+
true
|
97
|
+
end
|
98
|
+
def _pos(reverse=false)
|
99
|
+
reverse ? -(@pos0.nonzero?||0.0) : @size-@pos0
|
100
|
+
end
|
101
|
+
# :startdoc:
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
data/cursor/indexed.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# $Id: indexed.rb,v 1.7 2005/07/21 15:15:38 eric_mahurin Exp $
|
2
|
+
|
3
|
+
require 'cursor'
|
4
|
+
require 'cursor/usedeleteinsert'
|
5
|
+
|
6
|
+
class Cursor
|
7
|
+
# This class puts a cursor on an Array or String.
|
8
|
+
class Indexed < Cursor
|
9
|
+
include UseDeleteInsert
|
10
|
+
def initialize(data=[],pos=0)
|
11
|
+
@data = data
|
12
|
+
@pos = pos
|
13
|
+
end
|
14
|
+
# :stopdoc:
|
15
|
+
def new_data
|
16
|
+
@data.class.new
|
17
|
+
end
|
18
|
+
protected
|
19
|
+
def _delete1after?
|
20
|
+
@data.slice!(@pos)
|
21
|
+
end
|
22
|
+
def _delete1before?
|
23
|
+
@pos==0 ? nil : @data.slice!(@pos-=1)
|
24
|
+
end
|
25
|
+
def _insert1before(v)
|
26
|
+
@data[@pos,0] = (new_data << v)
|
27
|
+
@pos += 1
|
28
|
+
true
|
29
|
+
end
|
30
|
+
def _insert1after(v)
|
31
|
+
@data[@pos,0] = (new_data << v)
|
32
|
+
true
|
33
|
+
end
|
34
|
+
# :startdoc:
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Array
|
39
|
+
# convert an array to a cursor starting at +pos+
|
40
|
+
def to_cursor(pos=0)
|
41
|
+
Cursor::Indexed.new(self,pos)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class String
|
46
|
+
# convert a string to a cursor starting at +pos+
|
47
|
+
def to_cursor(pos=0)
|
48
|
+
Cursor::Indexed.new(self,pos)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
data/cursor/io.rb
ADDED
@@ -0,0 +1,342 @@
|
|
1
|
+
# $Id: io.rb,v 1.15 2005/07/21 15:15:38 eric_mahurin Exp $
|
2
|
+
|
3
|
+
require 'cursor'
|
4
|
+
require 'cursor/usenext'
|
5
|
+
|
6
|
+
class Cursor
|
7
|
+
# This class treats an IO (or StringIO) as a Cursor. An IO is already
|
8
|
+
# like a Cursor, but doesn't have as robust an interface. Keep in mind that deleting and
|
9
|
+
# inserting is a slow/painful process.
|
10
|
+
class IO < Cursor
|
11
|
+
include UseNext
|
12
|
+
def initialize(io)
|
13
|
+
@io = io
|
14
|
+
end
|
15
|
+
# :stopdoc:
|
16
|
+
def new_data
|
17
|
+
String.new
|
18
|
+
end
|
19
|
+
protected
|
20
|
+
def _delete1after?
|
21
|
+
ret = @io.getc or return(nil)
|
22
|
+
after = 0
|
23
|
+
while c = @io.getc
|
24
|
+
after += 1
|
25
|
+
@io.seek(-2,::IO::SEEK_CUR)
|
26
|
+
@io.putc(c)
|
27
|
+
@io.seek(+1,::IO::SEEK_CUR)
|
28
|
+
end
|
29
|
+
@io.seek(-1,::IO::SEEK_CUR)
|
30
|
+
@io.truncate(@io.pos)
|
31
|
+
@io.seek(-after,::IO::SEEK_CUR)
|
32
|
+
ret
|
33
|
+
end
|
34
|
+
def _insert1before(v)
|
35
|
+
after = 0
|
36
|
+
while c = @io.getc
|
37
|
+
after += 1
|
38
|
+
@io.seek(-1,::IO::SEEK_CUR)
|
39
|
+
@io.putc(v)
|
40
|
+
v = c
|
41
|
+
end
|
42
|
+
@io.putc(v)
|
43
|
+
@io.seek(-after,::IO::SEEK_CUR)
|
44
|
+
true
|
45
|
+
end
|
46
|
+
public
|
47
|
+
def read1next
|
48
|
+
@io.getc
|
49
|
+
end
|
50
|
+
def write1next(v)
|
51
|
+
@io.eof? ? nil : (@io.putc(v);true)
|
52
|
+
end
|
53
|
+
def write1next!(v)
|
54
|
+
@io.putc(v)
|
55
|
+
true
|
56
|
+
end
|
57
|
+
def skip1prev
|
58
|
+
@io.pos.nonzero? && (@io.seek(-1,::IO::SEEK_CUR);true)
|
59
|
+
end
|
60
|
+
def read1after
|
61
|
+
v0 = @io.getc
|
62
|
+
v0 && @io.ungetc(v0)
|
63
|
+
v0
|
64
|
+
end
|
65
|
+
def write1after!(v)
|
66
|
+
@io.putc(v)
|
67
|
+
@io.seek(-1,::IO::SEEK_CUR)
|
68
|
+
true
|
69
|
+
end
|
70
|
+
def skip1next
|
71
|
+
@io.getc ? true : nil
|
72
|
+
end
|
73
|
+
def skip1after
|
74
|
+
@io.eof? ? nil : true
|
75
|
+
end
|
76
|
+
def skip1before
|
77
|
+
@io.pos.zero? ? nil : true
|
78
|
+
end
|
79
|
+
def read(len,hold=false,buffer=nil)
|
80
|
+
len.nonzero? or return(buffer||"")
|
81
|
+
reverse = len<0
|
82
|
+
len = len.abs
|
83
|
+
if reverse
|
84
|
+
p0 = @io.pos
|
85
|
+
len = p0.nonzero? or return if (p0-len)<0
|
86
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
87
|
+
buffer1 = @io.read(len)
|
88
|
+
if hold.nil?
|
89
|
+
buffer2 = @io.read(nil)
|
90
|
+
len2 = buffer2.size
|
91
|
+
@io.seek(-(len+len2),::IO::SEEK_CUR)
|
92
|
+
@io.write(buffer2)
|
93
|
+
@io.truncate(@io.pos)
|
94
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
95
|
+
@positions && _adjust_delete(len,reverse)
|
96
|
+
elsif !hold
|
97
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
98
|
+
end
|
99
|
+
buffer1.reverse!
|
100
|
+
else
|
101
|
+
buffer1 = @io.read(len) or return
|
102
|
+
len = buffer1.size
|
103
|
+
if hold.nil?
|
104
|
+
buffer2 = @io.read(nil)
|
105
|
+
len2 = buffer2.size
|
106
|
+
@io.seek(-(len+len2),::IO::SEEK_CUR)
|
107
|
+
@io.write(buffer2)
|
108
|
+
@io.truncate(@io.pos)
|
109
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
110
|
+
@positions && _adjust_delete(len,reverse)
|
111
|
+
elsif hold
|
112
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
if buffer
|
116
|
+
if String===buffer
|
117
|
+
buffer.concat(buffer1)
|
118
|
+
else
|
119
|
+
buffer1.each_byte { |c| buffer << c }
|
120
|
+
end
|
121
|
+
else
|
122
|
+
buffer = buffer1
|
123
|
+
end
|
124
|
+
buffer
|
125
|
+
end
|
126
|
+
def read!(reverse=false,hold=false,buffer=new_data)
|
127
|
+
if reverse
|
128
|
+
len = @io.pos.nonzero? or return
|
129
|
+
@io.seek(0,::IO::SEEK_SET)
|
130
|
+
#@io.pos = 0 # BUGGY in v1.8.2
|
131
|
+
buffer1 = @io.read(len) or return
|
132
|
+
if hold.nil?
|
133
|
+
buffer2 = @io.read(nil)
|
134
|
+
len2 = buffer2.size
|
135
|
+
@io.seek(-(len+len2),::IO::SEEK_CUR)
|
136
|
+
@io.write(buffer2)
|
137
|
+
@io.truncate(@io.pos)
|
138
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
139
|
+
@positions && _adjust_delete(len,reverse)
|
140
|
+
elsif !hold
|
141
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
142
|
+
end
|
143
|
+
buffer1.reverse!
|
144
|
+
else
|
145
|
+
buffer1 = @io.read(nil)
|
146
|
+
len = buffer1.size.nonzero? or return
|
147
|
+
if hold.nil?
|
148
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
149
|
+
@io.truncate(@io.pos)
|
150
|
+
@positions && _adjust_delete(len,reverse)
|
151
|
+
elsif hold
|
152
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
if buffer
|
156
|
+
if String===buffer
|
157
|
+
buffer.concat(buffer1)
|
158
|
+
else
|
159
|
+
buffer1.each_byte { |c| buffer << c }
|
160
|
+
end
|
161
|
+
else
|
162
|
+
buffer = buffer1
|
163
|
+
end
|
164
|
+
buffer
|
165
|
+
end
|
166
|
+
def skip(len,hold=false)
|
167
|
+
len.nonzero? or return(0)
|
168
|
+
reverse = len<0
|
169
|
+
len = len.abs
|
170
|
+
if reverse
|
171
|
+
p0 = @io.pos
|
172
|
+
len = p0.nonzero? or return if (p0-len)<0
|
173
|
+
if hold.nil?
|
174
|
+
buffer2 = @io.read(nil)
|
175
|
+
len2 = buffer2.size
|
176
|
+
@io.seek(-(len+len2),::IO::SEEK_CUR)
|
177
|
+
@io.write(buffer2)
|
178
|
+
@io.truncate(@io.pos)
|
179
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
180
|
+
@positions && _adjust_delete(len,reverse)
|
181
|
+
elsif !hold
|
182
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
183
|
+
end
|
184
|
+
else
|
185
|
+
@io.seek(len,::IO::SEEK_CUR)
|
186
|
+
if @io.eof?
|
187
|
+
p0 = @io.pos
|
188
|
+
@io.seek(0,::IO::SEEK_END)
|
189
|
+
len -= p0-@io.pos
|
190
|
+
len.nonzero? or return
|
191
|
+
end
|
192
|
+
if hold.nil?
|
193
|
+
buffer2 = @io.read(nil)
|
194
|
+
len2 = buffer2.size
|
195
|
+
@io.seek(-(len+len2),::IO::SEEK_CUR)
|
196
|
+
@io.write(buffer2)
|
197
|
+
@io.truncate(@io.pos)
|
198
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
199
|
+
@positions && _adjust_delete(len,reverse)
|
200
|
+
elsif hold
|
201
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
len
|
205
|
+
end
|
206
|
+
def skip!(reverse=false,hold=false)
|
207
|
+
if reverse
|
208
|
+
len = @io.pos.nonzero? or return
|
209
|
+
if hold.nil?
|
210
|
+
buffer2 = @io.read(nil)
|
211
|
+
len2 = buffer2.size
|
212
|
+
@io.seek(-(len+len2),::IO::SEEK_CUR)
|
213
|
+
@io.write(buffer2)
|
214
|
+
@io.truncate(@io.pos)
|
215
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
216
|
+
@positions && _adjust_delete(len,reverse)
|
217
|
+
elsif !hold
|
218
|
+
@io.seek(0,::IO::SEEK_SET)
|
219
|
+
end
|
220
|
+
else
|
221
|
+
p0 = @io.pos
|
222
|
+
@io.seek(0,::IO::SEEK_END)
|
223
|
+
len = @io.pos-p0
|
224
|
+
len.nonzero? or return
|
225
|
+
@io.seek(-len,::IO::SEEK_CUR) if hold!=false
|
226
|
+
if hold.nil?
|
227
|
+
@io.truncate(@io.pos)
|
228
|
+
@positions && _adjust_delete(len,reverse)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
len
|
232
|
+
end
|
233
|
+
def write(value,reverse=false,hold=false,overwrite_only=false)
|
234
|
+
if String===value
|
235
|
+
value1 = reverse ? value.reverse : value
|
236
|
+
len = value.size
|
237
|
+
else
|
238
|
+
value1 = ""
|
239
|
+
len = 0;
|
240
|
+
until (v = value[len]).nil?
|
241
|
+
value1 << v
|
242
|
+
len += 1
|
243
|
+
end
|
244
|
+
value1 = value1.reverse if reverse
|
245
|
+
end
|
246
|
+
if reverse
|
247
|
+
if hold.nil?
|
248
|
+
@positions && _adjust_insert(len)
|
249
|
+
buffer2 = @io.read(nil)
|
250
|
+
len2 = buffer2.size
|
251
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
252
|
+
@io.write(value1)
|
253
|
+
@io.write(buffer2)
|
254
|
+
@io.seek(-(len+len2),::IO::SEEK_CUR)
|
255
|
+
else
|
256
|
+
len_overwrite = @io.pos
|
257
|
+
len_insert = len-len_overwrite
|
258
|
+
if len_insert<=0
|
259
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
260
|
+
@io.write(value1)
|
261
|
+
else
|
262
|
+
@io.seek(-len_overwrite,::IO::SEEK_CUR)
|
263
|
+
if overwrite_only
|
264
|
+
len = len_overwrite.nonzero? or return
|
265
|
+
else
|
266
|
+
@positions && _adjust_insert(len_insert)
|
267
|
+
buffer2 = @io.read(nil)
|
268
|
+
len2 = buffer2.size
|
269
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
270
|
+
@io.write(value1[0,len_insert])
|
271
|
+
@io.write(buffer2)
|
272
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
273
|
+
end
|
274
|
+
@io.write(value1[len_insert,len_overwrite])
|
275
|
+
|
276
|
+
end
|
277
|
+
@io.seek(-len,::IO::SEEK_CUR) if !hold
|
278
|
+
end
|
279
|
+
else
|
280
|
+
if hold.nil?
|
281
|
+
@positions && _adjust_insert(len)
|
282
|
+
buffer2 = @io.read(nil)
|
283
|
+
len2 = buffer2.size
|
284
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
285
|
+
@io.write(value1)
|
286
|
+
@io.write(buffer2)
|
287
|
+
@io.seek(-len2,::IO::SEEK_CUR)
|
288
|
+
else
|
289
|
+
if overwrite_only
|
290
|
+
len.nonzero? or return(0)
|
291
|
+
@io.seek(len,::IO::SEEK_CUR)
|
292
|
+
if @io.eof?
|
293
|
+
p0 = @io.pos
|
294
|
+
@io.seek(0,::IO::SEEK_END)
|
295
|
+
len -= p0-@io.pos
|
296
|
+
len.nonzero? or return
|
297
|
+
value1 = value1[0,len]
|
298
|
+
end
|
299
|
+
@io.seek(-len,::IO::SEEK_CUR)
|
300
|
+
end
|
301
|
+
@io.write(value1)
|
302
|
+
@io.seek(-len,::IO::SEEK_CUR) if hold
|
303
|
+
end
|
304
|
+
end
|
305
|
+
len
|
306
|
+
end
|
307
|
+
def scan_until(value,reverse=false,hold=false,buffer=nil)
|
308
|
+
if String===value && !reverse && hold==false && !buffer && !value.empty?
|
309
|
+
@io.gets(value)
|
310
|
+
else
|
311
|
+
super(value,reverse,hold,buffer||value.class.new)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
def pos=(p)
|
315
|
+
@io.seek(p,(p.nonzero?||1.0/p)<0 ? ::IO::SEEK_END : ::IO::SEEK_SET)
|
316
|
+
p
|
317
|
+
end
|
318
|
+
|
319
|
+
public
|
320
|
+
def close
|
321
|
+
@io.close
|
322
|
+
super
|
323
|
+
end
|
324
|
+
# :startdoc:
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
class IO
|
329
|
+
# convert an IO to a cursor
|
330
|
+
def to_cursor
|
331
|
+
Cursor::IO.new(self)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
class StringIO
|
336
|
+
# convert an IO to a cursor
|
337
|
+
def to_cursor
|
338
|
+
Cursor::IO.new(self)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
|