dmap 0.1.3 → 0.1.4
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/README.rdoc +4 -3
- data/Rakefile +1 -1
- data/lib/dmap.rb +13 -20
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -24,11 +24,12 @@ We all love examples, so here's an example of how to use this module:
|
|
24
24
|
# => <MSRV: [<MINM: "I'm a string!">]>
|
25
25
|
|
26
26
|
# Or write out what you want in code:
|
27
|
-
|
28
|
-
|
27
|
+
d = DMAP::Element.new("msrv",[DMAP::Element.new('minm',"I'm a string!")])
|
28
|
+
p d
|
29
29
|
# => <MSRV: [<MINM: "I'm a string!">]>
|
30
30
|
|
31
|
-
# All DMAP elements act like their Ruby counterparts
|
31
|
+
# All DMAP elements act like their Ruby counterparts
|
32
|
+
# (I've ballsed this up a little, functions taking blocks are playing up):
|
32
33
|
d.push(DMAP::Element.new('asdm'))
|
33
34
|
|
34
35
|
# They can also be pre-populated with data of an appropriate type
|
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.1.4"
|
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
@@ -9,8 +9,7 @@ module DMAP
|
|
9
9
|
# Represents any DMAP tag and its content.
|
10
10
|
# Will have methods appropriate to the dmap specified
|
11
11
|
class Element
|
12
|
-
attr_reader :
|
13
|
-
attr_reader :name
|
12
|
+
attr_reader :tag
|
14
13
|
attr_reader :real_class
|
15
14
|
|
16
15
|
# Accepts a string or an IO. The first four bytes (in either case) should be the
|
@@ -25,7 +24,6 @@ module DMAP
|
|
25
24
|
# Assume we have an IO object, if this fails then we probably have a string instead
|
26
25
|
begin
|
27
26
|
@tag = tag_or_dmap.read(4).upcase
|
28
|
-
@unparsed_content = true
|
29
27
|
@io = tag_or_dmap if new_content.nil?
|
30
28
|
rescue NoMethodError
|
31
29
|
@tag = tag_or_dmap[0..3].upcase
|
@@ -144,7 +142,7 @@ module DMAP
|
|
144
142
|
original_new
|
145
143
|
begin
|
146
144
|
# Lets assume its an io
|
147
|
-
@dmap_length = array_or_io.read(4).unpack("N")[0]
|
145
|
+
@dmap_length = array_or_io.read(4).unpack("N")[0]
|
148
146
|
@dmap_io = array_or_io
|
149
147
|
@dmap_start = @dmap_io.tell
|
150
148
|
@unparsed_data = true
|
@@ -152,7 +150,11 @@ module DMAP
|
|
152
150
|
rescue NoMethodError
|
153
151
|
begin
|
154
152
|
array_or_io.each do |element|
|
155
|
-
|
153
|
+
if element.is_a? DMAP::Element
|
154
|
+
self.push element
|
155
|
+
else
|
156
|
+
raise "Thisneeds to be a DMAP::Element. #{element.inspect}"
|
157
|
+
end
|
156
158
|
end
|
157
159
|
rescue NoMethodError
|
158
160
|
end
|
@@ -208,6 +210,8 @@ module DMAP
|
|
208
210
|
end
|
209
211
|
|
210
212
|
# Allows people to specify a integer and the size of the binary representation required
|
213
|
+
#
|
214
|
+
# If you create one with a wanted_box_size that's not 1,2,4,8 you'll run into trouble elsewhere (most likely)
|
211
215
|
class MeasuredInteger
|
212
216
|
attr_reader :value
|
213
217
|
attr_accessor :box_size, :binary, :signed
|
@@ -223,22 +227,20 @@ module DMAP
|
|
223
227
|
# current value.
|
224
228
|
def box_size=(wanted_box_size)
|
225
229
|
# Find the smallest number of bytes needed to express this number
|
226
|
-
@box_size = [wanted_box_size || 0,(Math.log(@value) / 2.07944154167984).ceil].max rescue
|
230
|
+
@box_size = [wanted_box_size || 0,(Math.log(@value) / 2.07944154167984).ceil].max rescue 1 # For when value = 0
|
227
231
|
end
|
228
232
|
|
229
233
|
def to_dmap
|
230
234
|
case @box_size
|
231
|
-
when 1,2,4
|
235
|
+
when 1,2,4,8
|
232
236
|
[@box_size,@value].pack("N"<<MeasuredInteger.pack_code(@box_size,@signed))
|
233
|
-
when 8
|
234
|
-
[@box_size,@value / 65536,@value % 65536].pack((@signed) ? "Nll" : "NNN") # FIXME: How do you do signed version :S
|
235
237
|
else
|
236
238
|
raise "I don't know how to unpack an integer #{@box_size} bytes long"
|
237
239
|
end
|
238
240
|
end
|
239
241
|
|
240
242
|
def self.pack_code(length,signed)
|
241
|
-
out = {1=>"C",2=>"S",4=>"N"}[length]
|
243
|
+
out = {1=>"C",2=>"S",4=>"N",8=>"Q"}[length] # FIXME: Lower case N won't work!
|
242
244
|
out.downcase if signed
|
243
245
|
return out
|
244
246
|
end
|
@@ -426,13 +428,4 @@ module DMAP
|
|
426
428
|
CEJS = [:signed, 'com.apple.itunes.jukebox-score']
|
427
429
|
ASDM = [:time, 'daap.songdatemodified']
|
428
430
|
AESF = [:number, 'com.apple.itunes.itms-storefrontid']
|
429
|
-
end
|
430
|
-
|
431
|
-
d = DMAP::Element.new("msrv",[DMAP::Element.new('minm',"I'm a string!")])
|
432
|
-
p d
|
433
|
-
# All DMAP elements act like their Ruby counterparts:
|
434
|
-
d.push(DMAP::Element.new('asdm'))
|
435
|
-
# They can also be pre-populated with data of an appropriate type
|
436
|
-
d.push(DMAP::Element.new('astm',123))
|
437
|
-
p d
|
438
|
-
# => <MSRV: [<MINM: "I'm a string!">, <ASDM: Fri Nov 06 11:18:29 +0000 2009>, <ASTM: 123>]>
|
431
|
+
end
|