plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

pack.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 }