format_parser 0.16.1 → 0.17.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80362b6ee92ad34550681e8c0447dcb93b11071beac25d743356a9c0b7a548f9
4
- data.tar.gz: c40fbcae9bd5417420ff5ea573c24f65462f3b0cf5269fc65024e6a237c98f45
3
+ metadata.gz: 45efce1fcb5395b66713b4704911473a6aaf6beab8dced2275299d05d42f051c
4
+ data.tar.gz: 760d1d686400e97cb58296bbf06862be7a19fedd6b2684075530c089d6685eac
5
5
  SHA512:
6
- metadata.gz: 7f20f7206574ea204393662e29251dc079ce615c593b21c0c4c35f3ba74a08fc9582e15443f23e45771ee2cb73b5b691ee6a31d37f5fb99e847d09d4c2e003cd
7
- data.tar.gz: 6a23e2bb7797a5834e0b2867096240a29ea899d2301f1496c94b2e9d35d29698dc8599bef7185785f7a26fc929bff1e9dda1f5d7a96bbfc37227b1a2d42b3c4b
6
+ metadata.gz: 0f3b357ff7b4121c4cad07a82ca94f13a4e92f3657e8984aa61a1c1a67f6144f726174a09b3b99c3c29b75dcd4c81970a5613e0e5a79e7c4eef52dbcdb779a50
7
+ data.tar.gz: 712e87ef7d506abcf7096d16c738058320dac9c1f2b2557ce08c6576748b37d3041bbe3d43260dcf846bfa7062a5de2840e30782e8c8edaabd15a6b19146d344
@@ -1,3 +1,11 @@
1
+ ## 0.17.0
2
+ * Remove parser factories. A parser should respond to `likely_match?` and `call`. If a parser has to be instantiated anew for
3
+ every call the parser should take care of instantiating itself.
4
+ * Add support for BMP files with core headers (older version of the BMP format)
5
+
6
+ ## 0.16.2
7
+ * All EXIF: Deal with EXIF orientations that get parsed as an array of [Orientation, nil] due to incorrect padding
8
+
1
9
  ## 0.16.1
2
10
  * All EXIF: Make sure the 0 orientation does not get silently treated as orientation 8, mislabling
3
11
  images which are not rotated as being rotated (orientation changed)
@@ -244,40 +244,25 @@ module FormatParser
244
244
 
245
245
  fitting_by_natures = assemble_parser_set[@parsers_per_nature, desired_natures]
246
246
  fitting_by_formats = assemble_parser_set[@parsers_per_format, desired_formats]
247
- factories = fitting_by_natures & fitting_by_formats
247
+ parsers = fitting_by_natures & fitting_by_formats
248
248
 
249
- if factories.empty?
249
+ if parsers.empty?
250
250
  raise ArgumentError, "No parsers provide both natures #{desired_natures.inspect} and formats #{desired_formats.inspect}"
251
251
  end
252
252
 
253
253
  # Order the parsers according to their priority value. The ones having a lower
254
254
  # value will sort higher and will be applied sooner
255
- factories_in_order_of_priority = factories.to_a.sort do |parser_factory_a, parser_factory_b|
256
- @parser_priorities[parser_factory_a] <=> @parser_priorities[parser_factory_b]
255
+ parsers_in_order_of_priority = parsers.to_a.sort do |parser_a, parser_b|
256
+ @parser_priorities[parser_a] <=> @parser_priorities[parser_b]
257
257
  end
258
258
 
259
259
  # If there is one parser that is more likely to match, place it first
260
- if first_match = factories_in_order_of_priority.find { |f| f.respond_to?(:likely_match?) && f.likely_match?(filename_hint) }
261
- factories_in_order_of_priority.delete(first_match)
262
- factories_in_order_of_priority.unshift(first_match)
260
+ if first_match = parsers_in_order_of_priority.find { |f| f.respond_to?(:likely_match?) && f.likely_match?(filename_hint) }
261
+ parsers_in_order_of_priority.delete(first_match)
262
+ parsers_in_order_of_priority.unshift(first_match)
263
263
  end
264
264
 
265
- factories_in_order_of_priority.map { |callable_or_class| instantiate_parser(callable_or_class) }
266
- end
267
-
268
- # Instantiates a parser object (an object that responds to `#call`) from a given class
269
- # or returns the parameter as is if it is callable by itself - i.e. if it is a Proc
270
- #
271
- # @param callable_or_responding_to_new[#call, #new] a callable or a Class/Module
272
- # @return [#call] a parser that can be called with an IO-ish argument
273
- def self.instantiate_parser(callable_or_responding_to_new)
274
- if callable_or_responding_to_new.respond_to?(:call)
275
- callable_or_responding_to_new
276
- elsif callable_or_responding_to_new.respond_to?(:new)
277
- callable_or_responding_to_new.new
278
- else
279
- raise ArgumentError, 'A parser should be either a class with an instance method #call or a Proc'
280
- end
265
+ parsers_in_order_of_priority
281
266
  end
282
267
 
283
268
  def self.string_to_lossy_utf8(str)
@@ -1,3 +1,3 @@
1
1
  module FormatParser
2
- VERSION = '0.16.1'
2
+ VERSION = '0.17.0'
3
3
  end
@@ -18,7 +18,7 @@ class FormatParser::AIFFParser
18
18
  'ANNO',
19
19
  ]
20
20
 
21
- def self.likely_match?(filename)
21
+ def likely_match?(filename)
22
22
  filename =~ /\.aiff?$/i
23
23
  end
24
24
 
@@ -84,5 +84,5 @@ class FormatParser::AIFFParser
84
84
  (sign == '1' ? -1.0 : 1.0) * (fraction.to_f / ((1 << 63) - 1)) * (2**exponent)
85
85
  end
86
86
 
87
- FormatParser.register_parser self, natures: :audio, formats: :aiff
87
+ FormatParser.register_parser new, natures: :audio, formats: :aiff
88
88
  end
@@ -4,9 +4,9 @@ class FormatParser::BMPParser
4
4
  include FormatParser::IOUtils
5
5
 
6
6
  VALID_BMP = 'BM'
7
- PERMISSIBLE_PIXEL_ARRAY_LOCATIONS = 40..512
7
+ PERMISSIBLE_PIXEL_ARRAY_LOCATIONS = 26..512
8
8
 
9
- def self.likely_match?(filename)
9
+ def likely_match?(filename)
10
10
  filename =~ /\.bmp$/i
11
11
  end
12
12
 
@@ -21,14 +21,41 @@ class FormatParser::BMPParser
21
21
  return unless PERMISSIBLE_PIXEL_ARRAY_LOCATIONS.cover?(pix_array_location)
22
22
 
23
23
  dib_header = safe_read(io, 40)
24
+ header_size = dib_header.unpack('V')[0]
25
+ case header_size
26
+ when 12 # OS21XBITMAPHEADER
27
+ parse_bitmap_core_header(dib_header)
28
+ else # More modern implementations
29
+ parse_modern_header(dib_header)
30
+ end
31
+ end
32
+
33
+ def parse_bitmap_core_header(dib_header)
34
+ _header_size, width, height, _num_color_planes, bit_depth = dib_header.unpack('VSSSS')
35
+
36
+ # In core bitmap format an unsigned int is used for dimensions,
37
+ # no inverse scan order is possible
38
+ data_order = :normal
39
+
40
+ FormatParser::Image.new(
41
+ format: :bmp,
42
+ width_px: width,
43
+ height_px: height,
44
+ color_mode: :rgb,
45
+ intrinsics: {
46
+ data_order: data_order,
47
+ bits_per_pixel: bit_depth
48
+ }
49
+ )
50
+ end
24
51
 
25
- _header_size, width, height, _planes, _bits_per_pixel,
52
+ def parse_modern_header(dib_header)
53
+ _header_size, width, height, _planes, bits_per_pixel,
26
54
  _compression_method, _image_size, horizontal_res,
27
55
  vertical_res, _n_colors, _i_colors = dib_header.unpack('Vl<2v2V2l<2V2')
28
56
 
29
57
  # There are cases where the height might by negative indicating the data
30
58
  # is ordered from top to bottom instead of bottom to top
31
- # http://www.dragonwins.com/domains/getteched/bmp/bmpfileformat.htm#The%20Image%20Header
32
59
  data_order = height < 0 ? :inverse : :normal
33
60
 
34
61
  FormatParser::Image.new(
@@ -39,10 +66,11 @@ class FormatParser::BMPParser
39
66
  intrinsics: {
40
67
  vertical_resolution: vertical_res,
41
68
  horizontal_resolution: horizontal_res,
42
- data_order: data_order
69
+ data_order: data_order,
70
+ bits_per_pixel: bits_per_pixel,
43
71
  }
44
72
  )
45
73
  end
46
74
 
47
- FormatParser.register_parser self, natures: :image, formats: :bmp
75
+ FormatParser.register_parser new, natures: :image, formats: :bmp
48
76
  end
@@ -7,7 +7,7 @@ class FormatParser::CR2Parser
7
7
  TIFF_HEADER = [0x49, 0x49, 0x2a, 0x00]
8
8
  CR2_HEADER = [0x43, 0x52, 0x02, 0x00]
9
9
 
10
- def self.likely_match?(filename)
10
+ def likely_match?(filename)
11
11
  filename =~ /\.cr2$/i
12
12
  end
13
13
 
@@ -44,5 +44,5 @@ class FormatParser::CR2Parser
44
44
  nil
45
45
  end
46
46
 
47
- FormatParser.register_parser self, natures: :image, formats: :cr2
47
+ FormatParser.register_parser new, natures: :image, formats: :cr2
48
48
  end
@@ -19,7 +19,7 @@ class FormatParser::DPXParser
19
19
 
20
20
  private_constant :ByteOrderHintIO
21
21
 
22
- def self.likely_match?(filename)
22
+ def likely_match?(filename)
23
23
  filename =~ /\.dpx$/i
24
24
  end
25
25
 
@@ -59,5 +59,5 @@ class FormatParser::DPXParser
59
59
  )
60
60
  end
61
61
 
62
- FormatParser.register_parser self, natures: :image, formats: :dpx
62
+ FormatParser.register_parser new, natures: :image, formats: :dpx
63
63
  end
@@ -42,7 +42,7 @@ module FormatParser::EXIFParser
42
42
 
43
43
  class EXIFResult < SimpleDelegator
44
44
  def rotated?
45
- __getobj__.orientation.to_i > 4
45
+ orientation.to_i > 4
46
46
  end
47
47
 
48
48
  def to_json(*maybe_coder)
@@ -52,7 +52,11 @@ module FormatParser::EXIFParser
52
52
  end
53
53
 
54
54
  def orientation
55
- __getobj__.orientation.to_i
55
+ # In some EXIF tags the value type is set oddly - it unpacks into multiple values,
56
+ # and it will look like this: [#<EXIFR::TIFF::Orientation:TopLeft(1)>, nil]
57
+ orientation_values = Array(__getobj__.orientation)
58
+ last_usable_value = orientation_values.compact[-1] # Use the last non-nil one
59
+ last_usable_value.to_i
56
60
  end
57
61
 
58
62
  def orientation_sym
@@ -162,4 +166,6 @@ module FormatParser::EXIFParser
162
166
  raw_exif_data ? EXIFResult.new(raw_exif_data) : nil
163
167
  end
164
168
  end
169
+
170
+ extend self
165
171
  end
@@ -1,7 +1,7 @@
1
1
  class FormatParser::FDXParser
2
2
  include FormatParser::IOUtils
3
3
 
4
- def self.likely_match?(filename)
4
+ def likely_match?(filename)
5
5
  filename =~ /\.fdx$/i
6
6
  end
7
7
 
@@ -30,5 +30,5 @@ class FormatParser::FDXParser
30
30
  end
31
31
  end
32
32
 
33
- FormatParser.register_parser self, natures: :document, formats: :fdx
33
+ FormatParser.register_parser new, natures: :document, formats: :fdx
34
34
  end
@@ -5,7 +5,7 @@ class FormatParser::FLACParser
5
5
  MAGIC_BYTE_STRING = 'fLaC'
6
6
  BLOCK_HEADER_BYTES = 4
7
7
 
8
- def self.likely_match?(filename)
8
+ def likely_match?(filename)
9
9
  filename =~ /\.flac$/i
10
10
  end
11
11
 
@@ -75,5 +75,5 @@ class FormatParser::FLACParser
75
75
  s.unpack('B*')[0].to_i(2)
76
76
  end
77
77
 
78
- FormatParser.register_parser self, natures: :audio, formats: :flac
78
+ FormatParser.register_parser new, natures: :audio, formats: :flac
79
79
  end
@@ -4,7 +4,7 @@ class FormatParser::GIFParser
4
4
  HEADERS = ['GIF87a', 'GIF89a'].map(&:b)
5
5
  NETSCAPE_AND_AUTHENTICATION_CODE = 'NETSCAPE2.0'
6
6
 
7
- def self.likely_match?(filename)
7
+ def likely_match?(filename)
8
8
  filename =~ /\.gif$/i
9
9
  end
10
10
 
@@ -48,5 +48,5 @@ class FormatParser::GIFParser
48
48
  )
49
49
  end
50
50
 
51
- FormatParser.register_parser self, natures: :image, formats: :gif, priority: 0
51
+ FormatParser.register_parser new, natures: :image, formats: :gif, priority: 0
52
52
  end
@@ -17,6 +17,10 @@ class FormatParser::JPEGParser
17
17
  filename =~ /\.jpe?g$/i
18
18
  end
19
19
 
20
+ def self.call(io)
21
+ new.call(io)
22
+ end
23
+
20
24
  def call(io)
21
25
  @buf = FormatParser::IOConstraint.new(io)
22
26
  @width = nil
@@ -11,7 +11,7 @@ class FormatParser::MOOVParser
11
11
  'm4a ' => :m4a,
12
12
  }
13
13
 
14
- def self.likely_match?(filename)
14
+ def likely_match?(filename)
15
15
  filename =~ /\.(mov|m4a|ma4|mp4|aac)$/i
16
16
  end
17
17
 
@@ -87,5 +87,5 @@ class FormatParser::MOOVParser
87
87
  maybe_atom_size >= minimum_ftyp_atom_size && maybe_ftyp_atom_signature == 'ftyp'
88
88
  end
89
89
 
90
- FormatParser.register_parser self, natures: :video, formats: FTYP_MAP.values, priority: 1
90
+ FormatParser.register_parser new, natures: :video, formats: FTYP_MAP.values, priority: 1
91
91
  end
@@ -53,7 +53,7 @@ class FormatParser::MP3Parser
53
53
  end
54
54
  end
55
55
 
56
- def self.likely_match?(filename)
56
+ def likely_match?(filename)
57
57
  filename =~ /\.mp3$/i
58
58
  end
59
59
 
@@ -297,5 +297,5 @@ class FormatParser::MP3Parser
297
297
  attrs
298
298
  end
299
299
 
300
- FormatParser.register_parser self, natures: :audio, formats: :mp3, priority: 99
300
+ FormatParser.register_parser new, natures: :audio, formats: :mp3, priority: 99
301
301
  end
@@ -6,7 +6,7 @@ class FormatParser::OggParser
6
6
  # Maximum size of an Ogg page
7
7
  MAX_POSSIBLE_PAGE_SIZE = 65307
8
8
 
9
- def self.likely_match?(filename)
9
+ def likely_match?(filename)
10
10
  filename =~ /\.ogg$/i
11
11
  end
12
12
 
@@ -218,5 +218,5 @@ class FormatParser::OggParser
218
218
  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
219
219
  ].freeze
220
220
 
221
- FormatParser.register_parser self, natures: :audio, formats: :ogg
221
+ FormatParser.register_parser new, natures: :audio, formats: :ogg
222
222
  end
@@ -9,7 +9,7 @@ class FormatParser::PDFParser
9
9
  #
10
10
  PDF_MARKER = /%PDF-1\.[0-8]{1}/
11
11
 
12
- def self.likely_match?(filename)
12
+ def likely_match?(filename)
13
13
  filename =~ /\.(pdf|ai)$/i
14
14
  end
15
15
 
@@ -21,5 +21,5 @@ class FormatParser::PDFParser
21
21
  FormatParser::Document.new(format: :pdf)
22
22
  end
23
23
 
24
- FormatParser.register_parser self, natures: :document, formats: :pdf, priority: 1
24
+ FormatParser.register_parser new, natures: :document, formats: :pdf, priority: 1
25
25
  end
@@ -15,7 +15,7 @@ class FormatParser::PNGParser
15
15
  6 => true,
16
16
  }
17
17
 
18
- def self.likely_match?(filename)
18
+ def likely_match?(filename)
19
19
  filename =~ /\.png$/i
20
20
  end
21
21
 
@@ -75,5 +75,5 @@ class FormatParser::PNGParser
75
75
  end
76
76
 
77
77
  # Give it priority 1 since priority 0 is reserved for JPEG, our most popular
78
- FormatParser.register_parser self, natures: :image, formats: :png, priority: 1
78
+ FormatParser.register_parser new, natures: :image, formats: :png, priority: 1
79
79
  end
@@ -3,7 +3,7 @@ class FormatParser::PSDParser
3
3
 
4
4
  PSD_HEADER = [0x38, 0x42, 0x50, 0x53]
5
5
 
6
- def self.likely_match?(filename)
6
+ def likely_match?(filename)
7
7
  filename =~ /\.psd$/i # Maybe also PSB at some point
8
8
  end
9
9
 
@@ -23,5 +23,5 @@ class FormatParser::PSDParser
23
23
  )
24
24
  end
25
25
 
26
- FormatParser.register_parser self, natures: :image, formats: :psd
26
+ FormatParser.register_parser new, natures: :image, formats: :psd
27
27
  end
@@ -5,7 +5,7 @@ class FormatParser::TIFFParser
5
5
  MAGIC_LE = [0x49, 0x49, 0x2A, 0x0].pack('C4')
6
6
  MAGIC_BE = [0x4D, 0x4D, 0x0, 0x2A].pack('C4')
7
7
 
8
- def self.likely_match?(filename)
8
+ def likely_match?(filename)
9
9
  filename =~ /\.tiff?$/i
10
10
  end
11
11
 
@@ -43,5 +43,5 @@ class FormatParser::TIFFParser
43
43
  safe_read(io, 2) == 'CR'
44
44
  end
45
45
 
46
- FormatParser.register_parser self, natures: :image, formats: :tif
46
+ FormatParser.register_parser new, natures: :image, formats: :tif
47
47
  end
@@ -1,7 +1,7 @@
1
1
  class FormatParser::WAVParser
2
2
  include FormatParser::IOUtils
3
3
 
4
- def self.likely_match?(filename)
4
+ def likely_match?(filename)
5
5
  filename =~ /\.wav$/i
6
6
  end
7
7
 
@@ -99,5 +99,5 @@ class FormatParser::WAVParser
99
99
  )
100
100
  end
101
101
 
102
- FormatParser.register_parser self, natures: :audio, formats: :wav
102
+ FormatParser.register_parser new, natures: :audio, formats: :wav
103
103
  end
@@ -5,7 +5,7 @@ class FormatParser::ZIPParser
5
5
  include OfficeFormats
6
6
  include FormatParser::IOUtils
7
7
 
8
- def self.likely_match?(filename)
8
+ def likely_match?(filename)
9
9
  filename =~ /\.(zip|docx|keynote|numbers|pptx|xlsx)$/i
10
10
  end
11
11
 
@@ -58,5 +58,5 @@ class FormatParser::ZIPParser
58
58
  end
59
59
  end
60
60
 
61
- FormatParser.register_parser self, natures: [:archive, :document], formats: :zip, priority: 2
61
+ FormatParser.register_parser new, natures: [:archive, :document], formats: :zip, priority: 2
62
62
  end
@@ -17,6 +17,7 @@ describe FormatParser::BMPParser do
17
17
  expect(parsed.intrinsics[:vertical_resolution]).to eq(2834)
18
18
  expect(parsed.intrinsics[:horizontal_resolution]).to eq(2834)
19
19
  expect(parsed.intrinsics[:data_order]).to eq(:normal)
20
+ expect(parsed.intrinsics[:bits_per_pixel]).to eq(24)
20
21
  end
21
22
 
22
23
  it 'parses a BMP file with negative height_px values (divergent scan order)' do
@@ -35,6 +36,7 @@ describe FormatParser::BMPParser do
35
36
  expect(parsed.intrinsics[:vertical_resolution]).to eq(2835)
36
37
  expect(parsed.intrinsics[:horizontal_resolution]).to eq(2835)
37
38
  expect(parsed.intrinsics[:data_order]).to eq(:inverse)
39
+ expect(parsed.intrinsics[:bits_per_pixel]).to eq(24)
38
40
  end
39
41
 
40
42
  it 'parses a BMP where the pixel array location is other than 54' do
@@ -52,6 +54,32 @@ describe FormatParser::BMPParser do
52
54
  expect(parsed.intrinsics).not_to be_nil
53
55
  end
54
56
 
57
+ it 'parses various BMP headers' do
58
+ bmp_path = fixtures_dir + '/BMP/test_v5header.bmp'
59
+ parsed = subject.call(File.open(bmp_path, 'rb'))
60
+
61
+ expect(parsed).not_to be_nil
62
+ expect(parsed.nature).to eq(:image)
63
+ expect(parsed.format).to eq(:bmp)
64
+ expect(parsed.color_mode).to eq(:rgb)
65
+ expect(parsed.width_px).to eq(40)
66
+ expect(parsed.height_px).to eq(27)
67
+ expect(parsed.intrinsics[:bits_per_pixel]).to eq(24)
68
+ expect(parsed.intrinsics[:data_order]).to eq(:normal)
69
+
70
+ bmp_path = fixtures_dir + '/BMP/test_coreheader.bmp'
71
+ parsed = subject.call(File.open(bmp_path, 'rb'))
72
+
73
+ expect(parsed).not_to be_nil
74
+ expect(parsed.nature).to eq(:image)
75
+ expect(parsed.format).to eq(:bmp)
76
+ expect(parsed.color_mode).to eq(:rgb)
77
+ expect(parsed.width_px).to eq(40)
78
+ expect(parsed.height_px).to eq(27)
79
+ expect(parsed.intrinsics[:bits_per_pixel]).to eq(24)
80
+ expect(parsed.intrinsics[:data_order]).to eq(:normal)
81
+ end
82
+
55
83
  it 'refuses to parse a BMP where the pixel array location is very large' do
56
84
  junk_data = [
57
85
  'BM',
@@ -1,15 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FormatParser::EXIFParser do
4
- let(:subject) do
5
- Object.new.tap { |o| o.extend FormatParser::EXIFParser }
6
- end
7
-
8
4
  describe 'is able to correctly parse orientation for all the TIFF EXIF examples from FastImage' do
9
5
  Dir.glob(fixtures_dir + '/exif-orientation-testimages/tiff-*/*.tif').each do |tiff_path|
10
6
  filename = File.basename(tiff_path)
11
7
  it "is able to parse #{filename}" do
12
- result = subject.exif_from_tiff_io(File.open(tiff_path, 'rb'))
8
+ result = described_class.exif_from_tiff_io(File.open(tiff_path, 'rb'))
13
9
  expect(result).not_to be_nil
14
10
  expect(result.orientation_sym).to be_kind_of(Symbol)
15
11
  # Filenames in this dir correspond with the orientation of the file
@@ -18,6 +14,14 @@ describe FormatParser::EXIFParser do
18
14
  end
19
15
  end
20
16
 
17
+ it 'is able to deal with an orientation tag which a tuple value for orientation' do
18
+ path = fixtures_dir + '/EXIF/double_orientation.exif.bin'
19
+ exif_data = File.open(path, 'rb') do |f|
20
+ described_class.exif_from_tiff_io(f)
21
+ end
22
+ expect(exif_data.orientation).to eq(1)
23
+ end
24
+
21
25
  describe 'IOExt' do
22
26
  it 'supports readbyte' do
23
27
  io = FormatParser::EXIFParser::IOExt.new(StringIO.new('hello'))
@@ -2,8 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  describe FormatParser::ZIPParser do
4
4
  it 'provides filename hints' do
5
- expect(FormatParser::ZIPParser).to be_likely_match('file.zip')
6
- expect(FormatParser::ZIPParser).not_to be_likely_match('file.tif')
5
+ expect(subject).to be_likely_match('file.zip')
6
+ expect(subject).not_to be_likely_match('file.tif')
7
7
  end
8
8
 
9
9
  it 'parses a ZIP archive with Zip64 extra fields (due to the number of files)' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: format_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.1
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noah Berman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-08-06 00:00:00.000000000 Z
12
+ date: 2019-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ks
@@ -303,8 +303,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
303
303
  - !ruby/object:Gem::Version
304
304
  version: '0'
305
305
  requirements: []
306
- rubyforge_project:
307
- rubygems_version: 2.7.6
306
+ rubygems_version: 3.0.6
308
307
  signing_key:
309
308
  specification_version: 4
310
309
  summary: A library for efficient parsing of file metadata