sdl4r 0.9.9 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/CHANGELOG +70 -1
  2. data/LICENSE +499 -497
  3. data/Rakefile +38 -28
  4. data/TODO +194 -45
  5. data/doc/classes/SDL4R/AbbreviationTimezoneProxy.html +151 -0
  6. data/doc/classes/SDL4R/ConstantTimezone.html +129 -0
  7. data/doc/classes/SDL4R/Element.html +148 -0
  8. data/doc/classes/SDL4R/Reader.html +683 -0
  9. data/doc/classes/SDL4R/RelativeTimezone.html +187 -0
  10. data/doc/classes/SDL4R/SdlBinary.html +188 -0
  11. data/doc/classes/SDL4R/SdlParseError.html +110 -0
  12. data/doc/classes/SDL4R/SdlTimeSpan.html +651 -0
  13. data/doc/classes/SDL4R/Serializer.html +557 -0
  14. data/doc/classes/SDL4R/Serializer/Ref.html +138 -0
  15. data/doc/classes/SDL4R/TZAbbreviationDB/Record.html +117 -0
  16. data/doc/classes/SDL4R/Tag.html +1274 -0
  17. data/doc/classes/SDL4R/Token.html +131 -0
  18. data/doc/created.rid +1 -0
  19. data/doc/files/CHANGELOG.html +290 -0
  20. data/doc/files/LICENSE.html +53 -0
  21. data/doc/files/README.html +405 -0
  22. data/doc/files/lib/sdl4r/abbreviation_timezone_proxy_rb.html +63 -0
  23. data/doc/files/lib/sdl4r/constant_timezone_rb.html +54 -0
  24. data/doc/files/lib/sdl4r/element_rb.html +54 -0
  25. data/doc/files/lib/sdl4r/reader_rb.html +68 -0
  26. data/doc/files/lib/sdl4r/relative_timezone_rb.html +62 -0
  27. data/doc/files/lib/sdl4r/sdl4r_rb.html +66 -0
  28. data/doc/files/lib/sdl4r/sdl4r_tzinfo_rb.html +64 -0
  29. data/doc/files/lib/sdl4r/sdl4r_version_rb.html +54 -0
  30. data/doc/files/lib/sdl4r/sdl_binary_rb.html +54 -0
  31. data/doc/files/lib/sdl4r/sdl_parse_error_rb.html +54 -0
  32. data/doc/files/lib/sdl4r/sdl_time_span_rb.html +54 -0
  33. data/doc/files/lib/sdl4r/serializer_rb.html +62 -0
  34. data/doc/files/lib/sdl4r/tag_rb.html +66 -0
  35. data/doc/files/lib/sdl4r/token_rb.html +54 -0
  36. data/doc/files/lib/sdl4r/tokenizer_rb.html +64 -0
  37. data/doc/files/lib/sdl4r/tz_abbreviation_db_rb.html +67 -0
  38. data/doc/files/lib/sdl4r_rb.html +54 -0
  39. data/doc/files/lib/sdl4r_tzinfo_rb.html +54 -0
  40. data/doc/fr_class_index.html +23 -0
  41. data/doc/fr_file_index.html +40 -0
  42. data/doc/fr_method_index.html +4711 -0
  43. data/doc/index.html +15 -0
  44. data/doc/rdoc-style.css +328 -0
  45. data/lib/sdl4r.rb +3 -1
  46. data/lib/sdl4r/abbreviation_timezone_proxy.rb +38 -0
  47. data/lib/sdl4r/constant_timezone.rb +58 -0
  48. data/{test/sdl4r/sdl_test.rb → lib/sdl4r/element.rb} +19 -14
  49. data/lib/sdl4r/reader.rb +772 -0
  50. data/lib/sdl4r/relative_timezone.rb +156 -0
  51. data/lib/sdl4r/sdl4r.rb +187 -45
  52. data/lib/sdl4r/sdl4r_tzinfo.rb +75 -0
  53. data/lib/sdl4r/sdl4r_version.rb +24 -0
  54. data/lib/sdl4r/sdl_parse_error.rb +1 -1
  55. data/lib/sdl4r/sdl_time_span.rb +5 -1
  56. data/lib/sdl4r/serializer.rb +473 -60
  57. data/lib/sdl4r/tag.rb +126 -51
  58. data/lib/sdl4r/token.rb +49 -0
  59. data/lib/sdl4r/tokenizer.rb +431 -0
  60. data/lib/sdl4r/tz_abbreviation_db.rb +266 -0
  61. data/read_jprof.html +16934 -0
  62. data/read_jprof_pull.html +14451 -0
  63. data/read_prof.html +4983 -0
  64. data/read_prof_pull.html +4896 -0
  65. data/test/sdl4r/parser_test.rb +577 -503
  66. data/test/sdl4r/read_jprof.rb +58 -0
  67. data/test/sdl4r/read_prof.rb +70 -0
  68. data/test/sdl4r/reader_test.rb +173 -0
  69. data/test/sdl4r/relative_timezone_test.rb +102 -0
  70. data/test/sdl4r/sdl4r_test.rb +611 -528
  71. data/test/sdl4r/sdl4r_tzinfo_test.rb +108 -0
  72. data/test/sdl4r/sdl_test_case.rb +60 -0
  73. data/test/sdl4r/serializer_test.rb +448 -11
  74. data/test/sdl4r/tag_test.rb +84 -5
  75. data/test/sdl4r/tokenizer_test.rb +128 -0
  76. metadata +69 -11
  77. data/lib/sdl4r/parser.rb +0 -648
  78. data/lib/sdl4r/parser/reader.rb +0 -184
  79. data/lib/sdl4r/parser/time_span_with_zone.rb +0 -57
  80. data/lib/sdl4r/parser/token.rb +0 -138
  81. data/lib/sdl4r/parser/tokenizer.rb +0 -507
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+
4
+ #--
5
+ #
6
+ # Simple Declarative Language (SDL) for Ruby
7
+ # Copyright 2005 Ikayzo, inc.
8
+ #
9
+ # This program is free software. You can distribute or modify it under the
10
+ # terms of the GNU Lesser General Public License version 2.1 as published by
11
+ # the Free Software Foundation.
12
+ #
13
+ # This program is distributed AS IS and WITHOUT WARRANTY. OF ANY KIND,
14
+ # INCLUDING MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
15
+ # See the GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with this program; if not, contact the Free Software Foundation, Inc.,
19
+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
+ #++
21
+
22
+ module SDL4R
23
+
24
+ require 'sdl4r/tz_abbreviation_db'
25
+
26
+ # Represents a Timezone which is distant from a standard timezone by a fixed offset.
27
+ #
28
+ class RelativeTimezone < TZInfo::Timezone
29
+
30
+ # Returns a timezone by its identifier (e.g. "Europe/London",
31
+ # "America/Chicago" or "UTC").
32
+ #
33
+ # Supports relative timezones in the following formats: "UTC+2", "GMT+01:30",
34
+ # "Europe/Paris-10:00".
35
+ #
36
+ # Raises InvalidTimezoneIdentifier if the timezone couldn't be found.
37
+ #
38
+ def self.get(identifier)
39
+ base_identifier, offset_text, offset = RelativeTimezone::parse_relative_identifier(identifier)
40
+
41
+ tz = TZAbbreviationDB.get_timezone(base_identifier)
42
+
43
+ offset ?
44
+ RelativeTimezone.new(base_identifier + offset_text.to_s, offset_text, offset, tz) :
45
+ tz
46
+ end
47
+
48
+ # Returns a proxy for the Timezone with the given identifier. The proxy
49
+ # will cause the real timezone to be loaded when an attempt is made to
50
+ # find a period or convert a time. get_proxy will not validate the
51
+ # identifier. If an invalid identifier is specified, no exception will be
52
+ # raised until the proxy is used.
53
+ #
54
+ # Supports relative timezones in the following format: "GMT+01:30", "CET-10:00".
55
+ #
56
+ def self.get_proxy(identifier)
57
+ base_identifier, offset_text, offset = RelativeTimezone::parse_relative_identifier(identifier)
58
+
59
+ proxy = TZAbbreviationDB.get_timezone_proxy(base_identifier)
60
+
61
+ offset ?
62
+ RelativeTimezone.new(base_identifier + offset_text.to_s, offset_text, offset, proxy) :
63
+ proxy
64
+ end
65
+
66
+ # Parses the specified identifier of the shape "GMT" or "CET+7" or "Asia/Shanghai-03:30" and
67
+ # returns an array containing respectively the simple zone identifier (e.g. "CET",
68
+ # "Asia/Shanghai"), the offset part (e.g. "-6", "+08:30") and the offset (seconds).
69
+ #
70
+ def self.parse_relative_identifier(identifier) # :nodoc:
71
+ offset = nil
72
+
73
+ if identifier =~ /^([a-zA-Z0-9\/_]+)(([+\-])(\d+)(?::(\d+))?)?$/
74
+ identifier, offset_text, sign_part, hour_part, minute_part = $1, $2, $3, $4, $5
75
+
76
+ if sign_part # relative offset
77
+ offset = 0
78
+ offset += 3600 * hour_part.to_i if hour_part
79
+ offset += 60 * minute_part.to_i if minute_part
80
+ offset = -offset if sign_part == '-'
81
+
82
+ offset = nil if offset == 0
83
+
84
+ # We regenerate/normalize the offset text "+7:3" ==> "+07:03".
85
+ offset_text = ""
86
+ if offset
87
+ offset_text << (offset >= 0 ? '+' : '-')
88
+
89
+ hours = offset.abs / 3600
90
+ minutes = (offset.abs % 3600) / 60
91
+ if minutes == 0
92
+ offset_text << hours.to_s
93
+ else
94
+ offset_text << sprintf("%02d:%02d", hours, minutes)
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ return identifier, offset_text, offset
101
+ end
102
+
103
+ def self.new(identifier, offset_text, offset, base_timezone)
104
+ o = super()
105
+ o.send(:_initialize, identifier, offset_text, offset, base_timezone)
106
+ o
107
+ end
108
+
109
+ # _base_timezone_:: timezone on which this RelativeTimezone is based
110
+ # _offset_:: the fixed offset (seconds)
111
+ #
112
+ def _initialize(identifier, offset_text, offset, base_timezone) # :nodoc:
113
+ raise ArgumentError, 'identifier' if identifier.nil?
114
+ raise ArgumentError, 'offset' if offset.nil?
115
+ raise ArgumentError, 'base_timezone' if base_timezone.nil?
116
+
117
+ @identifier = identifier
118
+ @base_timezone =
119
+ base_timezone.is_a?(String) ? TZInfo::Timezone.get(base_timezone) : base_timezone
120
+ @relative_offset_text = offset_text
121
+ @relative_offset = offset
122
+ end
123
+ protected :_initialize
124
+
125
+ attr_reader :identifier, :relative_offset
126
+
127
+ def period_for_utc(utc)
128
+ period = @base_timezone.period_for_utc(utc)
129
+
130
+ translated_offset =
131
+ period.offset ?
132
+ TZInfo::TimezoneOffsetInfo.new(
133
+ period.offset.utc_offset + @relative_offset,
134
+ period.offset.std_offset,
135
+ (period.offset.abbreviation.to_s + @relative_offset_text).to_sym) :
136
+ nil
137
+
138
+ return TZInfo::TimezonePeriod.new(nil, nil, translated_offset)
139
+ end
140
+
141
+ def periods_for_local(local)
142
+ periods = @base_timezone.periods_for_local(local)
143
+
144
+ return periods.collect { |period|
145
+ translated_offset =
146
+ period.offset ?
147
+ TZInfo::TimezoneOffsetInfo.new(
148
+ period.offset.utc_offset + @relative_offset,
149
+ period.offset.std_offset,
150
+ (period.offset.abbreviation.to_s + @relative_offset_text).to_sym) :
151
+ nil
152
+ TZInfo::TimezonePeriod.new(nil, nil, translated_offset)
153
+ }
154
+ end
155
+ end
156
+ end
@@ -22,7 +22,12 @@ require 'base64'
22
22
  require 'bigdecimal'
23
23
  require 'date'
24
24
 
25
- # Gathers utility methods.
25
+ require 'sdl4r/sdl4r_version'
26
+ require 'sdl4r/serializer'
27
+
28
+ # Utility methods and general constants for SDL4R.
29
+ #
30
+ # For more information about SDL4R, see the {link README file}[../../files/README.html]
26
31
  #
27
32
  module SDL4R
28
33
 
@@ -47,10 +52,10 @@ module SDL4R
47
52
  def self.format(o, add_quotes = true, line_prefix = "", indent = "\t")
48
53
  case o
49
54
  when String
50
- return format_string(o)
55
+ return format_string(o, add_quotes)
51
56
 
52
57
  when Symbol
53
- return format_string(o.to_s)
58
+ return format_string(o.to_s, add_quotes)
54
59
 
55
60
  when Bignum
56
61
  return o.to_s + "BD"
@@ -99,46 +104,77 @@ module SDL4R
99
104
  # Below, we use "#{o.year}" instead of "%Y" because "%Y" always emit 4 chars at least even if
100
105
  # the date is before 1000.
101
106
  when DateTime, Time
102
- milliseconds = get_datetime_milliseconds(o)
103
-
104
- if milliseconds == 0
105
- zone_part = o.strftime("%:z")
106
- if zone_part and zone_part != "+00:00"
107
- return o.strftime("#{o.year}/%m/%d %H:%M:%S#{zone_part}")
108
- else
109
- return o.strftime("#{o.year}/%m/%d %H:%M:%S")
110
- end
111
- else
112
- ms_part = milliseconds.to_s.ljust(3, '0')
113
- if zone_part and zone_part != "+00:00"
114
- return o.strftime("#{o.year}/%m/%d %H:%M:%S." + ms_part + zone_part)
115
- else
116
- return o.strftime("#{o.year}/%m/%d %H:%M:%S." + ms_part)
117
- end
118
- end
119
-
107
+ return format_time(o)
108
+
120
109
  when Date
121
- return o.strftime("#{o.year}/%m/%d")
110
+ return "#{o.strftime("#{o.year}/%m/%d")}"
122
111
 
123
112
  else
124
113
  return o.to_s
125
114
  end
126
115
  end
127
116
 
128
- # Creates and returns the object representing a datetime (DateTime in the default implementation).
129
- # This method is, by default, called by the Parser class.
130
- # It could be overriden as follows in order to get Time instances from all the SDL4R parsers.
117
+ def self.format_time(time)
118
+ s = "" # important as strftime() tends to return a US-ASCII string
119
+ s << time.strftime("#{time.year}/%m/%d %H:%M:%S") # %Y tends to return "88" for 1988 in many implementations
120
+
121
+ milliseconds = get_datetime_milliseconds(time)
122
+ s << sprintf(".%03d", milliseconds) if milliseconds != 0
123
+
124
+ zone_part = time.strftime("%z") # >> "+0130" -- "%:z" is not supported by every interpreter
125
+ unless zone_part.nil? or zone_part.empty? or zone_part == "+0000" or not zone_part =~ /[+-]\d+/
126
+ zone_part.insert(3, ":")
127
+ s << "-GMT" << zone_part
128
+ end
129
+
130
+ return s
131
+ end
132
+
133
+ @@use_datetime = true
134
+
135
+ # Indicates whether DateTime is used to represent times. If false, Time is used instead. True by
136
+ # default.
137
+ def self.use_datetime?
138
+ @@use_datetime
139
+ end
140
+
141
+ # Sets whether DateTime should be used for representing times at parsing.
142
+ # If set to false, Time will be used instead (true by default).
143
+ #
144
+ def self.use_datetime=(bool)
145
+ @@use_datetime = bool
146
+ end
147
+
148
+ # Creates and returns the object representing a time (DateTime by default).
149
+ # This method is called by the Parser class.
131
150
  #
132
- # module SDL4R
133
- # def self.new_date_time(year, month, day, hour, min, sec, time_zone_offset)
134
- # Time.utc(year, month, day, hour, min, sec)
135
- # end
136
- # end
151
+ # See #use_datetime=
137
152
  #
138
- def self.new_date_time(year, month, day, hour, min, sec, time_zone_offset)
139
- DateTime.civil(year, month, day, hour, min, sec, time_zone_offset)
153
+ def self.new_time(year, month, day, hour, min, sec, msec, timezone_code)
154
+ if @@use_datetime
155
+ timezone_code ||= Time.now.zone
156
+ sec_msec = (msec == 0)? sec : Rational(sec * 1000 + msec, 1000)
157
+ return DateTime.civil(year, month, day, hour, min, sec_msec, timezone_code)
158
+
159
+ else
160
+ if timezone_code =~ /\A(?:GMT|UTC)([+-]\d+:\d+)\Z/
161
+ timezone_code = $1
162
+ end
163
+ timezone_offset = Time.zone_offset(timezone_code, year) if timezone_code
164
+ if timezone_offset
165
+ timezone_offset_hour = timezone_offset.abs / 3600
166
+ timezone_offset_min = (timezone_offset.abs % 3600) / 60
167
+ return Time.xmlschema(
168
+ sprintf(
169
+ "%d-%02d-%02dT%02d:%02d:%02d.%03d#{timezone_offset >= 0 ? '+' : '-'}%02d:%02d",
170
+ year, month, day, hour, min, sec, msec, timezone_offset_hour, timezone_offset_min))
171
+
172
+ else
173
+ return Time.local(year, month, day, hour, min, sec, msec * 1000)
174
+ end
175
+ end
140
176
  end
141
-
177
+
142
178
  # Coerce the type to a standard SDL type or raises an ArgumentError.
143
179
  #
144
180
  # Returns +o+ if of the following classes:
@@ -175,7 +211,7 @@ module SDL4R
175
211
  raise ArgumentError, "#{o.class.name} is not coercible to an SDL type"
176
212
  end
177
213
 
178
- # Indicates whether 'o' is coercible to a SDL litteral type.
214
+ # Indicates whether 'o' is coercible to a SDL literal type.
179
215
  # See #coerce_or_fail
180
216
  #
181
217
  def self.is_coercible?(o)
@@ -187,6 +223,42 @@ module SDL4R
187
223
  false
188
224
  end
189
225
  end
226
+
227
+ # We disable the warnings as Ruby 1.8.7 prints one for the tested regex. We don't need this
228
+ # warning as we are precisely testing whether this regular expression works.
229
+ # Unfortunately, creating the regex with Regexp.new() doesn't help: we would have liked getting a
230
+ # RegexpError.
231
+ begin
232
+ old_verbose, $VERBOSE = $VERBOSE, nil
233
+ @@UNICODE_REGEXP_SUPPORTED = ('é' =~ Regexp.new("\\p{Alnum}")) != nil
234
+ ensure
235
+ $VERBOSE = old_verbose
236
+ end
237
+
238
+ def self.supports_unicode_identifiers?
239
+ @@UNICODE_REGEXP_SUPPORTED
240
+ end
241
+
242
+ IDENTIFIER_START_CLASS = @@UNICODE_REGEXP_SUPPORTED ? '[\\p{Alpha}_]' : '[a-zA-Z_]'
243
+
244
+ # Matches the first character of a valid SDL identifier.
245
+ IDENTIFIER_START_REGEXP =
246
+ @@UNICODE_REGEXP_SUPPORTED ? /\A#{IDENTIFIER_START_CLASS}/u : /\A#{IDENTIFIER_START_CLASS}/
247
+
248
+ IDENTIFIER_PART_CLASS =
249
+ @@UNICODE_REGEXP_SUPPORTED ? '[\\p{Alnum}_\\-\\.$]' : '[\\w\\-\\.$]'
250
+
251
+ # Matches characters of a valid SDL identifier after the first one.
252
+ # Works with one character long strings.
253
+ IDENTIFIER_PART_REGEXP =
254
+ @@UNICODE_REGEXP_SUPPORTED ?
255
+ /\A#{IDENTIFIER_PART_CLASS}\Z/u :
256
+ /\A#{IDENTIFIER_PART_CLASS}\Z/
257
+
258
+ # Matches a valid SDL identifier (start to end).
259
+ IDENTIFIER_REGEXP = @@UNICODE_REGEXP_SUPPORTED ?
260
+ /\A#{IDENTIFIER_START_CLASS}#{IDENTIFIER_PART_CLASS}*\Z/u :
261
+ /\A#{IDENTIFIER_START_CLASS}#{IDENTIFIER_PART_CLASS}*\Z/
190
262
 
191
263
  # Validates an SDL identifier String. SDL Identifiers must start with a
192
264
  # Unicode letter or underscore (_) and contain only unicode letters,
@@ -203,17 +275,17 @@ module SDL4R
203
275
  end
204
276
 
205
277
  # in Java, was if(!Character.isJavaIdentifierStart(identifier.charAt(0)))
206
- unless identifier =~ /^[a-zA-Z_]/
278
+ unless identifier =~ IDENTIFIER_START_REGEXP
207
279
  raise ArgumentError,
208
- "'" + identifier[0..0] +
280
+ "'" + identifier[/^./] +
209
281
  "' is not a legal first character for an SDL identifier. " +
210
282
  "SDL Identifiers must start with a unicode letter or " +
211
- "an underscore (_)."
283
+ "an underscore (_). (identifier=<#{identifier}>)"
212
284
  end
213
-
214
- unless identifier.length == 1 or identifier =~ /^[a-zA-Z_][a-zA-Z_0-9\-\.\$]*$/
285
+
286
+ unless identifier.length == 1 or identifier =~ IDENTIFIER_REGEXP
215
287
  for i in 1..identifier.length
216
- unless identifier[i..i] =~ /^[a-zA-Z_0-9\-\.\$]$/
288
+ unless identifier[i..i] =~ IDENTIFIER_PART_REGEXP
217
289
  raise ArgumentError,
218
290
  "'" + identifier[i..i] +
219
291
  "' is not a legal character for an SDL identifier. " +
@@ -225,16 +297,23 @@ module SDL4R
225
297
  end
226
298
  end
227
299
 
300
+ # Returns whether the specified SDL identifier is valid.
301
+ # See SDL4R#validate_identifier.
302
+ #
303
+ def self.valid_identifier?(identifier)
304
+ !IDENTIFIER_REGEXP.match(identifier).nil?
305
+ end
306
+
228
307
  # Creates and returns a tag named "root" and add all the tags specified in the given +input+.
229
308
  #
230
309
  # +input+:: String, IO, Pathname or URI.
231
310
  #
232
- # root = SDL4R::read(<<EOF
311
+ # root = SDL4R::read(<<EOS
233
312
  # planets {
234
313
  # earth area_km2=510900000
235
314
  # mars
236
315
  # }
237
- # EOF
316
+ # EOS
238
317
  # )
239
318
  #
240
319
  # root = SDL4R::read(Pathname.new("my_dir/my_file.sdl"))
@@ -288,11 +367,74 @@ module SDL4R
288
367
  return read("atts " + s).child.attributes
289
368
  end
290
369
 
370
+ # Loads the specified 'input' and deserializes into the returned object.
371
+ #
372
+ # _input_:: an input as accepted by SDL4R#read or a Tag.
373
+ #
374
+ # example:
375
+ #
376
+ # top = SDL4R::load(<<EOS
377
+ # food name="chili con carne" {
378
+ # ingredient "beans"
379
+ # ingredient "chili"
380
+ # ingredient "cheese"
381
+ # note 8.9
382
+ # }
383
+ # EOS
384
+ # )
385
+ #
386
+ # top.food.name # => "chili con carne"
387
+ # top.food.ingredient # => ["beans", "chili", "cheese"]
388
+ # top.food.note # => 8.9
389
+ #
390
+ def self.load(input)
391
+ if input.is_a? Tag
392
+ tag = input
393
+ else
394
+ tag = read(input)
395
+ end
396
+
397
+ return Serializer.new.deserialize(tag)
398
+ end
399
+
400
+ # Dumps the specified object to a given output or returns the corresponding SDL string if output
401
+ # is +nil+.
402
+ #
403
+ # _o_:: the root object (equivalent to a root SDL tag, therefore it's values and attributes are
404
+ # NOT dumped. See below for an example.)
405
+ # _output_:: an output as accepted by Tag#write or +nil+ in order to convert to a SDL string.
406
+ #
407
+ # example:
408
+ #
409
+ # food = OpenStruct.new(:name => 'french fries', 'comment' => 'eat with bier')
410
+ # food.fan = OpenStruct.new(:firstname => 'Homer')
411
+ #
412
+ # puts SDL4R::dump(:food => food)
413
+ #
414
+ # gives us
415
+ #
416
+ # food comment="eat with bier" name="french fries" {
417
+ # fan firstname="Homer"
418
+ # }
419
+ #
420
+ def self.dump(o, output = nil)
421
+ tag = Serializer.new.serialize(o)
422
+
423
+ if output.nil?
424
+ tag.children_to_string
425
+ else
426
+ tag.write(output)
427
+ output
428
+ end
429
+ end
430
+
291
431
  # The following is a not so readable way to implement module private methods in Ruby: we add
292
432
  # private methods to the singleton class of +self+ i.e. the SDL4R module.
293
433
  class << self
294
434
  private
295
435
 
436
+ SECONDS_IN_DAY = 24 * 3600 # :nodoc:
437
+
296
438
  # Returns the specified string 's' formatted as a SDL string.
297
439
  # See SDL4R#format.
298
440
  #
@@ -384,12 +526,12 @@ module SDL4R
384
526
  # least, some revisions of Ruby 1.9.
385
527
  #
386
528
  def get_datetime_milliseconds(datetime)
387
- if defined?(datetime.usec)
388
- return (datetime.usec / 1000).round
529
+ if datetime.respond_to?(:usec)
530
+ return (datetime.usec / 1000.0).round
389
531
  else
390
532
  # Here don't believe that we could use '%3N' to get the milliseconds directly: the "3" is
391
533
  # ignored for DateTime.strftime() in Ruby 1.8.
392
- nanoseconds = Integer(datetime.strftime("%N"))
534
+ nanoseconds = datetime.strftime("%N").to_i
393
535
  return (nanoseconds / 1000000).round
394
536
  end
395
537
  end