vpim 0.16
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/vpim/date.rb +198 -0
- data/lib/vpim/dirinfo.rb +229 -0
- data/lib/vpim/duration.rb +121 -0
- data/lib/vpim/enumerator.rb +29 -0
- data/lib/vpim/field.rb +511 -0
- data/lib/vpim/icalendar.rb +555 -0
- data/lib/vpim/maker/vcard.rb +337 -0
- data/lib/vpim/rfc2425.rb +247 -0
- data/lib/vpim/rrule.rb +482 -0
- data/lib/vpim/time.rb +42 -0
- data/lib/vpim/vcard.rb +210 -0
- data/lib/vpim/vevent.rb +381 -0
- data/lib/vpim/vpim.rb +96 -0
- data/lib/vpim/vpim.rb~ +96 -0
- metadata +60 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
$Id: enumerator.rb,v 1.2 2004/11/17 05:06:27 sam Exp $
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2005 Sam Roberts
|
|
5
|
+
|
|
6
|
+
This library is free software; you can redistribute it and/or modify it
|
|
7
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
|
8
|
+
details.
|
|
9
|
+
=end
|
|
10
|
+
|
|
11
|
+
module Vpim
|
|
12
|
+
# This is a way for an object to have multiple ways of being enumerated via
|
|
13
|
+
# argument to it's #each() method. An Enumerator mixes in Enumerable, so the
|
|
14
|
+
# standard APIS such as Enumerable#map(), Enumerable#to_a(), and
|
|
15
|
+
# Enumerable#find_all() can be used on it.
|
|
16
|
+
class Enumerator
|
|
17
|
+
include Enumerable
|
|
18
|
+
|
|
19
|
+
def initialize(obj, *args)
|
|
20
|
+
@obj = obj
|
|
21
|
+
@args = args
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def each(&block)
|
|
25
|
+
@obj.each(*@args, &block)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
data/lib/vpim/field.rb
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
$Id: field.rb,v 1.11 2005/01/07 03:32:16 sam Exp $
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2005 Sam Roberts
|
|
5
|
+
|
|
6
|
+
This library is free software; you can redistribute it and/or modify it
|
|
7
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
|
8
|
+
details.
|
|
9
|
+
=end
|
|
10
|
+
|
|
11
|
+
require 'vpim/rfc2425'
|
|
12
|
+
require 'vpim/vpim'
|
|
13
|
+
require 'date'
|
|
14
|
+
|
|
15
|
+
module Vpim
|
|
16
|
+
|
|
17
|
+
class DirectoryInfo
|
|
18
|
+
|
|
19
|
+
# A field in a directory info object.
|
|
20
|
+
class Field
|
|
21
|
+
private_class_method :new
|
|
22
|
+
|
|
23
|
+
def Field.create_array(fields)
|
|
24
|
+
case fields
|
|
25
|
+
when Hash
|
|
26
|
+
fields.map do |name,value|
|
|
27
|
+
DirectoryInfo::Field.create( name, value )
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
fields.to_ary
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Encode a field.
|
|
35
|
+
def Field.encode0(group, name, params={}, value='') # :nodoc:
|
|
36
|
+
line = ""
|
|
37
|
+
|
|
38
|
+
# A reminder of the line format:
|
|
39
|
+
# [<group>.]<name>;<pname>=<pvalue>,<pvalue>:<value>
|
|
40
|
+
|
|
41
|
+
if group
|
|
42
|
+
line << group << '.'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
line << name
|
|
46
|
+
|
|
47
|
+
params.each do |pname, pvalues|
|
|
48
|
+
|
|
49
|
+
unless pvalues.respond_to? :to_ary
|
|
50
|
+
pvalues = [ pvalues ]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
line << ';' << pname << '='
|
|
54
|
+
|
|
55
|
+
sep = "" # set to ',' after one pvalue has been appended
|
|
56
|
+
|
|
57
|
+
pvalues.each do |pvalue|
|
|
58
|
+
# check if we need to do any encoding
|
|
59
|
+
if pname.downcase == 'encoding' && pvalue == :b64
|
|
60
|
+
pvalue = 'b' # the RFC definition of the base64 param value
|
|
61
|
+
value = [ value.to_str ].pack('m').gsub("\n", '')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
line << sep << pvalue
|
|
65
|
+
sep =",";
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
line << ':'
|
|
70
|
+
|
|
71
|
+
line << Field.value_str(value)
|
|
72
|
+
|
|
73
|
+
line
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def Field.value_str(value) # :nodoc:
|
|
77
|
+
line = ''
|
|
78
|
+
case value
|
|
79
|
+
when Date
|
|
80
|
+
line << Vpim.encode_date(value)
|
|
81
|
+
|
|
82
|
+
when Time #, DateTime
|
|
83
|
+
line << Vpim.encode_date_time(value)
|
|
84
|
+
|
|
85
|
+
when Array
|
|
86
|
+
line << value.map { |v| Field.value_str(v) }.join(';')
|
|
87
|
+
|
|
88
|
+
when Symbol
|
|
89
|
+
line << value
|
|
90
|
+
|
|
91
|
+
else
|
|
92
|
+
line << value.to_str
|
|
93
|
+
end
|
|
94
|
+
line
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Decode a field.
|
|
98
|
+
def Field.decode0(atline) # :nodoc:
|
|
99
|
+
unless atline =~ %r{#{Bnf::LINE}}i
|
|
100
|
+
raise Vpim::InvalidEncodingError, atline
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
atgroup = $1
|
|
104
|
+
atname = $2
|
|
105
|
+
paramslist = $3
|
|
106
|
+
atvalue = $~[-1]
|
|
107
|
+
|
|
108
|
+
if atgroup.length > 0
|
|
109
|
+
atgroup.chomp!('.')
|
|
110
|
+
else
|
|
111
|
+
atgroup = nil
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
atparams = {}
|
|
115
|
+
|
|
116
|
+
# Collect the params, if any.
|
|
117
|
+
if paramslist.size > 1
|
|
118
|
+
|
|
119
|
+
# v3.0 and v2.1 params
|
|
120
|
+
paramslist.scan( %r{#{Bnf::PARAM}}i ) do
|
|
121
|
+
|
|
122
|
+
# param names are case-insensitive, and multi-valued
|
|
123
|
+
name = $1.downcase
|
|
124
|
+
params = $3
|
|
125
|
+
|
|
126
|
+
# v2.1 params have no '=' sign, figure out what kind of param it
|
|
127
|
+
# is (either its a known encoding, or we treat it as a 'type'
|
|
128
|
+
# param).
|
|
129
|
+
|
|
130
|
+
if $2 == ""
|
|
131
|
+
params = $1
|
|
132
|
+
case $1
|
|
133
|
+
when /quoted-printable/i
|
|
134
|
+
name = 'encoding'
|
|
135
|
+
|
|
136
|
+
when /base64/i
|
|
137
|
+
name = 'encoding'
|
|
138
|
+
|
|
139
|
+
else
|
|
140
|
+
name = 'type'
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# TODO - In ruby1.8 I can give an initial value to the atparams
|
|
145
|
+
# hash values instead of this.
|
|
146
|
+
unless atparams.key? name
|
|
147
|
+
atparams[name] = []
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
params.scan( %r{#{Bnf::PVALUE}} ) do
|
|
151
|
+
atparams[name] << ($1 || $2) # Used to do this, want to stop! .downcase
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
[ atgroup, atname, atparams, atvalue ]
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def initialize(line) # :nodoc:
|
|
160
|
+
@line = line.to_str
|
|
161
|
+
@group, @name, @params, @value = Field.decode0(@line)
|
|
162
|
+
self
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Create a field by decoding +line+, a String which must already be
|
|
166
|
+
# unfolded. Decoded fields are frozen, but see #copy().
|
|
167
|
+
def Field.decode(line)
|
|
168
|
+
new(line).freeze
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Create a field with name +name+ (a String), value +value+ (see below),
|
|
172
|
+
# and optional parameters, +params+. +params+ is a hash of the parameter
|
|
173
|
+
# name (a String) to either a single string or symbol, or an array of
|
|
174
|
+
# strings and symbols (parameters can be multi-valued).
|
|
175
|
+
#
|
|
176
|
+
# If 'encoding' => :b64 is specified as a parameter, the value will be
|
|
177
|
+
# base-64 encoded. If it's already base-64 encoded, then use String
|
|
178
|
+
# values ('encoding' => 'b'), and no further encoding will be done by
|
|
179
|
+
# this routine.
|
|
180
|
+
#
|
|
181
|
+
# Currently handled value types are:
|
|
182
|
+
# - Time, encoded as a date-time value
|
|
183
|
+
# - Date, encoded as a date value
|
|
184
|
+
# - String, encoded directly
|
|
185
|
+
# - Array of String, concatentated with ';' between them.
|
|
186
|
+
#
|
|
187
|
+
# TODO - need a way to encode String values as TEXT, at least optionally,
|
|
188
|
+
# so as to escape special chars, etc.
|
|
189
|
+
def Field.create(name, value="", params={})
|
|
190
|
+
line = Field.encode0(nil, name, params, value)
|
|
191
|
+
|
|
192
|
+
begin
|
|
193
|
+
new(line)
|
|
194
|
+
rescue Vpim::InvalidEncodingError => e
|
|
195
|
+
raise ArgumentError, e.to_s
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Create a copy of Field. If the original Field was frozen, this one
|
|
200
|
+
# won't be.
|
|
201
|
+
def copy
|
|
202
|
+
Marshal.load(Marshal.dump(self))
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# The String encoding of the Field. The String will be wrapped to a
|
|
206
|
+
# maximum line width of +width+, where +0+ means no wrapping, and nil is
|
|
207
|
+
# to accept the default wrapping (75, recommended by RFC2425).
|
|
208
|
+
#
|
|
209
|
+
# Note: Apple's Address Book 3.0.3 neither understands to unwrap lines
|
|
210
|
+
# when it imports vCards (it treats them as raw new-line characters), nor
|
|
211
|
+
# wraps long lines on export. On import, this is mostly a cosmetic
|
|
212
|
+
# problem, but wrapping can be disabled by setting width to +0+, if
|
|
213
|
+
# desired. On export, its a more serious bug, since Address Book wil
|
|
214
|
+
# encode the entire Note: section as a single, very long, line.
|
|
215
|
+
def encode(width=nil)
|
|
216
|
+
width = 75 unless width
|
|
217
|
+
l = @line
|
|
218
|
+
# Wrap to width, unless width is zero.
|
|
219
|
+
if width > 0
|
|
220
|
+
l = l.gsub(/.{#{width},#{width}}/) { |m| m + "\n " }
|
|
221
|
+
end
|
|
222
|
+
# Make sure it's terminated with no more than a single NL.
|
|
223
|
+
l.gsub(/\s*\z/, '') + "\n"
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
alias to_s encode
|
|
227
|
+
|
|
228
|
+
# The name.
|
|
229
|
+
def name
|
|
230
|
+
@name
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# The group, if present, or nil if not present.
|
|
234
|
+
def group
|
|
235
|
+
@group
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# An Array of all the param names.
|
|
239
|
+
def params
|
|
240
|
+
@params.keys
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# The Array of all values of the param +name+, or nil if there is no
|
|
244
|
+
# such param.
|
|
245
|
+
#
|
|
246
|
+
# TODO - this doesn't return [] if the param isn't found, because then
|
|
247
|
+
# you can't distinguish between a param with no values, and a param that
|
|
248
|
+
# isn't defined. But maybe it isn't useful? You can always do
|
|
249
|
+
# params.include?(a_name) if you want to know if it exists. Maybe this
|
|
250
|
+
# should take a block specifying the default value, even?
|
|
251
|
+
def param(name)
|
|
252
|
+
v = @params[name.downcase]
|
|
253
|
+
if v
|
|
254
|
+
v = v.collect do |p|
|
|
255
|
+
p.downcase.freeze
|
|
256
|
+
end
|
|
257
|
+
v.freeze
|
|
258
|
+
end
|
|
259
|
+
v
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
alias [] param
|
|
263
|
+
|
|
264
|
+
# Yield once for each param, +name+ is the parameter name, +value+ is an
|
|
265
|
+
# array of the parameter values.
|
|
266
|
+
def each_param(&block) #:yield: name, value
|
|
267
|
+
if @params
|
|
268
|
+
@params.each(&block)
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# The decoded value.
|
|
273
|
+
#
|
|
274
|
+
# The encoding specified by the #encoding, if any, is stripped.
|
|
275
|
+
#
|
|
276
|
+
# Note: Both the RFC 2425 encoding param ("b", meaning base-64) and the
|
|
277
|
+
# vCard 2.1 encoding params ("base64", "quoted-printable", "8bit", and
|
|
278
|
+
# "7bit") are supported.
|
|
279
|
+
def value
|
|
280
|
+
case encoding
|
|
281
|
+
when nil, '8bit', '7bit' then @value
|
|
282
|
+
|
|
283
|
+
# Hack - if the base64 lines started with 2 SPC chars, which is invalid,
|
|
284
|
+
# there will be extra spaces in @value. Since no SPC chars show up in
|
|
285
|
+
# b64 encodings, they can be safely stripped out before unpacking.
|
|
286
|
+
when 'b', 'base64' then @value.gsub(' ', '').unpack('m*').first
|
|
287
|
+
|
|
288
|
+
when 'quoted-printable' then @value.unpack('M*').first
|
|
289
|
+
|
|
290
|
+
else raise Vpim::InvalidEncodingError, "unrecognized encoding (#{encoding})"
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Is the #name of this Field +name+? Names are case insensitive.
|
|
295
|
+
def name?(name)
|
|
296
|
+
name.to_s.downcase == @name.downcase
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Is the #group of this field +group+? Group names are case insensitive.
|
|
300
|
+
# A +group+ of nil matches if the field has no group.
|
|
301
|
+
def group?(group)
|
|
302
|
+
g1 = @group ? @group.downcase : nil
|
|
303
|
+
g2 = group ? group.downcase : nil
|
|
304
|
+
g1 == g2
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Is the value of this field of type +kind+? RFC2425 allows the type of
|
|
308
|
+
# a fields value to be encoded in the VALUE parameter. Don't rely on its
|
|
309
|
+
# presence, they aren't required, and usually aren't bothered with. In
|
|
310
|
+
# cases where the kind of value might vary (an iCalendar DTSTART can be
|
|
311
|
+
# either a date or a date-time, for example), you are more likely to see
|
|
312
|
+
# the kind of value specified explicitly.
|
|
313
|
+
#
|
|
314
|
+
# The value types defined by RFC 2425 are:
|
|
315
|
+
# - uri:
|
|
316
|
+
# - text:
|
|
317
|
+
# - date: a list of 1 or more dates
|
|
318
|
+
# - time: a list of 1 or more times
|
|
319
|
+
# - date-time: a list of 1 or more date-times
|
|
320
|
+
# - integer:
|
|
321
|
+
# - boolean:
|
|
322
|
+
# - float:
|
|
323
|
+
def kind?(kind)
|
|
324
|
+
kind.downcase == self.kind
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# Is one of the values of the TYPE parameter of this field +type+? The
|
|
328
|
+
# type parameter values are case insensitive. False if there is no TYPE
|
|
329
|
+
# parameter.
|
|
330
|
+
#
|
|
331
|
+
# TYPE parameters are used for general categories, such as
|
|
332
|
+
# distinguishing between an email address used at home or at work.
|
|
333
|
+
def type?(type)
|
|
334
|
+
types = param('type')
|
|
335
|
+
|
|
336
|
+
if types
|
|
337
|
+
types = types.include?(type.to_str.downcase)
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Is this field marked as preferred? A vCard field is preferred if
|
|
342
|
+
# #type?('pref'). This method is not necessarily meaningful for
|
|
343
|
+
# non-vCard profiles.
|
|
344
|
+
def pref?
|
|
345
|
+
type?('pref')
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Is the value of this field +value+? The check is case insensitive.
|
|
349
|
+
def value?(value)
|
|
350
|
+
@value && @value.downcase == value.downcase
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# The value of the ENCODING parameter, if present, or nil if not
|
|
354
|
+
# present.
|
|
355
|
+
def encoding
|
|
356
|
+
e = param("encoding")
|
|
357
|
+
|
|
358
|
+
if e
|
|
359
|
+
if e.length > 1
|
|
360
|
+
raise Vpim::InvalidEncodingError, "multi-valued param 'encoding' (#{e})"
|
|
361
|
+
end
|
|
362
|
+
e = e.first
|
|
363
|
+
end
|
|
364
|
+
e
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
# The type of the value, as specified by the VALUE parameter, nil if
|
|
368
|
+
# unspecified.
|
|
369
|
+
def kind
|
|
370
|
+
v = param('value')
|
|
371
|
+
if v
|
|
372
|
+
if v.size > 1
|
|
373
|
+
raise InvalidEncodingError, "multi-valued param 'value' (#{values})"
|
|
374
|
+
end
|
|
375
|
+
v = v.first
|
|
376
|
+
end
|
|
377
|
+
v
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
# The value as an array of Time objects (all times and dates in
|
|
381
|
+
# RFC2425 are lists, even where it might not make sense, such as a
|
|
382
|
+
# birthday). The time will be UTC if marked as so (with a timezone of
|
|
383
|
+
# "Z"), and in localtime otherwise.
|
|
384
|
+
#
|
|
385
|
+
# TODO: support timezone offsets
|
|
386
|
+
#
|
|
387
|
+
# TODO - if year is before 1970, this won't work... but some people
|
|
388
|
+
# are generating calendars saying Canada Day started in 1753!
|
|
389
|
+
# That's just wrong! So, what to do? I add a message
|
|
390
|
+
# saying what the year is that breaks, so they at least know that
|
|
391
|
+
# its ridiculous! I think I need my own DateTime variant.
|
|
392
|
+
def to_time
|
|
393
|
+
begin
|
|
394
|
+
Vpim.decode_date_time_list(value).collect do |d|
|
|
395
|
+
# We get [ year, month, day, hour, min, sec, usec, tz ]
|
|
396
|
+
begin
|
|
397
|
+
if(d.pop == "Z")
|
|
398
|
+
Time.gm(*d)
|
|
399
|
+
else
|
|
400
|
+
Time.local(*d)
|
|
401
|
+
end
|
|
402
|
+
rescue ArgumentError => e
|
|
403
|
+
raise Vpim::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}"
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
rescue Vpim::InvalidEncodingError
|
|
407
|
+
Vpim.decode_date_list(value).collect do |d|
|
|
408
|
+
# We get [ year, month, day ]
|
|
409
|
+
begin
|
|
410
|
+
Time.gm(*d)
|
|
411
|
+
rescue ArgumentError => e
|
|
412
|
+
raise Vpim::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}"
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
# The value as an array of Date objects (all times and dates in
|
|
419
|
+
# RFC2425 are lists, even where it might not make sense, such as a
|
|
420
|
+
# birthday).
|
|
421
|
+
#
|
|
422
|
+
# The field value may be a list of either DATE or DATE-TIME values,
|
|
423
|
+
# decoding is tried first as a DATE-TIME, then as a DATE, if neither
|
|
424
|
+
# works an InvalidEncodingError will be raised.
|
|
425
|
+
def to_date
|
|
426
|
+
begin
|
|
427
|
+
Vpim.decode_date_time_list(value).collect do |d|
|
|
428
|
+
# We get [ year, month, day, hour, min, sec, usec, tz ]
|
|
429
|
+
Date.new(d[0], d[1], d[2])
|
|
430
|
+
end
|
|
431
|
+
rescue Vpim::InvalidEncodingError
|
|
432
|
+
Vpim.decode_date_list(value).collect do |d|
|
|
433
|
+
# We get [ year, month, day ]
|
|
434
|
+
Date.new(*d)
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
# The value as text. Text can have escaped newlines, commas, and escape
|
|
440
|
+
# characters, this method will strip them, if present.
|
|
441
|
+
#
|
|
442
|
+
# In theory, #value could also do this, but it would need to know that
|
|
443
|
+
# the value is of type 'text', and often for text values the 'type'
|
|
444
|
+
# parameter is not present, so knowledge of the expected type of the
|
|
445
|
+
# field is required from the decoder.
|
|
446
|
+
def to_text
|
|
447
|
+
Vpim.decode_text(value)
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
# The undecoded value, see +value+.
|
|
451
|
+
def value_raw
|
|
452
|
+
@value
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def inspect # :nodoc:
|
|
456
|
+
@line
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
# TODO def pretty_print() ...
|
|
460
|
+
|
|
461
|
+
# Set the group of this field to +group+.
|
|
462
|
+
def group=(group)
|
|
463
|
+
mutate(group, @name, @params, @value)
|
|
464
|
+
group
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# Set the value of this field to +value+. Valid values are as in
|
|
468
|
+
# Field.create().
|
|
469
|
+
def value=(value)
|
|
470
|
+
mutate(@group, @name, @params, value)
|
|
471
|
+
value
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
# Convert +value+ to text, then assign.
|
|
475
|
+
#
|
|
476
|
+
# TODO - unimplemented
|
|
477
|
+
def text=(text)
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# Set a the param +param+'s value to +pvalue+. Valid values are as in
|
|
481
|
+
# Field.create().
|
|
482
|
+
def []=(param,pvalue)
|
|
483
|
+
unless pvalue.respond_to?(:to_ary)
|
|
484
|
+
pvalue = [ pvalue ]
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
h = @params.dup
|
|
488
|
+
|
|
489
|
+
h[param.downcase] = pvalue
|
|
490
|
+
|
|
491
|
+
mutate(@group, @name, h, @value)
|
|
492
|
+
pvalue
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def mutate(g, n, p, v) #:nodoc:
|
|
496
|
+
line = Field.encode0(g, n, p, v)
|
|
497
|
+
|
|
498
|
+
begin
|
|
499
|
+
@group, @name, @params, @value = Field.decode0(line)
|
|
500
|
+
@line = line
|
|
501
|
+
rescue Vpim::InvalidEncodingError => e
|
|
502
|
+
raise ArgumentError, e.to_s
|
|
503
|
+
end
|
|
504
|
+
self
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
private :mutate
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
|