Module: SDL4R
- Defined in:
- lib/sdl4r.rb,
lib/sdl4r/tag.rb,
lib/sdl4r/sdl4r.rb,
lib/sdl4r/token.rb,
lib/sdl4r/reader.rb,
lib/sdl4r/element.rb,
lib/sdl4r/tokenizer.rb,
lib/sdl4r/sdl_binary.rb,
lib/sdl4r/serializer.rb,
lib/sdl4r/sdl4r_version.rb,
lib/sdl4r/sdl_time_span.rb,
lib/sdl4r/sdl_parse_error.rb,
lib/sdl4r/constant_timezone.rb,
lib/sdl4r/relative_timezone.rb,
lib/sdl4r/tz_abbreviation_db.rb,
lib/sdl4r/abbreviation_timezone_proxy.rb
Overview
To change this template, choose Tools | Templates and open the template in the editor.
Defined Under Namespace
Classes: AbbreviationTimezoneProxy, ConstantTimezone, Element, Reader, RelativeTimezone, SdlBinary, SdlParseError, SdlTimeSpan, Serializer, TZAbbreviationDB, Tag, Token, Tokenizer
Constant Summary collapse
- MAX_INTEGER_32 =
2**31 - 1
- MIN_INTEGER_32 =
-(2**31)
- MAX_INTEGER_64 =
2**63 - 1
- MIN_INTEGER_64 =
-(2**63)
- BASE64_WRAP_LINE_LENGTH =
72
- ANONYMOUS_TAG_NAME =
"content"
- ROOT_TAG_NAME =
"root"
- IDENTIFIER_START_CLASS =
@@UNICODE_REGEXP_SUPPORTED ? '[\\p{Alpha}_]' : '[a-zA-Z_]'
- IDENTIFIER_START_REGEXP =
Matches the first character of a valid SDL identifier.
@@UNICODE_REGEXP_SUPPORTED ? /\A#{IDENTIFIER_START_CLASS}/u : /\A#{IDENTIFIER_START_CLASS}/
- IDENTIFIER_PART_CLASS =
@@UNICODE_REGEXP_SUPPORTED ? '[\\p{Alnum}_\\-\\.$]' : '[\\w\\-\\.$]'
- IDENTIFIER_PART_REGEXP =
Matches characters of a valid SDL identifier after the first one. Works with one character long strings.
@@UNICODE_REGEXP_SUPPORTED ? /\A#{IDENTIFIER_PART_CLASS}\Z/u : /\A#{IDENTIFIER_PART_CLASS}\Z/
- IDENTIFIER_REGEXP =
Matches a valid SDL identifier (start to end).
@@UNICODE_REGEXP_SUPPORTED ? /\A#{IDENTIFIER_START_CLASS}#{IDENTIFIER_PART_CLASS}*\Z/u : /\A#{IDENTIFIER_START_CLASS}#{IDENTIFIER_PART_CLASS}*\Z/
- VERSION =
Version of the SDL library.
"0.9.11"
- @@use_datetime =
true
Class Method Summary collapse
-
.coerce_or_fail(o) ⇒ Object
Coerce the type to a standard SDL type or raises an ArgumentError.
- .disable_tzinfo ⇒ Object
-
.dump(o, output = nil) ⇒ Object
Dumps the specified object to a given output or returns the corresponding SDL string if output is
nil
. - .enable_tzinfo ⇒ Object
-
.format(o, add_quotes = true, line_prefix = "", indent = "\t") ⇒ Object
Creates an SDL string representation for a given object and returns it.
- .format_time(time) ⇒ Object
-
.is_coercible?(o) ⇒ Boolean
Indicates whether ‘o’ is coercible to a SDL literal type.
-
.load(input) ⇒ Object
Loads the specified ‘input’ and deserializes into the returned object.
-
.new_time(year, month, day, hour, min, sec, msec, timezone_code) ⇒ Object
(also: tzinfo_orig_new_time)
Creates and returns the object representing a time (DateTime by default).
-
.read(input) ⇒ Object
Creates and returns a tag named “root” and add all the tags specified in the given
input
. -
.SdlBinary(o) ⇒ Object
Try to coerce ‘o’ into a SdlBinary.
- .supports_unicode_identifiers? ⇒ Boolean
-
.to_attribute_hash(s) ⇒ Object
Parse a string representing the attributes portion of an SDL tag and return the results as a map.
-
.to_value(s) ⇒ Object
Parses and returns the value corresponding with the specified SDL literal.
-
.to_value_array(s) ⇒ Object
Example.
-
.tzinfo_replac_new_time(year, month, day, hour, min, sec, msec, timezone_code) ⇒ Object
Creates and returns the object representing a time (DateTime by default).
-
.use_datetime=(bool) ⇒ Object
Sets whether DateTime should be used for representing times at parsing.
-
.use_datetime? ⇒ Boolean
Indicates whether DateTime is used to represent times.
-
.valid_identifier?(identifier) ⇒ Boolean
Returns whether the specified SDL identifier is valid.
-
.validate_identifier(identifier) ⇒ Object
Validates an SDL identifier String.
Class Method Details
.coerce_or_fail(o) ⇒ Object
Coerce the type to a standard SDL type or raises an ArgumentError.
Returns o
if of the following classes: NilClass, String, Numeric, Float, TrueClass, FalseClass, Date, DateTime, Time, SdlTimeSpan, SdlBinary,
Rationals are turned into Floats using Rational#to_f. Symbols are turned into Strings using Symbol#to_s.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/sdl4r/sdl4r.rb', line 187 def self.coerce_or_fail(o) case o when Rational return o.to_f when Symbol return o.to_s when NilClass, String, Numeric, Float, TrueClass, FalseClass, Date, DateTime, Time, SdlTimeSpan, SdlBinary return o end raise ArgumentError, "#{o.class.name} is not coercible to an SDL type" end |
.disable_tzinfo ⇒ Object
69 70 71 72 73 74 |
# File 'lib/sdl4r/sdl4r_tzinfo.rb', line 69 def disable_tzinfo class << self undef_method :new_time define_method(:new_time, instance_method(:tzinfo_orig_new_time)) end end |
.dump(o, output = nil) ⇒ Object
Dumps the specified object to a given output or returns the corresponding SDL string if output is nil
.
- o
-
the root object (equivalent to a root SDL tag, therefore it’s values and attributes are
NOT dumped. See below for an example.)
- output
-
an output as accepted by Tag#write or
nil
in order to convert to a SDL string.
example:
food = OpenStruct.new(:name => 'french fries', 'comment' => 'eat with bier')
food.fan = OpenStruct.new(:firstname => 'Homer')
puts SDL4R::dump(:food => food)
gives us
food comment="eat with bier" name="french fries" {
fan firstname="Homer"
}
420 421 422 423 424 425 426 427 428 429 |
# File 'lib/sdl4r/sdl4r.rb', line 420 def self.dump(o, output = nil) tag = Serializer.new.serialize(o) if output.nil? tag.children_to_string else tag.write(output) output end end |
.enable_tzinfo ⇒ Object
62 63 64 65 66 67 |
# File 'lib/sdl4r/sdl4r_tzinfo.rb', line 62 def enable_tzinfo class << self undef_method :new_time if respond_to? :new_time define_method(:new_time, instance_method(:tzinfo_replac_new_time)) end end |
.format(o, add_quotes = true, line_prefix = "", indent = "\t") ⇒ Object
Creates an SDL string representation for a given object and returns it.
o
-
the object to format
add_quotes
-
indicates whether quotes will be added to Strings and characters (true by default)
line_prefix
-
the line prefix to use (“” by default)
indent
-
the indent string to use (“t” by default)
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/sdl4r/sdl4r.rb', line 52 def self.format(o, add_quotes = true, line_prefix = "", indent = "\t") case o when String return format_string(o, add_quotes) when Symbol return format_string(o.to_s, add_quotes) when Bignum return o.to_s + "BD" when Integer if MIN_INTEGER_32 <= o and o <= MAX_INTEGER_32 return o.to_s elsif MIN_INTEGER_64 <= o and o <= MAX_INTEGER_64 return o.to_s + "L" else return o.to_s + "BD" end when Float return (o.to_s + "F") when Rational return o.to_f.to_s + "F" when BigDecimal s = o.to_s('F') s.sub!(/\.0$/, "") return "#{s}BD" when NilClass return "null" when SdlBinary encoded_o = Base64.encode64(o.bytes) encoded_o.gsub!(/[\r\n]/m, "") # Remove the EOL inserted every 60 chars if add_quotes if encoded_o.length > BASE64_WRAP_LINE_LENGTH # FIXME: we should a constant or some parameter instead of hardcoded spaces wrap_lines_in_ascii(encoded_o, BASE64_WRAP_LINE_LENGTH, "#{line_prefix}#{indent}") encoded_o.insert(0, "[#{$/}") encoded_o << "#{$/}#{line_prefix}]" else encoded_o.insert(0, "[") encoded_o << "]" end end return encoded_o # Below, we use "#{o.year}" instead of "%Y" because "%Y" always emit 4 chars at least even if # the date is before 1000. when DateTime, Time return format_time(o) when Date return "#{o.strftime("#{o.year}/%m/%d")}" else return o.to_s end end |
.format_time(time) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/sdl4r/sdl4r.rb', line 117 def self.format_time(time) s = "" # important as strftime() tends to return a US-ASCII string s << time.strftime("#{time.year}/%m/%d %H:%M:%S") # %Y tends to return "88" for 1988 in many implementations milliseconds = get_datetime_milliseconds(time) s << sprintf(".%03d", milliseconds) if milliseconds != 0 zone_part = time.strftime("%z") # >> "+0130" -- "%:z" is not supported by every interpreter unless zone_part.nil? or zone_part.empty? or zone_part == "+0000" or not zone_part =~ /[+-]\d+/ zone_part.insert(3, ":") s << "-GMT" << zone_part end return s end |
.is_coercible?(o) ⇒ Boolean
Indicates whether ‘o’ is coercible to a SDL literal type. See #coerce_or_fail
217 218 219 220 221 222 223 224 225 |
# File 'lib/sdl4r/sdl4r.rb', line 217 def self.is_coercible?(o) begin coerce_or_fail(o) true rescue ArgumentError false end end |
.load(input) ⇒ Object
Loads the specified ‘input’ and deserializes into the returned object.
- input
-
an input as accepted by SDL4R#read or a Tag.
example:
top = SDL4R::load(<<EOS
food name="chili con carne" {
ingredient "beans"
ingredient "chili"
ingredient "cheese"
note 8.9
}
EOS
)
top.food.name # => "chili con carne"
top.food.ingredient # => ["beans", "chili", "cheese"]
top.food.note # => 8.9
390 391 392 393 394 395 396 397 398 |
# File 'lib/sdl4r/sdl4r.rb', line 390 def self.load(input) if input.is_a? Tag tag = input else tag = read(input) end return Serializer.new.deserialize(tag) end |
.new_time(year, month, day, hour, min, sec, msec, timezone_code) ⇒ Object Also known as: tzinfo_orig_new_time
Creates and returns the object representing a time (DateTime by default). This method is called by the Parser class.
See #use_datetime=
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/sdl4r/sdl4r.rb', line 153 def self.new_time(year, month, day, hour, min, sec, msec, timezone_code) if @@use_datetime timezone_code ||= Time.now.zone sec_msec = (msec == 0)? sec : Rational(sec * 1000 + msec, 1000) return DateTime.civil(year, month, day, hour, min, sec_msec, timezone_code) else if timezone_code =~ /\A(?:GMT|UTC)([+-]\d+:\d+)\Z/ timezone_code = $1 end timezone_offset = Time.zone_offset(timezone_code, year) if timezone_code if timezone_offset timezone_offset_hour = timezone_offset.abs / 3600 timezone_offset_min = (timezone_offset.abs % 3600) / 60 return Time.xmlschema( sprintf( "%d-%02d-%02dT%02d:%02d:%02d.%03d#{timezone_offset >= 0 ? '+' : '-'}%02d:%02d", year, month, day, hour, min, sec, msec, timezone_offset_hour, timezone_offset_min)) else return Time.local(year, month, day, hour, min, sec, msec * 1000) end end end |
.read(input) ⇒ Object
Creates and returns a tag named “root” and add all the tags specified in the given input
.
input
-
String, IO, Pathname or URI.
root = SDL4R::read(<<EOS
planets {
earth area_km2=510900000
mars
}
EOS
)
root = SDL4R::read(Pathname.new("my_dir/my_file.sdl"))
IO.open("my_dir/my_file.sdl", "r") { |io|
root = SDL4R::read(io)
}
root = SDL4R::read(URI.new("http://my_site/my_file.sdl"))
327 328 329 |
# File 'lib/sdl4r/sdl4r.rb', line 327 def self.read(input) Tag.new(ROOT_TAG_NAME).read(input) end |
.SdlBinary(o) ⇒ Object
Try to coerce ‘o’ into a SdlBinary. Raise an ArgumentError if it fails.
72 73 74 75 76 77 78 79 80 |
# File 'lib/sdl4r/sdl_binary.rb', line 72 def self.SdlBinary(o) if o.kind_of? SdlBinary return o elsif o.kind_of? String return SdlBinary.new(o) else raise ArgumentError, "can't coerce argument" end end |
.supports_unicode_identifiers? ⇒ Boolean
238 239 240 |
# File 'lib/sdl4r/sdl4r.rb', line 238 def self.supports_unicode_identifiers? @@UNICODE_REGEXP_SUPPORTED end |
.to_attribute_hash(s) ⇒ Object
Parse a string representing the attributes portion of an SDL tag and return the results as a map.
Example
hash = SDL4R.to_attribute_hash("value=1 debugging=on time=12:24:01");
# { "value" => 1, "debugging" => true, "time" => SdlTimeSpan.new(12, 24, 01) }
365 366 367 368 |
# File 'lib/sdl4r/sdl4r.rb', line 365 def self.to_attribute_hash(s) raise ArgumentError, "'s' cannot be null" if s.nil? return read("atts " + s).child.attributes end |
.to_value(s) ⇒ Object
337 338 339 340 |
# File 'lib/sdl4r/sdl4r.rb', line 337 def self.to_value(s) raise ArgumentError, "'s' cannot be null" if s.nil? return read(s).child.value end |
.to_value_array(s) ⇒ Object
Example
array = SDL4R.to_value_array("1 true 12:24:01")
Will return an int, a boolean, and a time span.
351 352 353 354 |
# File 'lib/sdl4r/sdl4r.rb', line 351 def self.to_value_array(s) raise ArgumentError, "'s' cannot be null" if s.nil? return read(s).child.values end |
.tzinfo_replac_new_time(year, month, day, hour, min, sec, msec, timezone_code) ⇒ Object
Creates and returns the object representing a time (DateTime by default). This method is called by the Parser class.
This implementation uses TZInfo in order to parse timezones (wider support of timezones and better support of DST and such issues).
See #use_datetime=
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/sdl4r/sdl4r_tzinfo.rb', line 40 def tzinfo_replac_new_time(year, month, day, hour, min, sec, msec, timezone_code) if timezone_code timezone = SDL4R::RelativeTimezone::get(timezone_code) tz_ref_time = Time.utc(year, month, day, hour, min, sec, msec * 1000) # Arbitrary decision: in ambiguous cases, we choose the not-DST offset. timezone_period = timezone.period_for_local(tz_ref_time, false) end if use_datetime? sec_msec = (msec == 0)? sec : Rational(sec * 1000 + msec, 1000) timezone_offset = timezone_code ? timezone_period.utc_total_offset_rational : Rational(Time.now.utc_offset, SECONDS_IN_DAY) return DateTime.civil(year, month, day, hour, min, sec_msec, timezone_offset) else return timezone_code ? timezone_period.to_utc(Time.utc(year, month, day, hour, min, sec, msec * 1000)) : Time.local(year, month, day, hour, min, sec, msec * 1000) end end |
.use_datetime=(bool) ⇒ Object
Sets whether DateTime should be used for representing times at parsing. If set to false, Time will be used instead (true by default).
144 145 146 |
# File 'lib/sdl4r/sdl4r.rb', line 144 def self.use_datetime=(bool) @@use_datetime = bool end |
.use_datetime? ⇒ Boolean
Indicates whether DateTime is used to represent times. If false, Time is used instead. True by default.
137 138 139 |
# File 'lib/sdl4r/sdl4r.rb', line 137 def self.use_datetime? @@use_datetime end |
.valid_identifier?(identifier) ⇒ Boolean
Returns whether the specified SDL identifier is valid. See SDL4R#validate_identifier.
303 304 305 |
# File 'lib/sdl4r/sdl4r.rb', line 303 def self.valid_identifier?(identifier) !IDENTIFIER_REGEXP.match(identifier).nil? end |
.validate_identifier(identifier) ⇒ Object
Validates an SDL identifier String. SDL Identifiers must start with a Unicode letter or underscore (_) and contain only unicode letters, digits, underscores (_), dashes(-), periods (.) and dollar signs ($).
Raises
ArgumentError if the identifier is not legal
TODO: support UTF-8 identifiers
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/sdl4r/sdl4r.rb', line 272 def self.validate_identifier(identifier) if identifier.nil? or identifier.empty? raise ArgumentError, "SDL identifiers cannot be null or empty." end # in Java, was if(!Character.isJavaIdentifierStart(identifier.charAt(0))) unless identifier =~ IDENTIFIER_START_REGEXP raise ArgumentError, "'" + identifier[/^./] + "' is not a legal first character for an SDL identifier. " + "SDL Identifiers must start with a unicode letter or " + "an underscore (_). (identifier=<#{identifier}>)" end unless identifier.length == 1 or identifier =~ IDENTIFIER_REGEXP for i in 1..identifier.length unless identifier[i..i] =~ IDENTIFIER_PART_REGEXP raise ArgumentError, "'" + identifier[i..i] + "' is not a legal character for an SDL identifier. " + "SDL Identifiers must start with a unicode letter or " + "underscore (_) followed by 0 or more unicode " + "letters, digits, underscores (_), dashes (-), periodss (.) and dollar signs ($)" end end end end |