Class: PacketGen::StructFu::IntString

Inherits:
Struct
  • Object
show all
Defined in:
lib/packetgen/structfu.rb

Overview

Provides a primitive for creating strings, preceeded by an Int type of length. By default, a string of length zero with a one-byte length is presumed.

Note that IntStrings aren’t used for much, but it seemed like a good idea at the time.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Struct

#force_binary

Constructor Details

#initialize(string = '', int = Int8, mode = nil) ⇒ IntString

Returns a new instance of IntString.



257
258
259
260
261
262
263
264
# File 'lib/packetgen/structfu.rb', line 257

def initialize(string='',int=Int8,mode=nil)
  if int < Int
    super(int.new,string,mode)
    calc
  else
    raise "IntStrings need a StructFu::Int for a length."
  end
end

Instance Attribute Details

#intObject

Returns the value of attribute int

Returns:

  • (Object)

    the current value of int



255
256
257
# File 'lib/packetgen/structfu.rb', line 255

def int
  @int
end

#modeObject

Returns the value of attribute mode

Returns:

  • (Object)

    the current value of mode



255
256
257
# File 'lib/packetgen/structfu.rb', line 255

def mode
  @mode
end

#stringObject

Returns the value of attribute string

Returns:

  • (Object)

    the current value of string



255
256
257
# File 'lib/packetgen/structfu.rb', line 255

def string
  @string
end

Instance Method Details

#calcObject

Calculates the size of a string, and sets it as the value.



267
268
269
270
# File 'lib/packetgen/structfu.rb', line 267

def calc
  int.v = string.to_s.size
  self.to_s
end

#lenObject

Shorthand for querying a length. Note that the usual “length” and “size” refer to the number of elements of this struct.



298
299
300
# File 'lib/packetgen/structfu.rb', line 298

def len
  self[:int].value
end

#len=(i) ⇒ Object

Override the size, if you must.



303
304
305
# File 'lib/packetgen/structfu.rb', line 303

def len=(i)
  self[:int].value=i
end

#parse(s) ⇒ Object

parse() is like read(), except that it interprets the string, either based on the declared length, or the actual length. Which strategy is used is dependant on which :mode is set (with self.mode).

:parse : Read the length, and then read in that many bytes of the string. The string may be truncated or padded out with nulls, as dictated by the value.

:fix : Skip the length, read the rest of the string, then set the length to what it ought to be.

else : If neither of these modes are set, just perfom a normal read(). This is the default.



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/packetgen/structfu.rb', line 333

def parse(s)
  unless s[0,int.width].size == int.width
    raise StandardError, "String is too short for type #{int.class}"
  else
    case mode 
    when :parse
      int.read(s[0,int.width])
      self[:string] = s[int.width,int.value]
      if string.size < int.value
        self[:string] += ("\x00" * (int.value - self[:string].size))
      end
    when :fix
      self.string = s[int.width,s.size]
    else
      return read(s)
    end
  end
  self.to_s
end

#read(s) ⇒ Object

Read takes a string, assumes an int width as previously defined upon initialization, but makes no guarantees the int value isn’t lying. You’re on your own to test for that (or use parse() with a :mode set).



311
312
313
314
315
316
317
318
319
# File 'lib/packetgen/structfu.rb', line 311

def read(s)
  unless s[0,int.width].size == int.width
    raise StandardError, "String is too short for type #{int.class}"
  else
    int.read(s[0,int.width])
    self[:string] = s[int.width,s.size]
  end
  self.to_s
end

#to_sObject

Returns the object as a string, depending on the mode set upon object creation.



273
274
275
276
277
278
279
280
281
282
# File 'lib/packetgen/structfu.rb', line 273

def to_s
  if mode == :parse
    "#{int}" + [string].pack("a#{len}")
  elsif mode == :fix
    self.int.v = string.size
    "#{int}#{string}"
  else
    "#{int}#{string}"
  end
end