dmap 0.1.6 → 0.2.1

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.
Files changed (3) hide show
  1. data/Rakefile +1 -1
  2. data/lib/dmap.rb +214 -205
  3. 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.6"
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"
@@ -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).upcase
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].upcase
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,@name = DMAP.const_get(@tag)
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
- "#{@tag.downcase}#{@real_class.to_dmap}"
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 parse_number(content,signed = false)
87
+ def parse_byte(content)
83
88
  begin
84
- if not content.nil? and content.is_a? Numeric
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,0,signed)
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("nn").join("."))
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,wanted_box_size = nil,signed = false)
224
- @value = value
225
- @binary = (box_size == 1)
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
- # Will set the box size to the largest value of the one you specify and the maximum needed for the
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"<<MeasuredInteger.pack_code(@box_size,@signed))
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 self.pack_code(length,signed)
247
- out = {1=>"C",-1=>"c",2=>"n",4=>"N",8=>"Q",-8=>"q"}[length * (signed ? -1 : 1)] # FIXME: pack codes for all signed cases
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
- def initialize(version = "1.0")
261
- @major,@minor = (version.to_s<<".0").split(".").collect{|n| n.to_i }
262
- if @major > 63 or @minor > 63
263
- raise RangeError "Neither major nor minor version numbers can be above 63. Surely that's enough?"
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("nn")
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
- #F�CH = [:number, 'dmap.haschildcontainers']
291
- ABAL = [:list, 'daap.browsealbumlisting']
292
- ABAR = [:list, 'daap.browseartistlisting']
293
- ABCP = [:list, 'daap.browsecomposerlisting']
294
- ABGN = [:list, 'daap.browsegenrelisting']
295
- ABPL = [:number, 'daap.baseplaylist']
296
- ABRO = [:list, 'daap.databasebrowse']
297
- ADBS = [:list, 'daap.databasesongs']
298
- AEAI = [:number, 'com.apple.itunes.itms-artistid']
299
- AECI = [:number, 'com.apple.itunes.itms-composerid']
300
- AECR = [:string, 'com.apple.itunes.content-rating']
301
- AEEN = [:string, 'com.apple.itunes.episode-num-str']
302
- AEES = [:number, 'com.apple.itunes.episode-sort']
303
- AEFP = [:number, 'com.apple.itunes.req-fplay']
304
- AEGD = [:number, 'com.apple.itunes.gapless-enc-dr']
305
- AEGE = [:number, 'com.apple.itunes.gapless-enc-del']
306
- AEGH = [:number, 'com.apple.itunes.gapless-heur']
307
- AEGI = [:number, 'com.apple.itunes.itms-genreid']
308
- AEGR = [:number, 'com.apple.itunes.gapless-resy']
309
- AEGU = [:number, 'com.apple.itunes.gapless-dur']
310
- AEHD = [:number, 'com.apple.itunes.is-hd-video']
311
- AEHV = [:number, 'com.apple.itunes.has-video']
312
- AEMK = [:number, 'com.apple.itunes.mediakind']
313
- AENN = [:string, 'com.apple.itunes.network-name']
314
- AENV = [:number, 'com.apple.itunes.norm-volume']
315
- AEPC = [:number, 'com.apple.itunes.is-podcast']
316
- AEPI = [:number, 'com.apple.itunes.itms-playlistid']
317
- AEPP = [:number, 'com.apple.itunes.is-podcast-playlist']
318
- AEPS = [:number, 'com.apple.itunes.special-playlist']
319
- AESF = [:number, 'com.apple.itunes.itms-storefrontid']
320
- AESG = [:number, 'com.apple.itunes.saved-genius']
321
- AESI = [:number, 'com.apple.itunes.itms-songid']
322
- AESN = [:string, 'com.apple.itunes.series-name']
323
- AESP = [:number, 'com.apple.itunes.smart-playlist']
324
- AESU = [:number, 'com.apple.itunes.season-num']
325
- AESV = [:number, 'com.apple.itunes.music-sharing-version']
326
- AGRP = [:string, 'daap.songgrouping']
327
- APLY = [:list, 'daap.databaseplaylists']
328
- APRM = [:number, 'daap.playlistrepeatmode']
329
- APRO = [:version,'daap.protocolversion']
330
- APSM = [:number, 'daap.playlistshufflemode']
331
- APSO = [:list, 'daap.playlistsongs']
332
- ARIF = [:list, 'daap.resolveinfo']
333
- ARSV = [:list, 'daap.resolve']
334
- ASAA = [:string, 'daap.songalbumartist']
335
- ASAI = [:number, 'daap.songalbumid']
336
- ASAL = [:string, 'daap.songalbum']
337
- ASAR = [:string, 'daap.songartist']
338
- ASBK = [:number, 'daap.bookmarkable']
339
- ASBO = [:number, 'daap.songbookmark']
340
- ASBR = [:number, 'daap.songbitrate']
341
- ASBT = [:number, 'daap.songbeatsperminute']
342
- ASCD = [:number, 'daap.songcodectype']
343
- ASCM = [:string, 'daap.songcomment']
344
- ASCN = [:string, 'daap.songcontentdescription']
345
- ASCO = [:number, 'daap.songcompilation']
346
- ASCP = [:string, 'daap.songcomposer']
347
- ASCR = [:number, 'daap.songcontentrating']
348
- ASCS = [:number, 'daap.songcodecsubtype']
349
- ASCT = [:string, 'daap.songcategory']
350
- ASDA = [:time, 'daap.songdateadded']
351
- ASDB = [:number, 'daap.songdisabled']
352
- ASDC = [:number, 'daap.songdisccount']
353
- ASDK = [:number, 'daap.songdatakind']
354
- ASDM = [:time, 'daap.songdatemodified']
355
- ASDN = [:number, 'daap.songdiscnumber']
356
- ASDP = [:time, 'daap.songdatepurchased']
357
- ASDR = [:time, 'daap.songdatereleased']
358
- ASDT = [:string, 'daap.songdescription']
359
- ASED = [:number, 'daap.songextradata']
360
- ASEQ = [:string, 'daap.songeqpreset']
361
- ASFM = [:string, 'daap.songformat']
362
- ASGN = [:string, 'daap.songgenre']
363
- ASGP = [:number, 'daap.songgapless']
364
- ASHP = [:number, 'daap.songhasbeenplayed']
365
- ASKY = [:string, 'daap.songkeywords']
366
- ASLC = [:string, 'daap.songlongcontentdescription']
367
- ASLS = [:number, 'daap.songlongsize']
368
- ASPU = [:string, 'daap.songpodcasturl']
369
- ASRV = [:signed, 'daap.songrelativevolume']
370
- ASSA = [:string, 'daap.sortartist']
371
- ASSC = [:string, 'daap.sortcomposer']
372
- ASSL = [:string, 'daap.sortalbumartist']
373
- ASSN = [:string, 'daap.sortname']
374
- ASSP = [:number, 'daap.songstoptime']
375
- ASSR = [:number, 'daap.songsamplerate']
376
- ASSS = [:string, 'daap.sortseriesname']
377
- ASST = [:number, 'daap.songstarttime']
378
- ASSU = [:string, 'daap.sortalbum']
379
- ASSZ = [:number, 'daap.songsize']
380
- ASTC = [:number, 'daap.songtrackcount']
381
- ASTM = [:number, 'daap.songtime']
382
- ASTN = [:number, 'daap.songtracknumber']
383
- ASUL = [:string, 'daap.songdataurl']
384
- ASUR = [:number, 'daap.songuserrating']
385
- ASYR = [:number, 'daap.songyear']
386
- ATED = [:number, 'daap.supportsextradata']
387
- AVDB = [:list, 'daap.serverdatabases']
388
- CEJC = [:signed, 'com.apple.itunes.jukebox-client-vote']
389
- CEJI = [:number, 'com.apple.itunes.jukebox-current']
390
- CEJS = [:signed, 'com.apple.itunes.jukebox-score']
391
- CEJV = [:number, 'com.apple.itunes.jukebox-vote']
392
- MBCL = [:list, 'dmap.bag']
393
- MCCR = [:list, 'dmap.contentcodesresponse']
394
- MCNA = [:string, 'dmap.contentcodesname']
395
- MCNM = [:number, 'dmap.contentcodesnumber']
396
- MCON = [:list, 'dmap.container']
397
- MCTC = [:number, 'dmap.containercount']
398
- MCTI = [:number, 'dmap.containeritemid']
399
- MCTY = [:number, 'dmap.contentcodestype']
400
- MDCL = [:list, 'dmap.dictionary']
401
- MEDS = [:number, 'dmap.editcommandssupported']
402
- MIID = [:number, 'dmap.itemid']
403
- MIKD = [:number, 'dmap.itemkind']
404
- MIMC = [:number, 'dmap.itemcount']
405
- MINM = [:string, 'dmap.itemname']
406
- MLCL = [:list, 'dmap.listing']
407
- MLID = [:number, 'dmap.sessionid']
408
- MLOG = [:list, 'dmap.loginresponse']
409
- MPCO = [:number, 'dmap.parentcontainerid']
410
- MPER = [:number, 'dmap.persistentid']
411
- MPRO = [:version,'dmap.protocolversion']
412
- MRCO = [:number, 'dmap.returnedcount']
413
- MSAL = [:number, 'dmap.supportsautologout']
414
- MSAS = [:number, 'dmap.authenticationschemes']
415
- MSAU = [:number, 'dmap.authenticationmethod']
416
- MSBR = [:number, 'dmap.supportsbrowse']
417
- MSDC = [:number, 'dmap.databasescount']
418
- MSED = [:number, 'unknown_msed']
419
- MSEX = [:number, 'dmap.supportsextensions']
420
- MSIX = [:number, 'dmap.supportsindex']
421
- MSLR = [:number, 'dmap.loginrequired']
422
- MSMA = [:number, 'unknown_msma']
423
- MSML = [:list, 'unknown_msml']
424
- MSPI = [:number, 'dmap.supportspersistentids']
425
- MSQY = [:number, 'dmap.supportsquery']
426
- MSRS = [:number, 'dmap.supportsresolve']
427
- MSRV = [:list, 'dmap.serverinforesponse']
428
- MSTC = [:time, 'dmap.utctime']
429
- MSTM = [:number, 'dmap.timeoutinterval']
430
- MSTO = [:signed, 'dmap.utcoffset']
431
- MSTS = [:string, 'dmap.statusstring']
432
- MSTT = [:number, 'dmap.status']
433
- MSUP = [:number, 'dmap.supportsupdate']
434
- MTCO = [:number, 'dmap.specifiedtotalcount']
435
- MUDL = [:list, 'dmap.deletedidlisting']
436
- MUPD = [:list, 'dmap.updateresponse']
437
- MUSR = [:number, 'dmap.serverrevision']
438
- MUTY = [:number, 'dmap.updatetype']
439
- MLIT = [:list, 'dmap.listingitem']
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.6
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-06 00:00:00 +00:00
12
+ date: 2009-11-07 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency