00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00109 #include <stdlib.h>
00110 #include <stdio.h>
00111 #include <assert.h>
00112 #include <memory.h>
00113 #include "desc.h"
00114 #include "bufr.h"
00115 #include "bitio.h"
00116
00117
00118
00119
00120
00121
00122
00123 #define MAXIOSTR 10
00124
00125 #define INCSIZE 1000
00126
00127
00128
00129
00130
00131
00132
00133
00134 typedef struct bitio_stream {
00135 int used;
00136 char *buf;
00137 long nbits;
00138
00139 size_t size;
00140
00141 } bitio_stream;
00142
00143 bitio_stream bios[MAXIOSTR];
00144 int first = 1;
00145
00146
00162 int bitio_i_open (void* buf, size_t size)
00163 {
00164 int i, handle;
00165
00166
00167
00168 if (first) {
00169 for (i = 0; i < MAXIOSTR; i ++) bios[i].used = 0;
00170 first = 0;
00171 }
00172
00173
00174
00175 for (handle = 0; handle < MAXIOSTR; handle ++) {
00176 if (!bios[handle].used) goto found;
00177 }
00178 return -1;
00179
00180
00181
00182 found:
00183 bios[handle].used = 1;
00184 bios[handle].buf = (char *) buf;
00185 bios[handle].size = size;
00186 bios[handle].nbits = 0;
00187 return handle;
00188 }
00189
00190
00207 int bitio_i_input (int handle, unsigned long* val, int nbits)
00208 {
00209 int i, bit;
00210 size_t byte;
00211 unsigned long l, bitval;
00212 char *pc;
00213
00214
00215 l = 0;
00216 for (i = nbits - 1; i >= 0; i --) {
00217
00218
00219
00220
00221 byte = (int) (bios[handle].nbits / 8);
00222 bit = (int) (bios[handle].nbits % 8);
00223 bit = 7 - bit;
00224 if (byte >= bios[handle].size) return 1;
00225
00226
00227
00228 pc = bios[handle].buf + byte;
00229 bitval = (unsigned long) ((*pc >> bit) & 1);
00230
00231
00232
00233
00234 if (bitval) {
00235 l |= (bitval << i);
00236 }
00237 bios[handle].nbits ++;
00238 }
00239 *val = l;
00240 return 1;
00241 }
00242
00243
00254 void bitio_i_close (int handle)
00255
00256 {
00257 bios[handle].used = 0;
00258 }
00259
00260
00271 int bitio_o_open ()
00272
00273 {
00274 int i, handle;
00275
00276
00277
00278 if (first) {
00279 for (i = 0; i < MAXIOSTR; i ++) bios[i].used = 0;
00280 first = 0;
00281 }
00282
00283
00284
00285 for (handle = 0; handle < MAXIOSTR; handle ++) {
00286 if (!bios[handle].used) goto found;
00287 }
00288 return -1;
00289
00290
00291
00292 found:
00293 bios[handle].buf = (char *) malloc (INCSIZE);
00294 if (bios[handle].buf == NULL) return -1;
00295 memset (bios[handle].buf, 0, INCSIZE);
00296 bios[handle].used = 1;
00297 bios[handle].nbits = 0;
00298 bios[handle].size = INCSIZE;
00299
00300 return handle;
00301 }
00302
00303
00322 long bitio_o_append (int handle, unsigned long val, int nbits)
00323
00324 {
00325
00326
00327
00328 assert (bios[handle].used);
00329 assert (sizeof (unsigned long) * 8 >= nbits);
00330
00331
00332
00333
00334 if ((bios[handle].nbits + nbits) / 8 + 1 > (long) bios[handle].size) {
00335 bios[handle].buf = realloc (bios[handle].buf, bios[handle].size + INCSIZE);
00336 if (bios[handle].buf == NULL) return 0;
00337 memset (bios[handle].buf + bios[handle].size, 0, INCSIZE);
00338 bios[handle].size += INCSIZE;
00339 }
00340
00341
00342
00343 bitio_o_outp (handle, val, nbits, bios[handle].nbits);
00344 bios[handle].nbits += nbits;
00345
00346 return bios[handle].nbits;
00347 }
00348
00349
00366 void bitio_o_outp (int handle, unsigned long val, int nbits, long bitpos)
00367
00368 {
00369 int i, bit, bitval;
00370 size_t byte;
00371 char *pc, c;
00372
00373
00374
00375
00376 assert (bios[handle].used);
00377 assert (sizeof (unsigned long) * 8 >= nbits);
00378
00379 for (i = nbits - 1; i >= 0; i --) {
00380
00381
00382
00383 bitval = (int) (val >> i) & 1;
00384
00385
00386
00387 byte = (int) (bitpos / 8);
00388 bit = (int) (bitpos % 8);
00389 bit = 7 - bit;
00390
00391
00392
00393 pc = bios[handle].buf + byte;
00394 if (bitval) {
00395 c = (char) (1 << bit);
00396 *pc |= c;
00397 }
00398 else {
00399 c = (char) (1 << bit);
00400 c ^= 0xff;
00401 *pc &= c;
00402 }
00403 bitpos ++;
00404 }
00405 }
00406
00407
00421 size_t bitio_o_get_size (int handle)
00422
00423 {
00424 if (!bios[handle].used) return 0;
00425
00426 return (size_t) ((bios[handle].nbits - 1) / 8 + 1);
00427 }
00428
00429
00430
00448 void *bitio_o_close (int handle, size_t* nbytes)
00449 {
00450
00451 if (!bios[handle].used) return NULL;
00452
00453
00454
00455 while (bios[handle].nbits % 8 != 0) bitio_o_append (handle, 0, 1);
00456
00457 *nbytes = (size_t) ((bios[handle].nbits - 1) / 8 + 1);
00458 bios[handle].used = 0;
00459 return (void *) bios[handle].buf;
00460 }
00461
00462