extract-curves 0.1.1-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. data/Changelog +21 -0
  2. data/bin/ec_rect2polar +22 -0
  3. data/bin/ec_rect2polar.rb +22 -0
  4. data/bin/ec_rev_lines +5 -0
  5. data/bin/ec_rev_lines.rb +5 -0
  6. data/bin/ec_sph_area +30 -0
  7. data/bin/ec_sph_area.rb +30 -0
  8. data/bin/extract_curves +1670 -0
  9. data/bin/extract_curves.rb +1670 -0
  10. data/ruby_ext/pav/extconf.rb +22 -0
  11. data/ruby_ext/pav/pav.dll +0 -0
  12. data/ruby_libs/pav/attr_cache.rb +211 -0
  13. data/ruby_libs/pav/attr_cache.t1.rb +32 -0
  14. data/ruby_libs/pav/cache.rb +31 -0
  15. data/ruby_libs/pav/collection/std.rb +58 -0
  16. data/ruby_libs/pav/dbg_log.rb +458 -0
  17. data/ruby_libs/pav/floatsio.rb +53 -0
  18. data/ruby_libs/pav/generator_cache.rb +165 -0
  19. data/ruby_libs/pav/graph/node.rb +602 -0
  20. data/ruby_libs/pav/graph/node_grp.rb +865 -0
  21. data/ruby_libs/pav/gtk.rb +6 -0
  22. data/ruby_libs/pav/gtk/button.rb +118 -0
  23. data/ruby_libs/pav/gtk/dialog.rb +29 -0
  24. data/ruby_libs/pav/gtk/guiobj.rb +772 -0
  25. data/ruby_libs/pav/gtk/icons.rb +124 -0
  26. data/ruby_libs/pav/gtk/rulers.rb +264 -0
  27. data/ruby_libs/pav/gtk/toolbar.rb +189 -0
  28. data/ruby_libs/pav/guiobj.rb +2 -0
  29. data/ruby_libs/pav/guiobj/info_asm.rb +41 -0
  30. data/ruby_libs/pav/guiobj/method.rb +211 -0
  31. data/ruby_libs/pav/guiobj/obj.rb +134 -0
  32. data/ruby_libs/pav/guiobj/signals.rb +9 -0
  33. data/ruby_libs/pav/heap.rb +54 -0
  34. data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
  35. data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
  36. data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
  37. data/ruby_libs/pav/icons/blob.gif +0 -0
  38. data/ruby_libs/pav/icons/contour.gif +0 -0
  39. data/ruby_libs/pav/icons/contour_carpet.gif +0 -0
  40. data/ruby_libs/pav/icons/curve.gif +0 -0
  41. data/ruby_libs/pav/icons/curve_carpet.gif +0 -0
  42. data/ruby_libs/pav/icons/expand_closed.xpm +1791 -0
  43. data/ruby_libs/pav/icons/expand_closed_hover.xpm +1775 -0
  44. data/ruby_libs/pav/icons/expand_open.xpm +1788 -0
  45. data/ruby_libs/pav/icons/expand_open_hover.xpm +1752 -0
  46. data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  47. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  48. data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
  49. data/ruby_libs/pav/icons/handle.xpm +213 -0
  50. data/ruby_libs/pav/icons/loop.gif +0 -0
  51. data/ruby_libs/pav/icons/loop_carpet.gif +0 -0
  52. data/ruby_libs/pav/icons/next.xpm +29 -0
  53. data/ruby_libs/pav/icons/next_hover.xpm +315 -0
  54. data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
  55. data/ruby_libs/pav/icons/prev.xpm +29 -0
  56. data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
  57. data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
  58. data/ruby_libs/pav/icons/shaved-core.gif +0 -0
  59. data/ruby_libs/pav/icons/vnext.xpm +29 -0
  60. data/ruby_libs/pav/icons/vprev.xpm +29 -0
  61. data/ruby_libs/pav/numeric/ext.rb +21 -0
  62. data/ruby_libs/pav/patterns/hsep.gif +0 -0
  63. data/ruby_libs/pav/patterns/tnode.gif +0 -0
  64. data/ruby_libs/pav/patterns/tnode_w_link.gif +0 -0
  65. data/ruby_libs/pav/patterns/vlink.gif +0 -0
  66. data/ruby_libs/pav/patterns/vsep.gif +0 -0
  67. data/ruby_libs/pav/patterns/yg_hrope.xpm +492 -0
  68. data/ruby_libs/pav/patterns/yg_hrope_thick.xpm +1904 -0
  69. data/ruby_libs/pav/patterns/yg_hrope_thin.xpm +130 -0
  70. data/ruby_libs/pav/patterns/yg_tnode.xpm +180 -0
  71. data/ruby_libs/pav/patterns/yg_tnode_thick.xpm +615 -0
  72. data/ruby_libs/pav/patterns/yg_tnode_thin.xpm +55 -0
  73. data/ruby_libs/pav/patterns/yg_tnode_w_link.xpm +190 -0
  74. data/ruby_libs/pav/patterns/yg_tnode_w_link_thick.xpm +676 -0
  75. data/ruby_libs/pav/patterns/yg_tnode_w_link_thin.xpm +62 -0
  76. data/ruby_libs/pav/patterns/yg_vrope.xpm +563 -0
  77. data/ruby_libs/pav/patterns/yg_vrope_thick.xpm +2047 -0
  78. data/ruby_libs/pav/patterns/yg_vrope_thin.xpm +166 -0
  79. data/ruby_libs/pav/pav_find.rb +90 -0
  80. data/ruby_libs/pav/pix.rb +402 -0
  81. data/ruby_libs/pav/pix/aapix.rb +378 -0
  82. data/ruby_libs/pav/pix/blob.rb +678 -0
  83. data/ruby_libs/pav/pix/circle.rb +73 -0
  84. data/ruby_libs/pav/pix/contour.rb +676 -0
  85. data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
  86. data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
  87. data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
  88. data/ruby_libs/pav/pix/contour/situations.rb +21 -0
  89. data/ruby_libs/pav/pix/curve.rb +1544 -0
  90. data/ruby_libs/pav/pix/img_obj.rb +865 -0
  91. data/ruby_libs/pav/pix/node.rb +159 -0
  92. data/ruby_libs/pav/pix/shaved_core.rb +697 -0
  93. data/ruby_libs/pav/pix/subpix.rb +212 -0
  94. data/ruby_libs/pav/rand_accessible.rb +16 -0
  95. data/ruby_libs/pav/rangeset.rb +63 -0
  96. data/ruby_libs/pav/search.rb +210 -0
  97. data/ruby_libs/pav/set.rb +130 -0
  98. data/ruby_libs/pav/string/bits.rb +523 -0
  99. data/ruby_libs/pav/string/ext.rb +58 -0
  100. data/ruby_libs/pav/string/observable.rb +155 -0
  101. data/ruby_libs/pav/string/text.rb +79 -0
  102. data/ruby_libs/pav/string/words.rb +42 -0
  103. data/ruby_libs/pav/sub_arr.rb +56 -0
  104. data/ruby_libs/pav/traced_obj.rb +79 -0
  105. data/web/index.html +280 -0
  106. data/web/media/icons/alt_handle.xpm +3832 -0
  107. data/web/media/icons/alt_handle_hover.xpm +3368 -0
  108. data/web/media/icons/alt_handle_pressed.xpm +3828 -0
  109. data/web/media/icons/blob.gif +0 -0
  110. data/web/media/icons/contour.gif +0 -0
  111. data/web/media/icons/contour_carpet.gif +0 -0
  112. data/web/media/icons/curve.gif +0 -0
  113. data/web/media/icons/curve_carpet.gif +0 -0
  114. data/web/media/icons/expand_closed.xpm +1791 -0
  115. data/web/media/icons/expand_closed_hover.xpm +1775 -0
  116. data/web/media/icons/expand_open.xpm +1788 -0
  117. data/web/media/icons/expand_open_hover.xpm +1752 -0
  118. data/web/media/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  119. data/web/media/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  120. data/web/media/icons/extract_curves/trace_mark.xpm +38 -0
  121. data/web/media/icons/handle.xpm +213 -0
  122. data/web/media/icons/loop.gif +0 -0
  123. data/web/media/icons/loop_carpet.gif +0 -0
  124. data/web/media/icons/next.xpm +29 -0
  125. data/web/media/icons/next_hover.xpm +315 -0
  126. data/web/media/icons/next_pressed.xpm +144 -0
  127. data/web/media/icons/prev.xpm +29 -0
  128. data/web/media/icons/prev_hover.xpm +315 -0
  129. data/web/media/icons/prev_pressed.xpm +144 -0
  130. data/web/media/icons/shaved-core.gif +0 -0
  131. data/web/media/icons/vnext.xpm +29 -0
  132. data/web/media/icons/vprev.xpm +29 -0
  133. data/web/media/title.jpeg +0 -0
  134. data/web/stylesheets/default.css +20 -0
  135. metadata +192 -0
@@ -0,0 +1,130 @@
1
+ require 'set'
2
+ require 'pav/search'
3
+
4
+ class SortedArrSet
5
+ attr_reader :arr, :comparator
6
+
7
+ def initialize(arr, &comparator)
8
+ @arr = arr
9
+ @comparator = comparator
10
+ end
11
+
12
+ def include?(m)
13
+ PSearch.bsearch(@arr, m, &@comparator) >= 0
14
+ end
15
+
16
+ alias_method :member?, :include?
17
+
18
+ def method_missing(id, *args, &block)
19
+ @arr.send(id, *args, &block)
20
+ end
21
+ end
22
+
23
+ class ObjIdSet < Hash
24
+ def initialize
25
+ super(0)
26
+ end
27
+
28
+ def add(obj)
29
+ self[obj.object_id] += 1
30
+ self
31
+ end
32
+
33
+ alias_method :<<, :add
34
+
35
+ def push(obj)
36
+ self[obj.object_id] += 1
37
+ obj
38
+ end
39
+
40
+ def pop_obj(obj)
41
+ if (left = (self[obj.object_id] -= 1)) < 1
42
+ warn("#{self.class.name}.pop_obj: Obj. not in set: #{
43
+ obj}!") if left < 0
44
+ self.delete(obj)
45
+ end
46
+ end
47
+
48
+ def delete(obj)
49
+ super(obj.object_id)
50
+ end
51
+
52
+ def member?(obj)
53
+ super(obj.object_id)
54
+ end
55
+
56
+ alias_method :include?, :member?
57
+
58
+ def each
59
+ self.each_key { |oid| yield(ObjectSpace._id2ref(oid)) }
60
+ end
61
+
62
+ alias_method :each_value, :each
63
+
64
+ def to_a
65
+ res = []
66
+ self.each { |obj| res << obj }
67
+ res
68
+ end
69
+
70
+ def first
71
+ self.each { |res| return res }
72
+ nil
73
+ end
74
+ end
75
+
76
+ class ObjIdSetWithArr < Array
77
+ attr_reader :set
78
+
79
+ def initialize
80
+ @set = Hash.new(0)
81
+ super()
82
+ end
83
+
84
+ def <<(obj)
85
+ @set[obj.object_id] += 1
86
+ super(obj)
87
+ self
88
+ end
89
+
90
+ alias_method :add, :<<
91
+
92
+ def push(obj)
93
+ @set[obj.object_id] += 1
94
+ super(obj)
95
+ end
96
+
97
+ def pop
98
+ if self.empty?
99
+ return nil
100
+ else
101
+ @set[(res=super).object_id] -= 1
102
+ res
103
+ end
104
+ end
105
+
106
+ def member?(obj)
107
+ @set.member?(obj.object_id)
108
+ end
109
+
110
+ alias_method :include?, :member?
111
+
112
+ def pop_obj(obj)
113
+ if (left = (@set[obj.object_id] -= 1)) < 1
114
+ @set.delete(obj.object_id)
115
+ if left < 0
116
+ warn("#{self.class.name}.pop_obj: Obj. not in set: #{
117
+ obj}!")
118
+ return
119
+ end
120
+ end
121
+ i = 0
122
+ while i < self.length
123
+ if obj.equal?(self.at(i))
124
+ self.delete_at(i)
125
+ return
126
+ end
127
+ i += 1
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,523 @@
1
+ require 'sync'
2
+ require 'pav/string/observable'
3
+
4
+ class BitArr
5
+ attr_reader :str, :length
6
+
7
+ include Sync_m
8
+ include Enumerable
9
+ include Comparable
10
+
11
+ alias_method :__ba_sync_init__, :initialize
12
+ protected :__ba_sync_init__
13
+
14
+ def initialize(bits="", length=nil)
15
+ if bits.kind_of? String
16
+ @length = length
17
+ if !length
18
+ @str = bits
19
+ @length = @str.length * 8
20
+ else
21
+ str_len = @length/8 + (@length%8 == 0 ? 0 : 1)
22
+ @str = bits[0, str_len]
23
+ @str << "\0" * (str_len - @str.length) if
24
+ str_len > @str.length
25
+ @str[str_len-1] &= (0xff >> 8 - length % 8) if
26
+ length % 8 != 0
27
+ end
28
+ self.__ba_sync_init__()
29
+ elsif bits.kind_of? Array
30
+ @str = "\0" * ((bits.length/8)+(bits.length%8==0 ? 0:1))
31
+ (@length = bits.length).times { |i|
32
+ if bits[i] != 0
33
+ @str[i/8] = @str[i/8] | (1 << i%8)
34
+ end
35
+ }
36
+ self.__ba_sync_init__()
37
+ elsif bits.kind_of? BitArr
38
+ initialize(bits.str, length)
39
+ elsif bits.kind_of? Integer
40
+ @str = ""
41
+ while bits > 0xff
42
+ @str << bits & 0xff
43
+ bits >>= 8
44
+ end
45
+ @length = @str.length * 8
46
+ if bits > 0
47
+ @str << bits
48
+ while bits > 0
49
+ @length += 1
50
+ bits >>= 1
51
+ end
52
+ end
53
+ self.__ba_sync_init__()
54
+ else
55
+ raise ArgumentError,
56
+ "Invalid bits argument: #{bits.inspect}"
57
+ end
58
+ end
59
+
60
+ def push(bit)
61
+ self.synchronize {
62
+ bit = bit & 1
63
+ if (ofs = @length % 8) == 0
64
+ @str << bit
65
+ else
66
+ @str[-1] = @str[-1] | (bit << ofs)
67
+ end
68
+ @length = @length + 1
69
+ self
70
+ }
71
+ end
72
+
73
+ alias_method :<<, :push
74
+
75
+ def delete_at(idx)
76
+ self.synchronize {
77
+ idx = -idx-1 if idx < 0
78
+ return nil if idx >= @length
79
+ byte_i, ofs = idx / 8, idx % 8
80
+ res = @str[byte_i][ofs]
81
+ @str[byte_i] = ( (@str[byte_i] & (0xff >> 8-ofs)) << 1 ) |
82
+ (@str[byte_i] & ((0xff << ofs+1) & 0xff))
83
+ for i in byte_i...@str.length-1
84
+ @str[i] = @str[i] >> 1 | ((@str[i+1] & 1) << 7)
85
+ end
86
+ if (@length = @length - 1) % 8 == 0
87
+ @str[-1] = ""
88
+ else
89
+ @str[-1] = @str[-1] >> 1
90
+ end
91
+ res
92
+ }
93
+ end
94
+
95
+ def slice!(i, len=nil)
96
+ self.synchronize {
97
+ if i.kind_of? Range
98
+ i, len = [i.first, i.last].min, (i.last - i.first).abs
99
+ len = len + 1 if !i.exclude_end?
100
+ elsif len == nil
101
+ return delete_at(i)
102
+ end
103
+ i = @length+i if i < 0
104
+ return nil if i >= @length || i < 0 || len < 1
105
+ res = self[i, len]
106
+ len = @length - i if i + len > @length
107
+ byte_i, ofs = i / 8, i % 8
108
+ if len <= 8 - ofs
109
+ @str[byte_i] = ((@str[byte_i] & (0xff >> 8-ofs))<<len) |
110
+ (@str[byte_i] & ((0xff << ofs+len) & 0xff))
111
+ ofs = 8 - len
112
+ else
113
+ del_algn_bits_cnt = len - 8 + ofs
114
+ @str.slice!(byte_i+1, del_algn_bits_cnt / 8)
115
+ if del_algn_bits_cnt % 8 > 0
116
+ del_algn_bits_cnt = del_algn_bits_cnt % 8
117
+ dst_mask = (0xff >> 8-ofs)
118
+ push_bits = @str[byte_i+1] >> del_algn_bits_cnt
119
+ @str[byte_i] = (@str[byte_i] & dst_mask) |
120
+ ((push_bits << ofs) & 0xff)
121
+ if ofs > del_algn_bits_cnt
122
+ byte_i = byte_i + 1
123
+ @str[byte_i] = push_bits >> 8-ofs
124
+ else
125
+ @str[byte_i+1] = ""
126
+ end
127
+ ofs = (ofs + 8-del_algn_bits_cnt) % 8
128
+ @str[byte_i] = @str[byte_i] << 8-ofs
129
+ end
130
+ end
131
+ for i in byte_i...@str.length-1
132
+ @str[i] = (@str[i] >> 8-ofs) |
133
+ ((@str[i+1] << ofs) & 0xff)
134
+ end
135
+ if @length % 8 <= 8-ofs
136
+ @str[-1] = ""
137
+ else
138
+ @str[-1] = @str[-1] >> 8-ofs
139
+ end
140
+ @length = @length - len
141
+ res
142
+ }
143
+ end
144
+
145
+ def at(i)
146
+ i = @length+i if i < 0
147
+ return 0 if i >= @length || i < 0
148
+ @str[i/8][i%8]
149
+ end
150
+
151
+ def [](i, len=nil)
152
+ self.synchronize {
153
+ if !len
154
+ if i.kind_of?(Range)
155
+ if i.last >= i.first
156
+ return self[i.first, i.last - i.first +
157
+ (i.exclude_end? ? 0 : 1)]
158
+ else
159
+ is = i
160
+ end
161
+ elsif i.kind_of?(Array)
162
+ is = i
163
+ elsif i.kind_of?(Integer)
164
+ i = @length+i if i < 0
165
+ return 0 if i >= @length || i < 0
166
+ return @str[i / 8][i % 8]
167
+ else
168
+ raise ArgumentError, "Wrong single argument"
169
+ end
170
+ else
171
+ i = @length+i if i < 0
172
+ return nil if len < 0 || i >= @length || i < 0
173
+ return BitArr.new if len == 0
174
+ len = @length - i if i + len > @length
175
+ byte_i, ofs = i / 8, i % 8
176
+ if ofs == 0
177
+ res = @str[byte_i, len/8]
178
+ if len % 8 > 0
179
+ res << @str[byte_i + len/8]
180
+ res[-1] = res[-1] & (0xff >> (8-len%8))
181
+ end
182
+ return BitArr.new(res, len)
183
+ end
184
+ mask,res = 0xff>>8-ofs, "\0"*(len/8 + (len%8==0 ? 0:1))
185
+ i = -1
186
+ (len/8).times { |i|
187
+ res[i] = (@str[byte_i] >> ofs) |
188
+ ((@str[byte_i+1] & mask) << (8 - ofs))
189
+ byte_i = byte_i + 1
190
+ }
191
+ if len % 8 != 0
192
+ res[i+1] = (@str[byte_i] >> ofs)
193
+ if ofs + len % 8 > 8
194
+ res[i+1] = res[i+1] |
195
+ ((@str[byte_i+1] & mask) << (8 - ofs))
196
+ end
197
+ res[i+1] = res[i+1] & (0xff >> 8 - len % 8)
198
+ end
199
+ return BitArr.new(res, len)
200
+ end
201
+ res = BitArr.new
202
+ is.each { |i|
203
+ i = @length+i if i < 0
204
+ if i >= @length || i < 0
205
+ res.push(0)
206
+ else
207
+ res.push(@str[i / 8][i % 8])
208
+ end
209
+ }
210
+ res
211
+ }
212
+ end
213
+
214
+ def []=(i, rval, len=nil)
215
+ self.synchronize {
216
+ rval, len = len, rval if len
217
+ rval = BitArr.new(rval) if rval.kind_of?(Array) ||
218
+ rval.kind_of?(String)
219
+ if !len
220
+ if i.kind_of? Range
221
+ return self[[i.first,i.last].min,
222
+ (i.last - i.first).abs +
223
+ (i.exclude_end? ? 0 : 1)] = rval
224
+ elsif i.kind_of? Array
225
+ is = i
226
+ elsif i.kind_of? Integer
227
+ if rval.kind_of?(BitArr)
228
+ return self.delete_at(i) if rval.empty?
229
+ return self[i,1] = rval
230
+ end
231
+ if rval == nil
232
+ return self.delete_at(i)
233
+ else
234
+ @str << "\0"*(i/8-@str.length+1) if
235
+ i/8 >= @str.length
236
+ @length = i + 1 if i+1 > @length
237
+ if rval == 0
238
+ return @str[i/8] = @str[i/8] &
239
+ ( (1 << (i%8)) ^ 0xff )
240
+ else
241
+ return @str[i/8] = @str[i/8] |
242
+ (1 << (i%8))
243
+ end
244
+ end
245
+ else
246
+ raise ArgumentError, "Invalid single argument"
247
+ end
248
+ else
249
+ len = 0 if len < 0
250
+ return self.slice!(i, len) if rval == nil
251
+ rval = BitArr.new(rval) if rval.kind_of? Integer
252
+ if len > rval.length
253
+ self.slice!(i + rval.length, len - rval.length)
254
+ len = rval.length
255
+ elsif len < rval.length
256
+ j = i + len
257
+ ins_len, byte_i, ofs = rval.length-len, j/8, j%8
258
+ if ofs + ins_len <= 8
259
+ shl_cnt = ins_len
260
+ else
261
+ shl_cnt = (ins_len - 8 + ofs) % 8
262
+ end
263
+ @str << "\0" if @length % 8 + shl_cnt > 8
264
+ (@str.length - 1).downto(byte_i + 1) { |k|
265
+ @str[k] = ((@str[k]<<shl_cnt) & 0xff) |
266
+ (@str[k-1] >> 8-shl_cnt)
267
+ }
268
+ if ofs + ins_len <= 8
269
+ @str[byte_i] = (@str[byte_i] &
270
+ (0xff >> 8-ofs)) |
271
+ (((@str[byte_i] &
272
+ ((0xff << ofs) & 0xff)) << ins_len) &
273
+ 0xff)
274
+ else
275
+ @str[byte_i] = @str[byte_i] &
276
+ (0xff >> 8-ofs)
277
+ @str[byte_i, 0] = "\0" *
278
+ ((ins_len - 8 + ofs) / 8)
279
+ end
280
+ @length = @length + ins_len
281
+ end
282
+ byte_i, ofs = (i+len-1) / 8, (i+len-1) % 8
283
+ if i + len > @length
284
+ @str << "\0" * (byte_i + 1 - @str.length)
285
+ @length = i + len
286
+ end
287
+ if byte_i == i / 8
288
+ @str[byte_i] = (@str[byte_i] &
289
+ ((0xff << ofs) & 0xff)) |
290
+ (@str[byte_i] & (0xff >> 8 - i % 8)) |
291
+ (rval.to_i << i % 8)
292
+ else
293
+ @str[byte_i] = (@str[byte_i] &
294
+ ((0xff << ofs) & 0xff)) |
295
+ rval[-8+ofs-1, ofs].str[0]
296
+ byte_i, ofs = i / 8, i % 8
297
+ @str[byte_i] = (@str[byte_i] & (0xff>>8-ofs)) |
298
+ (rval[0..8-ofs].to_i << ofs)
299
+ ofs = 8 - ofs
300
+ bytes_cnt = (i + rval.length) / 8 - byte_i - 1
301
+ @str[i, bytes_cnt] = rval[ofs, 8 * bytes_cnt].
302
+ str if bytes_cnt > 0
303
+ end
304
+ return
305
+ end
306
+ [is.length, rval.length].min.times { |i|
307
+ self[is[i]] = rval[rval_i]
308
+ }
309
+ if is.length > rval.length
310
+ del_is = (is[rval.length...is.length]).sort!
311
+ prev_i, c = del_is.last, 1
312
+ del_is.reverse_each { |i|
313
+ next if i == prev_i
314
+ if i = prev_i-1
315
+ c = c + 1
316
+ else
317
+ self.slice!(prev_i,c)
318
+ c = 1
319
+ end
320
+ prev_i = i
321
+ }
322
+ self.slice!(prev_i, c)
323
+ end
324
+ }
325
+ end
326
+
327
+ def each
328
+ self.synchronize {
329
+ @str.each_byte { |b|
330
+ 8.times { |i| yield b[i] }
331
+ }
332
+ }
333
+ end
334
+
335
+ def empty?
336
+ @length == 0
337
+ end
338
+
339
+ def to_s
340
+ self.synchronize {
341
+ @str.unpack("b#{@length}")[0]
342
+ }
343
+ end
344
+
345
+ def to_i
346
+ self.synchronize {
347
+ res = 0
348
+ shl_cnt = 0
349
+ @str.each_byte { |b|
350
+ res = res | (b << shl_cnt)
351
+ shl_cnt = shl_cnt + 8
352
+ }
353
+ res
354
+ }
355
+ end
356
+
357
+ def <=>(other)
358
+ if other.kind_of?(BitArr)
359
+ return @length <=> other.length if @length!=other.length
360
+ 0.upto((@length-1)/8) { |i|
361
+ return leg if (leg=(@str[i]<=>other.str[i]))!=0
362
+ }
363
+ return 0
364
+ elsif other.kind_of?(String)
365
+ return (@length/8) <=> other.length if
366
+ @length/8 != other.length
367
+ for i in 0.upto((@length-1)/8)
368
+ return leg if (leg = (@str[i] <=> other[i]))!=0
369
+ end
370
+ return 0
371
+ elsif other.kind_of?(Array)
372
+ return @length <=> other.length if @length!=other.length
373
+ for i in 0..@length
374
+ return leg if (leg = (self[i]<=>other[i])) != 0
375
+ end
376
+ return 0
377
+ elsif other.kind_of?(Integer)
378
+ return self.to_i <=> other
379
+ end
380
+ end
381
+ end
382
+
383
+ class IntBitPlaneArr
384
+ attr_reader :length, :bit_planes_cnt, :bit_arr
385
+
386
+ def initialize(bits="", length=nil, bit_planes_cnt=nil)
387
+ @bit_arr = BitArr.new(bits, length)
388
+ if bit_planes_cnt
389
+ @bit_planes_cnt = bit_planes_cnt
390
+ @length = @bit_arr.length * @bit_planes_cnt
391
+ else
392
+ if (@length = @bit_arr.length) == 0
393
+ @bit_planes_cnt = 0
394
+ else
395
+ @bit_planes_cnt = 1
396
+ end
397
+ end
398
+ end
399
+
400
+ def at(i)
401
+ i = @length+i if i < 0
402
+ return nil if i >= @length || i < 0
403
+ lm = 0
404
+ bp_start = 0
405
+ for p in 0...@bit_planes_cnt
406
+ lm |= (@bit_arr.at(bp_start + i) << p)
407
+ bp_start += @length
408
+ end
409
+ lm
410
+ end
411
+
412
+ def at?(i, val)
413
+ i = @length+i if i < 0
414
+ return val == nil if i >= @length || i < 0
415
+ bp_start = 0
416
+ for p in 0...@bit_planes_cnt
417
+ return false if (val & 1) != @bit_arr[bp_start + i]
418
+ bp_start += @length
419
+ val >>= 1
420
+ end
421
+ return val == 0
422
+ end
423
+
424
+ def bit_planes_cnt=(val)
425
+ @bit_planes_cnt = val
426
+ if val < @bit_planes_cnt
427
+ @bit_arr[@length*@bit_planes_cnt...@bit_arr.length]=nil
428
+ end
429
+ end
430
+
431
+ def [](i, len=nil)
432
+ if len
433
+ is = i...(i+len)
434
+ else
435
+ if i.kind_of?(Range) || i.kind_of?(Array)
436
+ is = i
437
+ elsif i.kind_of?(Integer)
438
+ return self.at(i)
439
+ else
440
+ raise ArgumentError,
441
+ "Invalid index: #{i.inspect}"
442
+ end
443
+ end
444
+ is.collect { |i| self.at(i) }
445
+ end
446
+
447
+ def []=(i, *args)
448
+ if args.length == 1
449
+ rval = args[0]
450
+ raise NotImplementError, "rval=nil" if !rval
451
+ raise NotImplementError, "i>length" if i>@length
452
+ rval = [rval] if rval.kind_of?(Integer)
453
+ if i.kind_of?(Range) || i.kind_of?(Array)
454
+ is = i
455
+ elsif i.kind_of?(Integer)
456
+ i = @length+i if i < 0
457
+ bp_start = 0
458
+ for p in 0...@bit_planes_cnt
459
+ bits = []
460
+ rval.each_with_index { |v, idx|
461
+ bits << (v&1)
462
+ rval[idx] >>= 1
463
+ }
464
+ @bit_arr[bp_start+i] = bits
465
+ bp_start += @length
466
+ end
467
+ not_all_0 = false
468
+ for v in rval
469
+ if v != 0
470
+ not_all_0 = true
471
+ break
472
+ end
473
+ end
474
+ while not_all_0
475
+ not_all_0 = false
476
+ bits = []
477
+ rval.each_with_index { |v, idx|
478
+ bits << (v&1)
479
+ rval[idx] >>= 1
480
+ not_all_0=true if rval[idx]!= 0
481
+ }
482
+ @bit_arr[bp_start+i] = bits
483
+ bp_start += @length
484
+ @bit_planes_cnt += 1
485
+ end
486
+ return
487
+ else
488
+ raise ArgumentError,
489
+ "Invalid index: #{i.inspect}"
490
+ end
491
+ elsif args.length == 2
492
+ len, rval = *args
493
+ is = i...(i+len)
494
+ else
495
+ raise ArgumentError,
496
+ "Invalid number of arguments: #{args.inspect}"
497
+ end
498
+ is.each_with_index { |i, idx|
499
+ self[i] = rval[idx]
500
+ }
501
+ end
502
+ end
503
+
504
+ class StringBitsObserver
505
+ def self.update(str, meth, args, block)
506
+ str.kill_bits
507
+ end
508
+ end
509
+
510
+ class String
511
+ def bits
512
+ self.add_observer(StringBitsObserver)
513
+ def bits
514
+ @bits = BitArr.new(self) unless @bits
515
+ @bits
516
+ end
517
+ self.bits
518
+ end
519
+
520
+ def kill_bits
521
+ @bits = nil
522
+ end
523
+ end