1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
/*
* Generic traversal routines.
*/
#include "stdinc.h"
#include "dat.h"
#include "fns.h"
static uint
etype(Entry *e)
{
uint t;
if(e->flags&_VtEntryDir)
t = BtDir;
else
t = BtData;
return t+e->depth;
}
void
initWalk(WalkPtr *w, Block *b, uint size)
{
memset(w, 0, sizeof *w);
switch(b->l.type){
case BtData:
return;
case BtDir:
w->data = b->data;
w->m = size / VtEntrySize;
w->isEntry = 1;
return;
default:
w->data = b->data;
w->m = size / VtScoreSize;
w->type = b->l.type;
w->tag = b->l.tag;
return;
}
}
int
nextWalk(WalkPtr *w, uchar score[VtScoreSize], uchar *type, u32int *tag, Entry **e)
{
if(w->n >= w->m)
return 0;
if(w->isEntry){
*e = &w->e;
entryUnpack(&w->e, w->data, w->n);
memmove(score, w->e.score, VtScoreSize);
*type = etype(&w->e);
*tag = w->e.tag;
}else{
*e = nil;
memmove(score, w->data+w->n*VtScoreSize, VtScoreSize);
*type = w->type-1;
*tag = w->tag;
}
w->n++;
return 1;
}
|