lib/rupert/parser.rb in rupert-0.0.1 vs lib/rupert/parser.rb in rupert-0.0.2

- old
+ new

@@ -1,7 +1,8 @@ require 'rupert/rpm/lead' -require 'rupert/rpm/signature' +require 'rupert/rpm/index' +require 'rupert/rpm/entry' module Rupert class Parser def initialize(raw_io) @raw_io = raw_io @@ -9,52 +10,68 @@ def parse # TODO Fit to current design (i.e. no parsing in Lead c'tor?) lead = RPM::Lead.new(@raw_io) - entry_count, store_size = parse_header - entries = parse_entries(entry_count) + signature = signature_from(parse_index(@raw_io)) - store = parse_store(store_size) - content = parse_content + # TODO I'd like to get rid of this duplication, but still don't know how. + # Ideally, raw signed content should be available from both archive and + # header, and concatenated to calculate checksum. + content = parse_content @raw_io + @raw_io.seek(-content.length, IO::SEEK_CUR) - signature = RPM::Signature.new(RPM::Signature::Index.new(entries, store)) + header = header_from(parse_index(@raw_io)) - RPM.new(lead, signature, content) + RPM.new(lead, signature, content, header) end private - def parse_header + def header_from(index) + RPM::Header.new index + end + + def signature_from(index) + RPM::Signature.new index + end + + def parse_header(raw_io) header_size = 16 header_format = "@8NN" - @raw_io.read(header_size).unpack(header_format) + raw_io.read(header_size).unpack(header_format) end - def parse_entries(count) - entry_size = 16 - entry_format = "NNNN" + def parse_store(size, raw_io) + StringIO.new(raw_io.read(nearest_multiple(8, size))) + end - entries = Hash.new - count.times do - tag, type, offset, count = @raw_io.read(entry_size).unpack(entry_format) - entry = RPM::Signature::Entry.new tag, type, offset, count - entries[entry.tag] = entry + def parse_content(raw_io) + raw_io.read.force_encoding(Encoding::ASCII_8BIT) + end + + def parse_index(raw_io) + index = RPM::Index.new + + entry_count, store_size = parse_header(raw_io) + entry_count.times do + index.add parse_entry(raw_io) end - entries - end + index.store = parse_store(store_size, raw_io) - def parse_store(size) - RPM::Signature::Store.new(StringIO.new(@raw_io.read(nearest_multiple(size, 8)))) + index end - def parse_content - @raw_io.read + def parse_entry(raw_io) + entry_size = 16 + entry_format = "NNNN" + + RPM::Entry.new(*raw_io.read(entry_size).unpack(entry_format)) end - def nearest_multiple(size, modulo) + def nearest_multiple(modulo, size) (size / modulo.to_f).ceil * modulo end end end