74 lines
1.5 KiB
Ruby
74 lines
1.5 KiB
Ruby
# -*- coding: binary -*-
|
|
|
|
# Rex::Struct2
|
|
module Rex
|
|
module Struct2
|
|
|
|
class Generic
|
|
|
|
require 'rex/struct2/element'
|
|
include Rex::Struct2::Element
|
|
|
|
attr_reader :default
|
|
attr_writer :default
|
|
|
|
attr_accessor :mask, :check_mask
|
|
|
|
def initialize(packspec, signed=false, default=nil)
|
|
@packspec = packspec
|
|
@default = default
|
|
|
|
bytelen = [ -1 ].pack(@packspec).length
|
|
self.mask = (1 << (8 * bytelen)) - 1
|
|
|
|
if signed
|
|
self.check_mask = 1 << (8 * bytelen - 1)
|
|
else
|
|
self.check_mask = 0
|
|
end
|
|
|
|
reset()
|
|
end
|
|
|
|
def reset
|
|
self.value = @default
|
|
end
|
|
|
|
def to_s
|
|
# I realize this will bomb out if this isn't an integer, for
|
|
# example if it is nil. That should only happen for a user
|
|
# error so that's what I want it to do...
|
|
string = [ @value ].pack(@packspec)
|
|
|
|
if restraint && restraint.max
|
|
return string.slice(0, restraint.max)
|
|
else
|
|
return string
|
|
end
|
|
# what to do for restraint.min?!?
|
|
end
|
|
|
|
def from_s(bytes)
|
|
value = bytes.unpack(@packspec)[0]
|
|
# return nil on unpack error
|
|
return if !value
|
|
len = slength()
|
|
# error on any restraint issues
|
|
return if restraint && restraint.max && len > restraint.max
|
|
return if restraint && restraint.min && len < restraint.min
|
|
# else set our value and return length used for this element
|
|
|
|
if (value & check_mask) != 0
|
|
value = -((~value & mask) + 1)
|
|
end
|
|
|
|
self.value = value
|
|
return(len)
|
|
end
|
|
|
|
end
|
|
|
|
# end Rex::Struct2
|
|
end
|
|
end
|