mu 5.7.9 → 5.7.10
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mu/command/cmd_musl.rb +4 -4
- data/lib/mu/command/cmd_runscale.rb +1 -81
- data/lib/mu/command/help.rb +0 -1
- data/lib/mu/har.rb +29 -10
- data/lib/mu/maker.rb +0 -4
- metadata +19 -22
- data/lib/mu/command/cmd_appid.rb +0 -531
- data/lib/mu/libxml.rb +0 -21
- data/lib/mu/xmlizable.rb +0 -559
data/lib/mu/libxml.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# Copyright (C) 2008 Mu Dynamics, Inc
|
2
|
-
#
|
3
|
-
# This program is confidential and proprietary to Mu Dynamics, Inc and
|
4
|
-
# may not be reproduced, published or disclosed to others without its
|
5
|
-
# authorization.
|
6
|
-
|
7
|
-
module LibXML
|
8
|
-
module XML
|
9
|
-
class Node
|
10
|
-
# Get first element, optionally with name.
|
11
|
-
def first_element name=nil
|
12
|
-
each_element do |element|
|
13
|
-
if not name or name == element.name
|
14
|
-
return element
|
15
|
-
end
|
16
|
-
end
|
17
|
-
return nil
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/mu/xmlizable.rb
DELETED
@@ -1,559 +0,0 @@
|
|
1
|
-
# Copyright (C) 2008 Mu Dynamics, Inc
|
2
|
-
#
|
3
|
-
# This program is confidential and proprietary to Mu Dynamics, Inc and
|
4
|
-
# may not be reproduced, published or disclosed to others without its
|
5
|
-
# authorization.
|
6
|
-
|
7
|
-
require 'libxml'
|
8
|
-
require 'mu/libxml'
|
9
|
-
|
10
|
-
# Helper mixin for XML serialization.
|
11
|
-
#
|
12
|
-
# Example:
|
13
|
-
# class MyObject
|
14
|
-
# include XMLizable
|
15
|
-
# xmlizable 'my-object' do
|
16
|
-
# xml_element :a, Integer
|
17
|
-
# xml_attribute :b, String, :required => true
|
18
|
-
# end
|
19
|
-
# ...
|
20
|
-
module XMLizable
|
21
|
-
class XMLParseError < StandardError ; end
|
22
|
-
|
23
|
-
def self.included klass
|
24
|
-
super
|
25
|
-
klass.extend XMLizableClassMethods
|
26
|
-
end
|
27
|
-
|
28
|
-
module XMLizableClassMethods
|
29
|
-
# Declare object to be XML serializable. If name is not given, the
|
30
|
-
# object itself cannot be serialized and only XMLizable subclasses can.
|
31
|
-
def xmlizable name=nil #block
|
32
|
-
if defined? @xmlizable_called
|
33
|
-
raise ArgumentError, "Only call xmlizable once"
|
34
|
-
end
|
35
|
-
@xmlizable_called = true
|
36
|
-
@xmlizable_name = name
|
37
|
-
@xmlizable_classes = {}
|
38
|
-
if name
|
39
|
-
# Add this class to ancestor's XMLizable class map.
|
40
|
-
classes = ancestors.select { |ancestor| ancestor < XMLizable }
|
41
|
-
classes.each do |ancestor|
|
42
|
-
if ancestor.instance_variable_defined? :@xmlizable_classes
|
43
|
-
classes =
|
44
|
-
ancestor.instance_variable_get :@xmlizable_classes
|
45
|
-
classes[name] = self
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Set xmlizable elements and attributes in block
|
51
|
-
@xmlizable_elements = []
|
52
|
-
@xmlizable_attributes = []
|
53
|
-
if block_given?
|
54
|
-
yield
|
55
|
-
end
|
56
|
-
|
57
|
-
# Re-init to merge in ancestor elements and attributes
|
58
|
-
init_elements_and_attrs
|
59
|
-
end
|
60
|
-
|
61
|
-
# Initialize @xmlizable_elements and @xmlizable_attributes
|
62
|
-
def init_elements_and_attrs
|
63
|
-
# Get non-duplicate elements/attibutes from ancestors (including
|
64
|
-
# current class)
|
65
|
-
elems = []
|
66
|
-
attrs = []
|
67
|
-
attr_names = Set.new
|
68
|
-
elem_names = Set.new
|
69
|
-
ancestors.each do |klass|
|
70
|
-
next unless klass < XMLizable
|
71
|
-
if klass.instance_variable_defined? :@xmlizable_elements
|
72
|
-
klass.xmlizable_elements.reverse_each do |e|
|
73
|
-
elems.unshift e unless elem_names.include? e.name
|
74
|
-
elem_names << e.name
|
75
|
-
end
|
76
|
-
end
|
77
|
-
if klass.instance_variable_defined? :@xmlizable_attributes
|
78
|
-
klass.xmlizable_attributes.reverse_each do |a|
|
79
|
-
attrs.unshift a unless attr_names.include? a.name
|
80
|
-
attr_names << a.name
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
@xmlizable_attributes = attrs.freeze
|
85
|
-
@xmlizable_elements = elems.freeze
|
86
|
-
end
|
87
|
-
|
88
|
-
# There may be subclasses that indirectly include XMLizable or that never
|
89
|
-
# call xmlizable. Use inherited hook to make sure they are initialized
|
90
|
-
def inherited(klass)
|
91
|
-
klass.init_elements_and_attrs
|
92
|
-
end
|
93
|
-
|
94
|
-
# Declare variable to be serialized as an XML element of type.
|
95
|
-
def xml_element name, klass, *opts
|
96
|
-
element = xml_object name, klass, *opts
|
97
|
-
@xmlizable_elements << element
|
98
|
-
end
|
99
|
-
|
100
|
-
# Declare variable to be serialized as an array of XML element with
|
101
|
-
# of type. The type must support to/from_libxml.
|
102
|
-
def xml_elements name, klass, *opts
|
103
|
-
element = xml_object name, klass, *opts
|
104
|
-
element.array = true
|
105
|
-
@xmlizable_elements << element
|
106
|
-
end
|
107
|
-
|
108
|
-
# Declare variable to be serialized as an XML attribute of type.
|
109
|
-
def xml_attribute name, klass, *opts
|
110
|
-
attribute = xml_object name, klass, *opts
|
111
|
-
@xmlizable_attributes << attribute
|
112
|
-
end
|
113
|
-
|
114
|
-
def xmlizable_name
|
115
|
-
@xmlizable_name
|
116
|
-
end
|
117
|
-
|
118
|
-
# Get list of elements.
|
119
|
-
def xmlizable_elements
|
120
|
-
@xmlizable_elements
|
121
|
-
end
|
122
|
-
|
123
|
-
# Get list of attributes.
|
124
|
-
def xmlizable_attributes
|
125
|
-
@xmlizable_attributes
|
126
|
-
end
|
127
|
-
|
128
|
-
# Create object to XML::Node. The object must be creatable by
|
129
|
-
# calling a constructor with no arguments.
|
130
|
-
def from_libxml node
|
131
|
-
if node.name != @xmlizable_name
|
132
|
-
xmlizable_classes = @xmlizable_classes
|
133
|
-
klass = xmlizable_classes[node.name]
|
134
|
-
if klass and klass != self
|
135
|
-
return klass.from_libxml(node)
|
136
|
-
else
|
137
|
-
raise XMLParseError, "Unknown element: #{node.name}"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
object = self.new
|
142
|
-
@xmlizable_attributes.each do |attribute|
|
143
|
-
value = node[attribute.xml_name]
|
144
|
-
if value
|
145
|
-
attribute_klass = attribute.klass
|
146
|
-
if attribute_klass == String
|
147
|
-
# Common case with no special treatment
|
148
|
-
elsif attribute_klass <= Integer
|
149
|
-
value = value.to_i
|
150
|
-
elsif attribute_klass <= Float
|
151
|
-
value = value.to_f
|
152
|
-
elsif attribute_klass <= TrueClass
|
153
|
-
if value == 'true'
|
154
|
-
value = true
|
155
|
-
elsif value == 'false'
|
156
|
-
value = false
|
157
|
-
else
|
158
|
-
raise XMLParseError, 'Invalid boolean value: ' +
|
159
|
-
value.inspect
|
160
|
-
end
|
161
|
-
elsif attribute_klass <= Symbol
|
162
|
-
begin
|
163
|
-
value = value.to_sym
|
164
|
-
rescue ArgumentError
|
165
|
-
raise XMLParseError, "Invalid value: #{value.inspect} in #{node.name}"
|
166
|
-
end
|
167
|
-
if attribute.enum and not attribute.enum.member? value
|
168
|
-
raise XMLParseError, "Invalid value: #{value.inspect} in #{node.name}"
|
169
|
-
end
|
170
|
-
end
|
171
|
-
object.send :"#{attribute.name}=", value
|
172
|
-
elsif attribute.required
|
173
|
-
raise XMLParseError, "Required attribute missing: " +
|
174
|
-
attribute.xml_name + ' in ' + node.name
|
175
|
-
else
|
176
|
-
object.send "#{attribute.name}=", attribute.default
|
177
|
-
end
|
178
|
-
end
|
179
|
-
@xmlizable_elements.each do |element|
|
180
|
-
element_node = node.first_element element.xml_name
|
181
|
-
if element_node
|
182
|
-
element_klass = element.klass
|
183
|
-
if element_klass == String or element_klass == Mu::Scenario::Field::Reference
|
184
|
-
content = element_node.content
|
185
|
-
case element.escape
|
186
|
-
when :default
|
187
|
-
content.delete! TAB_CR_LF
|
188
|
-
value = XMLizable.unescape content
|
189
|
-
when :no_newline
|
190
|
-
content.delete! TAB_CR
|
191
|
-
value = XMLizable.unescape content
|
192
|
-
when :regexp
|
193
|
-
value = content
|
194
|
-
else
|
195
|
-
raise XMLParseError, "Unknown escape type: #{element.escape}"
|
196
|
-
end
|
197
|
-
elsif element_klass == Integer
|
198
|
-
value = element_node.content.to_i(0)
|
199
|
-
elsif element.array
|
200
|
-
value = []
|
201
|
-
element_node.each_element do |value_node|
|
202
|
-
value << element.klass.from_libxml(value_node)
|
203
|
-
end
|
204
|
-
elsif element_klass == Float
|
205
|
-
value = element_node.content.to_f
|
206
|
-
elsif element_klass == Symbol
|
207
|
-
value = element_node.content
|
208
|
-
begin
|
209
|
-
value = value.to_sym
|
210
|
-
rescue ArgumentError
|
211
|
-
raise XMLParseError, "Invalid value: #{value.inspect} in #{node.name}"
|
212
|
-
end
|
213
|
-
if element.enum and not element.enum.member? value
|
214
|
-
raise XMLParseError, "Invalid value: #{value.inspect} in #{node.name}"
|
215
|
-
end
|
216
|
-
elsif element_klass == TrueClass
|
217
|
-
value = element_node.content
|
218
|
-
if value == 'true'
|
219
|
-
value = true
|
220
|
-
elsif value == 'false'
|
221
|
-
value = false
|
222
|
-
else
|
223
|
-
raise XMLParseError, 'Invalid boolean value: ' +
|
224
|
-
value.inspect
|
225
|
-
end
|
226
|
-
else
|
227
|
-
value_node = element_node.first_element
|
228
|
-
if not value_node
|
229
|
-
raise XMLParseError, 'Element missing value: ' +
|
230
|
-
element.xml_name + ' in ' + node.name
|
231
|
-
end
|
232
|
-
value = element_klass.from_libxml value_node
|
233
|
-
end
|
234
|
-
object.send :"#{element.name}=", value
|
235
|
-
elsif element.required
|
236
|
-
raise XMLParseError, 'Required element missing: ' +
|
237
|
-
element.xml_name + ' in ' + node.name
|
238
|
-
else
|
239
|
-
object.send :"#{element.name}=", element.default
|
240
|
-
end
|
241
|
-
end
|
242
|
-
object.post_from_libxml node
|
243
|
-
return object
|
244
|
-
end
|
245
|
-
|
246
|
-
private
|
247
|
-
|
248
|
-
# Create new XML serializable object. Internal helper method.
|
249
|
-
XMLObject = ::Struct.new :name, :klass, :default, :required, :internal,
|
250
|
-
:array, :enum, :xml_name, :label, :doc, :escape
|
251
|
-
def xml_object name, klass, *opts
|
252
|
-
# Get default value
|
253
|
-
if not opts[0].is_a? Hash
|
254
|
-
default = opts.shift
|
255
|
-
else
|
256
|
-
default = nil
|
257
|
-
end
|
258
|
-
array = false
|
259
|
-
if opts[-1]
|
260
|
-
required = opts[-1].fetch :required, false
|
261
|
-
internal = opts[-1].fetch :internal, false
|
262
|
-
enum = opts[-1][:enum]
|
263
|
-
xml_name = opts[-1].fetch :xml_name, name.to_s
|
264
|
-
label = opts[-1][:label]
|
265
|
-
doc = opts[-1][:doc]
|
266
|
-
escape = opts[-1].fetch :escape, :default
|
267
|
-
else
|
268
|
-
required = false
|
269
|
-
internal = false
|
270
|
-
enum = nil
|
271
|
-
xml_name = name.to_s
|
272
|
-
label = nil
|
273
|
-
doc = nil
|
274
|
-
escape = :default
|
275
|
-
end
|
276
|
-
return XMLObject.new(name, klass, default, required, internal,
|
277
|
-
array, enum, xml_name, label, doc, escape)
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
# Traverses the XMLizable tree rooted at the current node, passing
|
282
|
-
# each child node to the associated block. If the block returns a
|
283
|
-
# value other than nil or false the child is replaced with that
|
284
|
-
# value.
|
285
|
-
def xmlizable_replace_nodes &block
|
286
|
-
self.class.xmlizable_attributes.each do |attribute|
|
287
|
-
obj = self.send attribute.name
|
288
|
-
if nobj = block.call(obj)
|
289
|
-
self.send :"#{attribute.name}=", nobj
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
self.class.xmlizable_elements.each do |element|
|
294
|
-
obj = self.send element.name
|
295
|
-
recurse = element.klass <= XMLizable
|
296
|
-
if element.array
|
297
|
-
obj.each_with_index do |sub_obj,i|
|
298
|
-
if nsub_obj = block.call(sub_obj)
|
299
|
-
obj[i] = nsub_obj
|
300
|
-
elsif sub_obj and recurse
|
301
|
-
sub_obj.xmlizable_replace_nodes(&block)
|
302
|
-
end
|
303
|
-
end
|
304
|
-
else
|
305
|
-
if nobj = block.call(obj)
|
306
|
-
self.send :"#{element.name}=", nobj
|
307
|
-
elsif obj and recurse
|
308
|
-
obj.xmlizable_replace_nodes(&block)
|
309
|
-
end
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
def xmlizable_map! &block
|
315
|
-
self.class.xmlizable_attributes.each do |attribute|
|
316
|
-
obj = self.send attribute.name
|
317
|
-
if nobj = block.call(obj) and not nobj.equal?(obj)
|
318
|
-
self.send :"#{attribute.name}=", nobj
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
self.class.xmlizable_elements.each do |element|
|
323
|
-
obj = self.send element.name
|
324
|
-
if element.array
|
325
|
-
obj.each_with_index do |sub_obj,i|
|
326
|
-
if nsub_obj = block.call(sub_obj) and not nsub_obj.equal?(sub_obj)
|
327
|
-
obj[i] = nsub_obj
|
328
|
-
end
|
329
|
-
end
|
330
|
-
else
|
331
|
-
if nobj = block.call(obj) and not nobj.equal?(obj)
|
332
|
-
self.send :"#{element.name}=", nobj
|
333
|
-
end
|
334
|
-
end
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
def xmlizable_each &block
|
339
|
-
self.class.xmlizable_attributes.each do |attribute|
|
340
|
-
obj = self.send attribute.name
|
341
|
-
block.call(obj)
|
342
|
-
end
|
343
|
-
|
344
|
-
self.class.xmlizable_elements.each do |element|
|
345
|
-
obj = self.send element.name
|
346
|
-
if element.array
|
347
|
-
obj.each do |sub_obj|
|
348
|
-
block.call(sub_obj)
|
349
|
-
end
|
350
|
-
else
|
351
|
-
block.call(obj)
|
352
|
-
end
|
353
|
-
end
|
354
|
-
end
|
355
|
-
|
356
|
-
# Recuses through xmlizable tree, yielding each element and attribute
|
357
|
-
# to the supplied block. You can stop recursion at a given node
|
358
|
-
# with "throw :prune" (like Find.find from stdlib)
|
359
|
-
def xmlizable_find &block
|
360
|
-
catch :prune do
|
361
|
-
block.call(self)
|
362
|
-
|
363
|
-
self.class.xmlizable_attributes.each do |attribute|
|
364
|
-
catch :prune do
|
365
|
-
obj = self.send attribute.name
|
366
|
-
block.call(obj)
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
self.class.xmlizable_elements.each do |element|
|
371
|
-
obj = self.send element.name
|
372
|
-
next if not obj
|
373
|
-
|
374
|
-
recurse = element.klass <= XMLizable
|
375
|
-
if element.array
|
376
|
-
obj.each do |sub_obj|
|
377
|
-
next unless sub_obj
|
378
|
-
if recurse
|
379
|
-
sub_obj.xmlizable_find(&block)
|
380
|
-
end
|
381
|
-
end
|
382
|
-
else
|
383
|
-
if recurse
|
384
|
-
obj.xmlizable_find(&block)
|
385
|
-
end
|
386
|
-
end
|
387
|
-
end
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
|
-
# Same as xmlizable_find but only yields elements.
|
392
|
-
def xmlizable_find_elements &block
|
393
|
-
catch :prune do
|
394
|
-
block.call(self)
|
395
|
-
|
396
|
-
self.class.xmlizable_elements.each do |element|
|
397
|
-
obj = self.send element.name
|
398
|
-
next if not obj
|
399
|
-
|
400
|
-
recurse = element.klass <= XMLizable
|
401
|
-
if element.array
|
402
|
-
obj.each do |sub_obj|
|
403
|
-
next unless sub_obj
|
404
|
-
if recurse
|
405
|
-
sub_obj.xmlizable_find_elements(&block)
|
406
|
-
end
|
407
|
-
end
|
408
|
-
else
|
409
|
-
if recurse
|
410
|
-
obj.xmlizable_find_elements(&block)
|
411
|
-
end
|
412
|
-
end
|
413
|
-
end
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
417
|
-
# Convert object to XML::Node
|
418
|
-
def xmlizable_to_libxml
|
419
|
-
name = self.class.instance_variable_get :@xmlizable_name
|
420
|
-
if not name
|
421
|
-
raise ArgumentError, 'Cannot convert nameless class to XML: ' +
|
422
|
-
self.class.name
|
423
|
-
end
|
424
|
-
node = LibXML::XML::Node.new name
|
425
|
-
self.class.xmlizable_attributes.each do |attribute|
|
426
|
-
value = self.send attribute.name
|
427
|
-
if value == attribute.default and not attribute.required
|
428
|
-
next
|
429
|
-
end
|
430
|
-
node[attribute.xml_name] = value.to_s
|
431
|
-
end
|
432
|
-
self.class.xmlizable_elements.each do |element|
|
433
|
-
value = self.send element.name
|
434
|
-
element_klass = element.klass
|
435
|
-
if value == element.default and not element.required
|
436
|
-
next
|
437
|
-
end
|
438
|
-
element_node = LibXML::XML::Node.new element.xml_name
|
439
|
-
node << element_node
|
440
|
-
if element.array
|
441
|
-
value.each do |sub_value|
|
442
|
-
element_node << sub_value.to_libxml
|
443
|
-
end
|
444
|
-
elsif element_klass <= Integer or element_klass <= Float
|
445
|
-
element_node.content = value.to_s
|
446
|
-
elsif element_klass <= Symbol or element_klass <= TrueClass
|
447
|
-
element_node.content = value.to_s
|
448
|
-
elsif element_klass <= String
|
449
|
-
value = value.to_s.dup
|
450
|
-
case element.escape
|
451
|
-
when :default
|
452
|
-
element_node << XMLizable.escape(value, ESCAPES)
|
453
|
-
when :no_newline
|
454
|
-
element_node << XMLizable.escape(value, ESCAPES_NO_NEWLINE)
|
455
|
-
when :regexp
|
456
|
-
element_node << XMLizable.escape(value, ESCAPES_RE)
|
457
|
-
else
|
458
|
-
raise ArgumentError, "Unknown escape type: #{escape_table}"
|
459
|
-
end
|
460
|
-
else
|
461
|
-
element_node << value.to_libxml
|
462
|
-
end
|
463
|
-
end
|
464
|
-
return node
|
465
|
-
end
|
466
|
-
|
467
|
-
alias :to_libxml :xmlizable_to_libxml
|
468
|
-
|
469
|
-
# Hook for logic after de-serializing an object.
|
470
|
-
def post_from_libxml node
|
471
|
-
end
|
472
|
-
|
473
|
-
|
474
|
-
# Default map used for unescaping.
|
475
|
-
# Backslash escapes are not substituted unless they are defined here
|
476
|
-
# (or in a map explicitly passed to XMLizable.unescape). The exception
|
477
|
-
# to this is "\x" sequences like "\x0a" which are always substituted.
|
478
|
-
UNESCAPE_MAP = {
|
479
|
-
'n' => "\n",
|
480
|
-
't' => "\t",
|
481
|
-
'r' => "\r",
|
482
|
-
'\\' => "\\"
|
483
|
-
}
|
484
|
-
|
485
|
-
# 1 2 3
|
486
|
-
RE_ESCAPE = /\A([^\\]+)?(?:\\(?:(?:x([0-9a-fA-F]{1,2}))|(.)))?/
|
487
|
-
# 1: optional text in front with no escapes
|
488
|
-
# then we parse optional escape sequence:
|
489
|
-
# 2: hex from \x escape
|
490
|
-
# 3: char from other escapes
|
491
|
-
|
492
|
-
# Returns an unescaped copy of string s.
|
493
|
-
def self.unescape s, unescape_map=nil
|
494
|
-
unescape_map ||= UNESCAPE_MAP
|
495
|
-
|
496
|
-
input = s.dup
|
497
|
-
output = []
|
498
|
-
until input.empty?
|
499
|
-
input.slice! RE_ESCAPE
|
500
|
-
# leading text with no escape sequences
|
501
|
-
output << $1 if $1
|
502
|
-
if $2
|
503
|
-
# We have an \x escape code. Interpret hex and get character.
|
504
|
-
output << $2.hex.chr
|
505
|
-
elsif $3
|
506
|
-
# We have something like \t. Interpet it if we can, otherwise preserve both characters
|
507
|
-
output << unescape_map.fetch($3,"\\#$3")
|
508
|
-
end
|
509
|
-
end
|
510
|
-
output.join
|
511
|
-
end
|
512
|
-
|
513
|
-
# Default table used for converting ascii code to escaped representation
|
514
|
-
ESCAPES = Array.new 256 do |i|
|
515
|
-
case i
|
516
|
-
when 9; "\\t".freeze
|
517
|
-
when 13; "\\r".freeze
|
518
|
-
when 92; "\\\\".freeze
|
519
|
-
when 10; "\\n".freeze
|
520
|
-
when 32..126; i.chr.freeze
|
521
|
-
else ; ('\x%02x' % i).freeze
|
522
|
-
end
|
523
|
-
end
|
524
|
-
ESCAPES.freeze
|
525
|
-
# Text escaped with ESCAPES should not have any of these characters in it.
|
526
|
-
TAB_CR_LF = "\t\r\n".freeze
|
527
|
-
|
528
|
-
ESCAPES_NONE = Array.new(256) { |i| i.chr.freeze }
|
529
|
-
ESCAPES_NONE.freeze
|
530
|
-
|
531
|
-
# Regular expressions are escaped when writing to xml but not when
|
532
|
-
# reading from XML. This is necessary because XML doesn't allow
|
533
|
-
# some (all?) binary characters. Escaping doesn't change the meaning
|
534
|
-
# of the regex and does not need to be reversed when deserealizing.
|
535
|
-
ESCAPES_RE = Array.new 256 do |i|
|
536
|
-
case i
|
537
|
-
when 32..126; i.chr.freeze
|
538
|
-
else ; ('\x%02x' % i).freeze
|
539
|
-
end
|
540
|
-
end
|
541
|
-
ESCAPES_RE.freeze
|
542
|
-
|
543
|
-
# Alternate escape table that doesn't escape newline characters
|
544
|
-
ESCAPES_NO_NEWLINE = ESCAPES.dup
|
545
|
-
ESCAPES_NO_NEWLINE[10] = "\n".freeze
|
546
|
-
ESCAPES_NO_NEWLINE.freeze
|
547
|
-
# Text escaped with ESCAPES_NO_NEWLINE should not have any of these characters in it.
|
548
|
-
TAB_CR = "\t\r".freeze
|
549
|
-
|
550
|
-
# Takes input and a table that maps ascii codes to their representation
|
551
|
-
def self.escape input, escapes=nil
|
552
|
-
escapes ||= ESCAPES
|
553
|
-
output = []
|
554
|
-
input.each_byte do |i|
|
555
|
-
output << escapes[i]
|
556
|
-
end
|
557
|
-
output.join
|
558
|
-
end
|
559
|
-
end
|