2013-02-16 14 views
5

Ho una stringa compressa di 3 stringhe che è composta in un modo tale da avere un numero intero, che specifica la lunghezza del byte dell'elemento successivo e quindi i byte di quell'elemento e quindi il byte dell'elemento successivo, ecc. come se qualcuno lo facesse:Ruby String # unpack

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

Come posso disimballarlo correttamente in un modo semplice? La soluzione a questo problema Perl era: ci

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

è un più semplice:

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

per Ruby, che a quanto pare non supporta '/' e parentesi a disfare, sto usando qualcosa di simile modo per questo?

+1

A meno che qualcuno trova una soluzione semplice a questo, io considero fare una richiesta di funzionalità per espandere scompattare l'issue tracker di rubino, sembra che può essere utile se l'implementazione ottiene alcune caratteristiche Perl – Speed

risposta

0

Non vedo un modo per farlo con la stessa facilità della soluzione Perl (e sono d'accordo sarebbe bello presentare una richiesta di funzionalità per ottenere quella aggiunta nell'implementazione di pacchetto/decompressione di Ruby), ma potrei almeno fornire la soluzione in un minor numero di linee se questo aiuta:

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

Se avete bisogno di una seria elaborazione dati binari, c'è un gioiello per esso: http://bindata.rubyforge.org/ penso che si dovrebbe usare, invece di forgiatura spacchetta ONU cicli da corsa.

È possibile naturalmente archiviare una richiesta di funzione e attendere che venga implementata, ma suggerisco di utilizzare invece bindata gem, che è una soluzione IMO molto più solida.

1

IMHO non è facile come in PERL, ma questa è una soluzione che posso suggerire.

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