class StructPacking::Util

internal C-like_structure_declaration

Public Class Methods

internal_format_from(text) click to toggle source

Parse declaration string into internal format. Internal format is {:name=>“type”, …}

# File lib/struct_packing/util.rb, line 137
def self.internal_format_from(text)
  params = {}
  text.split(/[\n;]/).each do |line|
    line.gsub!(/^\s*/,'')
    line.gsub!(/\s*$/,'')

    idx = line.rindex(' ')
    type = line[0..idx-1]
    name = line[idx+1..line.length]

    if name =~ /(.*)\[\w*(\d+)\w*\]\w*/
      type += "[#{$2}]"
      name = $1
    end
 
    params[name.to_sym] = type
  end
  
  params
end
pack_template_from(text,mod=nil) click to toggle source

Parse declaration string into pack template.

# File lib/struct_packing/util.rb, line 130
def self.pack_template_from(text,mod=nil)
  internal = internal_format_from(text)
  types_to_template(internal.values,mod)
end

Private Class Methods

find_hier_mod(context_mod, sym) click to toggle source
# File lib/struct_packing/util.rb, line 111
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
parse_ctype_decl(decl, mod=nil) click to toggle source
# File lib/struct_packing/util.rb, line 22
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
  
  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
struct_template(type, arraylen, mod=nil) click to toggle source
# File lib/struct_packing/util.rb, line 11
def self.struct_template(type, arraylen, mod=nil)
  type =~ /struct\s*(\w*)\s*/

  if arraylen != ""
    find_hier_mod(mod, $1).pack_template * arraylen.to_i
  else
    find_hier_mod(mod, $1).pack_template
  end
  
end
template_of(sign, type) click to toggle source
# File lib/struct_packing/util.rb, line 43
def self.template_of(sign, type)
  case type
  when "ascii"
    'a'
  when "utf8"
    'U'
  when "byte"
    'C'
  when "char"
    'c'
  when "int8_t"
    sign ? 'c' : 'C'
  when "short"
    's'
  when "int16_t"
    sign ? 's' : 'S'
  when "int"
    sign ? 'i' : 'I'
  when "int32_t"
    sign ? 'l' : 'L'
  when "long"
    sign ? 'l' : 'L'
  when /long(\s*long)/
    sign ? 'q' : 'Q'
  when "int64_t"
    sign ? 'q' : 'Q'
  when "uint8_t"
    'C'
  when "uint16_t"
    'S'
  when "uint"
    'I'
  when "uint32_t"
    'L'
  when "uint64_t"
    'Q'
  when "big16"
    'n'
  when "big"
    'N'
  when "big32"
    'N'
  when "little16"
    'v'
  when "little"
    'V'
  when "little32"
    'V'
  when "float"
    'f'
  when /big\s*float/
    'g'
  when /little\s*float/
    'e'
  when "double"
    'd'
  when /big\s*double/
    'G'
  when /little\s*double/
    'E'
  end      
end
types_to_template(types, mod=nil) click to toggle source
# File lib/struct_packing/util.rb, line 106
def self.types_to_template(types, mod=nil)
  types.collect {|t| parse_ctype_decl(t,mod)}.join
end