xref: /plan9/sys/src/liboventi/pack.c (revision 368c31ab13393dea083228fdd1c3445076f83a4b)
1*368c31abSDavid du Colombier #include <u.h>
2*368c31abSDavid du Colombier #include <libc.h>
3*368c31abSDavid du Colombier #include <oventi.h>
4*368c31abSDavid du Colombier 
5*368c31abSDavid du Colombier /*
6*368c31abSDavid du Colombier  * integer conversion routines
7*368c31abSDavid du Colombier  */
8*368c31abSDavid du Colombier #define	U8GET(p)	((p)[0])
9*368c31abSDavid du Colombier #define	U16GET(p)	(((p)[0]<<8)|(p)[1])
10*368c31abSDavid du Colombier #define	U32GET(p)	((u32int)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
11*368c31abSDavid du Colombier #define	U48GET(p)	(((vlong)U16GET(p)<<32)|(vlong)U32GET((p)+2))
12*368c31abSDavid du Colombier #define	U64GET(p)	(((vlong)U32GET(p)<<32)|(vlong)U32GET((p)+4))
13*368c31abSDavid du Colombier 
14*368c31abSDavid du Colombier #define	U8PUT(p,v)	(p)[0]=(v)
15*368c31abSDavid du Colombier #define	U16PUT(p,v)	(p)[0]=(v)>>8;(p)[1]=(v)
16*368c31abSDavid du Colombier #define	U32PUT(p,v)	(p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v)
17*368c31abSDavid du Colombier #define	U48PUT(p,v,t32)	t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
18*368c31abSDavid du Colombier #define	U64PUT(p,v,t32)	t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
19*368c31abSDavid du Colombier 
20*368c31abSDavid du Colombier static int
checkSize(int n)21*368c31abSDavid du Colombier checkSize(int n)
22*368c31abSDavid du Colombier {
23*368c31abSDavid du Colombier 	if(n < 256 || n > VtMaxLumpSize) {
24*368c31abSDavid du Colombier 		vtSetError("bad block size");
25*368c31abSDavid du Colombier 		return 0;
26*368c31abSDavid du Colombier 	}
27*368c31abSDavid du Colombier 	return 1;
28*368c31abSDavid du Colombier }
29*368c31abSDavid du Colombier 
30*368c31abSDavid du Colombier 
31*368c31abSDavid du Colombier void
vtRootPack(VtRoot * r,uchar * p)32*368c31abSDavid du Colombier vtRootPack(VtRoot *r, uchar *p)
33*368c31abSDavid du Colombier {
34*368c31abSDavid du Colombier 	uchar *op = p;
35*368c31abSDavid du Colombier 
36*368c31abSDavid du Colombier 	U16PUT(p, r->version);
37*368c31abSDavid du Colombier 	p += 2;
38*368c31abSDavid du Colombier 	memmove(p, r->name, sizeof(r->name));
39*368c31abSDavid du Colombier 	p += sizeof(r->name);
40*368c31abSDavid du Colombier 	memmove(p, r->type, sizeof(r->type));
41*368c31abSDavid du Colombier 	p += sizeof(r->type);
42*368c31abSDavid du Colombier 	memmove(p, r->score, VtScoreSize);
43*368c31abSDavid du Colombier 	p +=  VtScoreSize;
44*368c31abSDavid du Colombier 	U16PUT(p, r->blockSize);
45*368c31abSDavid du Colombier 	p += 2;
46*368c31abSDavid du Colombier 	memmove(p, r->prev, VtScoreSize);
47*368c31abSDavid du Colombier 	p += VtScoreSize;
48*368c31abSDavid du Colombier 
49*368c31abSDavid du Colombier 	assert(p-op == VtRootSize);
50*368c31abSDavid du Colombier }
51*368c31abSDavid du Colombier 
52*368c31abSDavid du Colombier int
vtRootUnpack(VtRoot * r,uchar * p)53*368c31abSDavid du Colombier vtRootUnpack(VtRoot *r, uchar *p)
54*368c31abSDavid du Colombier {
55*368c31abSDavid du Colombier 	uchar *op = p;
56*368c31abSDavid du Colombier 
57*368c31abSDavid du Colombier 	memset(r, 0, sizeof(*r));
58*368c31abSDavid du Colombier 
59*368c31abSDavid du Colombier 	r->version = U16GET(p);
60*368c31abSDavid du Colombier 	if(r->version != VtRootVersion) {
61*368c31abSDavid du Colombier 		vtSetError("unknown root version");
62*368c31abSDavid du Colombier 		return 0;
63*368c31abSDavid du Colombier 	}
64*368c31abSDavid du Colombier 	p += 2;
65*368c31abSDavid du Colombier 	memmove(r->name, p, sizeof(r->name));
66*368c31abSDavid du Colombier 	r->name[sizeof(r->name)-1] = 0;
67*368c31abSDavid du Colombier 	p += sizeof(r->name);
68*368c31abSDavid du Colombier 	memmove(r->type, p, sizeof(r->type));
69*368c31abSDavid du Colombier 	r->type[sizeof(r->type)-1] = 0;
70*368c31abSDavid du Colombier 	p += sizeof(r->type);
71*368c31abSDavid du Colombier 	memmove(r->score, p, VtScoreSize);
72*368c31abSDavid du Colombier 	p +=  VtScoreSize;
73*368c31abSDavid du Colombier 	r->blockSize = U16GET(p);
74*368c31abSDavid du Colombier 	if(!checkSize(r->blockSize))
75*368c31abSDavid du Colombier 		return 0;
76*368c31abSDavid du Colombier 	p += 2;
77*368c31abSDavid du Colombier 	memmove(r->prev, p, VtScoreSize);
78*368c31abSDavid du Colombier 	p += VtScoreSize;
79*368c31abSDavid du Colombier 
80*368c31abSDavid du Colombier 	assert(p-op == VtRootSize);
81*368c31abSDavid du Colombier 	return 1;
82*368c31abSDavid du Colombier }
83*368c31abSDavid du Colombier 
84*368c31abSDavid du Colombier void
vtEntryPack(VtEntry * e,uchar * p,int index)85*368c31abSDavid du Colombier vtEntryPack(VtEntry *e, uchar *p, int index)
86*368c31abSDavid du Colombier {
87*368c31abSDavid du Colombier 	ulong t32;
88*368c31abSDavid du Colombier 	int flags;
89*368c31abSDavid du Colombier 	uchar *op;
90*368c31abSDavid du Colombier 
91*368c31abSDavid du Colombier 	p += index * VtEntrySize;
92*368c31abSDavid du Colombier 	op = p;
93*368c31abSDavid du Colombier 
94*368c31abSDavid du Colombier 	U32PUT(p, e->gen);
95*368c31abSDavid du Colombier 	p += 4;
96*368c31abSDavid du Colombier 	U16PUT(p, e->psize);
97*368c31abSDavid du Colombier 	p += 2;
98*368c31abSDavid du Colombier 	U16PUT(p, e->dsize);
99*368c31abSDavid du Colombier 	p += 2;
100*368c31abSDavid du Colombier 	flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask);
101*368c31abSDavid du Colombier 	U8PUT(p, flags);
102*368c31abSDavid du Colombier 	p++;
103*368c31abSDavid du Colombier 	memset(p, 0, 5);
104*368c31abSDavid du Colombier 	p += 5;
105*368c31abSDavid du Colombier 	U48PUT(p, e->size, t32);
106*368c31abSDavid du Colombier 	p += 6;
107*368c31abSDavid du Colombier 	memmove(p, e->score, VtScoreSize);
108*368c31abSDavid du Colombier 	p += VtScoreSize;
109*368c31abSDavid du Colombier 
110*368c31abSDavid du Colombier 	assert(p-op == VtEntrySize);
111*368c31abSDavid du Colombier }
112*368c31abSDavid du Colombier 
113*368c31abSDavid du Colombier int
vtEntryUnpack(VtEntry * e,uchar * p,int index)114*368c31abSDavid du Colombier vtEntryUnpack(VtEntry *e, uchar *p, int index)
115*368c31abSDavid du Colombier {
116*368c31abSDavid du Colombier 	uchar *op;
117*368c31abSDavid du Colombier 
118*368c31abSDavid du Colombier 	p += index * VtEntrySize;
119*368c31abSDavid du Colombier 	op = p;
120*368c31abSDavid du Colombier 
121*368c31abSDavid du Colombier 	e->gen = U32GET(p);
122*368c31abSDavid du Colombier 	p += 4;
123*368c31abSDavid du Colombier 	e->psize = U16GET(p);
124*368c31abSDavid du Colombier 	p += 2;
125*368c31abSDavid du Colombier 	e->dsize = U16GET(p);
126*368c31abSDavid du Colombier 	p += 2;
127*368c31abSDavid du Colombier 	e->flags = U8GET(p);
128*368c31abSDavid du Colombier 	e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift;
129*368c31abSDavid du Colombier 	e->flags &= ~VtEntryDepthMask;
130*368c31abSDavid du Colombier 	p++;
131*368c31abSDavid du Colombier 	p += 5;
132*368c31abSDavid du Colombier 	e->size = U48GET(p);
133*368c31abSDavid du Colombier 	p += 6;
134*368c31abSDavid du Colombier 	memmove(e->score, p, VtScoreSize);
135*368c31abSDavid du Colombier 	p += VtScoreSize;
136*368c31abSDavid du Colombier 
137*368c31abSDavid du Colombier 	assert(p-op == VtEntrySize);
138*368c31abSDavid du Colombier 
139*368c31abSDavid du Colombier 	if(!(e->flags & VtEntryActive))
140*368c31abSDavid du Colombier 		return 1;
141*368c31abSDavid du Colombier 
142*368c31abSDavid du Colombier 	if(!checkSize(e->psize) || !checkSize(e->dsize))
143*368c31abSDavid du Colombier 		return 0;
144*368c31abSDavid du Colombier 
145*368c31abSDavid du Colombier 	return 1;
146*368c31abSDavid du Colombier }
147*368c31abSDavid du Colombier 
148