00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022 #include "buff.h"
00023
00024 #define LSB_TO_ONE(i) ((i) ? ((1UL << (i)) - 1) : 0)
00025 #define LSB_TO_ZERO(i) (((i) == BUFFSIZE) ? 0 : (((unsigned long) -1) << (i)))
00026
00027 unsigned char bread_getchar(bread_t bin) {
00028 bin->courant++;
00029 if (bin->courant < bin->dernier)
00030 return bin->message[bin->courant];
00031 if (bin->courant == bin->dernier)
00032 return bin->message[bin->courant] & bin->masque_dernier;
00033 return 0;
00034 }
00035
00036 void bwrite_putchar(unsigned char c, bwrite_t bout) {
00037 bout->courant++;
00038 if (bout->courant < bout->dernier)
00039 bout->message[bout->courant] = c;
00040 if (bout->courant == bout->dernier) {
00041 bout->message[bout->courant] &= ~ bout->masque_dernier;
00042 bout->message[bout->courant] ^= c & bout->masque_dernier;
00043 }
00044 }
00045
00046 bread_t breadinit(unsigned char * message, int fin) {
00047 bread_t bin;
00048
00049 bin = malloc (sizeof (struct buff));
00050
00051 bin->message = message;
00052 bin->fin = fin;
00053
00054 bin->dernier = (fin - 1) / 8;
00055
00056 bin->masque_dernier = LSB_TO_ZERO((-fin) & 0x7);
00057
00058 bin->courant = -1;
00059 bin->val = 0;
00060 bin->size = 0;
00061 bin->lock = 0;
00062
00063 return bin;
00064 }
00065
00066 bwrite_t bwriteinit(unsigned char * message, int fin) {
00067 bwrite_t bout;
00068
00069 bout = malloc (sizeof (struct buff));
00070
00071 bout->message = message;
00072 bout->fin = fin;
00073
00074 bout->dernier = (fin - 1) / 8;
00075
00076 bout->masque_dernier = LSB_TO_ZERO((-fin) & 0x7);
00077
00078 bout->courant = -1;
00079 bout->val = 0;
00080 bout->size = BUFFSIZE;
00081 bout->lock = 0;
00082
00083 return bout;
00084 }
00085
00086
00087 void bfill(bread_t bin) {
00088 int i;
00089
00090 for (i = 0; i < BUFFSIZE; i += 8) {
00091 bin->val <<= 8;
00092 bin->val ^= bread_getchar(bin);
00093 }
00094 bin->size = BUFFSIZE;
00095 }
00096
00097
00098 void bflush(bwrite_t bout) {
00099 int i;
00100
00101 for (i = BUFFSIZE - 8; i >= 0; i -= 8)
00102 bwrite_putchar(bout->val >> i, bout);
00103 bout->val = 0;
00104 bout->size = BUFFSIZE;
00105 }
00106
00107 void bflush_partiel(bwrite_t bout) {
00108 int i;
00109
00110 for (i = BUFFSIZE - 8; i >= bout->size; i -= 8)
00111 bwrite_putchar(bout->val >> i, bout);
00112 bout->size -= i;
00113
00114 if (bout->size < 8) {
00115
00116
00117 bout->val >>= i;
00118
00119 bout->val &= LSB_TO_ZERO(bout->size);
00120
00121
00122
00123
00124
00125 bout->val ^= bread_getchar(bout) & LSB_TO_ONE(bout->size);
00126
00127 bout->courant--;
00128 bwrite_putchar(bout->val, bout);
00129 }
00130 bout->val = 0;
00131 bout->size = BUFFSIZE;
00132 }
00133
00134 void breadclose(bread_t bin) {
00135 free(bin);
00136 }
00137
00138 void bwriteclose(bwrite_t bout) {
00139 bflush_partiel(bout);
00140 free(bout);
00141 }
00142
00143 void bread_retour(bread_t bin) {
00144 bin->courant = -1;
00145 bin->size = 0;
00146 bin->val = 0;
00147 }
00148
00149
00150 int bread_available(bread_t bin) {
00151 return bin->fin - 8 * (bin->courant + 1) + bin->size;
00152 }
00153
00154
00155 int bwrite_available(bwrite_t bout) {
00156 return bout->fin - 8 * (bout->courant + 1) - BUFFSIZE + bout->size;
00157 }
00158
00159
00160 int bread_unlocked(bread_t bin) {
00161 return bin->fin - bin->lock;
00162 }
00163
00164
00165 int bwrite_unlocked(bwrite_t bout) {
00166 return bout->fin - bout->lock;
00167 }
00168
00169 int bread_position(bread_t bin) {
00170 return 8 * (bin->courant + 1) - bin->size;
00171 }
00172
00173 void bread_changer_position(bread_t bin, int i) {
00174
00175 bin->courant = i / 8 - 1;
00176
00177 bin->val = bread_getchar(bin);
00178
00179 bin->size = 8 - (i % 8);
00180 }
00181
00182
00183 void bread_decaler_fin(bread_t bin, int i) {
00184 bin->fin += i;
00185 bin->dernier = (bin->fin - 1) / 8;
00186 bin->masque_dernier = LSB_TO_ZERO((-bin->fin) & 0x7);
00187 bread_changer_position(bin, bread_position(bin));
00188 }
00189
00190 void bwrite_changer_position(bwrite_t bout, int i) {
00191
00192
00193
00194
00195 bflush_partiel(bout);
00196
00197
00198 bout->courant = i / 8 - 1;
00199
00200 bout->size = BUFFSIZE - (i % 8);
00201 if (i % 8 == 0)
00202 bout->val = 0;
00203 else {
00204
00205 bout->val = ((unsigned long) bout->message[i / 8]) << (BUFFSIZE - 8);
00206
00207 bout->val &= LSB_TO_ZERO(bout->size);
00208 }
00209 }
00210
00211
00212 void bwrite_decaler_fin(bwrite_t bout, int i) {
00213 bout->fin += i;
00214 bout->dernier = (bout->fin - 1) / 8;
00215 bout->masque_dernier = LSB_TO_ZERO((-bout->fin) & 0x7);
00216 }
00217
00218
00219 unsigned bread(int i, bread_t bin) {
00220 unsigned res = 0;
00221
00222 if (bin->size < i) {
00223 res = bin->val & LSB_TO_ONE(bin->size);
00224 i -= bin->size;
00225 res <<= i;
00226 bfill(bin);
00227 }
00228 bin->size -= i;
00229 res ^= (bin->val >> bin->size) & LSB_TO_ONE(i);
00230
00231 return res;
00232 }
00233
00234 void bread_lock(int i, bread_t bin) {
00235 bin->lock = 8 * (bin->courant + 1) - bin->size + i;
00236 }
00237
00238 void bwrite_lock(int i, bwrite_t bout) {
00239 bout->lock = 8 * (bout->courant + 1) + BUFFSIZE - bout->size + i;
00240 }
00241
00242
00243
00244 unsigned blook(int i, bread_t bin) {
00245 unsigned res = 0;
00246
00247 while (bin->size < i) {
00248 bin->val <<= 8;
00249 bin->val ^= bread_getchar(bin);
00250 bin->size += 8;
00251 }
00252 res ^= (bin->val >> (bin->size - i)) & LSB_TO_ONE(i);
00253
00254 return res;
00255 }
00256
00257
00258 void bstep(int i, bread_t bin) {
00259 if (bin->size < i) {
00260 i -= bin->size;
00261 bfill(bin);
00262 }
00263 bin->size -= i;
00264 }
00265
00266 int bread_bit(bread_t bin) {
00267 if (bin->size <= 0)
00268 bfill(bin);
00269 bin->size--;
00270 return (bin->val >> bin->size) & 1;
00271 }
00272
00273
00274 void bwrite(unsigned int x, int i, bwrite_t bout) {
00275 if (bout->size < i) {
00276 i -= bout->size;
00277 bout->val ^= x >> i;
00278 bflush(bout);
00279 x &= LSB_TO_ONE(i);
00280 }
00281
00282 bout->size -= i;
00283 bout->val ^= x << bout->size;
00284 }
00285
00286
00287 void bwrite_bit(unsigned int x, bwrite_t bout) {
00288 if (bout->size <= 0)
00289 bflush(bout);
00290 bout->size--;
00291 bout->val ^= x << bout->size;
00292 }
00293
00294
00295 void bwrite_bits(unsigned int x, int n, bwrite_t bout) {
00296 if (bout->size <= 0)
00297 bflush(bout);
00298 x = x ? -1 : 0;
00299 if (n > bout->size) {
00300 bout->val ^= x >> (BUFFSIZE - bout->size);
00301 n -= bout->size;
00302 bflush(bout);
00303 while (n > BUFFSIZE) {
00304 bout->val = x;
00305 n -= BUFFSIZE;
00306 bflush(bout);
00307 }
00308 }
00309 if (n > 0) {
00310 bout->size -= n;
00311 bout->val ^= (x >> (BUFFSIZE - n)) << bout->size;
00312 }
00313 }