URI:
       tpack.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tpack.c (4729B)
       ---
            1 #include "stdinc.h"
            2 #include "dat.h"
            3 #include "fns.h"
            4 #include "error.h"
            5 
            6 /*
            7  * integer conversion routines
            8  */
            9 #define        U8GET(p)        ((p)[0])
           10 #define        U16GET(p)        (((p)[0]<<8)|(p)[1])
           11 #define        U32GET(p)        (((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3])
           12 #define        U48GET(p)        (((uvlong)U16GET(p)<<32)|(uvlong)U32GET((p)+2))
           13 #define        U64GET(p)        (((uvlong)U32GET(p)<<32)|(uvlong)U32GET((p)+4))
           14 
           15 #define        U8PUT(p,v)        (p)[0]=(v)
           16 #define        U16PUT(p,v)        (p)[0]=(v)>>8;(p)[1]=(v)
           17 #define        U32PUT(p,v)        (p)[0]=((v)>>24)&0xFF;(p)[1]=((v)>>16)&0xFF;(p)[2]=((v)>>8)&0xFF;(p)[3]=(v)&0xFF
           18 #define        U48PUT(p,v,t32)        t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
           19 #define        U64PUT(p,v,t32)        t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
           20 
           21 void
           22 headerPack(Header *h, uchar *p)
           23 {
           24         memset(p, 0, HeaderSize);
           25         U32PUT(p, HeaderMagic);
           26         U16PUT(p+4, HeaderVersion);
           27         U16PUT(p+6, h->blockSize);
           28         U32PUT(p+8, h->super);
           29         U32PUT(p+12, h->label);
           30         U32PUT(p+16, h->data);
           31         U32PUT(p+20, h->end);
           32 }
           33 
           34 int
           35 headerUnpack(Header *h, uchar *p)
           36 {
           37         if(U32GET(p) != HeaderMagic){
           38                 werrstr("vac header bad magic");
           39                 return 0;
           40         }
           41         h->version = U16GET(p+4);
           42         if(h->version != HeaderVersion){
           43                 werrstr("vac header bad version");
           44                 return 0;
           45         }
           46         h->blockSize = U16GET(p+6);
           47         h->super = U32GET(p+8);
           48         h->label = U32GET(p+12);
           49         h->data = U32GET(p+16);
           50         h->end = U32GET(p+20);
           51         return 1;
           52 }
           53 
           54 void
           55 labelPack(Label *l, uchar *p, int i)
           56 {
           57         p += i*LabelSize;
           58         U8PUT(p, l->state);
           59         U8PUT(p+1, l->type);
           60         U32PUT(p+2, l->epoch);
           61         U32PUT(p+6, l->epochClose);
           62         U32PUT(p+10, l->tag);
           63 }
           64 
           65 int
           66 labelUnpack(Label *l, uchar *p, int i)
           67 {
           68         p += i*LabelSize;
           69         l->state = p[0];
           70         l->type = p[1];
           71         l->epoch = U32GET(p+2);
           72         l->epochClose = U32GET(p+6);
           73         l->tag = U32GET(p+10);
           74 
           75         if(l->type > BtMax){
           76 Bad:
           77                 werrstr(EBadLabel);
           78                 fprint(2, "%s: labelUnpack: bad label: 0x%.2ux 0x%.2ux 0x%.8ux "
           79                         "0x%.8ux 0x%.8ux\n", argv0, l->state, l->type, l->epoch,
           80                         l->epochClose, l->tag);
           81                 return 0;
           82         }
           83         if(l->state != BsBad && l->state != BsFree){
           84                 if(!(l->state&BsAlloc) || l->state & ~BsMask)
           85                         goto Bad;
           86                 if(l->state&BsClosed){
           87                         if(l->epochClose == ~(u32int)0)
           88                                 goto Bad;
           89                 }else{
           90                         if(l->epochClose != ~(u32int)0)
           91                                 goto Bad;
           92                 }
           93         }
           94         return 1;
           95 }
           96 
           97 u32int
           98 globalToLocal(uchar score[VtScoreSize])
           99 {
          100         int i;
          101 
          102         for(i=0; i<VtScoreSize-4; i++)
          103                 if(score[i] != 0)
          104                         return NilBlock;
          105 
          106         return U32GET(score+VtScoreSize-4);
          107 }
          108 
          109 void
          110 localToGlobal(u32int addr, uchar score[VtScoreSize])
          111 {
          112         memset(score, 0, VtScoreSize-4);
          113         U32PUT(score+VtScoreSize-4, addr);
          114 }
          115 
          116 void
          117 entryPack(Entry *e, uchar *p, int index)
          118 {
          119         ulong t32;
          120         int flags;
          121 
          122         p += index * VtEntrySize;
          123 
          124         U32PUT(p, e->gen);
          125         U16PUT(p+4, e->psize);
          126         U16PUT(p+6, e->dsize);
          127         flags = e->flags | ((e->depth << _VtEntryDepthShift) & _VtEntryDepthMask);
          128         U8PUT(p+8, flags);
          129         memset(p+9, 0, 5);
          130         U48PUT(p+14, e->size, t32);
          131 
          132         if(flags & VtEntryLocal){
          133                 if(globalToLocal(e->score) == NilBlock)
          134                         abort();
          135                 memset(p+20, 0, 7);
          136                 U8PUT(p+27, e->archive);
          137                 U32PUT(p+28, e->snap);
          138                 U32PUT(p+32, e->tag);
          139                 memmove(p+36, e->score+16, 4);
          140         }else
          141                 memmove(p+20, e->score, VtScoreSize);
          142 }
          143 
          144 int
          145 entryUnpack(Entry *e, uchar *p, int index)
          146 {
          147         p += index * VtEntrySize;
          148 
          149         e->gen = U32GET(p);
          150         e->psize = U16GET(p+4);
          151         e->dsize = U16GET(p+6);
          152         e->flags = U8GET(p+8);
          153         e->depth = (e->flags & _VtEntryDepthMask) >> _VtEntryDepthShift;
          154         e->flags &= ~_VtEntryDepthMask;
          155         e->size = U48GET(p+14);
          156 
          157         if(e->flags & VtEntryLocal){
          158                 e->archive = p[27];
          159                 e->snap = U32GET(p+28);
          160                 e->tag = U32GET(p+32);
          161                 memset(e->score, 0, 16);
          162                 memmove(e->score+16, p+36, 4);
          163         }else{
          164                 e->archive = 0;
          165                 e->snap = 0;
          166                 e->tag = 0;
          167                 memmove(e->score, p+20, VtScoreSize);
          168         }
          169 
          170         return 1;
          171 }
          172 
          173 int
          174 entryType(Entry *e)
          175 {
          176         return (((e->flags & _VtEntryDir) != 0) << 3) | e->depth;
          177 }
          178 
          179 
          180 void
          181 superPack(Super *s, uchar *p)
          182 {
          183         u32int t32;
          184 
          185         memset(p, 0, SuperSize);
          186         U32PUT(p, SuperMagic);
          187         assert(s->version == SuperVersion);
          188         U16PUT(p+4, s->version);
          189         U32PUT(p+6, s->epochLow);
          190         U32PUT(p+10, s->epochHigh);
          191         U64PUT(p+14, s->qid, t32);
          192         U32PUT(p+22, s->active);
          193         U32PUT(p+26, s->next);
          194         U32PUT(p+30, s->current);
          195         memmove(p+34, s->last, VtScoreSize);
          196         memmove(p+54, s->name, sizeof(s->name));
          197 }
          198 
          199 int
          200 superUnpack(Super *s, uchar *p)
          201 {
          202         memset(s, 0, sizeof(*s));
          203         if(U32GET(p) != SuperMagic)
          204                 goto Err;
          205         s->version = U16GET(p+4);
          206         if(s->version != SuperVersion)
          207                 goto Err;
          208         s->epochLow = U32GET(p+6);
          209         s->epochHigh = U32GET(p+10);
          210         s->qid = U64GET(p+14);
          211         if(s->epochLow == 0 || s->epochLow > s->epochHigh || s->qid == 0)
          212                 goto Err;
          213         s->active = U32GET(p+22);
          214         s->next = U32GET(p+26);
          215         s->current = U32GET(p+30);
          216         memmove(s->last, p+34, VtScoreSize);
          217         memmove(s->name, p+54, sizeof(s->name));
          218         s->name[sizeof(s->name)-1] = 0;
          219         return 1;
          220 Err:
          221         memset(s, 0, sizeof(*s));
          222         werrstr(EBadSuper);
          223         return 0;
          224 }