88 lines
2.4 KiB
Ruby
88 lines
2.4 KiB
Ruby
|
module Rex
|
||
|
|
||
|
###
|
||
|
#
|
||
|
# Transformer - more than meets the eye!
|
||
|
# -----------
|
||
|
#
|
||
|
# This class, aside from having a kickass name, is responsible for translating
|
||
|
# object instances of one or more types into a single list instance of one or
|
||
|
# more types. This is useful for translating object instances that be can
|
||
|
# either strings or an array of strings into an array of strings, for
|
||
|
# instance. It lets you make things take a uniform structure in an abstract
|
||
|
# manner.
|
||
|
#
|
||
|
###
|
||
|
class Transformer
|
||
|
|
||
|
# Translates the object instance supplied in src_instance to an instance of
|
||
|
# dst_class. The dst_class parameter's instance must support the <<
|
||
|
# operator. An example call to this method looks something like:
|
||
|
#
|
||
|
# Transformer.transform(string, Array, [ String ], target)
|
||
|
def Transformer.transform(src_instance, dst_class, supported_classes,
|
||
|
target = nil)
|
||
|
dst_instance = dst_class.new
|
||
|
|
||
|
if (src_instance.kind_of?(Array))
|
||
|
src_instance.each { |src_inst|
|
||
|
Transformer.transform_single(src_inst, dst_instance,
|
||
|
supported_classes, target)
|
||
|
}
|
||
|
elsif (!src_instance.kind_of?(NilClass))
|
||
|
Transformer.transform_single(src_instance, dst_instance,
|
||
|
supported_classes, target)
|
||
|
end
|
||
|
|
||
|
return dst_instance
|
||
|
end
|
||
|
|
||
|
protected
|
||
|
|
||
|
# Transform a single source instance.
|
||
|
def Transformer.transform_single(src_instance, dst_instance,
|
||
|
supported_classes, target)
|
||
|
# If the src instance's class is supported, just add it to the dst
|
||
|
# instance
|
||
|
if (supported_classes.include?(src_instance.class))
|
||
|
dst_instance << src_instance
|
||
|
# If the source instance is a string, query each of the supported
|
||
|
# classes to see if they can serialize it to their particular data
|
||
|
# type.
|
||
|
elsif (src_instance.kind_of?(String))
|
||
|
new_src_instance = nil
|
||
|
|
||
|
# Walk each supported class calling from_s if exported
|
||
|
supported_classes.each { |sup_class|
|
||
|
new_src_instance = sup_class.from_s(src_instance)
|
||
|
|
||
|
if (new_src_instance != nil)
|
||
|
dst_instance << new_src_instance
|
||
|
break
|
||
|
end
|
||
|
}
|
||
|
|
||
|
# If we don't have a valid new src instance, then we suck
|
||
|
if (new_src_instance == nil)
|
||
|
bomb_translation(src_instance, target)
|
||
|
end
|
||
|
# Otherwise, bomb translation
|
||
|
else
|
||
|
bomb_translation(src_instance, target)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def Transformer.bomb_translation(src_instance, target)
|
||
|
error = "Invalid source class (#{src_instance.class})"
|
||
|
|
||
|
if (target != nil)
|
||
|
error += " for #{target}"
|
||
|
end
|
||
|
|
||
|
raise ArgumentError, error, caller
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
end
|