Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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