#include #include #include "longlong.h" #include "sysfuncs.h" #include "memlib.h" #include "bitio_m_abstract.h" #include "bitio_m_random.h" random_bitio_buffer::random_bitio_buffer(FILE *f, mg_u_long length) { buffer = NULL; attachFile (f, length); } random_bitio_buffer::~random_bitio_buffer() { if (buffer != NULL) delete []buffer; } void random_bitio_buffer::attachFile (FILE *f, mg_u_long length) { // delete the old buffer if (buffer != NULL) { delete []buffer; buffer = NULL; } // reset all the values file = f; pos = 0; base = 0; used = 0; len = length - 1; shift = 0; // make sure the length is a power of 2 while (len != 0) { ++shift; len = len >> 1; } len = 1 << shift; // allocate a new buffer buffer = new u_char[len]; // fill up the buffer if (file != NULL) { fseek(file, 0, 0); size_t numbytes = fread(buffer, 1, len, file); if (len != numbytes){ #ifdef DEBUG fprintf(stderr, "[mgpp/lib/bitio_m_random.cpp L52] number of bytes read by fread does not match the requested amount\n"); #endif } } } random_bitio_buffer &random_bitio_buffer::operator= (const random_bitio_buffer &_rbb) { // delete the old buffer if (buffer != NULL) { delete []buffer; buffer = NULL; } file = _rbb.file; base = _rbb.base; used = _rbb.used; pos = _rbb.pos; len = _rbb.len; shift = _rbb.shift; // copy the buffer buffer = new u_char [len]; // memcpy (buffer, _rbb.buffer, len); memcpy (buffer, _rbb.buffer, len); return (*this); } void random_bitio_buffer::error() { } void random_bitio_buffer::writeRead() { if (used) { fseek(file, base, 0); fwrite(buffer, 1, len, file); } // else // { base += len; fseek(file, base, 0); size_t numbytes = fread(buffer, 1, len, file); if (numbytes != len) { #ifdef DEBUG fprintf(stderr, "[mgpp/lib/bitio_m_random.cpp L97] number of bytes read by fread does not match the requested amount\n"); #endif } pos = 0; used = 0; // } } void random_bitio_buffer::encodeBit(int bit) { do { if (bit != 0) { buffer[pos >> 3] |= 0x80 >> (pos & 0x07); } else { buffer[pos >> 3] &= 0xff7f >> (pos & 0x07); } used = 1; ++pos; if ((pos >> 3) >= len) { writeRead(); } } while (0); } void random_bitio_buffer::flush() { if (used != 0) { fseek(file, base, 0); fwrite(buffer, 1, len, file); used = 0; } } void random_bitio_buffer::encodeDone() { flush(); if (buffer != NULL) { delete []buffer; buffer = NULL; } } mg_u_long random_bitio_buffer::tell() { return ((base << 3) + pos); } void random_bitio_buffer::seek(mg_u_long toPos) { if (((toPos >> 3) >= base) && (((toPos+7) >> 3) < (base + len))) { pos = toPos - (base << 3); } else { flush(); base = toPos >> 3; base = (toPos >> (shift + 3)) << shift; fseek(file, base, 0); size_t numbytes = fread(buffer, 1, len, file); if (numbytes != len) { #ifdef DEBUG fprintf(stderr, "[mgpp/lib/bitio_m_random.cpp L166] number of bytes read by fread does not match the requested amount\n"); #endif } pos = toPos & 0x07; pos = toPos & ((8 << shift) - 1); } } int random_bitio_buffer::bit() { // fprintf(stderr, "Bit in"); ++pos; if (((pos - 1) >> 3) >= len) { writeRead(); pos = 1; } return (buffer[(pos - 1) >> 3] & (0x80 >> ((pos - 1) & 0x07))) != 0; } mg_s_long random_bitio_buffer::addff(mg_s_long b) { return b + b + bit(); } mg_s_long random_bitio_buffer::add00(mg_s_long b) { return addff(b); } int random_bitio_buffer::bitOffset() { return 0; } void random_bitio_buffer::done() { encodeDone(); } #ifdef USE_LONG_LONG void random_bitio_buffer::seek_LL(mg_ullong toPos) { if (((toPos >> 3) >= (mg_ullong) base) && (((toPos + 7) >> 3) < (mg_ullong) (base + len))) { pos = (mg_s_long) (toPos - (mg_ullong) (base << 3)); } else { flush(); base = (mg_s_long) ((toPos >> (shift + 3)) << shift); fseek(file, base, 0); size_t numbytes = fread(buffer, 1, len, file); if (numbytes != len) { #ifdef DEBUG fprintf(stderr, "[mgpp/lib/bitio_m_random.cpp L223] number of bytes read by fread does not match the requested amount\n"); #endif } pos = (mg_s_long) (toPos & ((8 << shift) - 1)); } } mg_ullong random_bitio_buffer::tell_LL() { return (((mg_ullong) base) << 3ull) + pos; } #endif