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
-
#big_endian_lengths(bytes) ⇒ Object
Fetch big-endian lengths.
- #binary_records ⇒ Object
-
#configure_record(record, bytes) ⇒ Object
Shift out bitfields for the first fields.
-
#initialize(body) ⇒ Dime
constructor
A new instance of Dime.
-
#read_data(record, bytes, attribute_set) ⇒ Object
Read in padded data.
- #xml_records ⇒ Object
Constructor Details
#initialize(body) ⇒ Dime
Returns a new instance of Dime.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/httpi/dime.rb', line 13 def initialize(body) bytes = body.unpack('C*') while bytes.length > 0 record = DimeRecord.new configure_record(record, bytes) big_endian_lengths(bytes).each do |attribute_set| read_data(record, bytes, attribute_set) end self << record end end |
Instance Method Details
#big_endian_lengths(bytes) ⇒ Object
Fetch big-endian lengths.
41 42 43 44 45 46 47 48 |
# File 'lib/httpi/dime.rb', line 41 def big_endian_lengths(bytes) 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 lengths end |
#binary_records ⇒ Object
67 68 69 |
# File 'lib/httpi/dime.rb', line 67 def binary_records select { |r| r.type_format == BINARY } end |
#configure_record(record, bytes) ⇒ Object
Shift out bitfields for the first fields.
29 30 31 32 33 34 35 36 37 38 |
# File 'lib/httpi/dime.rb', line 29 def configure_record(record, bytes) 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) end |
#read_data(record, bytes, attribute_set) ⇒ Object
Read in padded data.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/httpi/dime.rb', line 51 def read_data(record, bytes, 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 |
#xml_records ⇒ Object
63 64 65 |
# File 'lib/httpi/dime.rb', line 63 def xml_records select { |r| r.type_format == XML } end |