2013-02-16 15 views
5

Ich habe eine gepackte Zeichenkette mit 3 Strings, die so zusammengesetzt ist, dass ich eine ganze Zahl habe, die Byte-Länge des nächsten Elements und dann die Bytes dieses Elements und dann die Bytesize des nächsten Elements usw. als ob jemand tat:Ruby String # unpack

[a.bytesize, a, b.bytesize, b, c.bytesize, c].pack("na*na*na*") 

wie kann ich auf einfache Weise richtig auspacken das? Die Perl-Lösung für dieses Problem war:

my($a, $b, $c) = unpack("(n/a*)3", $data) 

für Ruby, die offenbar nicht ‚/‘ und Klammern in auspacken nicht unterstützt, verwende ich so etwas wie:

vals = [] 
3.times do 
    size = data.unpack("n").first 
    data.slice!(0, 2) 
    vals << data.unpack("a#{size}").first 
    data.slice!(0, size) 
end 

Gibt es eine einfachere Weg zu diesem?

+1

Es sei denn, jemand eine einfache Lösung für dieses Problem findet, werde ich prüfen, eine Feature-Anfrage machen auspacken issue tracker auf Rubys, scheint zu erweitern, wie es nützlich sein kann, wenn die Umsetzung einige Merkmale Perl bekommt – Speed

Antwort

0

Ich sehe keinen Weg, dies so einfach zu tun wie die Perl-Lösung (und stimme zu, dass eine Feature-Anfrage geschickt werden sollte, um diese in Rubys Pack/Unpack-Implementierung hinzuzufügen), aber ich könnte zumindest bereitstellen die Lösung in weniger Zeilen, wenn das hilft:

vals = [] 
until data.empty? 
    vals << data.slice!(0, data.slice!(0,2).unpack('n').first.to_i).unpack("a*").first 
end 
0

wenn Sie eine ernsthafte binäre Datenverarbeitung benötigen, ein Juwel ist für sie: http://bindata.rubyforge.org/ ich glaube, Sie es verwenden sollen, statt Schmiede un Laufschleifen auspackt.

Sie können natürlich auch eine Feature-Request-Datei und warten, bis es umgesetzt werden, aber ich schlage vor, Sie BinData Juwel verwenden stattdessen die IMO eine viel robustere Lösung ist.

1

IMHO ist es nicht so einfach wie in PERL, aber das ist etwas Lösung, die ich vorschlagen kann.

unpacked = [] 
a, b, c = *unpacked << data.slice!(0, data.slice!(0, 2).unpack('S>').first) \ 
      until data.empty?