lib/struct_packing/util.rb in struct_packing-0.0.2 vs lib/struct_packing/util.rb in struct_packing-0.0.3
- old
+ new
@@ -5,20 +5,41 @@
# internal C-like_structure_declaration
class Util
private
+
+ def self.struct_template(type, arraylen, mod=nil)
+ type =~ /struct\s*(\w*)\s*/
- def self.parse_ctype_decl(decl)
- decl =~ /^\s*(unsigned|signed)?\s*(ascii|utf8|byte|char|short|(?:u?int)(?:(?:8|16|32|64)_t)?|(?:big|little)?(?:16|32)|(?:big|little)?\s*(?:float|double)?|long(?:\s*long))\s*(?:\[\s*(\d+)\s*\])?\s*$/
+ if arraylen != ""
+ find_hier_mod(mod, $1).pack_template * arraylen.to_i
+ else
+ find_hier_mod(mod, $1).pack_template
+ end
+
+ end
- sign = !("unsigned" == $1)
- template = template_of(sign, $2)
- if $3 != nil and $3 == "1"
- template += $3
+ def self.parse_ctype_decl(decl, mod=nil)
+ decl =~ /^\s*(unsigned|signed)?\s*(ascii|utf8|byte|char|short|(?:u?int)(?:(?:8|16|32|64)_t)?|(?:big|little)?(?:16|32)|(?:big|little)?\s*(?:float|double)?|long(?:\s*long)|struct\s*\w*)\s*([\s\*]*)\s*(?:\[\s*(\d+)\s*\])?\s*$/
+
+ sign = !("unsigned" == $1) #sign modifier
+ type = $2
+ ptr = $3
+ arraylen = $4
+
+ if arraylen == nil or arraylen == "1"
+ arraylen = ""
end
- template
+
+ if ptr != nil and ptr != "" #pointer operator
+ 'P' + arraylen
+ elsif "struct" == type[0..5]
+ struct_template(type, arraylen, mod)
+ else
+ template_of(sign, type) + arraylen
+ end
end
def self.template_of(sign, type)
case type
when "ascii"
@@ -80,18 +101,36 @@
when /little\s*double/
'E'
end
end
- def self.types_to_template(types)
- types.collect {|t| parse_ctype_decl(t)}.join
+ def self.types_to_template(types, mod=nil)
+ types.collect {|t| parse_ctype_decl(t,mod)}.join
end
+
+ def self.find_hier_mod(context_mod, sym)
+ nesthier = context_mod.to_s.split("::")
+
+ parent = Kernel
+ mods = nesthier.collect {|m| x = parent.const_get(m); parent = x; x }
+ mods.unshift Kernel
+
+ finded = mods.reverse.collect {|m| m.const_defined?(sym) ? m.const_get(sym) : nil }
+ targetmod = finded.select {|f| f != nil }.first
+
+ if targetmod == nil
+ raise NameError
+ end
+ targetmod
+ end
+
+
public
# Parse declaration string into pack template.
- def self.pack_template_from(text)
+ def self.pack_template_from(text,mod=nil)
internal = internal_format_from(text)
- types_to_template(internal.values)
+ types_to_template(internal.values,mod)
end
# Parse declaration string into internal format.
# Internal format is {:name=>"type", ...}
def self.internal_format_from(text)