Class: HTTPI::Dime
- Inherits:
-
Array
- Object
- Array
- HTTPI::Dime
- Defined in:
- lib/httpi/dime.rb
Constant Summary collapse
- BINARY =
1
- XML =
2
Instance Method Summary collapse
- #binary_records ⇒ Object
-
#initialize(body) ⇒ Dime
constructor
A new instance of Dime.
- #xml_records ⇒ Object
Constructor Details
#initialize(body) ⇒ Dime
Returns a new instance of Dime.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/httpi/dime.rb', line 9 def initialize(body) bytes = body.unpack('C*') while bytes.length > 0 record = DimeRecord.new # Shift out bitfields for the first fields byte = bytes.shift record.version = (byte >> 3) & 31 # 5 bits DIME format version (always 1) record.first = (byte >> 2) & 1 # 1 bit Set if this is the first part in the message record.last = (byte >> 1) & 1 # 1 bit Set if this is the last part in the message record.chunked = byte & 1 # 1 bit This file is broken into chunked parts record.type_format = (bytes.shift >> 4) & 15 # 4 bits Type of file in the part (1 for binary data, 2 for XML) # 4 bits Reserved (skipped in the above command) # Fetch big-endian lengths lengths = [] # we can't use a hash since the order will be screwed in Ruby 1.8 lengths << [:options, (bytes.shift << 8) | bytes.shift] # 2 bytes Length of the "options" field lengths << [:id, (bytes.shift << 8) | bytes.shift] # 2 bytes Length of the "ID" or "name" field lengths << [:type, (bytes.shift << 8) | bytes.shift] # 2 bytes Length of the "type" field lengths << [:data, (bytes.shift << 24) | (bytes.shift << 16) | (bytes.shift << 8) | bytes.shift] # 4 bytes Size of the included file # Read in padded data lengths.each do |attribute_set| attribute, length = attribute_set content = bytes.slice!(0, length).pack('C*') if attribute == :data && record.type_format == BINARY content = StringIO.new(content) end record.send "#{attribute.to_s}=", content bytes.slice!(0, 4 - (length & 3)) if (length & 3) != 0 end self << record end end |