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.



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

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.



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

def v
  @v
end

Class Method Details

.typedef(*args) ⇒ Object

CStruct.typedef(name, factory, … )



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

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…



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

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



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

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



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

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



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

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



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

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 ] … )



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

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



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

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

#keysObject

Produce a list of field names



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

def keys
  @name_table
end