ipa_reader 0.6.1 → 0.7.0

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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ pkg
@@ -1,18 +1,16 @@
1
- ipa_reader
2
- by Nicholas Schlueter
3
- http://twitter.com/schlu
1
+ # ipa_reader
4
2
 
5
- == DESCRIPTION:
3
+ by [Nicholas Schlueter](http://twitter.com/schlu)
6
4
 
7
- Reads metadata form iPhone Package Archive Files (ipa).
5
+ ## DESCRIPTION
8
6
 
9
- == FEATURES/PROBLEMS:
7
+ Reads metadata form iPhone Package Archive Files (ipa).
10
8
 
11
9
  I am using this gem to get version to build the over the air iPhone Ad Hoc distribution plist file.
12
10
 
13
- == USAGE:
11
+ ## USAGE
14
12
 
15
- irb > require 'rubygems'
13
+ `irb > require 'rubygems'
16
14
  => true
17
15
  irb > require 'ipa_reader'
18
16
  => true
@@ -31,13 +29,13 @@ irb > ipa_file.url_schemes
31
29
  irb > ipa_file.bundle_identifier
32
30
  => "com.dcrails.multig"
33
31
  irb > ipa_file.icon_prerendered
34
- => false
32
+ => false`
35
33
 
36
- == INSTALL:
34
+ ## INSTALL
37
35
 
38
- gem install ipa_reader
36
+ `gem install ipa_reader`
39
37
 
40
- == LICENSE:
38
+ ## LICENSE
41
39
 
42
40
  (The MIT License)
43
41
 
data/Rakefile CHANGED
@@ -11,8 +11,11 @@ task 'gem:release' => 'test:run'
11
11
  Bones {
12
12
  name 'ipa_reader'
13
13
  authors 'Nicholas Schlueter'
14
+ summary 'Reads metadata form iPhone Package Archive Files (ipa).'
15
+ description 'I am using this gem to get version to build the over the air iPhone Ad Hoc distribution plist file.'
14
16
  email 'schlueter@gmail.com'
15
- url 'http://github.com/schlueter/Ipa-Reader'
17
+ url 'http://github.com/schlu/Ipa-Reader'
16
18
  depend_on "zip", "2.0.2"
19
+ depend_on "CFPropertyList", "2.1.1"
17
20
  }
18
21
 
@@ -4,6 +4,7 @@ rescue LoadError
4
4
  require 'rubygems'
5
5
  require 'zip'
6
6
  end
7
+
7
8
  module IpaReader
8
9
  class IpaFile
9
10
  attr_accessor :plist, :file_path
@@ -11,7 +12,8 @@ module IpaReader
11
12
  self.file_path = file_path
12
13
  info_plist_file = nil
13
14
  Zip::ZipFile.foreach(file_path) { |f| info_plist_file = f if f.name.match(/\/Info.plist/) }
14
- self.plist = Plist::Binary.decode_binary_plist(self.read_file(/\/Info.plist/))
15
+ cf_plist = CFPropertyList::List.new(:data => self.read_file(/\/Info.plist/), :format => CFPropertyList::List::FORMAT_BINARY)
16
+ self.plist = cf_plist.value.to_rb
15
17
  end
16
18
 
17
19
  def version
@@ -56,6 +58,7 @@ module IpaReader
56
58
  end
57
59
 
58
60
  def bundle_identifier
61
+ puts plist["CFBundleIdentifier"].class
59
62
  plist["CFBundleIdentifier"]
60
63
  end
61
64
 
@@ -1,490 +1,33 @@
1
- require "date"
2
- require "nkf"
3
- require "set"
4
- require "stringio"
1
+ begin
2
+ require 'cfpropertylist'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'cfpropertylist'
6
+ end
5
7
 
6
- module IpaReader
7
- module Plist
8
- module Binary
9
- # Encodes +obj+ as a binary property list. If +obj+ is an Array, Hash, or
10
- # Set, the property list includes its contents.
11
- def self.binary_plist(obj)
12
- encoded_objs = flatten_collection(obj)
13
- ref_byte_size = min_byte_size(encoded_objs.length - 1)
14
- encoded_objs.collect! {|o| binary_plist_obj(o, ref_byte_size)}
15
- # Write header and encoded objects.
16
- plist = "bplist00" + encoded_objs.join
17
- # Write offset table.
18
- offset_table_addr = plist.length
19
- offset = 8
20
- offset_table = []
21
- encoded_objs.each do |o|
22
- offset_table << offset
23
- offset += o.length
24
- end
25
- offset_byte_size = min_byte_size(offset)
26
- offset_table.each do |offset|
27
- plist += pack_int(offset, offset_byte_size)
28
- end
29
- # Write trailer.
30
- plist += "\0\0\0\0\0\0" # Six unused bytes
31
- plist += [
32
- offset_byte_size,
33
- ref_byte_size,
34
- encoded_objs.length >> 32, encoded_objs.length & 0xffffffff,
35
- 0, 0, # Index of root object
36
- offset_table_addr >> 32, offset_table_addr & 0xffffffff
37
- ].pack("CCNNNNNN")
38
- plist
39
- end
40
-
41
- def self.decode_binary_plist(plist)
42
- # Check header.
43
- unless plist[0, 6] == "bplist"
44
- raise ArgumentError, "argument is not a binary property list"
45
- end
46
- version = plist[6, 2]
47
- unless version == "00"
48
- raise ArgumentError,
49
- "don't know how to decode format version #{version}"
50
- end
51
- # Read trailer.
52
- trailer = plist[-26, 26].unpack("CCNNNNNN")
53
- offset_byte_size = trailer[0]
54
- ref_byte_size = trailer[1]
55
- encoded_objs_length = combine_ints(32, trailer[2], trailer[3])
56
- root_index = combine_ints(32, trailer[4], trailer[5])
57
- offset_table_addr = combine_ints(32, trailer[6], trailer[7])
58
- # Decode objects.
59
- root_offset = offset_for_index(plist, offset_table_addr,
60
- offset_byte_size, root_index)
61
- root_obj = decode_binary_plist_obj(plist, root_offset, ref_byte_size)
62
- unflatten_collection(root_obj, [root_obj], plist, offset_table_addr,
63
- offset_byte_size, ref_byte_size)
64
- end
65
-
66
- private
67
-
68
- # These marker bytes are prefixed to objects in a binary property list to
69
- # indicate the type of the object.
70
- CFBinaryPlistMarkerNull = 0x00 # :nodoc:
71
- CFBinaryPlistMarkerFalse = 0x08 # :nodoc:
72
- CFBinaryPlistMarkerTrue = 0x09 # :nodoc:
73
- CFBinaryPlistMarkerFill = 0x0F # :nodoc:
74
- CFBinaryPlistMarkerInt = 0x10 # :nodoc:
75
- CFBinaryPlistMarkerReal = 0x20 # :nodoc:
76
- CFBinaryPlistMarkerDate = 0x33 # :nodoc:
77
- CFBinaryPlistMarkerData = 0x40 # :nodoc:
78
- CFBinaryPlistMarkerASCIIString = 0x50 # :nodoc:
79
- CFBinaryPlistMarkerUnicode16String = 0x60 # :nodoc:
80
- CFBinaryPlistMarkerUID = 0x80 # :nodoc:
81
- CFBinaryPlistMarkerArray = 0xA0 # :nodoc:
82
- CFBinaryPlistMarkerSet = 0xC0 # :nodoc:
83
- CFBinaryPlistMarkerDict = 0xD0 # :nodoc:
84
-
85
- # POSIX uses a reference time of 1970-01-01T00:00:00Z; Cocoa's reference
86
- # time is in 2001. This interval is for converting between the two.
87
- NSTimeIntervalSince1970 = 978307200.0 # :nodoc:
88
-
89
- # Takes an object (nominally a collection, like an Array, Set, or Hash, but
90
- # any object is acceptable) and flattens it into a one-dimensional array.
91
- # Non-collection objects appear in the array as-is, but the contents of
92
- # Arrays, Sets, and Hashes are modified like so: (1) The contents of the
93
- # collection are added, one-by-one, to the one-dimensional array. (2) The
94
- # collection itself is modified so that it contains indexes pointing to the
95
- # objects in the one-dimensional array. Here's an example with an Array:
96
- #
97
- # ary = [:a, :b, :c]
98
- # flatten_collection(ary) # => [[1, 2, 3], :a, :b, :c]
99
- #
100
- # In the case of a Hash, keys and values are both appended to the one-
101
- # dimensional array and then replaced with indexes.
102
- #
103
- # hsh = {:a => "blue", :b => "purple", :c => "green"}
104
- # flatten_collection(hsh)
105
- # # => [{1 => 2, 3 => 4, 5 => 6}, :a, "blue", :b, "purple", :c, "green"]
106
- #
107
- # An object will never be added to the one-dimensional array twice. If a
108
- # collection refers to an object more than once, the object will be added
109
- # to the one-dimensional array only once.
110
- #
111
- # ary = [:a, :a, :a]
112
- # flatten_collection(ary) # => [[1, 1, 1], :a]
113
- #
114
- # The +obj_list+ and +id_refs+ parameters are private; they're used for
115
- # descending into sub-collections recursively.
116
- def self.flatten_collection(collection, obj_list = [], id_refs = {})
117
- case collection
118
- when Array, Set
119
- if id_refs[collection.object_id]
120
- return obj_list[id_refs[collection.object_id]]
121
- end
122
- obj_refs = collection.class.new
123
- id_refs[collection.object_id] = obj_list.length
124
- obj_list << obj_refs
125
- collection.each do |obj|
126
- flatten_collection(obj, obj_list, id_refs)
127
- obj_refs << id_refs[obj.object_id]
128
- end
129
- return obj_list
130
- when Hash
131
- if id_refs[collection.object_id]
132
- return obj_list[id_refs[collection.object_id]]
133
- end
134
- obj_refs = {}
135
- id_refs[collection.object_id] = obj_list.length
136
- obj_list << obj_refs
137
- collection.each do |key, value|
138
- key = key.to_s if key.is_a?(Symbol)
139
- flatten_collection(key, obj_list, id_refs)
140
- flatten_collection(value, obj_list, id_refs)
141
- obj_refs[id_refs[key.object_id]] = id_refs[value.object_id]
142
- end
143
- return obj_list
144
- else
145
- unless id_refs[collection.object_id]
146
- id_refs[collection.object_id] = obj_list.length
147
- obj_list << collection
148
- end
149
- return obj_list
150
- end
151
- end
152
-
153
- def self.unflatten_collection(collection, obj_list, plist,
154
- offset_table_addr, offset_byte_size, ref_byte_size)
155
- case collection
156
- when Array, Set
157
- collection.collect! do |index|
158
- if obj = obj_list[index]
159
- obj
160
- else
161
- offset = offset_for_index(plist, offset_table_addr, offset_byte_size,
162
- index)
163
- obj = decode_binary_plist_obj(plist, offset, ref_byte_size)
164
- obj_list[index] = obj
165
- unflatten_collection(obj, obj_list, plist, offset_table_addr,
166
- offset_byte_size, ref_byte_size)
167
- end
168
- end
169
- when Hash
170
- hsh = {}
171
- collection.each do |key, value|
172
- unless key_obj = obj_list[key]
173
- offset = offset_for_index(plist, offset_table_addr, offset_byte_size,
174
- key)
175
- key_obj = decode_binary_plist_obj(plist, offset, ref_byte_size)
176
- obj_list[key] = key_obj
177
- key_obj = unflatten_collection(key_obj, obj_list, plist,
178
- offset_table_addr, offset_byte_size, ref_byte_size)
179
- end
180
- unless value_obj = obj_list[value]
181
- offset = offset_for_index(plist, offset_table_addr, offset_byte_size,
182
- value)
183
- value_obj = decode_binary_plist_obj(plist, offset, ref_byte_size)
184
- obj_list[value] = value_obj
185
- value_obj = unflatten_collection(value_obj, obj_list, plist,
186
- offset_table_addr, offset_byte_size, ref_byte_size)
187
- end
188
- hsh[key_obj] = value_obj
189
- end
190
- collection.replace(hsh)
191
- end
192
- return collection
193
- end
194
-
195
- # Returns a binary property list fragment that represents +obj+. The
196
- # returned string is not a complete property list, just a fragment that
197
- # describes +obj+, and is not useful without a header, offset table, and
198
- # trailer.
199
- #
200
- # The following classes are recognized: String, Float, Integer, the Boolean
201
- # classes, Time, IO, StringIO, Array, Set, and Hash. IO and StringIO
202
- # objects are rewound, read, and the contents stored as data (i.e., Cocoa
203
- # applications will decode them as NSData). All other classes are dumped
204
- # with Marshal and stored as data.
205
- #
206
- # Note that subclasses of the supported classes will be encoded as though
207
- # they were the supported superclass. Thus, a subclass of (for example)
208
- # String will be encoded and decoded as a String, not as the subclass:
209
- #
210
- # class ExampleString < String
211
- # ...
212
- # end
213
- #
214
- # s = ExampleString.new("disquieting plantlike mystery")
215
- # encoded_s = binary_plist_obj(s)
216
- # decoded_s = decode_binary_plist_obj(encoded_s)
217
- # puts decoded_s.class # => String
218
- #
219
- # +ref_byte_size+ is the number of bytes to use for storing references to
220
- # other objects.
221
- def self.binary_plist_obj(obj, ref_byte_size = 4)
222
- case obj
223
- when String
224
- obj = obj.to_s if obj.is_a?(Symbol)
225
- # This doesn't really work. NKF's guess method is really, really bad
226
- # at discovering UTF8 when only a handful of characters are multi-byte.
227
- encoding = NKF.guess2(obj)
228
- if encoding == NKF::ASCII && obj =~ /[\x80-\xff]/
229
- encoding = NKF::UTF8
230
- end
231
- if [NKF::ASCII, NKF::BINARY, NKF::UNKNOWN].include?(encoding)
232
- result = (CFBinaryPlistMarkerASCIIString |
233
- (obj.length < 15 ? obj.length : 0xf)).chr
234
- result += binary_plist_obj(obj.length) if obj.length >= 15
235
- result += obj
236
- return result
237
- else
238
- # Convert to UTF8.
239
- if encoding == NKF::UTF8
240
- utf8 = obj
241
- else
242
- utf8 = NKF.nkf("-m0 -w", obj)
243
- end
244
- # Decode each character's UCS codepoint.
245
- codepoints = []
246
- i = 0
247
- while i < utf8.length
248
- byte = utf8[i]
249
- if byte & 0xe0 == 0xc0
250
- codepoints << ((byte & 0x1f) << 6) + (utf8[i+1] & 0x3f)
251
- i += 1
252
- elsif byte & 0xf0 == 0xe0
253
- codepoints << ((byte & 0xf) << 12) + ((utf8[i+1] & 0x3f) << 6) +
254
- (utf8[i+2] & 0x3f)
255
- i += 2
256
- elsif byte & 0xf8 == 0xf0
257
- codepoints << ((byte & 0xe) << 18) + ((utf8[i+1] & 0x3f) << 12) +
258
- ((utf8[i+2] & 0x3f) << 6) + (utf8[i+3] & 0x3f)
259
- i += 3
260
- else
261
- codepoints << byte
262
- end
263
- if codepoints.last > 0xffff
264
- raise(ArgumentError, "codepoint too high - only the Basic Multilingual Plane can be encoded")
265
- end
266
- i += 1
267
- end
268
- # Return string of 16-bit codepoints.
269
- data = codepoints.pack("n*")
270
- result = (CFBinaryPlistMarkerUnicode16String |
271
- (codepoints.length < 15 ? codepoints.length : 0xf)).chr
272
- result += binary_plist_obj(codepoints.length) if codepoints.length >= 15
273
- result += data
274
- return result
275
- end
276
- when Float
277
- return (CFBinaryPlistMarkerReal | 3).chr + [obj].pack("G")
278
- when Integer
279
- nbytes = min_byte_size(obj)
280
- size_bits = { 1 => 0, 2 => 1, 4 => 2, 8 => 3, 16 => 4 }[nbytes]
281
- return (CFBinaryPlistMarkerInt | size_bits).chr + pack_int(obj, nbytes)
282
- when TrueClass
283
- return CFBinaryPlistMarkerTrue.chr
284
- when FalseClass
285
- return CFBinaryPlistMarkerFalse.chr
286
- when Time
287
- return CFBinaryPlistMarkerDate.chr +
288
- [obj.to_f - NSTimeIntervalSince1970].pack("G")
289
- when IO, StringIO
290
- obj.rewind
291
- return binary_plist_data(obj.read)
292
- when Array
293
- # Must be an array of object references as returned by flatten_collection.
294
- result = (CFBinaryPlistMarkerArray | (obj.length < 15 ? obj.length : 0xf)).chr
295
- result += binary_plist_obj(obj.length) if obj.length >= 15
296
- result += obj.collect! { |i| pack_int(i, ref_byte_size) }.join
297
- when Set
298
- # Must be a set of object references as returned by flatten_collection.
299
- result = (CFBinaryPlistMarkerSet | (obj.length < 15 ? obj.length : 0xf)).chr
300
- result += binary_plist_obj(obj.length) if obj.length >= 15
301
- result += obj.to_a.collect! { |i| pack_int(i, ref_byte_size) }.join
302
- when Hash
303
- # Must be a table of object references as returned by flatten_collection.
304
- result = (CFBinaryPlistMarkerDict | (obj.length < 15 ? obj.length : 0xf)).chr
305
- result += binary_plist_obj(obj.length) if obj.length >= 15
306
- result += obj.keys.collect! { |i| pack_int(i, ref_byte_size) }.join
307
- result += obj.values.collect! { |i| pack_int(i, ref_byte_size) }.join
308
- else
309
- return binary_plist_data(Marshal.dump(obj))
310
- end
311
- end
312
-
313
- def self.decode_binary_plist_obj(plist, offset, ref_byte_size)
314
- case plist[offset]
315
- when CFBinaryPlistMarkerASCIIString..(CFBinaryPlistMarkerASCIIString | 0xf)
316
- length, offset = decode_length(plist, offset)
317
- return plist[offset, length]
318
- when CFBinaryPlistMarkerUnicode16String..(CFBinaryPlistMarkerUnicode16String | 0xf)
319
- length, offset = decode_length(plist, offset)
320
- codepoints = plist[offset, length * 2].unpack("n*")
321
- str = ""
322
- codepoints.each do |codepoint|
323
- if codepoint <= 0x7f
324
- ch = ' '
325
- ch[0] = to_i
326
- elsif codepoint <= 0x7ff
327
- ch = ' '
328
- ch[0] = ((codepoint & 0x7c0) >> 6) | 0xc0
329
- ch[1] = codepoint & 0x3f | 0x80
330
- else
331
- ch = ' '
332
- ch[0] = ((codepoint & 0xf000) >> 12) | 0xe0
333
- ch[1] = ((codepoint & 0xfc0) >> 6) | 0x80
334
- ch[2] = codepoint & 0x3f | 0x80
335
- end
336
- str << ch
337
- end
338
- return str
339
- when CFBinaryPlistMarkerReal | 3
340
- return plist[offset+1, 8].unpack("G").first
341
- when CFBinaryPlistMarkerInt..(CFBinaryPlistMarkerInt | 0xf)
342
- num_bytes = 2 ** (plist[offset] & 0xf)
343
- return unpack_int(plist[offset+1, num_bytes])
344
- when CFBinaryPlistMarkerTrue
345
- return true
346
- when CFBinaryPlistMarkerFalse
347
- return false
348
- when CFBinaryPlistMarkerDate
349
- secs = plist[offset+1, 8].unpack("G").first + NSTimeIntervalSince1970
350
- return Time.at(secs)
351
- when CFBinaryPlistMarkerData..(CFBinaryPlistMarkerData | 0xf)
352
- length, offset = decode_length(plist, offset)
353
- return StringIO.new(plist[offset, length])
354
- when CFBinaryPlistMarkerArray..(CFBinaryPlistMarkerArray | 0xf)
355
- ary = []
356
- length, offset = decode_length(plist, offset)
357
- length.times do
358
- ary << unpack_int(plist[offset, ref_byte_size])
359
- offset += ref_byte_size
360
- end
361
- return ary
362
- when CFBinaryPlistMarkerDict..(CFBinaryPlistMarkerDict | 0xf)
363
- hsh = {}
364
- keys = []
365
- length, offset = decode_length(plist, offset)
366
- length.times do
367
- keys << unpack_int(plist[offset, ref_byte_size])
368
- offset += ref_byte_size
369
- end
370
- length.times do |i|
371
- hsh[keys[i]] = unpack_int(plist[offset, ref_byte_size])
372
- offset += ref_byte_size
373
- end
374
- return hsh
375
- end
376
- end
377
-
378
- # Returns a binary property list fragment that represents a data object
379
- # with the contents of the string +data+. A Cocoa application would decode
380
- # this fragment as NSData. Like binary_plist_obj, the value returned by
381
- # this method is not usable by itself; it is only useful as part of a
382
- # complete binary property list with a header, offset table, and trailer.
383
- def self.binary_plist_data(data)
384
- result = (CFBinaryPlistMarkerData |
385
- (data.length < 15 ? data.length : 0xf)).chr
386
- result += binary_plist_obj(data.length) if data.length > 15
387
- result += data
388
- return result
389
- end
390
-
391
- # Determines the minimum number of bytes that is a power of two and can
392
- # represent the integer +i+. Raises a RangeError if the number of bytes
393
- # exceeds 16. Note that the property list format considers integers of 1,
394
- # 2, and 4 bytes to be unsigned, while 8- and 16-byte integers are signed;
395
- # thus negative integers will always require at least 8 bytes of storage.
396
- def self.min_byte_size(i)
397
- if i < 0
398
- i = i.abs - 1
399
- else
400
- if i <= 0xff
401
- return 1
402
- elsif i <= 0xffff
403
- return 2
404
- elsif i <= 0xffffffff
405
- return 4
406
- end
407
- end
408
- if i <= 0x7fffffffffffffff
409
- return 8
410
- elsif i <= 0x7fffffffffffffffffffffffffffffff
411
- return 16
412
- end
413
- raise(RangeError, "integer too big - exceeds 128 bits")
414
- end
415
-
416
- # Packs an integer +i+ into its binary representation in the specified
417
- # number of bytes. Byte order is big-endian. Negative integers cannot be
418
- # stored in 1, 2, or 4 bytes.
419
- def self.pack_int(i, num_bytes)
420
- if i < 0 && num_bytes < 8
421
- raise(ArgumentError, "negative integers require 8 or 16 bytes of storage")
422
- end
423
- case num_bytes
424
- when 1
425
- [i].pack("c")
426
- when 2
427
- [i].pack("n")
428
- when 4
429
- [i].pack("N")
430
- when 8
431
- [(i >> 32) & 0xffffffff, i & 0xffffffff].pack("NN")
432
- when 16
433
- [i >> 96, (i >> 64) & 0xffffffff, (i >> 32) & 0xffffffff,
434
- i & 0xffffffff].pack("NNNN")
435
- else
436
- raise(ArgumentError, "num_bytes must be 1, 2, 4, 8, or 16")
437
- end
438
- end
439
-
440
- def self.combine_ints(num_bits, *ints)
441
- i = ints.pop
442
- shift_bits = num_bits
443
- ints.reverse.each do |i_part|
444
- i += i_part << shift_bits
445
- shift_bits += num_bits
446
- end
447
- return i
448
- end
449
-
450
- def self.offset_for_index(plist, table_addr, offset_byte_size, index)
451
- offset = plist[table_addr + index * offset_byte_size, offset_byte_size]
452
- unpack_int(offset)
453
- end
454
-
455
- def self.unpack_int(s)
456
- case s.length
457
- when 1
458
- s.unpack("C").first
459
- when 2
460
- s.unpack("n").first
461
- when 4
462
- s.unpack("N").first
463
- when 8
464
- i = combine_ints(32, *(s.unpack("NN")))
465
- (i & 0x80000000_00000000 == 0) ?
466
- i :
467
- -(i ^ 0xffffffff_ffffffff) - 1
468
- when 16
469
- i = combine_ints(32, *(s.unpack("NNNN")))
470
- (i & 0x80000000_00000000_00000000_00000000 == 0) ?
471
- i :
472
- -(i ^ 0xffffffff_ffffffff_ffffffff_ffffffff) - 1
473
- else
474
- raise(ArgumentError, "length must be 1, 2, 4, 8, or 16 bytes")
475
- end
476
- end
477
-
478
- def self.decode_length(plist, offset)
479
- if plist[offset] & 0xf == 0xf
480
- offset += 1
481
- length = decode_binary_plist_obj(plist, offset, 0)
482
- offset += min_byte_size(length) + 1
483
- return length, offset
484
- else
485
- return (plist[offset] & 0xf), (offset + 1)
486
- end
8
+ # Adds to_rb functionality to return native ruby types rather than CFTypes
9
+ module CFPropertyList
10
+ class CFDictionary
11
+ def to_rb
12
+ hash_data = {}
13
+ value.keys.each do |key|
14
+ hash_data[key] = value[key].to_hash
15
+ end
16
+ hash_data
17
+ end
18
+ end
19
+ class CFType
20
+ def to_hash
21
+ self.value
22
+ end
23
+ end
24
+ class CFArray
25
+ def to_hash
26
+ hash_data = []
27
+ value.each do |obj|
28
+ hash_data << obj.to_hash
487
29
  end
30
+ hash_data
488
31
  end
489
32
  end
490
33
  end
@@ -75,7 +75,7 @@ module IpaReader
75
75
  end
76
76
 
77
77
  # Stopping the PNG file parsing
78
- if chunkType == "IEND":
78
+ if chunkType == "IEND"
79
79
  break
80
80
  end
81
81
  end
data/version.txt CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 0.7.0
metadata CHANGED
@@ -1,70 +1,77 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ipa_reader
3
- version: !ruby/object:Gem::Version
4
- hash: 5
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 6
9
- - 1
10
- version: 0.6.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Nicholas Schlueter
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-01-25 00:00:00 -05:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2012-09-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: zip
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.0.2
22
+ type: :runtime
23
23
  prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 11
30
- segments:
31
- - 2
32
- - 0
33
- - 2
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
34
29
  version: 2.0.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: CFPropertyList
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '='
36
+ - !ruby/object:Gem::Version
37
+ version: 2.1.1
35
38
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: bones
39
39
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- hash: 25
46
- segments:
47
- - 3
48
- - 4
49
- - 7
50
- version: 3.4.7
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.1.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: bones
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 3.8.0
51
54
  type: :development
52
- version_requirements: *id002
53
- description: Reads metadata form iPhone Package Archive Files (ipa).
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 3.8.0
62
+ description: I am using this gem to get version to build the over the air iPhone Ad
63
+ Hoc distribution plist file.
54
64
  email: schlueter@gmail.com
55
- executables:
65
+ executables:
56
66
  - ipa_reader
57
67
  extensions: []
58
-
59
- extra_rdoc_files:
68
+ extra_rdoc_files:
60
69
  - History.txt
61
- - README.txt
62
70
  - bin/ipa_reader
63
- - version.txt
64
- files:
65
- - .rvmrc
71
+ files:
72
+ - .gitignore
66
73
  - History.txt
67
- - README.txt
74
+ - README.md
68
75
  - Rakefile
69
76
  - bin/ipa_reader
70
77
  - lib/ipa_reader.rb
@@ -76,40 +83,31 @@ files:
76
83
  - test/MultiG.ipa
77
84
  - test/test_ipa_reader.rb
78
85
  - version.txt
79
- has_rdoc: true
80
- homepage: http://github.com/schlueter/Ipa-Reader
86
+ homepage: http://github.com/schlu/Ipa-Reader
81
87
  licenses: []
82
-
83
88
  post_install_message:
84
- rdoc_options:
89
+ rdoc_options:
85
90
  - --main
86
- - README.txt
87
- require_paths:
91
+ - README.md
92
+ require_paths:
88
93
  - lib
89
- required_ruby_version: !ruby/object:Gem::Requirement
94
+ required_ruby_version: !ruby/object:Gem::Requirement
90
95
  none: false
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- hash: 3
95
- segments:
96
- - 0
97
- version: "0"
98
- required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
101
  none: false
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- hash: 3
104
- segments:
105
- - 0
106
- version: "0"
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
107
106
  requirements: []
108
-
109
107
  rubyforge_project: ipa_reader
110
- rubygems_version: 1.3.7
108
+ rubygems_version: 1.8.24
111
109
  signing_key:
112
110
  specification_version: 3
113
- summary: Reads metadata form iPhone Package Archive Files (ipa)
114
- test_files:
111
+ summary: Reads metadata form iPhone Package Archive Files (ipa).
112
+ test_files:
115
113
  - test/test_ipa_reader.rb
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm 1.8.7@ipa_reader