sequence 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +58 -0
- data/GPL +340 -0
- data/Manifest.txt +36 -0
- data/README.txt +320 -0
- data/Rakefile +32 -0
- data/lib/assert.rb +16 -0
- data/lib/sequence/arraylike.rb +57 -0
- data/lib/sequence/buffered.rb +188 -0
- data/lib/sequence/circular.rb +272 -0
- data/lib/sequence/enum.rb +260 -0
- data/lib/sequence/file.rb +172 -0
- data/lib/sequence/functional.rb +152 -0
- data/lib/sequence/generator.rb +290 -0
- data/lib/sequence/indexed.rb +234 -0
- data/lib/sequence/io.rb +102 -0
- data/lib/sequence/list.rb +292 -0
- data/lib/sequence/ofhash.rb +38 -0
- data/lib/sequence/ofobjectivars.rb +29 -0
- data/lib/sequence/ofobjectmethods.rb +87 -0
- data/lib/sequence/position.rb +100 -0
- data/lib/sequence/reversed.rb +180 -0
- data/lib/sequence/shifting.rb +190 -0
- data/lib/sequence/singleitem.rb +50 -0
- data/lib/sequence/stringlike.rb +482 -0
- data/lib/sequence/subseq.rb +90 -0
- data/lib/sequence/usedata.rb +35 -0
- data/lib/sequence/version.rb +5 -0
- data/lib/sequence.rb +721 -0
- data/lib/weakrefset.rb +254 -0
- data/test/test.rb +609 -0
- data/test/test_all.rb +6 -0
- data/test/test_changes.rb +44 -0
- data/test/test_circulars.rb +89 -0
- data/test/test_rexscan.rb +899 -0
- data/test/test_seqrex.rb +204 -0
- data/test/test_sequences.rb +106 -0
- metadata +90 -0
@@ -0,0 +1,180 @@
|
|
1
|
+
# $Id$
|
2
|
+
# Copyright (C) 2006 Caleb Clausen
|
3
|
+
# Distributed under the terms of Ruby's license.
|
4
|
+
|
5
|
+
require 'sequence'
|
6
|
+
|
7
|
+
class Sequence
|
8
|
+
class Circular< Sequence; end #forward decl
|
9
|
+
# This class can be used to reverse the direction of operations on a given
|
10
|
+
# sequence. It has a separate position, independant of the original sequence's.
|
11
|
+
class Reversed < Sequence
|
12
|
+
#when reversed and circular, always put the Circular outermost.
|
13
|
+
class<<self
|
14
|
+
alias new__no_circular new
|
15
|
+
def new(sequence,pos=0)
|
16
|
+
if Circular===sequence
|
17
|
+
Circular.new(new__no_circular(sequence.data,pos))
|
18
|
+
else
|
19
|
+
new__no_circular(sequence,pos)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def initialize(sequence,pos=0)
|
26
|
+
@seq = sequence
|
27
|
+
@pos=pos
|
28
|
+
@size=sequence.size
|
29
|
+
extend @seq.like
|
30
|
+
|
31
|
+
@seq.on_change_notify self
|
32
|
+
end
|
33
|
+
|
34
|
+
def translate_pos(pos)
|
35
|
+
@size-pos
|
36
|
+
end
|
37
|
+
|
38
|
+
def change_notification(cu,first,oldsize,newsize)
|
39
|
+
# Process.kill("INT",0)
|
40
|
+
assert cu==@seq
|
41
|
+
# @pos =translate_pos cu._adjust_pos_on_change(translate_pos(pos), first,oldsize,newsize)
|
42
|
+
first=translate_pos(first+oldsize)
|
43
|
+
@pos =_adjust_pos_on_change((pos), first,oldsize,newsize)
|
44
|
+
@size+=newsize-oldsize
|
45
|
+
assert @size==@seq.size
|
46
|
+
notify_change(self, first,oldsize,newsize)
|
47
|
+
end
|
48
|
+
|
49
|
+
# :stopdoc:
|
50
|
+
def new_data
|
51
|
+
@seq.new_data
|
52
|
+
end
|
53
|
+
=begin ***
|
54
|
+
def read1after
|
55
|
+
@seq.read1before
|
56
|
+
end
|
57
|
+
def read1before
|
58
|
+
@seq.read1after
|
59
|
+
end
|
60
|
+
|
61
|
+
def skip1next
|
62
|
+
@seq.skip1prev
|
63
|
+
end
|
64
|
+
def skip1prev
|
65
|
+
@seq.skip1next
|
66
|
+
end
|
67
|
+
def skip1after
|
68
|
+
@seq.skip1before
|
69
|
+
end
|
70
|
+
def skip1before
|
71
|
+
@seq.skip1after
|
72
|
+
end
|
73
|
+
def delete1after
|
74
|
+
v0 = @seq.delete1before
|
75
|
+
v0 && @positions && _adjust_delete
|
76
|
+
v0
|
77
|
+
end
|
78
|
+
def delete1before
|
79
|
+
v0 = @seq.delete1after
|
80
|
+
v0 && @positions && _adjust_delete
|
81
|
+
v0
|
82
|
+
end
|
83
|
+
def delete1after?
|
84
|
+
v0 = @seq.delete1before?
|
85
|
+
v0.nil? || @positions && _adjust_delete
|
86
|
+
v0
|
87
|
+
end
|
88
|
+
def delete1before?
|
89
|
+
v0 = @seq.delete1after?
|
90
|
+
v0.nil? || @positions && _adjust_delete
|
91
|
+
v0
|
92
|
+
end
|
93
|
+
def write1next(v)
|
94
|
+
@seq.write1prev(v)
|
95
|
+
end
|
96
|
+
def write1prev(v)
|
97
|
+
@seq.write1next(v)
|
98
|
+
end
|
99
|
+
def write1after(v)
|
100
|
+
@seq.write1before(v)
|
101
|
+
end
|
102
|
+
def write1before(v)
|
103
|
+
@seq.write1after(v)
|
104
|
+
end
|
105
|
+
def write1next?(v)
|
106
|
+
@seq.write1prev?(v)
|
107
|
+
end
|
108
|
+
def write1prev?(v)
|
109
|
+
@seq.write1next?(v)
|
110
|
+
end
|
111
|
+
def write1after?(v)
|
112
|
+
@seq.write1before?(v)
|
113
|
+
end
|
114
|
+
def write1before?(v)
|
115
|
+
@seq.write1after?(v)
|
116
|
+
end
|
117
|
+
def insert1before(v)
|
118
|
+
@positions && _adjust_insert
|
119
|
+
@seq.insert1after(v)
|
120
|
+
end
|
121
|
+
def insert1after(v)
|
122
|
+
@positions && _adjust_insert
|
123
|
+
@seq.insert1before(v)
|
124
|
+
end
|
125
|
+
def scan1next(v)
|
126
|
+
@seq.scan1prev(v)
|
127
|
+
end
|
128
|
+
def scan1prev(v)
|
129
|
+
@seq.scan1next(v)
|
130
|
+
end
|
131
|
+
def modify1next(lookup)
|
132
|
+
@seq.modify1prev(lookup)
|
133
|
+
end
|
134
|
+
def modify1prev(lookup)
|
135
|
+
@seq.modify1next(lookup)
|
136
|
+
end
|
137
|
+
=end
|
138
|
+
attr_reader :pos,:size
|
139
|
+
def _pos=(pos)
|
140
|
+
@pos=pos
|
141
|
+
end
|
142
|
+
|
143
|
+
def read(len)
|
144
|
+
assert @pos>=0
|
145
|
+
assert @size>=@pos
|
146
|
+
start =@size-@pos-len
|
147
|
+
start<0 and start=0
|
148
|
+
result=@seq[start...@size-@pos] or return ""
|
149
|
+
@pos+=result.size
|
150
|
+
result.reverse
|
151
|
+
end
|
152
|
+
|
153
|
+
def modify(*args)
|
154
|
+
first,len,only1=_parse_slice_args( *args[0..-2] )
|
155
|
+
# puts "first=#{first}, len=#{len}"
|
156
|
+
first=@size-first-len
|
157
|
+
@seq.modify first, len, args.last.reverse
|
158
|
+
#notify_change(self,first,len,args.last.size) #?? is this a good idea?
|
159
|
+
args.last
|
160
|
+
end
|
161
|
+
|
162
|
+
def eof?
|
163
|
+
@pos>=@size
|
164
|
+
end
|
165
|
+
|
166
|
+
def closed?
|
167
|
+
super or @seq.closed?
|
168
|
+
end
|
169
|
+
|
170
|
+
def reverse
|
171
|
+
@seq.position(0)
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
# :startdoc:
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# $Id$
|
2
|
+
# Copyright (C) 2006 Caleb Clausen
|
3
|
+
# Distributed under the terms of Ruby's license.
|
4
|
+
|
5
|
+
require 'sequence'
|
6
|
+
|
7
|
+
class Sequence
|
8
|
+
#a primary sequence (presumably unidirectional) with a secondary sequence
|
9
|
+
#as backup. the primary is traversed in the forward direcion only. the
|
10
|
+
#secondary holds a copy of data as it comes from the primary sequence. the
|
11
|
+
#position can be independantly changed to any location; if before the
|
12
|
+
#current position of the primary sequence, the secondary sequence is used
|
13
|
+
#instead. all writes go to the secondary sequence.
|
14
|
+
|
15
|
+
|
16
|
+
class Shifting < Sequence
|
17
|
+
def initialize(seq,data= Sequence::Indexed.new(seq.new_data))
|
18
|
+
@seq=seq #primary
|
19
|
+
@data = data #secondary
|
20
|
+
@offset=@seq.pos
|
21
|
+
|
22
|
+
extend @seq.like
|
23
|
+
|
24
|
+
@seq.on_change_notify self
|
25
|
+
end
|
26
|
+
# :stopdoc:
|
27
|
+
def new_data
|
28
|
+
@data.new_data
|
29
|
+
end
|
30
|
+
|
31
|
+
def change_notification(cu,first,oldsize,newsize)
|
32
|
+
assert @seq==cu
|
33
|
+
|
34
|
+
if first<=@offset
|
35
|
+
if first+oldsize>=@offset
|
36
|
+
offset=first
|
37
|
+
end
|
38
|
+
@offset-=oldsize-newsize
|
39
|
+
end
|
40
|
+
|
41
|
+
#modify @data (shift buffer) to suit
|
42
|
+
if first<@offset
|
43
|
+
@data.prepend @seq[first...@offset]
|
44
|
+
@offset=first
|
45
|
+
elsif first<@data.size+@offset #if change within already shifted data
|
46
|
+
@data[first-@offset,oldsize]= @seq[first,newsize]
|
47
|
+
end
|
48
|
+
|
49
|
+
notify_change(self,first,oldsize,newsize)
|
50
|
+
end
|
51
|
+
=begin ***
|
52
|
+
protected
|
53
|
+
def _delete1after?
|
54
|
+
@pos.nonzero? && (@pos0 -= 1) && @data.slice!(0)
|
55
|
+
end
|
56
|
+
def _delete1before?
|
57
|
+
@pos==@data.size ? nil : @data.slice!(-1)
|
58
|
+
end
|
59
|
+
def _insert1before(v)
|
60
|
+
@data << v
|
61
|
+
true
|
62
|
+
end
|
63
|
+
def _insert1after(v)
|
64
|
+
@data[0,0] = (@data.class.new << v)
|
65
|
+
@pos += 1
|
66
|
+
true
|
67
|
+
end
|
68
|
+
=end
|
69
|
+
protected
|
70
|
+
def history_mode?
|
71
|
+
!@data.eof?
|
72
|
+
end
|
73
|
+
|
74
|
+
public
|
75
|
+
def read(len)
|
76
|
+
assert oldpos=pos
|
77
|
+
if history_mode?
|
78
|
+
rest=@seq.pos-pos
|
79
|
+
len<=rest and return @data.read(len)
|
80
|
+
@data.append @seq.read(len-rest)
|
81
|
+
else
|
82
|
+
assert @data.pos+@offset==@seq.pos
|
83
|
+
@data.append @seq.read(len)
|
84
|
+
end
|
85
|
+
result=@data.read!
|
86
|
+
# assert pos==oldpos+len || pos==size
|
87
|
+
return result
|
88
|
+
end
|
89
|
+
|
90
|
+
def _pos= x;
|
91
|
+
assert @data.empty?|| (0..@data.size)===pos-@offset
|
92
|
+
#assert @data.size+@offset==@seq.pos
|
93
|
+
if @data.empty?
|
94
|
+
diff=x-@offset
|
95
|
+
@data<<
|
96
|
+
if diff<0
|
97
|
+
@offset=x
|
98
|
+
diff=-diff
|
99
|
+
@seq[x,diff] rescue
|
100
|
+
case data_class
|
101
|
+
when ::Array: [nil]
|
102
|
+
when ::String: "\0"
|
103
|
+
else fail
|
104
|
+
end*diff
|
105
|
+
|
106
|
+
else #diff>=0
|
107
|
+
@seq.read(diff)
|
108
|
+
end
|
109
|
+
|
110
|
+
@data.pos=x-@offset
|
111
|
+
assert @data.size+@offset==@seq.pos
|
112
|
+
assert( (0..@data.size)===x-@offset )
|
113
|
+
elsif x<@offset
|
114
|
+
offset=@offset
|
115
|
+
@offset=x
|
116
|
+
@data.prepend((
|
117
|
+
@seq[x...offset] rescue
|
118
|
+
case data_class
|
119
|
+
when ::Array: [nil]
|
120
|
+
when ::String: "\0"
|
121
|
+
else fail
|
122
|
+
end*(offset-x)
|
123
|
+
))
|
124
|
+
# assert @data.size+@offset==@seq.pos
|
125
|
+
assert( (0..@data.size)===x-@offset )
|
126
|
+
elsif x>@data.size+@offset
|
127
|
+
# assert @seq.pos==@data.size+@offset
|
128
|
+
@data<<@seq.read(x-@data.size-@offset)
|
129
|
+
@data.pos=@data.size
|
130
|
+
#assert @data.size+@offset==@seq.pos
|
131
|
+
assert( (0..@data.size)===x-@offset )
|
132
|
+
else
|
133
|
+
@data.pos=x-@offset
|
134
|
+
#assert @data.size+@offset==@seq.pos
|
135
|
+
assert( (0..@data.size)===x-@offset )
|
136
|
+
end
|
137
|
+
#assert @data.size+@offset==@seq.pos
|
138
|
+
assert( (0..@data.size)===x-@offset )
|
139
|
+
# assert(pos==x || pos==size)
|
140
|
+
x
|
141
|
+
end
|
142
|
+
|
143
|
+
def modify *args
|
144
|
+
newvals=args.pop
|
145
|
+
first,len,only1=_parse_slice_args( *args )
|
146
|
+
only1 and newvals=new_data<<newvals
|
147
|
+
|
148
|
+
assert @data.size+@offset==@seq.pos
|
149
|
+
|
150
|
+
oldpos=pos
|
151
|
+
|
152
|
+
if @data.empty?
|
153
|
+
@offset=first
|
154
|
+
@data<<newvals
|
155
|
+
@data.pos=_adjust_pos_on_change(oldpos, first, len, newvals.size)-@offset
|
156
|
+
#assert @data.size+@offset==@seq.pos
|
157
|
+
else
|
158
|
+
#if first...first+len outside of @data, read it into @data first
|
159
|
+
oldpos=pos
|
160
|
+
self._pos=first
|
161
|
+
self._pos=first+len
|
162
|
+
self._pos=oldpos #then revert to orig position
|
163
|
+
|
164
|
+
assert( (0...@data.size)===first-@offset )
|
165
|
+
assert( (0...@data.size)===first+len-@offset )
|
166
|
+
@data.modify first-@offset,len,newvals
|
167
|
+
#assert @data.size+@offset==@seq.pos
|
168
|
+
end
|
169
|
+
notify_change(self,first,len,newvals.size)
|
170
|
+
|
171
|
+
#assert @data.size+@offset==@seq.pos
|
172
|
+
|
173
|
+
newvals
|
174
|
+
end
|
175
|
+
|
176
|
+
def pos; @data.pos+@offset end
|
177
|
+
|
178
|
+
def_delegators :@seq, :size
|
179
|
+
|
180
|
+
def eof?; @data.eof? and @seq.eof? end
|
181
|
+
# :startdoc:
|
182
|
+
|
183
|
+
def closed?
|
184
|
+
super or @seq.closed?
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright (C) 2006 Caleb Clausen
|
2
|
+
# Distributed under the terms of Ruby's license.
|
3
|
+
require 'sequence'
|
4
|
+
|
5
|
+
class Sequence
|
6
|
+
#represnts a seq over a single item
|
7
|
+
class SingleItem < Sequence
|
8
|
+
include ArrayLike
|
9
|
+
def initialize(obj)
|
10
|
+
@obj=obj
|
11
|
+
@eof=false
|
12
|
+
end
|
13
|
+
|
14
|
+
def read1
|
15
|
+
result=readahead1
|
16
|
+
@eof=true
|
17
|
+
result
|
18
|
+
end
|
19
|
+
|
20
|
+
def readahead1
|
21
|
+
@obj unless @eof
|
22
|
+
end
|
23
|
+
|
24
|
+
def size; 1 end
|
25
|
+
|
26
|
+
def eof?; @eof end
|
27
|
+
|
28
|
+
def read(len)
|
29
|
+
@eof and return []
|
30
|
+
@eof=true
|
31
|
+
return [@obj]
|
32
|
+
end
|
33
|
+
|
34
|
+
def begin!
|
35
|
+
@eof=false
|
36
|
+
end
|
37
|
+
|
38
|
+
def end!
|
39
|
+
@eof=true
|
40
|
+
end
|
41
|
+
|
42
|
+
def pos
|
43
|
+
@eof ? 1 : 0
|
44
|
+
end
|
45
|
+
|
46
|
+
def _pos=(pos)
|
47
|
+
@eof=pos.nonzero?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|