class CStruct def self.new *p pre = p.pop if p.last.kind_of? Hash Class.new do include CStruct::Mix eval <<-EOF attr_accessor #{p.map{|n,v| ":#{n}" }.join', '} def self._directives ["#{p.map{|n,v|"#{v}"}.join}", #{post}] end def initialize data = nil #{p.map{|n,v|"@#{n}"}.join', '} = _parse data end def _create super #{p.map{|n,v|"@#{n}"}.join', '} end EOF end end end module CStruct::Mix def _parse data = nil return unless data pre, pos = self.class._directives if pos.nil? or pos == 0 then data.unpack pre elsif pos == 1 then data.unpack pre+'a*' else # Statisch lange Daten, Laengen von var und der Rest in var (*dat, var) = data.unpack pre + ('N'*(pos-1)) + 'a*' dat[ 0...-pos ] + # Statisch lange Daten var.unpack( # Variabel lange Daten dat[ -pos...-1 ].inject( data.length-var.length) {|i,j| j.push i-j.last # Differenzieren }.map {|i| "a#{i}" }.join) # Packstring zusammensetzen end end def _create *data pre, pos = self.class._directives if pos.nil? or pos == 0 then data.pack pre elsif pos == 1 then data.pack pre+'a*' else r = data[ 0...-pos ].pack pre r += data[ -pos..-1 ].inject( [r.length]) {|i,j| j.push i+j.last}[1...-1].pack 'N*' r + data[ -pos..-1 ].pack( 'a*'*(pos-1)) end end end