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)