void Database::_WriteBlock(Item towrite, uint64_t blockpos) { backing.seekg(blockpos); backing.seekp(blockpos); uint64_t blkhdrs[4]; if (backing.eof()) { blkhdrs[0] = 0; blkhdrs[1] = towrite.itemsize; blkhdrs[2] = towrite.itemsize; blkhdrs[3] = towrite.itemsize + (sizeof(uint64_t)*4) + 1; backing.write(0, 1); backing.write((char*)&blkhdrs, sizeof(uint64_t)*4); backing.write(towrite.item, towrite.itemsize); backing.flush(); } else { _GetLock(blockpos, true); backing.read((char*)blkhdrs, sizeof(uint64_t)*4); if (towrite.itemsize + 1 + (sizeof(uint64_t)*4) <= blkhdrs[3]) { //Block large enough or non-existent block backing.write(0, 1); blkhdrs[0] = 0; blkhdrs[1] = towrite.itemsize; blkhdrs[2] = towrite.itemsize; //Keep blkhdrs[3] backing.write((char*)&blkhdrs, sizeof(uint64_t)*4); backing.write(towrite.item, towrite.itemsize); backing.flush(); _ReleaseLock(blockpos, true); } else { //Have to continue to a new block, allocate or reuse std::streampos currentpos = backing.tellp(); backing.seekp(0, std::ios::end); std::streampos endpos = backing.tellp(); backing.seekp(currentpos, std::ios::beg); blkhdrs[0] = (uint64_t) endpos; //Keep blkhdrs[1] blkhdrs[2] = towrite.itemsize; //Keep blkhdrs[3] uint64_t blockcancontain = blkhdrs[3] - ((sizeof(uint64_t)*4) + 1); backing.write(0, 1); backing.write((char*)&blkhdrs, sizeof(uint64_t)*4); backing.write(towrite.item, blockcancontain); backing.flush(); _ReleaseLock(blockpos, true); //Continue to next block! Item process; process.itemsize = towrite.itemsize-blockcancontain; process.item = towrite.item+blockcancontain; _WriteBlock(process, blockpos); } } }
Block getWordBlock(std::string word, std::fstream& f, bool createIfReauired = false) { seekRW(f, 0); BlockOffset currentOffset = 0; Block b {readBlockFromFile(f)}; for(auto c : word) { unsigned int i = char2int(c); if (b.offsets[i] == 0 ) { if (!createIfReauired) { b.data=0; return b; } BlockOffset off = f.tellp(); Block newBlock {}; seekRW(f, 0, f.end); BlockOffset newCurrent = b.offsets[i] = writeBlockToFile(newBlock, f); seekRW(f, off); writeBlockToFile(b, f); seekRW(f, newCurrent); currentOffset = newCurrent; b = newBlock; } else { currentOffset = b.offsets[i]; seekRW(f, currentOffset); b = readBlockFromFile(f); } } return b; }
void Folder::writeData(std::fstream &file, BSAULong fileNamesLength) const { m_OffsetWrite = static_cast<BSAULong>(file.tellp()) + fileNamesLength; writeBString(file, getFullPath()); for (std::vector<File::Ptr>::const_iterator iter = m_Files.begin(); iter != m_Files.end(); ++iter) { (*iter)->writeHeader(file); } }
/*! \brief Close and truncate the file, and update digest * Truncation is needed to remove any detritus from previously-saved states. */ void resultsfile::finishwithfile(std::fstream& file) { std::streampos length = file.tellp(); // close and truncate file file.close(); truncate(length); // re-open and update digest file.open(fname.c_str(), std::ios::in); filedigest.process(file); }
BlockOffset writeBlockToFile(Block b, std::fstream& f) { BlockOffset off = f.tellp(); f.write(reinterpret_cast<char *>(&b.data), sizeof(b.data)); for(auto& o : b.offsets) { f.write(reinterpret_cast<char *>(&o), sizeof(o)); } f.seekp(off, f.beg); return off; }
/*! \brief If this is the first time, write the header * \note This method also updates the write position so that the header is not * overwritten on the next write. */ void resultsfile::writeheaderifneeded(std::fstream& file) { if (!headerwritten) { writeheader(file); // update flag headerwritten = true; // update file-write position fileptr = file.tellp(); } }
void IndexDataStructure::writeAt(std::fstream & _output_file, std::streampos _position) { // remember the write file position std::streampos w_pos = _output_file.tellp(); // go to asked write position _output_file.seekp(_position); writeToNext(_output_file); // restore original write position _output_file.seekp(w_pos); }
int serialize(linked_list<T>& list, std::fstream& out) { if(!out.is_open()) throw serialize_exception(); serialize(LINKEDLIST_SERIAL_ID, out); int byte_count_pos = out.tellp(); out.seekp(sizeof(int), std::ios::cur); int byte_count = 0; byte_count += serialize(list.list_size, out); for(typename linked_list<T>::link* current = (list.head)->next; current != NULL; current = current->next) byte_count += serialize(current->element, out); int end_pos = out.tellp(); out.seekp(byte_count_pos); serialize(byte_count, out); out.seekp(end_pos); return byte_count + sizeof(int) + sizeof(long); // content + header }
void IndexDataStructure::writeToNext(std::fstream & _output_file) { m_is_indexed = true; m_index_position = _output_file.tellp(); _output_file.write((char *)(&m_count), sizeof(m_count)); _output_file.write((char *)(m_keys), sizeof(m_keys[0]) * m_max_count); _output_file.write((char *)(m_addresses), sizeof(m_addresses[0]) * m_max_count); _output_file.write((char *)(&m_next_sibling_address), sizeof(m_next_sibling_address)); // skip free block space _output_file.seekp(m_block_size - m_real_data_size, _output_file.cur); }
void resultsfile::checkformodifications(std::fstream& file) { assert(file.good()); trace << "DEBUG (resultsfile): checking file for modifications." << std::endl; // check for user modifications sha curdigest; file.seekg(0); curdigest.process(file); // reset file file.clear(); if (curdigest == filedigest) file.seekp(fileptr); else { cerr << "NOTICE: file modifications found - appending." << std::endl; // set current write position to end-of-file file.seekp(0, std::ios_base::end); fileptr = file.tellp(); } }