_  _   ,_
/^\/^\-/ @D
~(________/ PERL.LT
|L |L
L L
Straipsniai  Funkcijos 
Funkcijos/pack - paversti sąrašą į binarinę formą
  • pack TEMPLATE,LIST

    Pasiima reikšmių LIST ir paverčia jį į stringą, naudodamas taisykles, perduotas TEMPLATE. Rezultate stringas yra paverstų reikšmių sujungimas. Paprastai kiekviena paversta reikšmė atrodo kaip jo mašininio-lygio reprezentacija. Pvz., 32-bit sistemose paverstas sveikasis skaičius gali būti parodommas kaip 4 baitų seka.

    TEMPLATE yra simbolių seka, kuri duoda taisykles ir reikšmių tipą kaip kad:

        a	Stringas su sutartinais dvejetainiais duomenimis, atskirtais nuliais.
        A	Tekstinis (ASCII) stringas, atskirtas tarpais.
        Z	Null pabaigtas (ASCIZ) stringas, atskirtas null'ais.
        b	bit'ų stringas (didėjančia bitų tvarka kiekviename (each) baite, kaip kad vec()).
        B	bitų stringas (mažėjančia bitų tvarka kiekviename (each) baite).
        h	A hex stringas (pirmiausia žemesni bitai).
        H	A hex stringas (aukštesni bitai pirmiausia).
        c	Ženklinta char reikšmė.
        C	Neženklinta char reikšmė.  Tik bytes.  Žr. U Unicode'ui.
        s	Ženklinta short reikšmė.
        S	Nežinklenta short reikšmė.
    	  (Ši 'short' yra būtent 16 bitų, kas gali skirtis nuo vietinio C kompiliatoriaus 'short'.  Jei norite prigimtinio ilgio short'ų, naudokite '!' priedėlį.)
        i	Ženklinta integer reikšmė.
        I	Neženklinta integer reikšmė.
    	  (Šis 'integer' yra bent 32 bitų pločio. Jo tikslus dydis priklauso nuo vietinio C kompiliatoriaus 'int', ir gali būti didesnis nei 'long', aprašytas toliau.)
        l	Ženklinta long reikšmė.
        L	Neženklinta long riekšmė.
    	  (Šis 'long' yra tiksliai 32 bitų, kas gali skirtis nuo to, ką vietinis C kompiliatorius vadina 'long'.  Jei norima prigimtinio ilgio long, naudokite '!' priedėlį.)
        n	Neženklintas short "network" (big-endian) tvarka.
        N	Neženklintas long "network" (big-endian) tvarka.
        v	Neženklintas short "VAX" (little-endian) tvarka.
        V	Neženklintas long "VAX" (little-endian) tvarka.
    	  (Šitie 'shorts' ir 'longs' yra tiksliai 16 bitų ir tiksliai 32 bitų, atitinkamai.)
        q	Ženklinta quad (64-bit) reikšmė.
        Q	Neženklinta quad reikšmė.
    	  (Šie yra galimi tik sistemose, palaikančiose 64-bit sveikąsias reikšmes IR, jei Perlas buvo sukompiliuotas su palaikymu.
               Kitu atveju duoda lemtingą klaidą.)
        j   Ženklinta integer reikšmė (Perl vidinis integer, IV).
        J   Neženklinta integer reikšmė (Perl vidinis neženklintas integer, UV).
        f	Vieno tikslumo (single-precision) float prigimtiniu formatu.
        d	Dvigubo tikslumo (double-precision) float prigimtiniu formatu.
        F	Slankaus kablelio reikšmė prigimtiniu formatu (Perlo vidinė slankaus kablelio riekšmė, NV).
        D	Long dvigubo tiklsumo float prigimtiniame formate. (Šie yra galimi tik sistemose, kurios juos palaiko IR, jei Perlas buvo sukompiliuotas su palaikymu. Kitu atveju duoda lemtingą klaidą.)
        p	Rodyklė į null-pabaigą stringą.
        P	Rodyklė į struktūrą (fiksuoto ilgio(length) stringas).
        u	uuencoded stringas.
        U	Unicode simbolio numeris. Užkoduoja į UTF-8 (ar UTF-EBCDIC EBCDIC platformose).
        w	BER suspaustas sveikasis. Jo baitai parodo neženklintą sveikąjį pagrindu 128, pirmiausia reikšmingiausi skaitmenys, su kiek galima mažiau skaitmenų. Aštuntas bitas (high bit) yra nustatytas kiekvienam baitui, išskyrus paskutinį.
        x	null baitas.
        X	Atsarginė baito kopija padaroma.
        @	Null užpildo besąlyginę poziciją, skaičiuojant nuo pačio giliausio ()-group.
        (	()-group pradžia.

    Sekančios taisyklės liečia:

    • Po kiekviennos raidės pasirinktinai gali eiti skaičius, pasikartojimų skaitliukas. Su visais tipais, išskyrus a , A , Z , b , B, h , H , @ , x , X ir P ši funkcija susigrobs tiek reikšmių iš LIST. * skaitliukui reiškia naudoti tiek elementų, kiek liko, išskyrus @ , x , X , kur tas tolygu 0 ir u , kur tai tolygu 1 (ar 45, kas tolygu). Skaitinis pasikartojimų skaitliukas (repeat count) galiu būti apskliaustas laužtiniais skliaustais, kaip kad pack 'C[80]', @arr .

      Galima skaitliuką pakeisti šablonu, įdėtu į laužtinius skliaustus; tada supakuotas šablono ilgis baitais yra naudojamas skaitliuko vietoje. Pvz., x[L] praleidžia long (praleidžia baitų kiekį jame); šablonas $t X[$t] $t unpack() (išpakuoja) dvigubai, ką $t išpakuoja. Jei šablonas skliaustuose turi lygiavimo komandų (kaip kad x![d] ), jo supakuoto ilgis yra skaičiuojamas lyg šablono pradžia turi didžiausią galimą lygiavimą.

      Kai naudojamas su Z , * duoda rezultatą besitęsiančio null baito (taigi, supakuotas rezultatas bus ilgesnis negu baitinis length (elemento ilgis)).

      Skaitliukas u interpretuojamas kaip maksimalus baitų skaičius užkodavimui vienoje išvesties eilutėje, kur 0 ir 1 pakeičiami 45.

    • a , A ir Z tipai praryja tik vieną reikšmę, bet supakuoja ją kaip ilgio skaitiklio stringą, į tarpus sukišdamas tuščias reikšmes ar tarpus. Išpakuojant A nukerta besitempiančius tarpus ir tuščias reikšmes, Z nukerta viską po pirmo null, o a gražina duomenis pažodžiui. Pakavimo metu a ir Z yra tolygūs.

      Jei reikšmė pakavimui yr aper ilga, ji sutrumpinama. Jei per ilga ir paduodamas atskiras skaitiklis, Z supakuoja tik $count-1 baitų, po kurių seka null baitas. Taigi Z visada supakuoja sekantį tuščią baitą visais atvejais.

    • Kaip b ir B laukai supakuoja stringą tiek bitų ilgio. Keikvienas įvesties pack() lauko baitas generuoja 1 bitą rezultato. Kiekvienas rezultato bitas yra paremtas mažiausiai reikšmingu atitinkamos įvesties baitu, t.y. ord($byte)%2. Tiesą sakant "0" ir "1" baitai generuoja 0 ir 1 bitus, kaip kad daro baitai "\0" ir "\1" .

      Pradedant nuo pack() įvesties stringo pradžios, kiekvienas baitų aštuntukas yra paverčiamas į vieną išvesties baitą. Su formatu b pirmasis aštuntuko baitas apsprendžia mažiausiai reikšmingą baito bitą ir su formatu B nustato reikšmingiausią baito bitą.

      Jei įvesties stringo ilgis nesidalina iš 8, liekana supakuojama tarsi įvesties stringas būtų atskirtas tuščiais baitais pabaigoje. Panašiai per unpack()'avimą extra bitai yra tiesiog ignoruojami.

      Jei pack() įvesties stringas yra ilgesnis nei reikia, extra baitai ignoruojami. * pack() skaitliukui liepia naudoti visus įvesties lauko baitus. unpack()'avimo metu bitai yra paverčiami į "0" ir "1" stringą.

    • h ir H laukai supakuoja stringą tiek bitų (4-bit grupės, pristatomos kaip šešiolektainiai skaitmenys, 0-9a-f) ilgio.

      Kiekvienas įvesties lauko baitas pack() generuoja 4 rezultato bitus. Neabėcėliniams baitams rezultatas yra paremtas 4 mažiausiai reikšmingais įvesties baito bitais , t.y. ord($byte)%16. Tiesą sakant, bitai "0" ir "1" generuoja baitus 0 ir 1, kaip ir "\0" bei "\1" baitai. Baitams "a".."f" ir "A".."F" rezultatas yra suderinamas su įprastiniais šešioliktainiais skaitmenimis, taip kad "a" ir "A" abu generuos baitą 0xa==10 . Rezultatas baitams "g".."z" ir "G".."Z" nėra gerai apibrėžtas.

      Pradedant nuo pack() įvesties stringo pradžia, kiekviena baitų pora paverčiama į 1 išvesties baitą. Su formatu h, pirmasis poros baitas nulemia mažiausiai reikšmingą išvesties baito bitą, o su formatu H apsprendžia reikšmingiausią bitą.

      Jei įvesties stringo ilgis nelygus, šis elgiasi tarsi pabaigoje būtų prikimštas tuščių baitų. Panašiai unpack()'avimo metu "extra" bitai ignoruojami.

      Jei pack() įvesties stringas yra ilgesnis nei reikalaujama, extra baitai ignoruojami. * skaitikliui reiškia, kad reikia panaudoti visus įvesties lauko baitus. unpack()'uojant bitus, jie yra paverčiami į šešioliktainių skaitmenų stringą.

    • p tipas supakuoja pointerį į null-pasibaigiantį string'ą. Esate pats atsakingas, kad stringas nebūtų laikina reikšmė (kas gali potencialiai būti atrezervuota prieš panaudojant supakuotą rezultatą). P tipas supakuoja nuorodą į struktūrą ilgio nurodyto dydžio. NULL pointeris yra sukuriamas, jei atitinkamos reikšmės p ar P yra undef, panašiai unpack().

    • / šablono simbolis leidžia pakavimą ir stringų išpakavimą, kur supakuota struktūra turi baitų skaitiklį, po kurio seka pats stringas. Rašote length-item/string-item.

      length-item gali būti bet kuri pack šablono raidė ir aprašo kaip ilgio reikšmė yra supakuota. Daugiausia, matyt, bus naudojami sveikųjų skaičių pakavimo, kaip kad n (Java stringams), w (ASN.1 ar SNMP) ir N (Sun XDR).

      pack, string-item privalo, dabar, būti "A*" , "a*" or "Z*" . unpack stringo ilgis yra apsprendžiamas, atsižvelgus į length-item, bet, jei uždėsite '*', jis bus ignoruojamas. Kitiems kodams unpack pritaiko ilgio reikšmę kitam elementui, kuris negali turėti skaitiklio.

          unpack 'C/a', "\04Gurusamy";        duoda 'Guru'
          unpack 'a3/A* A*', '007 Bond  J ';  duoda (' Bond','J')
          pack 'n/a* w/a*','hello,','world';  duoda "\000\006hello,\005world"

      length-item negražinamas atskirai nuo unpack.

      Pridedant skaitiklį prie length-item raidės nebūtinai bus naudinga, nebent raidė yra A , a ar Z . Supakuojant su length-item a ar Z gali duoti "\000" simbolius, kuriuos Perlas nelaiko legaliais skaitiniais stringais.

    • Sveikieji tipai s, S , l , ir L, po jų iš karto gali eiti ! priedėlis, parodyti prigimtinius short ar long - kaip galite matyti iš pavyzdžio aukščiau, plikas l reiškia tiksliai 32 bitus, prigimtinis long (kaip lokaliame C kompiliatoriuje) gali būti didesnis. Tai pagrinde tinkama 64-bit platformoms. Pamatysie, ar naudojant ! kas nors keičiasi:

      	print length(pack("s")), " ", length(pack("s!")), "\n";
      	print length(pack("l")), " ", length(pack("l!")), "\n";

      i! ir I! taip pat veikia, bet tik dėl pilnumo; jie yra identiški i ir I .

      Tikslus dydis (baitais) prigimtinių short, int, long ir long long platformoje, kur Perlas sukurtas (built) taip pat galimas per Config:

             use Config;
             print $Config{shortsize},    "\n";
             print $Config{intsize},      "\n";
             print $Config{longsize},     "\n";
             print $Config{longlongsize}, "\n";

      ($Config{longlongsize} bus neapibrėžtas, jei sistema nepalaiko long long.)

    • Sveikieji formatai s, S , i , I , l , L , j ir J yra įgimtai neportabilūs tarp procesorių ir operacinių sistemų, nes jie paiso vietinių baitų tvarkos ir baigtumo (little-endian ar big-endian). Pvz. 4-baitų sveikasis 0x12345678 (305419896 dešimtainis) būtų sutvarkytas prigimtinai (sulygiuotas ir sutvarkytas CPU registrų) į baitus, kaip kad

       	0x12 0x34 0x56 0x78	# big-endian
       	0x78 0x56 0x34 0x12	# little-endian

      Pagrindinai Intel ir VAX CPUs yra little-endian, o visi kiti, pvz. Motorola m68k/88k, PPC, Sparc, HP PA, Power ir Cray yra big-endian. Alpha ir MIPS gali būti dvejopi: Digital/Compaq naudojo/naudoja juos little-endian režime; SGI/Cray naudoja juos big-endian režime.

      Pavadinimai `big-endian' ir `little-endian' yra šmaikšti nuoroda į klasikinę "Guliverio kelionę" ("On Holy Wars and a Plea for Peace" Danny Cohen raštą, USC/ISI IEN 137, April 1, 1980) ir kiaušinių valgymo Liliputų įpročius.

      Kai kurios sitemos turi netgi keistesnes baitų tvarkymo sekas, kaip kad

       	0x56 0x78 0x12 0x34
       	0x34 0x12 0x78 0x56

      Galima pastebėti sistemos pirmenybę su

       	print join(" ", map { sprintf "%#02x", $_ }
                                  unpack("C*",pack("L",0x12345678))), "\n";

      Baitų tvarka platformoje, kur Perlas buvo įdiegtas taip pat galima per Config:

      	use Config;
      	print $Config{byteorder}, "\n";

      Baitų tvarkos '1234' ir '12345678' yra little-endian, '4321' ir '87654321' yra big-endian.

      Jei norite portabiliai supakuotų sveikųjų, naudokitės formatais n , N , v ir V , jų baitų pabaigos ir dydžiai yra žinomi. Žr. taip pat perlport.

    • Realieji skaičiai (float ir double) yra prigimtiniame mašinos formate; dėl gausybės formatų, esančių aplink ir trūkstant standartinės "tinklo" reprezentacijos, jokios keitimosi infrastruktūros taip ir nebuvo padarytos. Tai reiškia, kad supakavus slankaius kablelio duomenis, parašytos viename kompiuteryje, jie laisvai gali būti neperskaitomi kitoje - net jei abu kompiuteriai naudoja IEEE slankaus kablelio aritmetiką (mat atminties reprezentacija baitų pabaigos klausimai nėra IEEE veiklos dalis). Žr. taip pat perlport.

      Įsidėmėkite, kad Perlas naudoja double viduje, visoms skaitinėms kalkuliacijoms ir paverčiant iš double į float, o atvirkštiniame variante double vėl praras tikslumą (t.y. unpack("f", pack("f", $foo)) nebūtinai bendrai bus lygu $foo).

    • Jei šablonas prasideda U , rezultato stringas bus laikomas kaip UTF-8 užkoduotas Unicode. Galima priversti UTF-8 užkodavimą pirminiame U0 , o baitai, kurie seka bus interpretuojami kaip Unicode simboliai. Jei nenorite, kad taip atsitiktų, galite pradėti savo šabloną C0 (ar kuo kitu) priversti Perlą neužkoduoti UTF-8 stringo, o tada po jo parašyti U* kur nors šablone.

    • Patys sau turite pasidaryti lygiavimą ir atskyrimą, įterpiant, pvz pakankamai 'x''ų pakavimo metu. Nėra kaip pack() ir unpack() žinoti, kur baitai nueina, ar iš kur ateina. Tad pack (ir unpack) valdo išvestį kaip paprastą baitų seką.

    • ()-group yra apskliaustas sub-TEMPLATE. Group gali pasiimti skaitliuką kaip postfixą arba unpack()'ui per / šablono simbolį. Kiekvieno pakartojimo per grupe metu, pozicionavimas @ prasideda vėl ties 0. Tad

          pack( '@1A((@2A)@3A)', 'a', 'b', 'c' )

      rezultatas yra stringas "\0a\0\0bc".

    • x ir X priima ! modifikatorių. Šiuo atveju jie elgiasi kaip lygiavimo komandos: šokinėja pirmyn/atgal iki artimiausios pozicijos keliuose count baituose. Pavyzdžiui, pack() ar unpack() C struct {char c; double d; char cc[2]} gali prireikti šablonąC x![d] d C[2] ; tai perša išvadą, kad double privalo būti sulygiuoti double dydyje.

      Lygiavimo komandoms 0 count'ai yra tolygūs 1 count'ams ; abiejų rezultatai - jokių operacijų.

    • Komentaras TEMPLATE prasideda # ir eina per visą eilutę. Tarpai gali būti naudojami atskirti pakavimo kodus vieną nuo kitų, bet ! modifikatorius ir skaitliukas turi sekti be jokių tarpų.

    • Jei TEMPLATE reikalauja daugiau argumentų pack()'uoti negu jam paduodama, pack() ima papildomus "" argumentus. Jei TEMPLATE reikalauja mažiau argumentų pack()'uoti negu jam perduota, extra argumentai yra ignoruojami.

    Pavyzdžiai:

        $foo = pack("CCCC",65,66,67,68);
        # foo eq "ABCD"
        $foo = pack("C4",65,66,67,68);
        # same thing
        $foo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
        # same thing with Unicode circled letters
        $foo = pack("ccxxcc",65,66,67,68);
        # foo eq "AB\0\0CD"
        # note: the above examples featuring "C" and "c" are true
        # only on ASCII and ASCII-derived systems such as ISO Latin 1
        # and UTF-8.  In EBCDIC the first example would be
        # $foo = pack("CCCC",193,194,195,196);
        $foo = pack("s2",1,2);
        # "\1\0\2\0" on little-endian
        # "\0\1\0\2" on big-endian
        $foo = pack("a4","abcd","x","y","z");
        # "abcd"
        $foo = pack("aaaa","abcd","x","y","z");
        # "axyz"
        $foo = pack("a14","abcdefg");
        # "abcdefg\0\0\0\0\0\0\0"
        $foo = pack("i9pl", gmtime);
        # a real struct tm (on my system anyway)
        $utmp_template = "Z8 Z8 Z16 L";
        $utmp = pack($utmp_template, @utmp1);
        # a struct utmp (BSDish)
        @utmp2 = unpack($utmp_template, $utmp);
        # "@utmp1" eq "@utmp2"
        sub bintodec {
    	unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
        }
        $foo = pack('sx2l', 12, 34);
        # short 12, two zero bytes padding, long 34
        $bar = pack('s@4l', 12, 34);
        # short 12, zero fill to position 4, long 34
        # $foo eq $bar

    Tas pats šablonas bendrai gali būti naudojamas ir unpack()'ui.

algirdas@perl.lt 2005.04.11 - $dabar