ipa_reader 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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