Class: StructFu::IntString

Inherits:
Struct
  • Object
show all
Defined in:
lib/packetfu/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.



184
185
186
187
188
189
190
191
# File 'lib/packetfu/structfu.rb', line 184

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



182
183
184
# File 'lib/packetfu/structfu.rb', line 182

def int
  @int
end

#modeObject

Returns the value of attribute mode

Returns:

  • (Object)

    the current value of mode



182
183
184
# File 'lib/packetfu/structfu.rb', line 182

def mode
  @mode
end

#stringObject

Returns the value of attribute string

Returns:

  • (Object)

    the current value of string



182
183
184
# File 'lib/packetfu/structfu.rb', line 182

def string
  @string
end

Instance Method Details

#calcObject

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



194
195
196
197
# File 'lib/packetfu/structfu.rb', line 194

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.



225
226
227
# File 'lib/packetfu/structfu.rb', line 225

def len
	self[:int].value
end

#len=(i) ⇒ Object

Override the size, if you must.



230
231
232
# File 'lib/packetfu/structfu.rb', line 230

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.



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/packetfu/structfu.rb', line 260

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).



238
239
240
241
242
243
244
245
246
# File 'lib/packetfu/structfu.rb', line 238

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.



200
201
202
203
204
205
206
207
208
209
# File 'lib/packetfu/structfu.rb', line 200

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