Class: Rex::Struct2::CStruct

Inherits:
SStruct
  • Object
show all
Includes:
Element
Defined in:
lib/rex/struct2/c_struct.rb

Constant Summary collapse

@@dt_table =
{
  'int8'      => proc { |*a| Rex::Struct2::Generic.new('C',  true, *a) },
  'uint8'     => proc { |*a| Rex::Struct2::Generic.new('C', false, *a) },
  'int16v'    => proc { |*a| Rex::Struct2::Generic.new('v',  true, *a) },
  'uint16v'   => proc { |*a| Rex::Struct2::Generic.new('v', false, *a) },
  'int32v'    => proc { |*a| Rex::Struct2::Generic.new('V',  true, *a) },
  'uint32v'   => proc { |*a| Rex::Struct2::Generic.new('V', false, *a) },
  'int64v'    => proc { |*a| Rex::Struct2::Generic.new('q',  true, *a) },
  'uint64v'   => proc { |*a| Rex::Struct2::Generic.new('Q', false, *a) },
  'int16n'    => proc { |*a| Rex::Struct2::Generic.new('n',  true, *a) },
  'uint16n'   => proc { |*a| Rex::Struct2::Generic.new('n', false, *a) },
  'int32n'    => proc { |*a| Rex::Struct2::Generic.new('N',  true, *a) },
  'uint32n'   => proc { |*a| Rex::Struct2::Generic.new('N', false, *a) },
  'string'    => proc { |*a| Rex::Struct2::SString.new(*a) },
  'sstruct'   => proc { |*a| Rex::Struct2::SStruct.new(*a) },
  'object'    => proc { |o| o },
  'template'  => proc { |o| o.make_struct },
}

Instance Attribute Summary collapse

Attributes included from Element

#container, #restraint, #value

Attributes inherited from SStruct

#leftover

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Element

#slength, #update_restraint

Methods inherited from SStruct

#<<, #add_element, #each, #from_s, #length, #reset, #to_s

Constructor Details

#initialize(*dts) ⇒ CStruct

Returns a new instance of CStruct.



79
80
81
82
83
84
85
# File 'lib/rex/struct2/c_struct.rb', line 79

def initialize(*dts)
	super()
	@name_table = [ ]
	@v = Rex::Struct2::CStruct_Values.new(self)

	return self.add_from_dt(*dts)
end

Instance Attribute Details

#vObject (readonly)

Returns the value of attribute v.



49
50
51
# File 'lib/rex/struct2/c_struct.rb', line 49

def v
  @v
end

Class Method Details

.typedef(*args) ⇒ Object

CStruct.typedef(name, factory, … )



71
72
73
74
75
76
77
# File 'lib/rex/struct2/c_struct.rb', line 71

def CStruct.typedef(*args)
	while args.length >= 2
		name    = args.shift
		factory = args.shift
		@@dt_table[name] = factory
	end
end

Instance Method Details

#[](index, *other) ⇒ Object

ya ya, I know, these are weird. I’m not sure why I even bothered to inherit from array…



147
148
149
150
151
152
153
154
155
# File 'lib/rex/struct2/c_struct.rb', line 147

def [](index, *other)
	if index.kind_of?(String)
		i = @name_table.index(index)
		return if !i
		return super(i)
	else
		return super(index, *other)
	end
end

#[]=(index, *other) ⇒ Object



157
158
159
160
161
162
163
164
165
# File 'lib/rex/struct2/c_struct.rb', line 157

def []=(index, *other)
	if index.kind_of?(String)
		i = @name_table.index(index)
		return if !i
		return super(i, *other)
	else
		return super(index, *other)
	end
end

#add_from_dt(*dts) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rex/struct2/c_struct.rb', line 87

def add_from_dt(*dts)
	dts.each { | dt |
		return if !dt.kind_of?(Array) || dt.length < 2

		type = dt[0]
		name = dt[1]

		factory = @@dt_table[type]

		return if !factory

		# call with the arguments passed in
		obj = factory.call(*(dt[2 .. -1]))

		self.add_object(name, obj)
	}

	return dts.length
end

#add_object(*objs) ⇒ Object



107
108
109
110
111
112
# File 'lib/rex/struct2/c_struct.rb', line 107

def add_object(*objs)
	while objs.length >= 2
		@name_table << objs.shift
		self        << objs.shift
	end
end

#apply_restraint(*ress) ⇒ Object

apply_restraint( name, restraint, name2, restraint2 … )



114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/rex/struct2/c_struct.rb', line 114

def apply_restraint(*ress)
	while ress.length >= 2
		name = ress.shift
		res  = ress.shift
		self[name].restraint = res

		# update the restrainted object, so it will update the value
		# of the restrainter, with the initial size.  If you don't
		# want this behavior, um, you'll have to be careful with what
		# you supply as default values...
		self[name].update_restraint
	end
	return self
end

#create_restraints(*ress) ⇒ Object

create_restraints( [ name, stuff_to_restraint_constructor ] … )



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/rex/struct2/c_struct.rb', line 130

def create_restraints(*ress)
	ress.each { |r|
		# make a copy before we modify...
		r = r.dup
		# resolve names into objects
		r[1] = self[r[1]] if r[1]
		r[2] = self[r[2]] if r[2]

		# build and apply the restraint
		self.apply_restraint(r[0], Rex::Struct2::Restraint.new(*r[1 .. -1]))
	}

	return self
end

#each_pair(&block) ⇒ Object

Iterate through all fields and values



173
174
175
176
177
# File 'lib/rex/struct2/c_struct.rb', line 173

def each_pair(&block)
	@name_table.each do |k|
		block.call(k, self.v[k])
	end
end

#keysObject

Produce a list of field names



168
169
170
# File 'lib/rex/struct2/c_struct.rb', line 168

def keys
	@name_table
end