changelog shortlog tags branches changeset file revisions annotate raw help

Mercurial > hg > ventivac / appl/lib/venti.b

revision 127: 7f377ffc9ad3
parent 118: bd3834e3d91a
child 128: 42396bd501da
     1.1--- a/appl/lib/venti.b	Mon Aug 20 13:08:21 2007 +0200
     1.2+++ b/appl/lib/venti.b	Mon Aug 20 13:51:43 2007 +0200
     1.3@@ -8,6 +8,7 @@
     1.4 BIT16SZ:	con 2;
     1.5 BIT32SZ:	con 4;
     1.6 BIT48SZ:	con 6;
     1.7+BIT64SZ:	con 8;
     1.8 SCORE:	con 20;
     1.9 STR:		con BIT16SZ;
    1.10 H: con BIT16SZ+BIT8SZ+BIT8SZ;		# minimum header length: size[2] op[1] tid[1]
    1.11@@ -473,6 +474,123 @@
    1.12 	return s;
    1.13 }
    1.14 
    1.15+
    1.16+Root.new(name, rtype: string, score: Score, blocksize: int, prev: ref Score): ref Root
    1.17+{
    1.18+	return ref Root(Rootversion, name, rtype, score, blocksize, prev);
    1.19+}
    1.20+
    1.21+Root.pack(r: self ref Root): array of byte
    1.22+{
    1.23+	d := array[Rootsize] of byte;
    1.24+	i := 0;
    1.25+	i = p16(d, i, r.version);
    1.26+	i = ptstring(d, i, r.name, Rootnamelen);
    1.27+	if(i < 0)
    1.28+		return nil;
    1.29+	i = ptstring(d, i, r.rtype, Rootnamelen);
    1.30+	if(i < 0)
    1.31+		return nil;
    1.32+	i = pscore(d, i, r.score);
    1.33+	i = p16(d, i, r.blocksize);
    1.34+	if(r.prev == nil) {
    1.35+		for(j := 0; j < Scoresize; j++)
    1.36+			d[i+j] = byte 0;
    1.37+		i += Scoresize;
    1.38+	} else 
    1.39+		i = pscore(d, i, *r.prev);
    1.40+	if(i != len d) {
    1.41+		sys->werrstr("root pack, bad length: "+string i);
    1.42+		return nil;
    1.43+	}
    1.44+	return d;
    1.45+}
    1.46+
    1.47+Root.unpack(d: array of byte): ref Root
    1.48+{
    1.49+	if(len d != Rootsize){
    1.50+		sys->werrstr("root entry is wrong length");
    1.51+		return nil;
    1.52+	}
    1.53+	r := ref blankroot;
    1.54+	r.version = g16(d, 0);
    1.55+	if(r.version != Rootversion && r.version != Rootversionvar){
    1.56+		sys->werrstr("unknown root version");
    1.57+		return nil;
    1.58+	}
    1.59+	o := BIT16SZ;
    1.60+	r.name = gtstring(d, o, Rootnamelen);
    1.61+	o += Rootnamelen;
    1.62+	r.rtype = gtstring(d, o, Rootnamelen);
    1.63+	o += Rootnamelen;
    1.64+	r.score = gscore(d, o);
    1.65+	o += Scoresize;
    1.66+	r.blocksize = g16(d, o);
    1.67+	o += BIT16SZ;
    1.68+	r.prev = ref gscore(d, o);
    1.69+	return r;
    1.70+}
    1.71+
    1.72+
    1.73+Entry.new(psize, dsize, flags: int, size: big, score: Venti->Score): ref Entry
    1.74+{
    1.75+	return ref Entry(0, psize, dsize, (flags&Entrydepthmask)>>Entrydepthshift, flags, size, score);
    1.76+}
    1.77+
    1.78+Entry.pack(e: self ref Entry): array of byte
    1.79+{
    1.80+	d := array[Entrysize] of byte;
    1.81+	i := 0;
    1.82+	i = p32(d, i, e.gen);
    1.83+	i = p16(d, i, e.psize);
    1.84+	i = p16(d, i, e.dsize);
    1.85+	e.flags |= e.depth<<Entrydepthshift;
    1.86+	d[i++] = byte e.flags;
    1.87+	for(j := 0; j < 5; j++)
    1.88+		d[i++] = byte 0;
    1.89+	i = p48(d, i, e.size);
    1.90+	i = pscore(d, i, e.score);
    1.91+	if(i != len d) {
    1.92+		sys->werrstr(sys->sprint("bad length, have %d, want %d", i, len d));
    1.93+		return nil;
    1.94+	}
    1.95+	return d;
    1.96+}
    1.97+
    1.98+Entry.unpack(d: array of byte): ref Entry
    1.99+{
   1.100+	if(len d != Entrysize){
   1.101+		sys->werrstr("entry is wrong length");
   1.102+		return nil;
   1.103+	}
   1.104+	e := ref blankentry;
   1.105+	i := 0;
   1.106+	e.gen = g32(d, i);
   1.107+	i += BIT32SZ;
   1.108+	e.psize = g16(d, i);
   1.109+	i += BIT16SZ;
   1.110+	e.dsize = g16(d, i);
   1.111+	i += BIT16SZ;
   1.112+	e.flags = int d[i];
   1.113+	e.depth = (e.flags & Entrydepthmask) >> Entrydepthshift;
   1.114+	e.flags &= ~Entrydepthmask;
   1.115+	i += BIT8SZ;
   1.116+	i += 5;			# padding
   1.117+	e.size = g48(d, i);
   1.118+	i += BIT48SZ;
   1.119+	e.score = gscore(d, i);
   1.120+	i += Scoresize;
   1.121+	if((e.flags & Entryactive) == 0)
   1.122+		return e;
   1.123+	varblocks := e.flags&Entryvarblocks;
   1.124+	if(!checksize(e.psize) || (varblocks && e.dsize != 0 || !varblocks && !checksize(e.dsize))){
   1.125+		sys->werrstr(sys->sprint("bad blocksize (%d or %d)", e.psize, e.dsize));
   1.126+		return nil;
   1.127+	}
   1.128+	return e;
   1.129+}
   1.130+
   1.131+
   1.132 readn(fd: ref Sys->FD, buf: array of byte, nb: int): int
   1.133 {
   1.134 	for(nr := 0; nr < nb;){
   1.135@@ -555,3 +673,90 @@
   1.136 		}
   1.137 	return n;
   1.138 }
   1.139+
   1.140+checksize(n: int): int
   1.141+{
   1.142+	if(n < 256 || n > Venti->Maxlumpsize) {
   1.143+		sys->werrstr("bad block size");
   1.144+		return 0;
   1.145+	}
   1.146+	return 1;
   1.147+}
   1.148+
   1.149+gtstring(a: array of byte, o: int, n: int): string
   1.150+{
   1.151+	e := o + n;
   1.152+	if(e > len a)
   1.153+		return nil;
   1.154+	for(i := o; i < e; i++)
   1.155+		if(a[i] == byte 0)
   1.156+			break;
   1.157+	return string a[o:i];
   1.158+}
   1.159+
   1.160+gscore(f: array of byte, i: int): Score
   1.161+{
   1.162+	s := Score(array[Scoresize] of byte);
   1.163+	s.a[0:] = f[i:i+Scoresize];
   1.164+	return s;
   1.165+}
   1.166+
   1.167+g16(f: array of byte, i: int): int
   1.168+{
   1.169+	return (int f[i] << 8) | int f[i+1];
   1.170+}
   1.171+
   1.172+g32(f: array of byte, i: int): int
   1.173+{
   1.174+	return (((((int f[i+0] << 8) | int f[i+1]) << 8) | int f[i+2]) << 8) | int f[i+3];
   1.175+}
   1.176+
   1.177+g48(f: array of byte, i: int): big
   1.178+{
   1.179+	b1 := (((((int f[i+0] << 8) | int f[i+1]) << 8) | int f[i+2]) << 8) | int f[i+3];
   1.180+	b0 := (int f[i+4] << 8) | int f[i+5];
   1.181+	return (big b1 << 16) | big b0;
   1.182+}
   1.183+
   1.184+p16(d: array of byte, i: int, v: int): int
   1.185+{
   1.186+	d[i+0] = byte (v>>8);
   1.187+	d[i+1] = byte v;
   1.188+	return i+BIT16SZ;
   1.189+}
   1.190+
   1.191+p32(d: array of byte, i: int, v: int): int
   1.192+{
   1.193+	p16(d, i+0, v>>16);
   1.194+	p16(d, i+2, v);
   1.195+	return i+BIT32SZ;
   1.196+}
   1.197+
   1.198+p48(d: array of byte, i: int, v: big): int
   1.199+{
   1.200+	p16(d, i+0, int (v>>32));
   1.201+	p32(d, i+2, int v);
   1.202+	return i+BIT48SZ;
   1.203+}
   1.204+
   1.205+ptstring(d: array of byte, i: int, s: string, l: int): int
   1.206+{
   1.207+	a := array of byte s;
   1.208+	if(len a > l) {
   1.209+		sys->werrstr("string too long: "+s);
   1.210+		return -1;
   1.211+	}
   1.212+	for(j := 0; j < len a; j++)
   1.213+		d[i+j] = a[j];
   1.214+	while(j < l)
   1.215+		d[i+j++] = byte 0;
   1.216+	return i+l;
   1.217+}
   1.218+
   1.219+pscore(d: array of byte, i: int, s: Score): int
   1.220+{
   1.221+	for(j := 0; j < Scoresize; j++)
   1.222+		d[i+j] = s.a[j];
   1.223+	return i+Scoresize;
   1.224+}
   1.225+