From 6f4d00ee45693290fae042b27536b54f77b96acd Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 23 Sep 2013 23:00:39 +0200 Subject: fossil: import from plan 9 R=rsc https://codereview.appspot.com/7988047 --- src/cmd/fossil/pack.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 src/cmd/fossil/pack.c (limited to 'src/cmd/fossil/pack.c') diff --git a/src/cmd/fossil/pack.c b/src/cmd/fossil/pack.c new file mode 100644 index 00000000..9fd2070c --- /dev/null +++ b/src/cmd/fossil/pack.c @@ -0,0 +1,225 @@ +#include "stdinc.h" +#include "dat.h" +#include "fns.h" +#include "error.h" + +/* + * integer conversion routines + */ +#define U8GET(p) ((p)[0]) +#define U16GET(p) (((p)[0]<<8)|(p)[1]) +#define U32GET(p) (((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]) +#define U48GET(p) (((uvlong)U16GET(p)<<32)|(uvlong)U32GET((p)+2)) +#define U64GET(p) (((uvlong)U32GET(p)<<32)|(uvlong)U32GET((p)+4)) + +#define U8PUT(p,v) (p)[0]=(v) +#define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v) +#define U32PUT(p,v) (p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v) +#define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32) +#define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32) + +void +headerPack(Header *h, uchar *p) +{ + memset(p, 0, HeaderSize); + U32PUT(p, HeaderMagic); + U16PUT(p+4, HeaderVersion); + U16PUT(p+6, h->blockSize); + U32PUT(p+8, h->super); + U32PUT(p+12, h->label); + U32PUT(p+16, h->data); + U32PUT(p+20, h->end); +} + +int +headerUnpack(Header *h, uchar *p) +{ + if(U32GET(p) != HeaderMagic){ + vtSetError("vac header bad magic"); + return 0; + } + h->version = U16GET(p+4); + if(h->version != HeaderVersion){ + vtSetError("vac header bad version"); + return 0; + } + h->blockSize = U16GET(p+6); + h->super = U32GET(p+8); + h->label = U32GET(p+12); + h->data = U32GET(p+16); + h->end = U32GET(p+20); + return 1; +} + +void +labelPack(Label *l, uchar *p, int i) +{ + p += i*LabelSize; + U8PUT(p, l->state); + U8PUT(p+1, l->type); + U32PUT(p+2, l->epoch); + U32PUT(p+6, l->epochClose); + U32PUT(p+10, l->tag); +} + +int +labelUnpack(Label *l, uchar *p, int i) +{ + p += i*LabelSize; + l->state = p[0]; + l->type = p[1]; + l->epoch = U32GET(p+2); + l->epochClose = U32GET(p+6); + l->tag = U32GET(p+10); + + if(l->type > BtMax){ +Bad: + vtSetError(EBadLabel); + fprint(2, "%s: labelUnpack: bad label: 0x%.2ux 0x%.2ux 0x%.8ux " + "0x%.8ux 0x%.8ux\n", argv0, l->state, l->type, l->epoch, + l->epochClose, l->tag); + return 0; + } + if(l->state != BsBad && l->state != BsFree){ + if(!(l->state&BsAlloc) || l->state & ~BsMask) + goto Bad; + if(l->state&BsClosed){ + if(l->epochClose == ~(u32int)0) + goto Bad; + }else{ + if(l->epochClose != ~(u32int)0) + goto Bad; + } + } + return 1; +} + +u32int +globalToLocal(uchar score[VtScoreSize]) +{ + int i; + + for(i=0; igen); + U16PUT(p+4, e->psize); + U16PUT(p+6, e->dsize); + flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask); + U8PUT(p+8, flags); + memset(p+9, 0, 5); + U48PUT(p+14, e->size, t32); + + if(flags & VtEntryLocal){ + if(globalToLocal(e->score) == NilBlock) + abort(); + memset(p+20, 0, 7); + U8PUT(p+27, e->archive); + U32PUT(p+28, e->snap); + U32PUT(p+32, e->tag); + memmove(p+36, e->score+16, 4); + }else + memmove(p+20, e->score, VtScoreSize); +} + +int +entryUnpack(Entry *e, uchar *p, int index) +{ + p += index * VtEntrySize; + + e->gen = U32GET(p); + e->psize = U16GET(p+4); + e->dsize = U16GET(p+6); + e->flags = U8GET(p+8); + e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift; + e->flags &= ~VtEntryDepthMask; + e->size = U48GET(p+14); + + if(e->flags & VtEntryLocal){ + e->archive = p[27]; + e->snap = U32GET(p+28); + e->tag = U32GET(p+32); + memset(e->score, 0, 16); + memmove(e->score+16, p+36, 4); + }else{ + e->archive = 0; + e->snap = 0; + e->tag = 0; + memmove(e->score, p+20, VtScoreSize); + } + + return 1; +} + +int +entryType(Entry *e) +{ + return (((e->flags & VtEntryDir) != 0) << 3) | e->depth; +} + + +void +superPack(Super *s, uchar *p) +{ + u32int t32; + + memset(p, 0, SuperSize); + U32PUT(p, SuperMagic); + assert(s->version == SuperVersion); + U16PUT(p+4, s->version); + U32PUT(p+6, s->epochLow); + U32PUT(p+10, s->epochHigh); + U64PUT(p+14, s->qid, t32); + U32PUT(p+22, s->active); + U32PUT(p+26, s->next); + U32PUT(p+30, s->current); + memmove(p+34, s->last, VtScoreSize); + memmove(p+54, s->name, sizeof(s->name)); +} + +int +superUnpack(Super *s, uchar *p) +{ + memset(s, 0, sizeof(*s)); + if(U32GET(p) != SuperMagic) + goto Err; + s->version = U16GET(p+4); + if(s->version != SuperVersion) + goto Err; + s->epochLow = U32GET(p+6); + s->epochHigh = U32GET(p+10); + s->qid = U64GET(p+14); + if(s->epochLow == 0 || s->epochLow > s->epochHigh || s->qid == 0) + goto Err; + s->active = U32GET(p+22); + s->next = U32GET(p+26); + s->current = U32GET(p+30); + memmove(s->last, p+34, VtScoreSize); + memmove(s->name, p+54, sizeof(s->name)); + s->name[sizeof(s->name)-1] = 0; + return 1; +Err: + memset(s, 0, sizeof(*s)); + vtSetError(EBadSuper); + return 0; +} + -- cgit v1.2.3