void LogSequence2::load(std::istream & input) { CRC8 crch; CRC32 crcd; unsigned char buf[9]; // Read type uint8_t type; crch.readData(input, (unsigned char*)&type, sizeof(type)); if(type!=TYPE_SEQLOG) { //throw "Trying to read a LOGArray but data is not LogArray"; } // Read numbits crch.readData(input, (unsigned char*)&numbits, sizeof(numbits)); // Read numentries uint64_t numentries64 = csd::VByte::decode(input); unsigned int pos = csd::VByte::encode(buf, numentries64); crch.update(buf, pos); // Validate Checksum Header crc8_t filecrch = crc8_read(input); if(crch.getValue()!=filecrch) { throw "Checksum error while reading LogSequence2 header."; } // Update local variables and validate maxval = maxVal(numbits); numentries = (size_t) numentries64; if(numbits>sizeof(size_t)*8 || numentries64>std::numeric_limits<size_t>::max()) { throw "This data structure is too big for this machine"; } // Calculate data size, reserve buffer. size_t numbytes = numBytesFor(numbits, numentries); data.resize(numElementsFor(numbits, numentries)); arraysize = data.size(); array = &data[0]; // Read data crcd.readData(input, (unsigned char*)&array[0], numbytes); // Validate checksum data crc32_t filecrcd = crc32_read(input); if(crcd.getValue()!=filecrcd) { throw "Checksum error while reading LogSequence2 Data"; } IsMapped = false; }
size_t LogSequence2::load(const unsigned char *ptr, const unsigned char *ptrMax, ProgressListener *listener) { size_t count = 0; // Read type CHECKPTR(&ptr[count], ptrMax, 1); if(ptr[count]!=TYPE_SEQLOG) { throw "Trying to read a LOGArray but data is not LogArray"; } count++; // Read numbits CHECKPTR(&ptr[count], ptrMax, 1); numbits = ptr[count++]; // Read numentries uint64_t numentries64; count += csd::VByte::decode(&ptr[count], ptrMax, &numentries64); // Validate Checksum Header CRC8 crch; crch.update(&ptr[0], count); CHECKPTR(&ptr[count], ptrMax, 1); if(crch.getValue()!=ptr[count++]) throw "Checksum error while reading LogSequence2 header."; // Update local variables and validate maxval = maxVal(numbits); numentries = (size_t) numentries64; if(numbits>sizeof(size_t)*8 || numentries64>std::numeric_limits<size_t>::max()) { throw "This data structure is too big for this machine"; } // Setup array of data arraysize = numBytesFor(numbits, numentries); array = (size_t *) &ptr[count]; count+=arraysize; IsMapped = true; if(&ptr[count]>=ptrMax) throw "LogSequence2 tries to read beyond the end of the file"; CHECKPTR(&ptr[count], ptrMax, 4); count+=4; // CRC of data return count; }
size_t CSD_PFC::load(unsigned char *ptr, unsigned char *ptrMax) { size_t count=0; // Type if(ptr[count++] != PFC) throw std::runtime_error("Trying to read a CSD_PFC but type does not match"); count += VByte::decode(&ptr[count], ptrMax, &numstrings); count += VByte::decode(&ptr[count], ptrMax, &bytes); count += VByte::decode(&ptr[count], ptrMax, &blocksize); // CRC CRC8 crch; crch.update(&ptr[0], count); if(crch.getValue()!=ptr[count++]) throw std::runtime_error("CRC Error while reading CSD_PFC Header."); // Blocks if(blocks) delete blocks; blocks = new hdt::LogSequence2(); count += blocks->load(&ptr[count], ptrMax); nblocks = blocks->getNumberOfElements()-1; // Read packed data if(!isMapped) free(text); text = &ptr[count]; count+=bytes; // Ignore data CRC. count+=4; isMapped=true; return count; }
CSD* CSD_PFC::load(istream & fp) { CRC8 crch; CRC32 crcd; unsigned char buf[27]; // 9 bytes per VByte (max) * 3 values. CSD_PFC *dicc = new CSD_PFC(); // Load variables dicc->type = PFC; // Type already read by CSD dicc->numstrings = (uint32_t) VByte::decode(fp); dicc->bytes = VByte::decode(fp); dicc->blocksize = (uint32_t) VByte::decode(fp); // Calculate variables CRC crch.update(&dicc->type, sizeof(dicc->type)); uint8_t pos = 0; pos += VByte::encode(&buf[pos], dicc->numstrings); pos += VByte::encode(&buf[pos], dicc->bytes); pos += VByte::encode(&buf[pos], dicc->blocksize); crch.update(buf, pos); crc8_t filecrc = crc8_read(fp); if(crch.getValue()!=filecrc) { throw std::runtime_error("Checksum error while reading Plain Front Coding Header."); } // Load blocks dicc->blocks = new hdt::LogSequence2(); dicc->blocks->load(fp); dicc->nblocks = dicc->blocks->getNumberOfElements()-1; // Load strings if(dicc->bytes && dicc->numstrings) { dicc->text = (unsigned char *)malloc(dicc->bytes); const unsigned int blocksize = 8192; uint64_t counter=0; unsigned char *ptr = (unsigned char *)dicc->text; while(counter<dicc->bytes && fp.good()) { crcd.readData(fp, ptr, dicc->bytes-counter > blocksize ? blocksize : dicc->bytes-counter); ptr += fp.gcount(); counter += fp.gcount(); } if(counter!=dicc->bytes) { throw std::runtime_error("Could not read all the data section of the Plain Front Coding."); } } else { // Make sure that all is zero. dicc->text = NULL; dicc->numstrings = 0; dicc->bytes = 0; dicc->nblocks = 0; delete dicc->blocks; } crc32_t filecrcd = crc32_read(fp); if(filecrcd!=crcd.getValue()) { throw std::runtime_error("Checksum error in the data section of the Plain Front Coding."); } return dicc; }