[3365] | 1 | #include <stdlib.h>
|
---|
| 2 | #include <stdio.h>
|
---|
| 3 |
|
---|
| 4 | #include "longlong.h"
|
---|
| 5 | #include "sysfuncs.h"
|
---|
| 6 | #include "memlib.h"
|
---|
| 7 |
|
---|
| 8 | #include "bitio_m_abstract.h"
|
---|
| 9 | #include "bitio_m_random.h"
|
---|
| 10 |
|
---|
[25147] | 11 | random_bitio_buffer::random_bitio_buffer(FILE *f, mg_u_long length)
|
---|
[3365] | 12 | {
|
---|
| 13 | buffer = NULL;
|
---|
| 14 | attachFile (f, length);
|
---|
| 15 | }
|
---|
| 16 |
|
---|
| 17 | random_bitio_buffer::~random_bitio_buffer() {
|
---|
[8692] | 18 | if (buffer != NULL) delete []buffer;
|
---|
[3365] | 19 | }
|
---|
| 20 |
|
---|
[25147] | 21 | void random_bitio_buffer::attachFile (FILE *f, mg_u_long length) {
|
---|
[3365] | 22 | // delete the old buffer
|
---|
| 23 | if (buffer != NULL) {
|
---|
[8692] | 24 | delete []buffer;
|
---|
[3365] | 25 | buffer = NULL;
|
---|
| 26 | }
|
---|
| 27 |
|
---|
| 28 | // reset all the values
|
---|
| 29 | file = f;
|
---|
| 30 | pos = 0;
|
---|
| 31 | base = 0;
|
---|
| 32 | used = 0;
|
---|
| 33 | len = length - 1;
|
---|
| 34 | shift = 0;
|
---|
| 35 |
|
---|
| 36 | // make sure the length is a power of 2
|
---|
| 37 | while (len != 0) {
|
---|
[9612] | 38 | ++shift;
|
---|
[3365] | 39 | len = len >> 1;
|
---|
| 40 | }
|
---|
| 41 | len = 1 << shift;
|
---|
| 42 |
|
---|
| 43 | // allocate a new buffer
|
---|
| 44 | buffer = new u_char[len];
|
---|
| 45 |
|
---|
| 46 | // fill up the buffer
|
---|
| 47 | if (file != NULL) {
|
---|
| 48 | fseek(file, 0, 0);
|
---|
[25147] | 49 | size_t numbytes = fread(buffer, 1, len, file);
|
---|
| 50 |
|
---|
| 51 | if (len != numbytes){
|
---|
| 52 | #ifdef DEBUG
|
---|
| 53 | fprintf(stderr, "[mgpp/lib/bitio_m_random.cpp L52] number of bytes read by fread does not match the requested amount\n");
|
---|
| 54 | #endif
|
---|
| 55 | }
|
---|
[3365] | 56 | }
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | random_bitio_buffer &random_bitio_buffer::operator= (const random_bitio_buffer &_rbb) {
|
---|
| 60 | // delete the old buffer
|
---|
| 61 | if (buffer != NULL) {
|
---|
[8692] | 62 | delete []buffer;
|
---|
[3365] | 63 | buffer = NULL;
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | file = _rbb.file;
|
---|
| 67 |
|
---|
| 68 | base = _rbb.base;
|
---|
| 69 | used = _rbb.used;
|
---|
| 70 | pos = _rbb.pos;
|
---|
| 71 | len = _rbb.len;
|
---|
| 72 | shift = _rbb.shift;
|
---|
| 73 |
|
---|
| 74 | // copy the buffer
|
---|
| 75 | buffer = new u_char [len];
|
---|
| 76 | // memcpy (buffer, _rbb.buffer, len);
|
---|
| 77 | memcpy (buffer, _rbb.buffer, len);
|
---|
| 78 |
|
---|
| 79 | return (*this);
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | void random_bitio_buffer::error() {
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | void random_bitio_buffer::writeRead()
|
---|
| 86 | {
|
---|
| 87 | if (used)
|
---|
| 88 | {
|
---|
| 89 | fseek(file, base, 0);
|
---|
| 90 | fwrite(buffer, 1, len, file);
|
---|
| 91 | }
|
---|
| 92 | // else
|
---|
| 93 | // {
|
---|
| 94 | base += len;
|
---|
| 95 | fseek(file, base, 0);
|
---|
[25147] | 96 | size_t numbytes = fread(buffer, 1, len, file);
|
---|
| 97 | if (numbytes != len)
|
---|
| 98 | {
|
---|
| 99 | #ifdef DEBUG
|
---|
| 100 | fprintf(stderr, "[mgpp/lib/bitio_m_random.cpp L97] number of bytes read by fread does not match the requested amount\n");
|
---|
| 101 | #endif
|
---|
| 102 | }
|
---|
[3365] | 103 | pos = 0;
|
---|
| 104 | used = 0;
|
---|
| 105 | // }
|
---|
| 106 | }
|
---|
| 107 |
|
---|
| 108 | void random_bitio_buffer::encodeBit(int bit)
|
---|
| 109 | {
|
---|
| 110 | do
|
---|
| 111 | {
|
---|
| 112 | if (bit != 0)
|
---|
| 113 | {
|
---|
| 114 | buffer[pos >> 3] |= 0x80 >> (pos & 0x07);
|
---|
| 115 | }
|
---|
| 116 | else
|
---|
| 117 | {
|
---|
| 118 | buffer[pos >> 3] &= 0xff7f >> (pos & 0x07);
|
---|
| 119 | }
|
---|
| 120 | used = 1;
|
---|
[9612] | 121 | ++pos;
|
---|
[3365] | 122 |
|
---|
| 123 | if ((pos >> 3) >= len)
|
---|
| 124 | {
|
---|
| 125 | writeRead();
|
---|
| 126 | }
|
---|
| 127 | }
|
---|
| 128 | while (0);
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | void random_bitio_buffer::flush()
|
---|
| 132 | {
|
---|
| 133 | if (used != 0)
|
---|
| 134 | {
|
---|
| 135 | fseek(file, base, 0);
|
---|
| 136 | fwrite(buffer, 1, len, file);
|
---|
| 137 | used = 0;
|
---|
| 138 | }
|
---|
| 139 | }
|
---|
| 140 |
|
---|
| 141 | void random_bitio_buffer::encodeDone()
|
---|
| 142 | {
|
---|
| 143 | flush();
|
---|
| 144 | if (buffer != NULL) {
|
---|
[8692] | 145 | delete []buffer;
|
---|
[3365] | 146 | buffer = NULL;
|
---|
| 147 | }
|
---|
| 148 | }
|
---|
| 149 |
|
---|
[25147] | 150 | mg_u_long random_bitio_buffer::tell()
|
---|
[3365] | 151 | {
|
---|
| 152 | return ((base << 3) + pos);
|
---|
| 153 | }
|
---|
| 154 |
|
---|
[25147] | 155 | void random_bitio_buffer::seek(mg_u_long toPos)
|
---|
[3365] | 156 | {
|
---|
| 157 | if (((toPos >> 3) >= base) && (((toPos+7) >> 3) < (base + len)))
|
---|
| 158 | {
|
---|
| 159 | pos = toPos - (base << 3);
|
---|
| 160 | }
|
---|
| 161 | else
|
---|
| 162 | {
|
---|
| 163 | flush();
|
---|
| 164 | base = toPos >> 3;
|
---|
| 165 | base = (toPos >> (shift + 3)) << shift;
|
---|
| 166 | fseek(file, base, 0);
|
---|
[25147] | 167 | size_t numbytes = fread(buffer, 1, len, file);
|
---|
| 168 | if (numbytes != len)
|
---|
| 169 | {
|
---|
| 170 | #ifdef DEBUG
|
---|
| 171 | fprintf(stderr, "[mgpp/lib/bitio_m_random.cpp L166] number of bytes read by fread does not match the requested amount\n");
|
---|
| 172 | #endif
|
---|
| 173 | }
|
---|
[3365] | 174 | pos = toPos & 0x07;
|
---|
| 175 | pos = toPos & ((8 << shift) - 1);
|
---|
| 176 | }
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 | int random_bitio_buffer::bit()
|
---|
| 180 | {
|
---|
| 181 | // fprintf(stderr, "Bit in");
|
---|
[9612] | 182 | ++pos;
|
---|
[3365] | 183 | if (((pos - 1) >> 3) >= len)
|
---|
| 184 | {
|
---|
| 185 | writeRead();
|
---|
| 186 | pos = 1;
|
---|
| 187 | }
|
---|
| 188 | return (buffer[(pos - 1) >> 3] & (0x80 >> ((pos - 1) & 0x07))) != 0;
|
---|
| 189 | }
|
---|
| 190 |
|
---|
[25147] | 191 | mg_s_long random_bitio_buffer::addff(mg_s_long b)
|
---|
[3365] | 192 | {
|
---|
| 193 | return b + b + bit();
|
---|
| 194 | }
|
---|
| 195 |
|
---|
[25147] | 196 | mg_s_long random_bitio_buffer::add00(mg_s_long b)
|
---|
[3365] | 197 | {
|
---|
| 198 | return addff(b);
|
---|
| 199 | }
|
---|
| 200 |
|
---|
| 201 | int random_bitio_buffer::bitOffset()
|
---|
| 202 | {
|
---|
| 203 | return 0;
|
---|
| 204 | }
|
---|
| 205 |
|
---|
| 206 | void random_bitio_buffer::done()
|
---|
| 207 | {
|
---|
| 208 | encodeDone();
|
---|
| 209 | }
|
---|
| 210 |
|
---|
| 211 |
|
---|
| 212 | #ifdef USE_LONG_LONG
|
---|
| 213 | void random_bitio_buffer::seek_LL(mg_ullong toPos)
|
---|
| 214 | {
|
---|
| 215 | if (((toPos >> 3) >= (mg_ullong) base) &&
|
---|
| 216 | (((toPos + 7) >> 3) < (mg_ullong) (base + len)))
|
---|
| 217 | {
|
---|
[25147] | 218 | pos = (mg_s_long) (toPos - (mg_ullong) (base << 3));
|
---|
[3365] | 219 | }
|
---|
| 220 | else
|
---|
| 221 | {
|
---|
| 222 | flush();
|
---|
[25147] | 223 | base = (mg_s_long) ((toPos >> (shift + 3)) << shift);
|
---|
[3365] | 224 |
|
---|
| 225 | fseek(file, base, 0);
|
---|
[25147] | 226 | size_t numbytes = fread(buffer, 1, len, file);
|
---|
| 227 | if (numbytes != len)
|
---|
| 228 | {
|
---|
| 229 | #ifdef DEBUG
|
---|
| 230 | fprintf(stderr, "[mgpp/lib/bitio_m_random.cpp L223] number of bytes read by fread does not match the requested amount\n");
|
---|
| 231 | #endif
|
---|
| 232 | }
|
---|
| 233 | pos = (mg_s_long) (toPos & ((8 << shift) - 1));
|
---|
[3365] | 234 | }
|
---|
| 235 | }
|
---|
| 236 |
|
---|
| 237 | mg_ullong random_bitio_buffer::tell_LL()
|
---|
| 238 | {
|
---|
| 239 | return (((mg_ullong) base) << 3ull) + pos;
|
---|
| 240 | }
|
---|
| 241 | #endif
|
---|
| 242 |
|
---|