dmap 0.1.6 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/dmap.rb +214 -205
- metadata +2 -2
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ begin
|
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "dmap"
|
8
|
-
gem.version = "0.1
|
8
|
+
gem.version = "0.2.1"
|
9
9
|
gem.summary = %Q{Parses Apple's DMAP strings (4-byte serialization method)}
|
10
10
|
gem.description = %Q{Apple uses a system of serialization (I think its called dmap…) where a 4-byte string tells of the information following, both its type and what it represents. Its used in the DAAP (Protocol), QuickTime mov structure and doubtless many other places.}
|
11
11
|
gem.email = "jphastings@gmail.com"
|
data/lib/dmap.rb
CHANGED
@@ -20,18 +20,18 @@ module DMAP
|
|
20
20
|
#
|
21
21
|
# NB. if you specify `content` while passing a dmap tag you will overwrite anything
|
22
22
|
# that was in the dmap!
|
23
|
-
def initialize(tag_or_dmap,new_content = nil)
|
23
|
+
def initialize(tag_or_dmap,new_content = nil)
|
24
24
|
# Assume we have an IO object, if this fails then we probably have a string instead
|
25
25
|
begin
|
26
|
-
@tag = tag_or_dmap.read(4)
|
26
|
+
@tag = tag_or_dmap.read(4)
|
27
27
|
@io = tag_or_dmap if new_content.nil?
|
28
28
|
rescue NoMethodError
|
29
|
-
@tag = tag_or_dmap[0..3]
|
29
|
+
@tag = tag_or_dmap[0..3]
|
30
30
|
end
|
31
31
|
|
32
32
|
# Find out the details of this tag
|
33
33
|
begin
|
34
|
-
type
|
34
|
+
@name,type = DMAP::TAGS[@tag.to_sym]
|
35
35
|
rescue NameError
|
36
36
|
raise NameError, "I don't know how to interpret the tag '#{@tag}'. Please extend the DMAP module!"
|
37
37
|
end
|
@@ -62,7 +62,12 @@ module DMAP
|
|
62
62
|
|
63
63
|
# Adds the tag to a request to create the dmap
|
64
64
|
def to_dmap
|
65
|
-
|
65
|
+
begin
|
66
|
+
"#{@tag.downcase}#{@real_class.to_dmap}"
|
67
|
+
rescue
|
68
|
+
warn("Error while putting #{@tag} to dmap")
|
69
|
+
raise
|
70
|
+
end
|
66
71
|
end
|
67
72
|
|
68
73
|
private
|
@@ -79,27 +84,43 @@ module DMAP
|
|
79
84
|
@real_class = Array.new(content || @io || [])
|
80
85
|
end
|
81
86
|
|
82
|
-
def
|
87
|
+
def parse_byte(content)
|
83
88
|
begin
|
84
|
-
|
85
|
-
@real_class = MeasuredInteger.new(content,nil,signed)
|
86
|
-
elsif not content.nil? and (content[0].is_a? Numeric and content[1].is_a? Numeric)
|
87
|
-
@real_class = MeasuredInteger.new(content[0],content[1],signed)
|
88
|
-
else
|
89
|
-
box_size = @io.read(4).unpack("N")[0]
|
90
|
-
case box_size
|
91
|
-
when 1,2,4
|
92
|
-
num = @io.read(box_size).unpack(MeasuredInteger.pack_code(box_size,signed))[0]
|
93
|
-
when 8
|
94
|
-
num = @io.read(box_size).unpack("NN")
|
95
|
-
num = num[0]*65536 + num[1]
|
96
|
-
else
|
97
|
-
raise "I don't know how to unpack an integer #{box_size} bytes long"
|
98
|
-
end
|
99
|
-
@real_class = MeasuredInteger.new(num,box_size,signed)
|
100
|
-
end
|
89
|
+
@real_class = MeasuredInteger.new(@io.read(@io.read(4).unpack("N")[0]).unpack("C")[0],1,false)
|
101
90
|
rescue NoMethodError
|
102
|
-
@real_class = MeasuredInteger.new(0,
|
91
|
+
@real_class = MeasuredInteger.new(content || 0,1,false)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def parse_short(content)
|
96
|
+
begin
|
97
|
+
@real_class = MeasuredInteger.new(@io.read(@io.read(4).unpack("N")[0]).unpack("n")[0],2,false)
|
98
|
+
rescue NoMethodError
|
99
|
+
@real_class = MeasuredInteger.new(content || 0,2,false)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse_integer(content)
|
104
|
+
begin
|
105
|
+
@real_class = MeasuredInteger.new(@io.read(@io.read(4).unpack("N")[0]).unpack("N")[0],4,false) # Use L?
|
106
|
+
rescue NoMethodError
|
107
|
+
@real_class = MeasuredInteger.new(content || 0,4,false)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def parse_long(content)
|
112
|
+
begin
|
113
|
+
@real_class = MeasuredInteger.new(@io.read(@io.read(4).unpack("N")[0]).unpack("Q")[0],8,false)
|
114
|
+
rescue NoMethodError
|
115
|
+
@real_class = MeasuredInteger.new(content || 0,8,false)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def parse_signed_integer(content)
|
120
|
+
begin
|
121
|
+
@real_class = MeasuredInteger.new(@io.read(@io.read(4).unpack("N")[0]).unpack("l")[0],4,true)
|
122
|
+
rescue NoMethodError
|
123
|
+
@real_class = MeasuredInteger.new(content || 0,4,true)
|
103
124
|
end
|
104
125
|
end
|
105
126
|
|
@@ -107,9 +128,9 @@ module DMAP
|
|
107
128
|
def parse_version(content)
|
108
129
|
begin
|
109
130
|
# FIXME: Are version numbers x.y ?
|
110
|
-
@real_class = Version.new(@io.read(@io.read(4).unpack("N")[0]).unpack("
|
131
|
+
@real_class = Version.new(@io.read(@io.read(4).unpack("N")[0]).unpack("CCCC").join("."))
|
111
132
|
rescue NoMethodError
|
112
|
-
@real_class = Version.new(content || "1.0")
|
133
|
+
@real_class = Version.new(content || "0.1.0.0")
|
113
134
|
end
|
114
135
|
end
|
115
136
|
|
@@ -120,10 +141,6 @@ module DMAP
|
|
120
141
|
@real_class = Time.now
|
121
142
|
end
|
122
143
|
end
|
123
|
-
|
124
|
-
def parse_signed(content)
|
125
|
-
parse_number(content,true)
|
126
|
-
end
|
127
144
|
end
|
128
145
|
|
129
146
|
# We may not always want to parse an entire DMAP in one go, here we extend Array so that
|
@@ -150,7 +167,6 @@ module DMAP
|
|
150
167
|
@dmap_io = array_or_io
|
151
168
|
@dmap_start = @dmap_io.tell
|
152
169
|
@unparsed_data = true
|
153
|
-
parse_dmap if @@parse_immediately
|
154
170
|
rescue NoMethodError
|
155
171
|
begin
|
156
172
|
array_or_io.each do |element|
|
@@ -165,6 +181,7 @@ module DMAP
|
|
165
181
|
@unparsed_data = false
|
166
182
|
end
|
167
183
|
|
184
|
+
parse_dmap if @@parse_immediately
|
168
185
|
end
|
169
186
|
|
170
187
|
[:==, :===, :=~, :clone, :display, :dup, :enum_for, :eql?, :equal?, :hash, :to_a, :to_enum, :each, :length].each do |method_name|
|
@@ -220,56 +237,46 @@ module DMAP
|
|
220
237
|
attr_reader :value
|
221
238
|
attr_accessor :box_size, :binary, :signed
|
222
239
|
|
223
|
-
def initialize(value,
|
224
|
-
@value = value
|
225
|
-
@
|
226
|
-
self.box_size = wanted_box_size
|
240
|
+
def initialize(value,box_size = 1,signed = false)
|
241
|
+
@value = value.to_i
|
242
|
+
@box_size = box_size
|
227
243
|
@signed = signed
|
228
244
|
end
|
229
245
|
|
230
|
-
|
231
|
-
# current value.
|
232
|
-
def box_size=(wanted_box_size)
|
233
|
-
# Find the smallest number of bytes needed to express this number
|
234
|
-
@box_size = [wanted_box_size || 0,(Math.log((Math.log(@value) / 2.07944154167984).ceil)/0.693147180559945).ceil].max rescue 1 # For when value = 0
|
235
|
-
end
|
236
|
-
|
237
|
-
def to_dmap
|
246
|
+
def to_dmap # TODO: Tidy me
|
238
247
|
case @box_size
|
239
248
|
when 1,2,4,8
|
240
|
-
[@box_size,@value].pack("N"<<
|
249
|
+
[@box_size,@value].pack("N"<<pack_code)
|
241
250
|
else
|
242
251
|
raise "I don't know how to unpack an integer #{@box_size} bytes long"
|
243
252
|
end
|
244
253
|
end
|
245
254
|
|
246
|
-
def
|
247
|
-
|
248
|
-
return out
|
255
|
+
def pack_code
|
256
|
+
{1=>"C",-1=>"c",2=>"n",4=>"N",8=>"Q",-8=>"q"}[@box_size * (@signed ? -1 : 1)] # FIXME: pack codes for all signed cases
|
249
257
|
end
|
250
258
|
|
251
259
|
def inspect
|
252
|
-
# This is a bit of a guess, no change to the data, just helps inspection
|
253
|
-
return (@value == 1) ? "true" : "false" if @binary
|
254
260
|
@value
|
255
261
|
end
|
256
262
|
end
|
257
263
|
|
258
264
|
# A class to store version numbers
|
259
265
|
class Version
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
266
|
+
attr_accessor :maximus,:major,:minor,:minimus
|
267
|
+
def initialize(version = "0.1.0.0")
|
268
|
+
@maximus,@major,@minor,@minimus = (version.to_s<<".0.0.0").split(".").collect{|n| n.to_i }
|
269
|
+
if @maximus > 255 or @major > 255 or @minor > 255 or @minimus > 255
|
270
|
+
raise RangeError "None of the version points can be above 255. Surely that's enough?"
|
264
271
|
end
|
265
272
|
end
|
266
273
|
|
267
274
|
def to_dmap
|
268
|
-
"\000\000\000\004"<<[@major,@minor].pack("
|
275
|
+
"\000\000\000\004"<<[@maximus,@major,@minor,@minimus].pack("CCCC")
|
269
276
|
end
|
270
277
|
|
271
278
|
def inspect
|
272
|
-
"v#{@major}.#{@minor}"
|
279
|
+
"v#{@maximus}.#{@major}.#{@minor}.#{@minimus}"
|
273
280
|
end
|
274
281
|
end
|
275
282
|
|
@@ -287,154 +294,156 @@ module DMAP
|
|
287
294
|
end
|
288
295
|
end
|
289
296
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
297
|
+
TAGS = {
|
298
|
+
:abal => ['daap.browsealbumlisting', :list],
|
299
|
+
:abar => ['daap.browseartistlisting', :list],
|
300
|
+
:abcp => ['daap.browsecomposerlisting', :list],
|
301
|
+
:abgn => ['daap.browsegenrelisting', :list],
|
302
|
+
:abpl => ['daap.baseplaylist', :byte],
|
303
|
+
:abro => ['daap.databasebrowse', :list],
|
304
|
+
:adbs => ['daap.databasesongs', :list],
|
305
|
+
:aeAI => ['com.apple.itunes.itms-artistid', :integer],
|
306
|
+
:aeCI => ['com.apple.itunes.itms-composerid', :integer],
|
307
|
+
:aeCR => ['com.apple.itunes.content-rating', :string],
|
308
|
+
:aeEN => ['com.apple.itunes.episode-num-str', :string],
|
309
|
+
:aeES => ['com.apple.itunes.episode-sort', :integer],
|
310
|
+
:aeFP => ['com.apple.itunes.req-fplay', :byte],
|
311
|
+
:aeGU => ['com.apple.itunes.gapless-dur', :long],
|
312
|
+
:aeGD => ['com.apple.itunes.gapless-enc-dr', :integer],
|
313
|
+
:aeGE => ['com.apple.itunes.gapless-enc-del', :integer],
|
314
|
+
:aeGH => ['com.apple.itunes.gapless-heur', :integer],
|
315
|
+
:aeGI => ['com.apple.itunes.itms-genreid', :integer],
|
316
|
+
:aeGR => ['com.apple.itunes.gapless-resy', :long],
|
317
|
+
:aeHD => ['com.apple.itunes.is-hd-video', :byte],
|
318
|
+
:aeHV => ['com.apple.itunes.has-video', :byte],
|
319
|
+
:aeMK => ['com.apple.itunes.mediakind', :byte],
|
320
|
+
:aeNN => ['com.apple.itunes.network-name', :string],
|
321
|
+
:aeNV => ['com.apple.itunes.norm-volume', :integer],
|
322
|
+
:aePC => ['com.apple.itunes.is-podcast', :byte],
|
323
|
+
:aePI => ['com.apple.itunes.itms-playlistid', :integer],
|
324
|
+
:aePP => ['com.apple.itunes.is-podcast-playlist', :byte],
|
325
|
+
:aePS => ['com.apple.itunes.special-playlist', :byte],
|
326
|
+
:aeSU => ['com.apple.itunes.season-num', :integer],
|
327
|
+
:aeSF => ['com.apple.itunes.itms-storefrontid', :integer],
|
328
|
+
:aeSG => ['com.apple.itunes.saved-genius', :byte],
|
329
|
+
:aeSI => ['com.apple.itunes.itms-songid', :integer],
|
330
|
+
:aeSN => ['com.apple.itunes.series-name', :string],
|
331
|
+
:aeSP => ['com.apple.itunes.smart-playlist', :byte],
|
332
|
+
:aeSV => ['com.apple.itunes.music-sharing-version', :integer],
|
333
|
+
:agrp => ['daap.songgrouping', :string],
|
334
|
+
:aply => ['daap.databaseplaylists', :list],
|
335
|
+
:aprm => ['daap.playlistrepeatmode', :byte],
|
336
|
+
:apro => ['daap.protocolversion', :version],
|
337
|
+
:apsm => ['daap.playlistshufflemode', :byte],
|
338
|
+
:apso => ['daap.playlistsongs', :list],
|
339
|
+
:arif => ['daap.resolveinfo', :list],
|
340
|
+
:arsv => ['daap.resolve', :list],
|
341
|
+
:asaa => ['daap.songalbumartist', :string],
|
342
|
+
:asai => ['daap.songalbumid', :long],
|
343
|
+
:asal => ['daap.songalbum', :string],
|
344
|
+
:asar => ['daap.songartist', :string],
|
345
|
+
:asbk => ['daap.bookmarkable', :byte],
|
346
|
+
:asbo => ['daap.songbookmark', :integer],
|
347
|
+
:asbr => ['daap.songbitrate', :short],
|
348
|
+
:asbt => ['daap.songbeatsperminute', :short],
|
349
|
+
:ascd => ['daap.songcodectype', :integer],
|
350
|
+
:ascm => ['daap.songcomment', :string],
|
351
|
+
:ascn => ['daap.songcontentdescription', :string],
|
352
|
+
:asco => ['daap.songcompilation', :byte],
|
353
|
+
:ascp => ['daap.songcomposer', :string],
|
354
|
+
:ascr => ['daap.songcontentrating', :byte],
|
355
|
+
:ascs => ['daap.songcodecsubtype', :integer],
|
356
|
+
:asct => ['daap.songcategory', :string],
|
357
|
+
:asda => ['daap.songdateadded', :time],
|
358
|
+
:asdb => ['daap.songdisabled', :byte],
|
359
|
+
:asdc => ['daap.songdisccount', :short],
|
360
|
+
:asdk => ['daap.songdatakind', :byte],
|
361
|
+
:asdm => ['daap.songdatemodified', :time],
|
362
|
+
:asdn => ['daap.songdiscnumber', :short],
|
363
|
+
:asdp => ['daap.songdatepurchased', :time],
|
364
|
+
:asdr => ['daap.songdatereleased', :time],
|
365
|
+
:asdt => ['daap.songdescription', :string],
|
366
|
+
:ased => ['daap.songextradata', :short],
|
367
|
+
:aseq => ['daap.songeqpreset', :string],
|
368
|
+
:asfm => ['daap.songformat', :string],
|
369
|
+
:asgn => ['daap.songgenre', :string],
|
370
|
+
:asgp => ['daap.songgapless', :byte],
|
371
|
+
:ashp => ['daap.songhasbeenplayed', :byte],
|
372
|
+
:asky => ['daap.songkeywords', :string],
|
373
|
+
:aslc => ['daap.songlongcontentdescription', :string],
|
374
|
+
:asls => ['daap.songlongsize', :long],
|
375
|
+
:aspu => ['daap.songpodcasturl', :string],
|
376
|
+
:asrv => ['daap.songrelativevolume', :signed_byte],
|
377
|
+
:assu => ['daap.sortalbum', :string],
|
378
|
+
:assa => ['daap.sortartist', :string],
|
379
|
+
:assc => ['daap.sortcomposer', :string],
|
380
|
+
:assl => ['daap.sortalbumartist', :string],
|
381
|
+
:assn => ['daap.sortname', :string],
|
382
|
+
:assp => ['daap.songstoptime', :integer],
|
383
|
+
:assr => ['daap.songsamplerate', :integer],
|
384
|
+
:asss => ['daap.sortseriesname', :string],
|
385
|
+
:asst => ['daap.songstarttime', :integer],
|
386
|
+
:assz => ['daap.songsize', :integer],
|
387
|
+
:astc => ['daap.songtrackcount', :short],
|
388
|
+
:astm => ['daap.songtime', :integer],
|
389
|
+
:astn => ['daap.songtracknumber', :short],
|
390
|
+
:asul => ['daap.songdataurl', :string],
|
391
|
+
:asur => ['daap.songuserrating', :byte],
|
392
|
+
:asyr => ['daap.songyear', :short],
|
393
|
+
:ated => ['daap.supportsextradata', :short],
|
394
|
+
:avdb => ['daap.serverdatabases', :list],
|
395
|
+
:ceJC => ['com.apple.itunes.jukebox-client-vote', :signed_byte],
|
396
|
+
:ceJI => ['com.apple.itunes.jukebox-current', :integer],
|
397
|
+
:ceJS => ['com.apple.itunes.jukebox-score', :signed_short],
|
398
|
+
:ceJV => ['com.apple.itunes.jukebox-vote', :integer],
|
399
|
+
:"f\215ch" => ['dmap.haschildcontainers', :byte],
|
400
|
+
:mbcl => ['dmap.bag', :list],
|
401
|
+
:mccr => ['dmap.contentcodesresponse', :list],
|
402
|
+
:mcna => ['dmap.contentcodesname', :string],
|
403
|
+
:mcnm => ['dmap.contentcodesnumber', :integer],
|
404
|
+
:mcon => ['dmap.container', :list],
|
405
|
+
:mctc => ['dmap.containercount', :integer],
|
406
|
+
:mcti => ['dmap.containeritemid', :integer],
|
407
|
+
:mcty => ['dmap.contentcodestype', :short],
|
408
|
+
:mdcl => ['dmap.dictionary', :list],
|
409
|
+
:meds => ['dmap.editcommandssupported', :integer],
|
410
|
+
:miid => ['dmap.itemid', :integer],
|
411
|
+
:mikd => ['dmap.itemkind', :byte],
|
412
|
+
:mimc => ['dmap.itemcount', :integer],
|
413
|
+
:minm => ['dmap.itemname', :string],
|
414
|
+
:mlcl => ['dmap.listing', :list],
|
415
|
+
:mlid => ['dmap.sessionid', :integer],
|
416
|
+
:mlit => ['dmap.listingitem', :list],
|
417
|
+
:mlog => ['dmap.loginresponse', :list],
|
418
|
+
:mpco => ['dmap.parentcontainerid', :integer],
|
419
|
+
:mper => ['dmap.persistentid', :long],
|
420
|
+
:mpro => ['dmap.protocolversion', :version],
|
421
|
+
:mrco => ['dmap.returnedcount', :integer],
|
422
|
+
:msau => ['dmap.authenticationmethod', :byte],
|
423
|
+
:msal => ['dmap.supportsautologout', :byte],
|
424
|
+
:msas => ['dmap.authenticationschemes', :integer],
|
425
|
+
:msbr => ['dmap.supportsbrowse', :byte],
|
426
|
+
:msdc => ['dmap.databasescount', :integer],
|
427
|
+
:msed => ['unknown_msed', :byte], # TODO: Figure out what these are for
|
428
|
+
:msex => ['dmap.supportsextensions', :byte],
|
429
|
+
:msix => ['dmap.supportsindex', :byte],
|
430
|
+
:mslr => ['dmap.loginrequired', :byte],
|
431
|
+
:msma => ['unknown_msma', :long],
|
432
|
+
:msml => ['unknown_msml', :list],
|
433
|
+
:mspi => ['dmap.supportspersistentids', :byte],
|
434
|
+
:msqy => ['dmap.supportsquery', :byte],
|
435
|
+
:msrs => ['dmap.supportsresolve', :byte],
|
436
|
+
:msrv => ['dmap.serverinforesponse', :list],
|
437
|
+
:mstc => ['dmap.utctime', :time],
|
438
|
+
:mstm => ['dmap.timeoutinterval', :integer],
|
439
|
+
:msto => ['dmap.utcoffset', :signed_integer],
|
440
|
+
:msts => ['dmap.statusstring', :string],
|
441
|
+
:mstt => ['dmap.status', :integer],
|
442
|
+
:msup => ['dmap.supportsupdate', :byte],
|
443
|
+
:mtco => ['dmap.specifiedtotalcount', :integer],
|
444
|
+
:mudl => ['dmap.deletedidlisting', :list],
|
445
|
+
:mupd => ['dmap.updateresponse', :list],
|
446
|
+
:musr => ['dmap.serverrevision', :integer],
|
447
|
+
:muty => ['dmap.updatetype', :byte],
|
448
|
+
}
|
440
449
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JP Hastings-Spital
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-07 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|