lib/struct_packing/base.rb in struct_packing-0.0.2 vs lib/struct_packing/base.rb in struct_packing-0.0.3
- old
+ new
@@ -8,84 +8,142 @@
private
def self.included(base)
base.extend ClassMethods
+ base.attr_mapped_struct
+
+ base.instance_eval { @selfclass = base }
+ base.instance_eval { def selfclass ; @selfclass ; end }
end
-
- public
+ protected
+
+ # get self class or eign class.
+ def selfclass
+ if defined?(self.class.selfclass)
+ self.class.selfclass
+ else
+ eign = (class << self; self ; end)
+ eign.selfclass
+ end
+ end
+
# Get structure format string used in packing this object.
#
# This method work as just wrapper to same name class-method.
def internal_format
- self.class.internal_format
+ selfclass.send(:internal_format)
end
+
+ public
- # Get field name list of this class.
- def field_names
- self.class.field_names
- end
-
- # Get field type list of this class.
- def field_types
- self.class.field_types
- end
-
- # Get Ruby's pack tenplate string for this class.
+ # Get Ruby's pack template string for this class.
def pack_template
- self.class.pack_template
+ selfclass.pack_template
end
# Common extending methods for Packable and Unpackable.
#
# Automatically extend on including StructPacking::Base module.
module ClassMethods
private
-
- # TODO temporary initializer for @@struct_internal_format
- def check_vardef
- if not self.class_variable_defined?(:@@struct_internal_format)
- class_eval("@@struct_internal_format = ''")
+
+ def self.extended(base)
+ base.class_eval do
+ begin
+ @struct_field_getter = superclass.class_eval { @struct_field_getter }
+ rescue
+ @struct_field_getter = nil
+ end
+ begin
+ @struct_field_setter = superclass.class_eval { @struct_field_setter }
+ rescue
+ @struct_field_setter = nil
+ end
+ begin
+ @struct_internal_format = superclass.class_eval { @struct_internal_format }
+ if @struct_internal_format == nil
+ @struct_internal_format = ""
+ end
+ rescue
+ @struct_internal_format = ""
+ end
end
end
- public
+ protected
# Get internal structure format used to pack a object of this class.
def internal_format
- check_vardef # TODO Find more good way!
-
- Util.internal_format_from( self.class_variable_get(:@@struct_internal_format) )
+ Util.internal_format_from( @struct_internal_format)
end
+
+ public
# Set structure format for this class by string.
def byte_format=(text)
- check_vardef # TODO Find more good way!
-
- self.class_variable_set(:@@struct_internal_format, text)
+ @struct_internal_format = text
true
end
- # Get field name list of this class.
- def field_names
- internal_format.keys
+ public
+
+ # Get Ruby's pack template string for this class.
+ def pack_template
+ if self.to_s =~ /^.*<(.*):0x.*/
+ clsname = $1
+ else
+ clsname = self.to_s
+ end
+
+ Util.pack_template_from( @struct_internal_format, clsname )
end
-
- # Get field type list of this class.
- def field_types
- internal_format.values
+
+ # Call getter procedure to get field of target object.
+ def get_field_value(obj, name)
+ begin
+ @struct_field_getter.call(obj, name)
+ rescue
+ 0
+ end
end
+
+ # Call setter procedure to set value to the field of target object.
+ def set_field_value(obj, name, value)
+ begin
+ @struct_field_setter.call(obj, name, value)
+ rescue
+ end
+ end
- # Get Ruby's pack tenplate string for this class.
- def pack_template
- check_vardef # TODO Find more good way!
-
- Util.pack_template_from( self.class_variable_get(:@@struct_internal_format) )
+ # Set gettter procedure.
+ def set_field_getter(&block)
+ @struct_field_getter = block
end
+
+ # Set settter procedure.
+ def set_field_setter(&block)
+ @struct_field_setter = block
+ end
+
+ # Declare this struct as accessible by hash-style-access(access by [] operator).
+ def hash_mapped_struct
+ set_field_getter {|obj, name| obj[name.to_sym] }
+ set_field_setter {|obj, name, value| obj[name.to_sym] = value }
+ end
+
+ # Declare this struct as accessible by attr-style-access(access by {name}= operator).
+ # This is default behavior.
+ def attr_mapped_struct
+ set_field_getter {|obj, name| obj.send(name) }
+ set_field_setter {|obj, name, value| obj.send("#{name}=", value) }
+ end
+ alias :define_struct :byte_format=
+
end
end
end