Class: Hexdump::Reader Private

Inherits:
Object
  • Object
show all
Defined in:
lib/hexdump/reader.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Since:

  • 1.0.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type, offset: nil, length: nil, zero_pad: false) ⇒ Reader

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes the reader.

Parameters:

  • type (Type)

    The type to decode the data as.

  • offset (Integer, nil) (defaults to: nil)

    Controls whether to offset N number of bytes before starting to read data.

  • length (Integer, nil) (defaults to: nil)

    Controls control many bytes to read.

  • zero_pad (Boolean) (defaults to: false)

    Controls whether the remaining data will be padded with zeros.

Since:

  • 1.0.0



44
45
46
47
48
49
# File 'lib/hexdump/reader.rb', line 44

def initialize(type, offset: nil, length: nil, zero_pad: false)
  @type     = type
  @offset   = offset
  @length   = length
  @zero_pad = zero_pad
end

Instance Attribute Details

#lengthInteger? (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Controls control many bytes to read.

Returns:

  • (Integer, nil)

Since:

  • 1.0.0



26
27
28
# File 'lib/hexdump/reader.rb', line 26

def length
  @length
end

#offsetInteger? (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Controls whether to offset N number of bytes before starting to read data.

Returns:

  • (Integer, nil)

Since:

  • 1.0.0



21
22
23
# File 'lib/hexdump/reader.rb', line 21

def offset
  @offset
end

#typeType (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The type to decode the data as.

Returns:

Since:

  • 1.0.0



16
17
18
# File 'lib/hexdump/reader.rb', line 16

def type
  @type
end

Instance Method Details

#each(data) {|raw, value| ... } ⇒ Enumerator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parameters:

Yields:

  • (raw, value)

Yield Parameters:

  • raw (String)
  • value (Integer, Float, nil)

Returns:

  • (Enumerator)

Since:

  • 1.0.0



297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/hexdump/reader.rb', line 297

def each(data,&block)
  return enum_for(__method__,data) unless block

  case @type
  when Type::UInt
    each_uint(data,&block)
  when Type::Float
    each_float(data,&block)
  when Type::Int
    each_int(data,&block)
  else
    raise(TypeError,"unsupported type: #{@type.inspect}")
  end
end

#each_byte(data) {|byte| ... } ⇒ Enumerator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Reads each byte from the given data.

Yields:

  • (byte)

Yield Parameters:

  • byte (Integer)

Returns:

  • (Enumerator)

Raises:

  • (ArgumentError)

Since:

  • 1.0.0



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/hexdump/reader.rb', line 66

def each_byte(data)
  return enum_for(__method__,data) unless block_given?

  unless data.respond_to?(:each_byte)
    raise(ArgumentError,"the given data must respond to #each_byte")
  end

  count = 0

  data.each_byte do |b|
    count += 1

    # offset the first @offset number of bytes
    if @offset.nil? || count > @offset
      yield b
    end

    # stop reading after @length number of bytes
    break if @length && count >= @length
  end
end

#each_float(data) {|raw, float| ... } ⇒ Enumerator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parameters:

Yields:

  • (raw, float)

Yield Parameters:

  • raw (String)
  • float (Float, nil)

Returns:

  • (Enumerator)

Since:

  • 1.0.0



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/hexdump/reader.rb', line 259

def each_float(data)
  return enum_for(__method__,data) unless block_given?

  pack_format = case @type.endian
                when :little
                  case @type.size
                  when 4 then 'e'
                  when 8 then 'E'
                  else
                    raise(TypeError,"unsupported type size #{@type.size} for #{@type.inspect}")
                  end
                when :big
                  case @type.size
                  when 4 then 'g'
                  when 8 then 'G'
                  else
                    raise(TypeError,"unsupported type size #{@type.size} for #{@type.inspect}")
                  end
                else
                  raise(TypeError,"unsupported endian #{@type.endian} for #{@type.inspect}")
                end

  each_slice(data) do |slice|
    yield slice, slice.unpack1(pack_format)
  end
end

#each_int(data) {|raw, int| ... } ⇒ Enumerator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parameters:

Yields:

  • (raw, int)

Yield Parameters:

  • raw (String)
  • int (Integer, nil)

Returns:

  • (Enumerator)

Since:

  • 1.0.0



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/hexdump/reader.rb', line 212

def each_int(data)
  return enum_for(__method__,data) unless block_given?

  pack_format = case @type.size
                when 1
                  'c'
                when 2
                  case @type.endian
                  when :little then 's<'
                  when :big    then 's>'
                  else
                    raise(TypeError,"unsupported endian #{@type.endian} for #{@type.inspect}")
                  end
                when 4
                  case @type.endian
                  when :little then 'l<'
                  when :big    then 'l>'
                  else
                    raise(TypeError,"unsupported endian #{@type.endian} for #{@type.inspect}")
                  end
                when 8
                  case @type.endian
                  when :little then 'q<'
                  when :big    then 'q>'
                  else
                    raise(TypeError,"unsupported endian #{@type.endian} for #{@type.inspect}")
                  end
                else
                  raise(TypeError,"unsupported type size #{@type.size} for #{@type.inspect}")
                end

  each_slice(data) do |slice|
    yield slice, slice.unpack1(pack_format)
  end
end

#each_slice(data) {|slice| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Reads each string of the same number of bytes as the #type's size.

Parameters:

Yields:

  • (slice)

Yield Parameters:

Raises:

  • (ArgumentError)

Since:

  • 1.0.0



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/hexdump/reader.rb', line 100

def each_slice(data)
  return enum_for(__method__,data) unless block_given?

  unless data.respond_to?(:each_byte)
    raise(ArgumentError,"the given data must respond to #each_byte")
  end

  if @type.size == 1
    each_byte(data) do |b|
      yield b.chr
    end
  else
    buffer = String.new("\0" * @type.size, capacity: @type.size,
                                           encoding: Encoding::BINARY)
    index  = 0

    each_byte(data) do |b|
      buffer[index] = b.chr(Encoding::BINARY)
      index += 1

      if index >= @type.size
        yield buffer.dup
        index = 0
      end
    end

    if index > 0
      if @zero_pad
        # zero pad the rest of the buffer
        (index..(@type.size - 1)).each do |i|
          buffer[i] = "\0"
        end

        yield buffer
      else
        # yield the remaining partial buffer
        yield buffer[0,index]
      end
    end
  end
end

#each_uint(data) {|raw, uint| ... } ⇒ Enumerator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parameters:

Yields:

  • (raw, uint)

Yield Parameters:

  • raw (String)
  • uint (Integer, nil)

Returns:

  • (Enumerator)

Raises:

  • (ArgumentError)

Since:

  • 1.0.0



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/hexdump/reader.rb', line 155

def each_uint(data,&block)
  return enum_for(__method__,data) unless block_given?

  unless data.respond_to?(:each_byte)
    raise(ArgumentError,"the given data must respond to #each_byte")
  end

  if @type.size == 1
    each_byte(data) do |b|
      yield b.chr, b
    end
  else
    pack_format = case @type.size
                  when 1
                    'c'
                  when 2
                    case @type.endian
                    when :little then 'S<'
                    when :big    then 'S>'
                    else
                      raise(TypeError,"unsupported endian #{@type.endian} for #{@type.inspect}")
                    end
                  when 4
                    case @type.endian
                    when :little then 'L<'
                    when :big    then 'L>'
                    else
                      raise(TypeError,"unsupported endian #{@type.endian} for #{@type.inspect}")
                    end
                  when 8
                    case @type.endian
                    when :little then 'Q<'
                    when :big    then 'Q>'
                    else
                      raise(TypeError,"unsupported endian #{@type.endian} for #{@type.inspect}")
                    end
                  else
                    raise(TypeError,"unsupported type size #{@type.size} for #{@type.inspect}")
                  end

    each_slice(data) do |slice|
      yield slice, slice.unpack1(pack_format)
    end
  end
end

#zero_pad?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)

Since:

  • 1.0.0



51
52
53
# File 'lib/hexdump/reader.rb', line 51

def zero_pad?
  @zero_pad
end