lib/vcard/field.rb in vcard-0.1.1 vs lib/vcard/field.rb in vcard-0.2.0

- old
+ new

@@ -1,14 +1,12 @@ -=begin - Copyright (C) 2008 Sam Roberts +# Copyright (C) 2008 Sam Roberts - This library is free software; you can redistribute it and/or modify it - under the same terms as the ruby language itself, see the file COPYING for - details. -=end +# This library is free software; you can redistribute it and/or modify it +# under the same terms as the ruby language itself, see the file COPYING for +# details. -module Vpim +module Vcard class DirectoryInfo # A field in a directory info object. class Field @@ -17,11 +15,11 @@ # case-insensitive, configurably, so it can down case them # - perhaps should have pvalue_set/del/add, perhaps case-insensitive, or # pvalue_iset/idel/iadd, where set sets them all, add adds if not present, # and del deletes any that are present # - I really, really, need a case-insensitive string... - # - should allow nil as a field value, its not the same as '', if there is + # - should allow nil as a field value, its not the same as "", if there is # more than one pvalue, the empty string will show up. This isn't strictly # disallowed, but its odd. Should also strip empty strings on decoding, if # I don't already. private_class_method :new @@ -35,62 +33,62 @@ fields.to_ary end end # Encode a field. - def Field.encode0(group, name, params={}, value='') # :nodoc: + def Field.encode0(group, name, params={}, value="") # :nodoc: line = "" # A reminder of the line format: # [<group>.]<name>;<pname>=<pvalue>,<pvalue>:<value> if group - line << group << '.' + line << group << "." end line << name params.each do |pname, pvalues| unless pvalues.respond_to? :to_ary pvalues = [ pvalues ] end - line << ';' << pname << '=' + line << ";" << pname << "=" - sep = "" # set to ',' after one pvalue has been appended + sep = "" # set to "," after one pvalue has been appended pvalues.each do |pvalue| # check if we need to do any encoding - if pname.casecmp('ENCODING') == 0 && pvalue == :b64 - pvalue = 'B' # the RFC definition of the base64 param value - value = [ value.to_str ].pack('m').gsub("\n", '') + if pname.casecmp("ENCODING") == 0 && pvalue == :b64 + pvalue = "B" # the RFC definition of the base64 param value + value = [ value.to_str ].pack("m").gsub("\n", "") end line << sep << pvalue sep =","; end end - line << ':' + line << ":" line << Field.value_str(value) line end def Field.value_str(value) # :nodoc: - line = '' + line = "" case value when Date - line << Vpim.encode_date(value) + line << ::Vcard.encode_date(value) when Time #, DateTime - line << Vpim.encode_date_time(value) + line << ::Vcard.encode_date_time(value) when Array - line << value.map { |v| Field.value_str(v) }.join(';') + line << value.map { |v| Field.value_str(v) }.join(";") when Symbol line << value else @@ -101,11 +99,11 @@ end # Decode a field. def Field.decode0(atline) # :nodoc: unless atline =~ %r{#{Bnf::LINE}}i - raise Vpim::InvalidEncodingError, atline + raise ::Vcard::InvalidEncodingError, atline end atgroup = $1.upcase atname = $2.upcase paramslist = $3 @@ -115,11 +113,11 @@ # strip it. I'm not absolutely sure this is allowed... it certainly # breaks round-trip encoding. atvalue.strip! if atgroup.length > 0 - atgroup.chomp!('.') + atgroup.chomp!(".") else atgroup = nil end atparams = {} @@ -132,25 +130,25 @@ # param names are case-insensitive, and multi-valued name = $1.upcase params = $3 - # v2.1 params have no '=' sign, figure out what kind of param it - # is (either its a known encoding, or we treat it as a 'TYPE' + # v2.1 params have no "=" sign, figure out what kind of param it + # is (either its a known encoding, or we treat it as a "TYPE" # param). if $2 == "" params = $1 case $1 when /quoted-printable/i - name = 'ENCODING' + name = "ENCODING" when /base64/i - name = 'ENCODING' + name = "ENCODING" else - name = 'TYPE' + name = "TYPE" end end # TODO - In ruby1.8 I can give an initial value to the atparams # hash values instead of this. @@ -186,29 +184,29 @@ # Create a field with name +name+ (a String), value +value+ (see below), # and optional parameters, +params+. +params+ is a hash of the parameter # name (a String) to either a single string or symbol, or an array of # strings and symbols (parameters can be multi-valued). # - # If 'ENCODING' => :b64 is specified as a parameter, the value will be + # If "ENCODING" => :b64 is specified as a parameter, the value will be # base-64 encoded. If it's already base-64 encoded, then use String - # values ('ENCODING' => 'B'), and no further encoding will be done by + # values ("ENCODING" => "B"), and no further encoding will be done by # this routine. # # Currently handled value types are: # - Time, encoded as a date-time value # - Date, encoded as a date value # - String, encoded directly - # - Array of String, concatentated with ';' between them. + # - Array of String, concatentated with ";" between them. # # TODO - need a way to encode String values as TEXT, at least optionally, # so as to escape special chars, etc. def Field.create(name, value="", params={}) line = Field.encode0(nil, name, params, value) begin new(line) - rescue Vpim::InvalidEncodingError => e + rescue ::Vcard::InvalidEncodingError => e raise ArgumentError, e.to_s end end # Create a copy of Field. If the original Field was frozen, this one @@ -234,11 +232,11 @@ # Wrap to width, unless width is zero. if width > 0 l = l.gsub(/.{#{width},#{width}}/) { |m| m + "\n " } end # Make sure it's terminated with no more than a single NL. - l.gsub(/\s*\z/, '') + "\n" + l.gsub(/\s*\z/, "") + "\n" end alias to_s encode # The name. @@ -304,21 +302,21 @@ # - should use the VALUE parameter # - should also take a default value type, so it can be converted # if VALUE parameter is not present. def value case encoding - when nil, '8BIT', '7BIT' then @value + when nil, "8BIT", "7BIT" then @value # Hack - if the base64 lines started with 2 SPC chars, which is invalid, # there will be extra spaces in @value. Since no SPC chars show up in # b64 encodings, they can be safely stripped out before unpacking. - when 'B', 'BASE64' then @value.gsub(' ', '').unpack('m*').first + when "B", "BASE64" then @value.gsub(" ", "").unpack("m*").first - when 'QUOTED-PRINTABLE' then @value.unpack('M*').first + when "QUOTED-PRINTABLE" then @value.unpack("M*").first else - raise Vpim::InvalidEncodingError, "unrecognized encoding (#{encoding})" + raise ::Vcard::InvalidEncodingError, "unrecognized encoding (#{encoding})" end end # Is the #name of this Field +name+? Names are case insensitive. def name?(name) @@ -358,30 +356,30 @@ # TYPE parameters are used for general categories, such as # distinguishing between an email address used at home or at work. def type?(type) type = type.to_str - types = param('TYPE') + types = param("TYPE") if types types = types.detect { |t| t.casecmp(type) == 0 } end end # Is this field marked as preferred? A vCard field is preferred if - # #type?('PREF'). This method is not necessarily meaningful for + # #type?("PREF"). This method is not necessarily meaningful for # non-vCard profiles. def pref? - type? 'PREF' + type? "PREF" end # Set whether a field is marked as preferred. See #pref? def pref=(ispref) if ispref - pvalue_iadd('TYPE', 'PREF') + pvalue_iadd("TYPE", "PREF") else - pvalue_idel('TYPE', 'PREF') + pvalue_idel("TYPE", "PREF") end end # Is the value of this field +value+? The check is case insensitive. # FIXME - it shouldn't be insensitive, make a #casevalue? method. @@ -390,25 +388,25 @@ end # The value of the ENCODING parameter, if present, or nil if not # present. def encoding - e = param('ENCODING') + e = param("ENCODING") if e if e.length > 1 - raise Vpim::InvalidEncodingError, "multi-valued param 'ENCODING' (#{e})" + raise ::Vcard::InvalidEncodingError, "multi-valued param 'ENCODING' (#{e})" end e = e.first.upcase end e end # The type of the value, as specified by the VALUE parameter, nil if # unspecified. def kind - v = param('VALUE') + v = param("VALUE") if v if v.size > 1 raise InvalidEncodingError, "multi-valued param 'VALUE' (#{values})" end v = v.first.downcase @@ -428,29 +426,29 @@ # That's just wrong! So, what to do? I add a message # saying what the year is that breaks, so they at least know that # its ridiculous! I think I need my own DateTime variant. def to_time begin - Vpim.decode_date_time_list(value).collect do |d| + ::Vcard.decode_date_time_list(value).collect do |d| # We get [ year, month, day, hour, min, sec, usec, tz ] begin if(d.pop == "Z") Time.gm(*d) else Time.local(*d) end rescue ArgumentError => e - raise Vpim::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}" + raise ::Vcard::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}" end end - rescue Vpim::InvalidEncodingError - Vpim.decode_date_list(value).collect do |d| + rescue ::Vcard::InvalidEncodingError + ::Vcard.decode_date_list(value).collect do |d| # We get [ year, month, day ] begin Time.gm(*d) rescue ArgumentError => e - raise Vpim::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}" + raise ::Vcard::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}" end end end end @@ -461,31 +459,31 @@ # The field value may be a list of either DATE or DATE-TIME values, # decoding is tried first as a DATE-TIME, then as a DATE, if neither # works an InvalidEncodingError will be raised. def to_date begin - Vpim.decode_date_time_list(value).collect do |d| + ::Vcard.decode_date_time_list(value).collect do |d| # We get [ year, month, day, hour, min, sec, usec, tz ] Date.new(d[0], d[1], d[2]) end - rescue Vpim::InvalidEncodingError - Vpim.decode_date_list(value).collect do |d| + rescue ::Vcard::InvalidEncodingError + ::Vcard.decode_date_list(value).collect do |d| # We get [ year, month, day ] Date.new(*d) end end end # The value as text. Text can have escaped newlines, commas, and escape # characters, this method will strip them, if present. # # In theory, #value could also do this, but it would need to know that - # the value is of type 'TEXT', and often for text values the 'VALUE' + # the value is of type "TEXT", and often for text values the "VALUE" # parameter is not present, so knowledge of the expected type of the # field is required from the decoder. def to_text - Vpim.decode_text(value) + ::Vcard.decode_text(value) end # The undecoded value, see +value+. def value_raw @value @@ -514,14 +512,14 @@ # Set a the param +pname+'s value to +pvalue+, replacing any value it # currently has. See Field.create() for a description of +pvalue+. # # Example: - # if field['TYPE'] - # field['TYPE'] << 'HOME' + # if field["TYPE"] + # field["TYPE"] << "HOME" # else - # field['TYPE'] = [ 'HOME' ] + # field["TYPE"] = [ "HOME" ] # end # # TODO - this could be an alias to #pvalue_set def []=(pname,pvalue) unless pvalue.respond_to?(:to_ary) @@ -595,10 +593,10 @@ line = Field.encode0(g, n, p, v) begin @group, @name, @params, @value = Field.decode0(line) @line = line - rescue Vpim::InvalidEncodingError => e + rescue ::Vcard::InvalidEncodingError => e raise ArgumentError, e.to_s end self end