lib/onix/reader.rb in onix-0.5.1 vs lib/onix/reader.rb in onix-0.6.0

- old
+ new

@@ -1,7 +1,5 @@ -require 'thread' -require 'timeout' require 'stringio' module ONIX # This is the primary class for reading data from an ONIX file, and there's @@ -64,68 +62,59 @@ else throw "Unable to read from path or file" end @product_klass = product_klass + @header = nil - # create a sized queue to store each product read from the file - # We use a separate thread to read products from the source file. - # This queue is a thread-safe way to transfer products from that - # thread back into the main one. - @queue = SizedQueue.new(100) - - # launch a reader thread - Thread.abort_on_exception = true - Thread.new { read_input } - - # don't return from the constructor until the reading thread - # has spun up and put at least one item into the queue. If - # it finds no Products in the file, it queues a nil, so we - # shouldn't get stuck here indefinitely - while @queue.size == 0 - sleep 0.05 + while @header.nil? + obj = read_next + if obj.kind_of?(ONIX::Header) + @header = obj + end end end # Iterate over all the products in an ONIX file # def each(&block) - obj = @queue.pop - while !obj.nil? + while !(obj = read_next).nil? yield obj - obj = @queue.pop end end private - # Walk the ONIX file, and grab the bits we're interested in. + # Walk the ONIX file, and grab the next header or product fragment. If we + # encounter other useful bits of info along the way (encoding, etc) then + # store them for later. # - # High level attributes and the header are stored as attributes of the reader - # class. Products are placed in a queue, ready to be popped off when the - # user uses the each() method. - # - def read_input + def read_next while @reader.read + @xml_lang = @reader.xml_lang if @xml_lang.nil? @xml_version = @reader.xml_version.to_f if @xml_version.nil? @encoding = encoding_const_to_name(@reader.encoding) if @encoding.nil? + if @reader.node_type == LibXML::XML::Reader::TYPE_DOCUMENT_TYPE uri = @reader.expand.to_s m, major, minor, rev = *uri.match(/.+(\d)\.(\d)\/(\d*).*/) @version = [major.to_i, minor.to_i, rev.to_i] elsif @reader.name == "Header" && @reader.node_type == LibXML::XML::Reader::TYPE_ELEMENT - @header = ONIX::Header.from_xml(@reader.expand.to_s) + str = @reader.read_outer_xml @reader.next_sibling + return ONIX::Header.from_xml(str) elsif @reader.name == "Product" && @reader.node_type == LibXML::XML::Reader::TYPE_ELEMENT - node = @reader.expand - @queue.push @product_klass.from_xml(node.to_s) + str = @reader.read_outer_xml @reader.next_sibling + return @product_klass.from_xml(str) end end - @queue.push nil + return nil end + # simple mapping of encoding constants to a string + # def encoding_const_to_name(const) case const when LibXML::XML::Encoding::UTF_8 "utf-8" when LibXML::XML::Encoding::UTF_16LE