Prende una LISTA di valori e la converte in una stringa utilizzando le regole fornite da TEMPLATE. La stringa risultante è la concatenazione dei valori convertiti. Solitamente, ogni valore convertito equivale alla sua rappresentazione a livello di elaboratore. Per esempio, sulle macchine a 32 bit, un intero convertito può essere rappresentato da una sequenza di 4 byte.
Il TEMPLATE è una sequenza di caratteri che forniscono l'ordine ed il tipo dei valori, come indicato di seguito:
a Una stringa con dati binari arbitrari, sara` completata da null.
A Una stringa tesuale (ASCII), sara` completata da spazi.
Z Una stringa terminata da null (ASCIZ), sara` completata da null.
b Una stringa di bit (ordine ascendente dei bit all'interno di ciascun bye, come vec()).
B Una stringa di bit (ordine discendente dei bit all'interno di ciascun bye).
h Una stringa esadecimale (nybble basso per primo).
H Una stringa esadecimale (nybble alto per primo).
c Un carattere con segno.
C Un carattere senza segno. Supporta solo i byte. Per l'Unicode, si veda U.
s Un intero short con segno.
S Un intero short senza segno.
(Questo 'short' ['corto', NdT] e` _esattamente_
di 16 bit, il che puo` differire da cio`
che un compilatore C locale chiama 'short'. Se desiderate
degli interi corti della lunghezza nativa, utilizzate
il suffisso '!').
i Un intero con segno.
I Un intero senza segno.
(Questo 'intero' e` di _almeno_ 32 bit. La sua
esatta dimensione dipende da cio` che un
compilatore C locale chiama 'int', e potrebbe persino
essere piu` grande del 'long' descritto di
seguito).
l Un intero long con segno.
L Un intero long senza segno.
(Questo 'long' ['lungo', NdT] e` _esattamente_ di 32 bit, il che
puo` differire da cio` che un compilatore
C locale chiama 'long'. Se desiderate degli interi
lunghi della lunghezza nativa, utilizzate il suffisso
'!').
n Un intero short senza segno in ordine di "rete" (big-endian).
N Un intero long senza segno in ordine di "rete" (big-endian).
v Un intero short senza segno in ordine "VAX" (little-endian).
V Un intero long senza segno in ordine "VAX" (little-endian).
(Questi 'short' e 'long' sono _esattamente_ di 16 bit
ed _esattamente_ di 32 bit, rispettivamente).
q Un quad con segnp (64-bit).
Q Un quad senza segno.
(I quad sono disponibili solo se il vostro sistema
supporta gli interi a 64 bit, _e_ se Perl e`
stato compilato per supportarli.
In caso contario verra` generato un errore bloccante).
j Un intero con sengo (un intero di Perl, IV).
J Un intero senza segno (un intero senza segno di Perl, UV).
f Un numero in virgola mobile in singola precisione, in formato nativo.
d Un numero in virgola mobile in doppia precisione, in formato nativo.
F Un numero in virgola mobile nel formato nativo nativo
(un numero in virgola mobile interno di Perl, NV).
D Un numero in virgola mobile long in doppia precisione,
in formato nativo.
(I numeri in doppia precisione long sono disponibili
solo se il vostro sistema supporta i numeri lunghi
in doppia precisione, _e_ se Perl e` stato
compilato per supportarli.
In caso contario verra` generato un errore bloccante).
p Un puntatore ad una stringa terminata da null.
P Un puntatore ad una struttura (stringa a lunghezza fissa).
u Una stringa uuencoded.
U Un numero di carattere Unicode. Internamente, e` codificato in UTF-8.
(o UTF-EBCDIC su sistemi EBCDIC).
w Un intero compresso BER (non un BER ASN.1, si consulti perlpacktut per
dettagli). I suoi byte rappresentano un
intero senza segno in base 128, con la cifra piu`
significativa per prima, e con il minore numero di cifre
possibile. L'ottavo bit (il bit alto) viene impostato
su ciascun byte, tranne l'ultimo.
x Un byte null.
X Effettua il backup di un byte.
@ Riempie con null fino ad una posizione assoluta.
( Inizia un gruppo ().
Valgono le seguenti regole:
Ciascuna lettera può, opzionalmente, essere seguita da un numero,
che indica il numero di ripetizioni. Con tutti i tipi tranne a, A,
Z, b, B, h, H, @, x, X e P, la funziona pack
preleverà quel numero di valori da LISTA. Un * come numero di
ripetizioni indica di usare tutti gli elementi rimasti, tranne che per
@, x, X, dove equivale a 0, e u, dove equivale a 1 (o 45,
che è lo stesso). Il numero di ripetizioni può essere
racchiuso tra parentesi quadre, come in pack 'C[80]', @arr.
È possibile sostituire il numero di ripetizioni con un template,
racchiuso tra parentesi quadre; a questo punto, la lunghezza in byte di
questo template viene utilizzata come conteggio delle ripetizioni. Per
esempio, x[L] salta un intero long (salta cioè il numero di
byte in un intero); il template $t X[$t] $t scompatta [con unpack()), NdT]
il doppio di quanto compatti $t. Se il template tra parentesi contiene dei
comandi di allineamento (come ad esempio x![d]), la lunghezza
compattata viene calcolata come se l'inizio del template avesse
l'allineamento massimo possibile.
Quando viene utilizzato con Z, * provoca l'aggiunta di un byte
null alla fine (cosicché il risultato compattato sia di
un'unità più lungo del byte length dell'elemento).
Il numero di ripetizioni per u viene interpretato come il numero
massimo di byte da codificare per ciascuna linea di output, con 0 ed 1
sostituiti da 45.
I tipi a, A, and Z prelevano solamente un valore, ma lo
compattano come una stringa della lunghezza specificata, completando
con null o spazi se necessario. Al momento di scompattare, A
rimuove eventuali spazi e null all'inizio, Z rimuove tutto dopo il
primo null, e a restituisce i dati così come sono. Per
compattare, a e Z sono equivalenti.
Se il valore-da-compattare è troppo lungo, esso viene troncato.
Se è troppo lungo e viene fornito esplicitamente un conteggio,
Z compatta solo $conteggio-1 byte, seguiti da un null. Dunque,
Z compatta sempre un null al termine della stringa, in qualsiasi
circostanza.
Allo stesso modo, i campi b e B compattano una stringa lunga il
numero di bit specificato. Ciascun byte dell'input di pack() genera un
bit del risultato. Ogni bit del risultato è basato sul bit meno
significativo del byte di input corrispondente, cioè con
ord($byte)%2. In particolare i byte "0" e "1" generato i bit
0 e 1, e così fanno i byte "\0" e "\1".
A partire dall'inizio della stringa in input a pack(), ciascun gruppo
di 8 byte viene convertito in 1 byte di output. Con il formato b, il
primo byte del gruppo di 8 determina il bit meno significativo di un
byte, mentre con il formato B determina quello più
significativo.
Se la lunghezza della stringa in input non è divisibile esattamente per 8, la parte rimanente viene compattata come se la stringa in input fosse completata di byte null alla fine. In maniera analoga, al momento di utilizzare unpack() i bit "extra" vengono ingorati.
Se la stringa in input a pack() è più lunga di
quanto necessario, i byte in più vengono ignorati. Un *
come conteggio delle ripetizioni di pack() indica di utilizzare
tutti i byte dell'input. Al momento di utilizzare unpack() i bit
sono convertiti in una stringa di "0" e "1".
I campi h e H compattano una stringa lunga il numero di
nybble (gruppi di 4 bit, rappresentati come cifre esadecimali,
0-9a-f) specificato.
Ciascun byte in input a pack() genera 4 bit del risultato. Per i
byte non alfabetici, il risultato è basato sui 4 bit meno
significativi del byte in input, cioè come in ord($byte)%16.
In particolare, i byte "0" e "1" generano nybble 0 e 1,
così come i byte "\0" e "\1". Per i byte "a".."f"
e "A".."F" il risultato è compatibile con le solite cifre
esadecimali, dunque "a" e "A" generano entrambi il nybble
0xa==10. Il risultato per i byte "g".."z" e "G".."Z" non
è ben definito.
A partire dall'inizio della stringa in input a pack(), ciascuna
coppia di byte viene convertita in 1 byte dell'output. Con il
formato h il primo byte della coppia determina il nybble meno
significativo del byte il output, e con il formato H esso ne
determina il nybble più significativo.
Se la lunghezza della stringa in input non è pari, allora essa viene completata con un byte null alla fine. In maniera analoga, al momento dell'utilizzo di unpack() i nybble "extra" vengono ignorati.
Se la stringa in input a pack() è più lunga del
necessario, i byte in più vengono ignorati. Un * come
conteggio delle ripetizioni di pack() indica di utilizzare tutti i
byte dell'input. Al momento di utilizzare unpack() i bit sono
convertiti in una stringa di cifre esadecimali.
Il tipo p compatta un puntatore ad una stringa terminata da
null. Siete responsabile dell'assicurarvi che la stringa non sia
un valore temporaneo (che può potenzialmente essere
deallocato prima che utilizziate il risultato compattato). Il tipo
P compatta un puntatore ad una struttura della dimensione
indicata dalla lunghezza. Viene creato un puntatore a NULL che il
corrispondentente valore per p o P è undef.
Un comportamento simile si ha con unpack().
Il template / permette di compattare e scompattare
stringhe in cui la struttura compattata contiene un conteggio di
byte seguito dalla stringa stessa. Dovete scrivere
lunghezza-elemento/stringa-elemento.
La lunghezza-elemento può essere qualsiasi lettera di
template di pack, e descrive come è compattato il valore
di lunghezza. Quelle di utilizzo più frequente sono quelle di
compattamento degli interi, quali n (per stringhe Java), c<w>
(per ASN.1 o SNMP) e N (per Sun, XDR).
Per pack, la stringa-elemento deve, al momento, essere "A*", "a*"
oppure "Z*". Con unpack la lunghezza della stringa è
ottenuta da lunghezza-elemento, ma se inserite il carattere '*'
viene ingorata. Per tutti gli altri codici, unpack applica il valore della
lunghezza all'elemento successivo, che non deve avere un conteggio delle ripetizioni.
unpack 'C/a', "\04Gurusamy"; restituisce 'Guru'
unpack 'a3/A* A*', '007 Bond J '; restituisce (' Bond','J')
pack 'n/a* w/a*','hello,','world'; restituisce "\000\006hello,\005world" [ciao mondo, NdT]
La lunghezza-elemento non viene restituita esplicitamente da
unpack.
L'aggiunta di un conteggio a lunghezza-elemento non è
probabilmente di alcuna utilità, a meno che la lettera non
sia A, a o Z. Compattare con una lunghezza-elemento di
a o Z può causare l'inserimento di catteri "\000",
che Perl non considera legali all'interno delle stringhe numeriche.
I tipi interi s, S, l e L possono essere immediatamente
seguiti da un suffisso !, che indica che essi sono short o long
nativi, come potete vedere sopra, ad esempio un l solitario indica
esattamente 32 bit, mentre il long nativo (come è
considerato dal compilatore C locale) può essere più
grande. Questo è un problema soprattutto nei sistemi a 64-bit.
Potete controllare se l'utilizzo di ! crea qualche differenza in
questa maniera
print length(pack("s")), " ", length(pack("s!")), "\n";
print length(pack("l")), " ", length(pack("l!")), "\n";
Anche i! e I! funzionano, ma solo per questioni di completezza;
essi sono identici a i and I.
Le reali dimensioni (in byte) degli short, int, long e long long nativi sui sistemi dove Perl è stato compilato sono disponibili anche tramite Config:
use Config;
print $Config{shortsize}, "\n";
print $Config{intsize}, "\n";
print $Config{longsize}, "\n";
print $Config{longlongsize}, "\n";
($Config{longlongsize} risulterà non definito se il
vostro sistema non supporta i long lon).
I formati interi s, S, i, I, l, L, j e J
sono intrinsecamente non portabili tra diversi processori e sistemi
operativi, poiché essi obbediscono all'ordine dei byte ed
al tipo di endian locali. Per esempio, un intero di 4 byte 0x12345678
(305419896 in decimale) viene ordinato nativamente (ordinato e gestito
dai registri della CPU) in byte come:
0x12 0x34 0x56 0x78 # big-endian 0x78 0x56 0x34 0x12 # little-endian
Fondamentalmente, le CPU Intel e VAX sono little-endian, mentre tutti gli altri, ad esempio Motorola m68k/88k, PPC, Sparc, HP PA, Power, e Cray, sono big-endian. Alpha e MIPS possono essere entrambi: Digital/Compaq li usava/usa in modalità little-endian; SGI/Cray li usa in modalità big-endian.
I nomi 'big-endian' e 'little-endian' sono riferimenti fumettistici al classico "Gulliver's Travels" ["I viaggi di Gulliver", NdT] (attraverso il foglio "On Holy Wars and a Plea for Peace" di Danny Cohen, USC/ISI IEN 137, April 1, 1980) ["Sulle guerre sante ed un appello per la pace", NdT] e le abitudini dei Lillipuziani per quanto riguarda il mangiare le uova.
Alcuni sistemi possono avere un ordine dei byte più strano, come:
0x56 0x78 0x12 0x34 0x34 0x12 0x78 0x56
Potete conoscere la preferenza del vostro sistema con:
print join(" ", map { sprintf "%#02x", $_ }
unpack("C*",pack("L",0x12345678))), "\n";
L'ordine dei byte sul sistema dove Perl è stato compilato è inoltre disponibile tramite Config:
use Config;
print $Config{byteorder}, "\n";
I byteorder '1234' e '12345678' sono little-endian, '4321'
e '87654321' sono big-endian.
Se desiderate degli interi compattati portabili, utilizzati i formati
n, N, v, e V: la loro dimensione e tipo di endian sono
conosciuti. Consultate anche perlport.
I numeri reali (float e double) sono unicamente nel formato nativo della macchina; a causa del gran numero di formati a virgola mobile presenti, ed a causa dell'assenza di una rappresentazione "di rete" standard, non è stata creato alcuno strumento per l'interscambio. Ciò significa che i dati in virgola mobile compattati scritti su una macchina potrebbero non essere leggibili su un'altra, persino se entrambe usano l'aritmetica in virgola mobile IEEE (poiché il tipo di endian delle rappresentazioni in memoria non rientra nelle specifiche IEEE). Consultate anche perlport.
Va notato che Perl usa i double internamente per tutti i calcoli numerici,
e la conversione da double a float e viceversa causa una perdita di
precisione (ad esempio, unpack("f", pack("f", $pippo)) non è
generalmente equivalente a $pippo).
Se lo schema inizia con U, la stringa risultante verrà trattata
come codificata in Unicode. Potete forzare la codifica UTF8 su una stringa
inserendo un U0 iniziale, ed i byte che seguono saranno interpretati
come caratteri Unicode. Se non volete che ciò accada, potete far
iniziare il vostro schema con C0 (o qualsiasi altra cosa) per forzare
Perl a non codificare in UTF8 la vostra stringa, facendo poi seguire a
ciò un U* da qualche parte nel vostro schema.
Dovete occuparvi voi di eventuali allineamenti o completamenti, inserendo
ad esempio sufficienti 'x' quando state compattando. Non c'è
alcun modo in cui pack() ed unpack() possono sapere dove vanno o da dove
vengono i byte. Quindi, pack (e unpack) gestisce il suo output ed
input come fossero delle pure sequenze di byte.
Un gruppo () è un sotto-TEMPLATE racchiuso tra parentesi. Un gruppo
può avere un conteggio di ripetizioni, sia alla fine che tramite il
template di caratteri /. All'interno di ogni ripetizione di un gruppo,
il posizionamento tramite @ fa ripartire di nuovo da 0. Quindi, il
risultato di
pack( '@1A((@2A)@3A)', 'a', 'b', 'c' )
è la stringa "\0a\0\0bc".
x ed X accettano il modificatore !. In questo caso si comportano
come comandi di allineamento; saltano avanti e indietro alla posizione
allineata più vicina ad un multiplo di un numero di byte pari a
conteggio. Per esempio, per utilizzare pack() o unpack() su una
struct {char c; double d; char cc[2]} del C, potreste dover utilizzare
il template C x![d] d C[2]; questo assume che i double siano allineati
alla dimensione dei double.
Per i comandi di allineamento, un conteggio di 0 equivale ad un
conteggio di 1; entrambi non risultano in alcuna operazione.
Un commento in un TEMPLATE inizia con # e termina con la fine della
linea. Per separate i codici compattati gli uni dagli altri, possono
essere utilizzati degli spazi, ma deve seguire immediatamente un
modificatore ! ed un numero di ripetizioni.
Se TEMPLATE richiede più argomenti per pack() di quanti ne siano
stati in realtà forniti, pack() assume un numero addizionale di
argomenti "". Se TEMPLATE richiede meno argomenti per pack() di quanti
ne siano stati in realtà forniti, gli argomenti in più
vengono ignorati.
Esempi:
$pippo = pack("CCCC",65,66,67,68);
# pippo eq "ABCD"
$pippo = pack("C4",65,66,67,68);
# stessa cosa
$pippo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
# stessa cosa con le lettere cerchiate Unicode
$pippo = pack("ccxxcc",65,66,67,68);
# pippo eq "AB\0\0CD"
# nota: gli esempi qui sopra che utilizzano "C" e "c" sono validi
# solo su sistemi ASCII o derivati come ISO Latin 1 e UTF-8.
# In EBCDIC il primo esempio diventerebbe
# $pippo = pack("CCCC",193,194,195,196);
$pippo = pack("s2",1,2);
# "\1\0\2\0" su little-endian
# "\0\1\0\2" su big-endian
$pippo = pack("a4","abcd","x","y","z");
# "abcd"
$pippo = pack("aaaa","abcd","x","y","z");
# "axyz"
$pippo = pack("a14","abcdefg");
# "abcdefg\0\0\0\0\0\0\0"
$pippo = pack("i9pl", gmtime);
# un vera struct tm (almeno, sul mio sistema)
$utmp_template = "Z8 Z8 Z16 L";
$utmp = pack($utmp_template, @utmp1);
# una struct utmp (in stile BSD)
@utmp2 = unpack($utmp_template, $utmp);
# "@utmp1" eq "@utmp2"
sub bintodec {
unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}
$pippo = pack('sx2l', 12, 34);
# short 12, completamento con due zeri, long 34
$pluto = pack('s@4l', 12, 34);
# short 12, riempito con zeri fino alla posizione 4, long 34
# $pippo eq $pluto
Lo stesso template può in genere venire usato anche in unpack().