conform.c (2450B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <libsec.h> 5 #include <ctype.h> 6 #include "iso9660.h" 7 8 /* 9 * We keep an array sorted by bad atom pointer. 10 * The theory is that since we don't free memory very often, 11 * the array will be mostly sorted already and insertions will 12 * usually be near the end, so we won't spend much time 13 * keeping it sorted. 14 */ 15 16 /* 17 * Binary search a Tx list. 18 * If no entry is found, return a pointer to 19 * where a new such entry would go. 20 */ 21 static Tx* 22 txsearch(char *atom, Tx *t, int n) 23 { 24 while(n > 0) { 25 if(atom < t[n/2].bad) 26 n = n/2; 27 else if(atom > t[n/2].bad) { 28 t += n/2+1; 29 n -= (n/2+1); 30 } else 31 return &t[n/2]; 32 } 33 return t; 34 } 35 36 void 37 addtx(char *b, char *g) 38 { 39 Tx *t; 40 Conform *c; 41 42 if(map == nil) 43 map = emalloc(sizeof(*map)); 44 c = map; 45 46 if(c->nt%32 == 0) 47 c->t = erealloc(c->t, (c->nt+32)*sizeof(c->t[0])); 48 t = txsearch(b, c->t, c->nt); 49 if(t < c->t+c->nt && t->bad == b) { 50 fprint(2, "warning: duplicate entry for %s in _conform.map\n", b); 51 return; 52 } 53 54 if(t != c->t+c->nt) 55 memmove(t+1, t, (c->t+c->nt - t)*sizeof(Tx)); 56 t->bad = b; 57 t->good = g; 58 c->nt++; 59 } 60 61 char* 62 conform(char *s, int isdir) 63 { 64 Tx *t; 65 char buf[10], *g; 66 Conform *c; 67 68 c = map; 69 s = atom(s); 70 if(c){ 71 t = txsearch(s, c->t, c->nt); 72 if(t < c->t+c->nt && t->bad == s) 73 return t->good; 74 } 75 76 sprint(buf, "%c%.6d", isdir ? 'D' : 'F', c ? c->nt : 0); 77 g = atom(buf); 78 addtx(s, g); 79 return g; 80 } 81 82 #ifdef NOTUSED 83 static int 84 isalldigit(char *s) 85 { 86 while(*s) 87 if(!isdigit(*s++)) 88 return 0; 89 return 1; 90 } 91 #endif 92 93 static int 94 goodcmp(const void *va, const void *vb) 95 { 96 Tx *a, *b; 97 98 a = (Tx*)va; 99 b = (Tx*)vb; 100 return strcmp(a->good, b->good); 101 } 102 103 static int 104 badatomcmp(const void *va, const void *vb) 105 { 106 Tx *a, *b; 107 108 a = (Tx*)va; 109 b = (Tx*)vb; 110 if(a->good < b->good) 111 return -1; 112 if(a->good > b->good) 113 return 1; 114 return 0; 115 } 116 117 void 118 wrconform(Cdimg *cd, int n, ulong *pblock, ulong *plength) 119 { 120 char buf[1024]; 121 int i; 122 Conform *c; 123 124 c = map; 125 *pblock = cd->nextblock; 126 if(c==nil || n==c->nt){ 127 *plength = 0; 128 return; 129 } 130 131 Cwseek(cd, cd->nextblock*Blocksize); 132 qsort(c->t, c->nt, sizeof(c->t[0]), goodcmp); 133 for(i=n; i<c->nt; i++) { 134 snprint(buf, sizeof buf, "%s %s\n", c->t[i].good, c->t[i].bad); 135 Cwrite(cd, buf, strlen(buf)); 136 } 137 qsort(c->t, c->nt, sizeof(c->t[0]), badatomcmp); 138 *plength = Cwoffset(cd) - *pblock*Blocksize; 139 chat("write _conform.map at %lud+%lud\n", *pblock, *plength); 140 Cpadblock(cd); 141 }