plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }