mu 5.7.9 → 5.7.10
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/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
|