14 #include "lcf/reader_lcf.h"
19 std::string LcfReader::error_str;
21 LcfReader::LcfReader(std::istream& filestream, std::string encoding)
23 , encoder(std::move(encoding))
25 offset = filestream.tellg();
28 size_t LcfReader::Read0(
void *ptr,
size_t size,
size_t nmemb) {
33 stream.read(
reinterpret_cast<char*
>(ptr), size*nmemb);
34 auto bytes_read = stream.gcount();
36 size_t result = bytes_read / size;
38 if (result != nmemb && !Eof()) {
39 perror(
"Reading error: ");
45 void LcfReader::Read(
void *ptr,
size_t size,
size_t nmemb) {
47 Read0(ptr, size, nmemb);
49 if (Read0(ptr, size, nmemb) != nmemb) {
50 fprintf(stderr,
"Read error at %" PRIu32
". The file is probably corrupted\n", Tell());
56 void LcfReader::Read<bool>(
bool& ref) {
61 void LcfReader::Read<int8_t>(int8_t& ref) {
66 void LcfReader::Read<uint8_t>(uint8_t& ref) {
71 void LcfReader::Read<int16_t>(int16_t& ref) {
77 void LcfReader::Read<uint32_t>(uint32_t& ref) {
82 int LcfReader::ReadInt() {
84 unsigned char temp = 0;
88 if (Read0(&temp, 1, 1) == 0) {
95 fprintf(stderr,
"Invalid compressed integer at %" PRIu32
"\n", Tell());
98 }
while (temp & 0x80);
100 return loops > 5 ? 0 : value;
104 void LcfReader::Read<int32_t>(int32_t& ref) {
109 void LcfReader::Read<double>(
double& ref) {
115 void LcfReader::Read<bool>(std::vector<bool> &buffer,
size_t size) {
118 for (
unsigned i = 0; i < size; ++i) {
121 buffer.push_back(val > 0);
126 void LcfReader::Read<uint8_t>(std::vector<uint8_t> &buffer,
size_t size) {
129 for (
unsigned int i = 0; i < size; ++i) {
132 buffer.push_back(val);
137 void LcfReader::Read<int16_t>(std::vector<int16_t> &buffer,
size_t size) {
139 size_t items = size / 2;
140 for (
unsigned int i = 0; i < items; ++i) {
144 buffer.push_back(val);
147 Seek(1, FromCurrent);
153 void LcfReader::Read<int32_t>(std::vector<int32_t> &buffer,
size_t size) {
155 size_t items = size / 4;
156 for (
unsigned int i = 0; i < items; ++i) {
160 buffer.push_back(val);
163 Seek(size % 4, FromCurrent);
169 void LcfReader::Read<uint32_t>(std::vector<uint32_t> &buffer,
size_t size) {
171 size_t items = size / 4;
172 for (
unsigned int i = 0; i < items; ++i) {
176 buffer.push_back(val);
179 Seek(size % 4, FromCurrent);
184 void LcfReader::ReadBits(DBBitArray &buffer,
size_t size) {
185 buffer = DBBitArray(size);
186 for (
size_t i = 0; i < size; ++i) {
188 Read(&val,
sizeof(val), 1);
189 buffer[i] =
static_cast<bool>(val);
193 void LcfReader::ReadString(std::string& ref,
size_t size) {
195 Read((size > 0 ? &ref.front():
nullptr), 1, size);
199 void LcfReader::ReadString(DBString& ref,
size_t size) {
200 auto& tmp = StrBuffer();
201 ReadString(tmp, size);
207 bool LcfReader::IsOk()
const {
208 return stream.good() && encoder.IsOk();
211 bool LcfReader::Eof()
const {
215 void LcfReader::Seek(
size_t pos, SeekMode mode) {
216 constexpr
auto fast_seek_size = 32;
218 case LcfReader::FromStart:
219 stream.seekg(pos, std::ios_base::beg);
220 offset = stream.tellg();
222 case LcfReader::FromCurrent:
223 if (pos <= fast_seek_size) {
226 char buf[fast_seek_size];
227 stream.read(buf, pos);
228 offset += stream.gcount();
230 stream.seekg(pos, std::ios_base::cur);
231 offset = stream.tellg();
234 case LcfReader::FromEnd:
235 stream.seekg(pos, std::ios_base::end);
236 offset = stream.tellg();
239 assert(
false &&
"Invalid SeekMode");
243 uint32_t LcfReader::Tell() {
254 int LcfReader::Peek() {
255 return stream.peek();
258 void LcfReader::Skip(
const struct LcfReader::Chunk& chunk_info,
const char* where) {
259 fprintf(stderr,
"Skipped Chunk %02X (%" PRIu32
" byte) in lcf at %" PRIX32
" (%s)\n",
260 chunk_info.ID, chunk_info.length, Tell(), where);
262 for (uint32_t i = 0; i < chunk_info.length; ++i) {
264 LcfReader::Read(
byte);
265 fprintf(stderr,
"%02X ",
byte);
266 if ((i+1) % 16 == 0) {
267 fprintf(stderr,
"\n");
273 fprintf(stderr,
"\n");
276 void LcfReader::SetError(
const char* fmt, ...) {
281 vsprintf(str, fmt, args);
289 const std::string& LcfReader::GetError() {
293 void LcfReader::Encode(std::string& str) {
297 int LcfReader::IntSize(
unsigned int x) {
306 #ifdef WORDS_BIGENDIAN
307 void LcfReader::SwapByteOrder(uint16_t& us)
313 void LcfReader::SwapByteOrder(uint32_t& ui)
316 ((ui<<8) & 0x00FF0000) |
317 ((ui>>8) & 0x0000FF00) |
321 void LcfReader::SwapByteOrder(
double& d)
323 uint32_t *p =
reinterpret_cast<uint32_t *
>(&d);
331 void LcfReader::SwapByteOrder(uint16_t& ) {}
332 void LcfReader::SwapByteOrder(uint32_t& ) {}
333 void LcfReader::SwapByteOrder(
double& ) {}
336 void LcfReader::SwapByteOrder(int16_t& s)
338 SwapByteOrder((uint16_t&) s);
341 void LcfReader::SwapByteOrder(int32_t& s)
343 SwapByteOrder((uint32_t&) s);