1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "lebo.h"
5 #include "bebo.h"
6 #include "debug.h"
7 #include "chain.h"
8
9 /* functions to deal with bit chains, weird bit orderings an such */
10
11 #define Upper(byte, nbits) ((byte)>>(nbits))
12 #define Lower(byte, nbits) ((bytes)&MSK(nbits))
13 #define IsCut(bbits, ebits) (((ebits)/8 - (bbits)/8) > 0)
14
15 /* 8: H L | 8: Next */
16 /* Put at most 8 bits*/
17 static void
put8bits(Chain * ch,void * p,int nbits)18 put8bits(Chain *ch, void *p, int nbits)
19 {
20 int e, nbye, nbie, nle;
21 uchar low, high, byte;
22
23 byte = *(uchar *)p;
24 e = ch->e+nbits-1; /* offset of last bit to put in */
25 nbie = ch->e%8;
26 nbye = ch->e/8;
27 nle = 8 - nbie;
28
29
30 if(IsCut(ch->e, e))
31 ch->buf[nbye + 1] = byte >> nle;
32
33 high = (byte & MSK(nle)) << nbie;
34 low = ch->buf[nbye]&MSK(nbie);
35
36
37 ch->buf[nbye] = low|high;
38 ch->e += nbits;
39 }
40
41 /* Get at most 8 bits*/
42 static uchar
get8bits(Chain * ch,int nbits)43 get8bits(Chain *ch, int nbits)
44 {
45 int b, nbyb, nbib, nlb;
46 uchar low, high, res;
47
48 b = ch->b+nbits-1;
49 nbib = ch->b % 8;
50 nbyb = ch->b / 8;
51 nlb = 8 - nbib;
52 if(nlb > nbits)
53 nlb = nbits;
54
55 low = MSK(nlb) & (ch->buf[nbyb] >> nbib);
56 if(IsCut(ch->b, b))
57 high = (ch->buf[nbyb + 1] & MSK(nbib)) << nlb;
58 else
59 high = 0;
60 res = MSK(nbits)&(high | low);
61 ch->b += nbits;
62 return res;
63 }
64
65 /*
66 * Putbits and getbits could be made more efficient
67 * simply by using memmove in the special case where
68 * a bunch of bytes is aligned, but I don't care.
69 * Packing in words would also help the so inclined.
70 */
71 void
putbits(Chain * ch,void * p,int nbits)72 putbits(Chain *ch, void *p, int nbits)
73 {
74 int nby, nbi, i;
75 uchar *vp;
76
77 vp = p;
78 nby = nbits / 8;
79 nbi = nbits % 8;
80
81 for(i = 0; i < nby; i++)
82 put8bits(ch, vp++, 8);
83
84 if(nbi != 0)
85 put8bits(ch, vp, nbi);
86 }
87
88 void
getbits(void * p,Chain * ch,int nbits)89 getbits(void *p, Chain *ch, int nbits)
90 {
91 int nby, nbi, i;
92 uchar *vp;
93
94 assert(ch->e >= ch->b);
95 nby = nbits / 8;
96 nbi = nbits % 8;
97
98 vp = p;
99 for(i = 0; i < nby; i++)
100 *vp++ = get8bits(ch, 8);
101
102 if(nbi != 0)
103 *vp = get8bits(ch, nbi);
104 }
105
106 static void
revbych(Chain * ch)107 revbych(Chain *ch)
108 {
109 int i, nb;
110
111 nb = (ch->e-ch->b+7)/8;
112
113 for(i = 0; i < nb; i++)
114 ch->buf[i] = rtab[ch->buf[i]];
115 }
116
117 void
printchain(Chain * ch)118 printchain(Chain *ch)
119 {
120 int i, ng, nb;
121 uchar msk, c;
122 Chain *ch2;
123
124 fprint(2, "chain buf:%#p b:%d e:%d\n", ch->buf, ch->b, ch->e);
125 ch2 = malloc(sizeof(Chain));
126 if(ch2 == nil)
127 sysfatal("no memory");
128 memmove(ch2, ch, sizeof(Chain));
129
130
131 ng = 8;
132 nb = (ch2->e-ch2->b+7)/8;
133
134 for(i = 0; i < nb; i++){
135 if(ch2->e - ch2->b < ng)
136 ng = ch2->e - ch2->b;
137 getbits(&c, ch2, ng);
138 if(i != 0 && i%15 == 0)
139 fprint(2, "\n");
140 if(ng < 8){
141 msk = MSK(ng);
142 fprint(2, "%#2.2x ", c&msk);
143 }
144 else
145 fprint(2, "%#2.2x ", c);
146
147 }
148 if(i%16 != 0)
149 fprint(2, "\n");
150
151 free(ch2);
152 }
153
154 /* Good for debugging */
155 static void
printchslice(Chain * ch,int b,int e)156 printchslice(Chain *ch, int b, int e)
157 {
158 Chain *ch2;
159
160 fprint(2, "Slice [%d, %d], b:%d e:%d\n", b, e, ch->b, ch->e);
161 ch2 = malloc(sizeof(Chain));
162 if(ch2 == nil)
163 sysfatal("memory");
164 memmove(ch2, ch, sizeof(Chain));
165 if(b > e){
166 fprint(2, "bad args in region\n");
167 return;
168 }
169 if(b < ch2->b || b > ch2->e || e > ch2-> e || e < ch2->b){
170 fprint(2, "bad region\n");
171 return;
172 }
173 ch2->b = b;
174 ch2->e = e;
175
176 fprint(2, "Slice - ");
177 printchain(ch2);
178 free(ch2);
179 }
180
181
182 static u32int
revbytes(u32int * v)183 revbytes(u32int *v)
184 {
185 u32int rv;
186 uchar *a, *b;
187
188 a = (uchar *)v;
189 b = (uchar *)&rv;
190
191 b[3] = rtab[a[3]];
192 b[2] = rtab[a[2]];
193 b[1] = rtab[a[1]];
194 b[0] = rtab[a[0]];
195
196 return rv;
197 }
198
199 u32int
hmsbputl(u32int * v)200 hmsbputl(u32int *v)
201 {
202 u32int rv, bev;
203
204 hbeputl(&bev, *v);
205 rv = revbytes(&bev);
206
207 return rv;
208 }
209
210 u32int
msbhgetl(u32int * v)211 msbhgetl(u32int *v)
212 {
213 u32int rv, rev;
214
215 rev = revbytes(v);
216 rv = lehgetl(&rev);
217 return rv;
218 }
219
220