void macIcon(iw_context* context, const char* filename) { //16x16 //32x32 //128x128 //256x256 //512x512 //1024x1024 ByteStream stream; iw_iodescr writedescr; memset(&writedescr, 0, sizeof(struct iw_iodescr)); writedescr.write_fn = stream_writefn; writedescr.seek_fn = stream_seekfn; writedescr.fp = &stream; stream.put('i'); stream.put('c'); stream.put('n'); stream.put('s'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('i'); stream.put('c'); stream.put('0'); stream.put('8'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('-'); scale(context, 256, 256); iw_write_file_by_fmt(context, &writedescr, IW_FORMAT_PNG); int icon08size = static_cast<int>(stream.size() - 8); stream.put('i'); stream.put('c'); stream.put('0'); stream.put('9'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('-'); scale(context, 512, 512); iw_write_file_by_fmt(context, &writedescr, IW_FORMAT_PNG); int icon09size = static_cast<int>(stream.size() - icon08size - 8); stream.put('i'); stream.put('c'); stream.put('1'); stream.put('0'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('-'); scale(context, 1024, 1024); iw_write_file_by_fmt(context, &writedescr, IW_FORMAT_PNG); int icon10size = static_cast<int>(stream.size() - icon09size - icon08size - 8); std::vector<byte> size = convertIntToByteArray(static_cast<int>(stream.size())); for (int i = 0; i < 4; ++i) stream.set( 4 + i, size[i]); size = convertIntToByteArray(icon08size); for (int i = 0; i < 4; ++i) stream.set(12 + i, size[i]); size = convertIntToByteArray(icon09size); for (int i = 0; i < 4; ++i) stream.set(icon08size + 8 + 4 + i, size[i]); size = convertIntToByteArray(icon10size); for (int i = 0; i < 4; ++i) stream.set(icon08size + icon09size + 8 + 4 + i, size[i]); stream.save(filename); }
size_t BuiltinProtocolHandlersLocal::write(const ByteStream &byteStream) { if (d->m_fd == -1) { return 0; } return ::write(d->m_fd, byteStream.data(), byteStream.size()); }
void Ball::exportToWindowsIcon(Path filename, Path directory) { //16x16 //32x32 //48x48 //256x256 ByteStream stream; writeIcoHeader(stream); writeIconDirEntry(stream, 16, 16, iconHeaderSize + iconDirEntrySize * 4); writeIconDirEntry(stream, 32, 32, iconHeaderSize + iconDirEntrySize * 4 + getBMPSize(16, 16)); writeIconDirEntry(stream, 48, 48, iconHeaderSize + iconDirEntrySize * 4 + getBMPSize(16, 16) + getBMPSize(32, 32)); writeIconDirEntry(stream, 256, 256, iconHeaderSize + iconDirEntrySize * 4 + getBMPSize(16, 16) + getBMPSize(32, 32) + getBMPSize(48, 48)); writeBMP(stream, scale(16, 16, transparent, directory)); writeBMP(stream, scale(32, 32, transparent, directory)); writeBMP(stream, scale(48, 48, transparent, directory)); scale(256, 256, transparent, directory)->save(stream); std::vector<byte> pngSize = convertIntToByteArrayLE(static_cast<int>(stream.size()) - (iconHeaderSize + iconDirEntrySize * 4 + getBMPSize(16, 16) + getBMPSize(32, 32) + getBMPSize(48, 48))); for (int i = 0; i < 4; ++i) stream.set(i + iconHeaderSize + iconDirEntrySize * 3 + 8, pngSize[i]); stream.save(filename); }
void net::Server::sendChunkUpdate(const Client* to, const ChunkCoord& wcc, bool dirtyOnly) { auto chunk = world->getChunk(wcc); if (!dirtyOnly || clientChunkDirty(to, wcc)) { ByteStream bs; world->serializeChunk(bs, wcc); auto packet = enet_packet_create(bs.data(), bs.size(), ENET_PACKET_FLAG_RELIABLE); enet_peer_send(to->peer, CHAN_CHUNK, packet); } }
void net::Server::sendPlayerCameraUpdate(const Client* to, Entity::ID followID) { ByteStream bs; // TODO: put this somewhere better // TODO: for now, this is the only server->client message on CHAN_PLAYERCMD, // but this should have a message type later. bs.write(followID, LE); auto packet = enet_packet_create(bs.data(), bs.size(), ENET_PACKET_FLAG_RELIABLE); enet_peer_send(to->peer, CHAN_PLAYERCMD, packet); }
void Ball::exportToMacIcon(Path filename, Path directory) { //16x16 //32x32 //128x128 //256x256 //512x512 //1024x1024 ByteStream stream; stream.put('i'); stream.put('c'); stream.put('n'); stream.put('s'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('i'); stream.put('c'); stream.put('0'); stream.put('8'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('-'); scale(256, 256, transparent, directory)->save(stream); int icon08size = static_cast<int>(stream.size() - 8); stream.put('i'); stream.put('c'); stream.put('0'); stream.put('9'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('-'); scale(512, 512, transparent, directory)->save(stream); int icon09size = static_cast<int>(stream.size() - icon08size - 8); stream.put('i'); stream.put('c'); stream.put('1'); stream.put('0'); stream.put('-'); stream.put('-'); stream.put('-'); stream.put('-'); scale(1024, 1024, transparent, directory)->save(stream); int icon10size = static_cast<int>(stream.size() - icon09size - icon08size - 8); std::vector<byte> size = convertIntToByteArray(static_cast<int>(stream.size())); for (int i = 0; i < 4; ++i) stream.set( 4 + i, size[i]); size = convertIntToByteArray(icon08size); for (int i = 0; i < 4; ++i) stream.set(12 + i, size[i]); size = convertIntToByteArray(icon09size); for (int i = 0; i < 4; ++i) stream.set(icon08size + 8 + 4 + i, size[i]); size = convertIntToByteArray(icon10size); for (int i = 0; i < 4; ++i) stream.set(icon08size + icon09size + 8 + 4 + i, size[i]); stream.save(filename); }
bool ByteStream::saveToFile(const ByteStream& byteStream, const std::string& fileName) { std::ofstream file(fileName.c_str(), std::ios_base::out | std::ios_base::binary); if(!file.is_open()) { return false; } file.write(byteStream.data(), byteStream.size()); file.flush(); return true; }
ByteStream InertialPacketBuilder::buildPacket() { uint8 payloadLen = 0; ByteStream payloadBytes; //loop through all the fields for(InertialDataField field : m_fields) { //field length = (1 field len byte + 1 field desc byte + n field data bytes) size_t fieldLen = (1 + 1 + field.fieldData().size()); //increase the payload length payloadLen += static_cast<uint8>(fieldLen); //add the field length byte to the payloadBytes payloadBytes.append_uint8(static_cast<uint8>(fieldLen)); //add the field descriptor byte to the payloadBytes payloadBytes.append_uint8(field.fieldDescriptor()); //add the field data bytes to the payloadBytes (if any) payloadBytes.appendByteStream(field.fieldData()); } ByteStream result; //add the first two "Sync" bytes result.append_uint16(InertialPacketInfo::INERTIAL_PACKET_START_OF_PACKET); //add the descriptor set byte result.append_uint8(m_descriptorSet); //add the payload length byte result.append_uint8(payloadLen); //add the payloadBytes that we just built up result.appendByteStream(payloadBytes); //calculate the checksum for the packet from all the bytes uint16 checksum = result.calculateFletcherChecksum(0, result.size() - 1); //add the checksum bytes result.append_uint16(checksum); //return the result bytes that we created return result; }
void MeshSaverImplv1_0::WriteIndexData(MeshBuffer* buffer, ChunkOutputStream& outStream) { ByteStream indices; buffer->GetOptimizedIndices(indices); OutputSerializer& ser = outStream.BeginChunk(MCID_INDEX_DATA); uint32 size = (uint32)indices.size(); uint32 count = buffer->GetIndexCount(); ser << size << count; if ((size / count) == 4) { OutputSerializer::UIntArray arr(reinterpret_cast<uint32*>(indices.data()), count); ser << arr; } else { OutputSerializer::UShortArray arr(reinterpret_cast<uint16*>(indices.data()), count); ser << arr; } outStream.EndChunk(); }
void NodeEeprom::parseEepromPage(const ByteStream& pageData, uint16 pageIndex) { //get the number of bytes in the page ByteStream uint16 dataLength = static_cast<uint16>(pageData.size()); uint16 mapLocation; //loop through all the data in the page for(uint16 pos = 0; pos < dataLength; pos += 2) { //calculate the eeprom location that this value should be stored in in the map mapLocation = pos + (EEPROMS_PER_PAGE * pageIndex); //just storing everything as uint16 uint16 eepromVal = pageData.read_uint16(pos); //update the cache value updateCache(mapLocation, eepromVal); } }
void MeshSaverImplv1_0::WriteVertexBufferData(MeshBuffer* buffer, uint32 numVB, ChunkOutputStream& outStream) { ByteStream bytes; for (uint32 i = 0; i < numVB; ++i) { OutputSerializer& ser = outStream.BeginChunk(MCID_VERTEX_BUFFER_DATA); uint32 vertexCount = buffer->GetVertexCount(); uint32 vertexStride = buffer->GetVertexStride(i); uint32 bufferSize = vertexCount * vertexStride; uint16 streamIndex = (uint16)i; ser << bufferSize << vertexCount << streamIndex << vertexStride; buffer->GetVertices(i, bytes); OutputSerializer::UByteArray arr(bytes.data(), (uint32)bytes.size()); NEX_ASSERT(arr.second == bufferSize); ser << arr; outStream.EndChunk(); } }
void windowsIcon(iw_context* context, const char* filename) { //16x16 //32x32 //48x48 //256x256 ByteStream stream; writeIcoHeader(stream); writeIconDirEntry(stream, 16, 16, iconHeaderSize + iconDirEntrySize * 4); writeIconDirEntry(stream, 32, 32, iconHeaderSize + iconDirEntrySize * 4 + getBMPSize(16, 16)); writeIconDirEntry(stream, 48, 48, iconHeaderSize + iconDirEntrySize * 4 + getBMPSize(16, 16) + getBMPSize(32, 32)); writeIconDirEntry(stream, 256, 256, iconHeaderSize + iconDirEntrySize * 4 + getBMPSize(16, 16) + getBMPSize(32, 32) + getBMPSize(48, 48)); scale(context, 16, 16); iw_image img; iw_get_output_image(context, &img); writeBMP(stream, &img); scale(context, 32, 32); iw_get_output_image(context, &img); writeBMP(stream, &img); scale(context, 48, 48); iw_get_output_image(context, &img); writeBMP(stream, &img); scale(context, 256, 256); iw_get_output_image(context, &img); iw_iodescr writedescr; memset(&writedescr, 0, sizeof(struct iw_iodescr)); writedescr.write_fn = stream_writefn; writedescr.seek_fn = stream_seekfn; writedescr.fp = &stream; iw_write_file_by_fmt(context, &writedescr, IW_FORMAT_PNG); std::vector<byte> pngSize = convertIntToByteArrayLE(static_cast<int>(stream.size()) - (iconHeaderSize + iconDirEntrySize * 4 + getBMPSize(16, 16) + getBMPSize(32, 32) + getBMPSize(48, 48))); for (int i = 0; i < 4; ++i) stream.set(i + iconHeaderSize + iconDirEntrySize * 3 + 8, pngSize[i]); stream.save(filename); }
static toff_t sizeproc(thandle_t h) { ByteStream *bs = (ByteStream*)h; return (toff_t) bs->size(); }
void Client::start(){ bool hasHeader = false; Packet pak; ByteStream header; ByteStream* read = &header; pak.mData.reserve(1024); header.reserve(16); header.setDataSize(startHandshake()); bool error = false; while(!error){ if(mSocket->canRead()){ int result = mSocket->read(read->data() + read->tell(), read->size() - read->tell()); if(result == -1){ error = true; break; }else if(result > 0){ read->skip(result); if(read->tell() != read->size()) continue; if(mHandshakeStage != HS_COMPLETE){ read->setDataSize(onReceiveHandshake(read)); read->seek(0); continue; } if(!hasHeader){ uint32 hSize = Packet::getHeaderSize(*read); if(read->size() < hSize){ read->setDataSize(hSize); continue; } read->seek(0); pak.deserialise(*read); hasHeader = true; read = &pak.mData; read->seek(0); read->setDataSize(pak.mHeader.mBodySize + pak.mHeader.mBodySize / mChunkSize); }else{ read->dechunk(mChunkSize); read->seek(0); onReceivePacket(&pak); hasHeader = false; read = &header; read->seek(0); read->setDataSize(1); } } if(error) break; } if(mSocket->canWrite() && mSendData.size()){ mSendLock->lock(); while(mSendData.size()){ ByteStream* stream = mSendData.front(); mSocket->write(stream->data(), stream->size()); delete stream; mSendData.pop(); } mSendLock->unlock(); } }; mSocket->getLastError(); disconnect(); }
void net::Server::sendDeletedEntityUpdate(const Client* to, Entity::ID id) { ByteStream bs; world->entityManager.serializeEntityDelete(bs, id); auto packet = enet_packet_create(bs.data(), bs.size(), ENET_PACKET_FLAG_RELIABLE); enet_peer_send(to->peer, CHAN_ENTITY, packet); }
unsigned BlockFile::put(ByteStream const& buf, unsigned offset, unsigned minSize) { //M_REQUIRE(isOpen()); //M_REQUIRE(isReadWrite()); //M_REQUIRE(minSize <= MaxSpanSize); //M_REQUIRE(buf.size() <= MaxSpanSize); //M_REQUIRE(offset/blockSize() < countBlocks()); //M_REQUIRE( (offset + minSize - 1)/blockSize() == offset/blockSize() // fits into a single block // || offset % blockSize() == 0); // or starts at block offset 0 unsigned nbytes = buf.size(); if (nbytes == 0) return 0; unsigned blockNo = blockNumber(offset); unsigned blockOffset = this->blockOffset(offset); if (m_mode == ReadWriteLength) { minSize = retrieve(blockNo, blockOffset); if (minSize > MaxFileSize) return minSize; // it's an error code nbytes += 3; } unsigned newSpan = countSpans(nbytes); unsigned oldSpan = countSpans(minSize); if (nbytes <= minSize) { if (m_buffer.m_number != blockNo) { if (unsigned rc = fetch(blockNo, oldSpan)) return rc; } resize(newSpan); copy(buf, blockOffset, nbytes); ::zero(m_buffer.m_data + blockOffset + minSize, minSize - nbytes); m_isDirty = true; if (newSpan < oldSpan) { m_buffer.m_capacity = fileOffset(newSpan); m_buffer.m_size = nbytes; m_buffer.m_span = newSpan; unsigned span = oldSpan - newSpan - 1; if (span == 0) { if (m_buffer.m_number + newSpan == countBlocks()) { if (m_sizeInfo[m_buffer.m_number] == minSize) m_sizeInfo[m_buffer.m_number + newSpan] = 0; m_sizeInfo[m_buffer.m_number] = nbytes; } } else { if (unsigned rc = fetch(blockNo + newSpan)) return rc; m_buffer.m_size = 0; m_buffer.m_capacity = fileOffset(span); m_sizeInfo[m_buffer.m_number] = 0; } } else if (m_buffer.m_size == blockOffset + minSize) { m_sizeInfo[m_buffer.m_number] = (m_buffer.m_size -= minSize - nbytes); } } else if ( blockNo == countBlocks() - 1 && m_sizeInfo[blockNo] == blockOffset + minSize && ::modulo(offset, m_mask) + nbytes <= m_blockSize) { resize(newSpan); copy(buf, blockOffset, nbytes); m_isDirty = true; m_sizeInfo[blockNo] = (m_buffer.m_size += nbytes - minSize); } // TODO: // else if ( newSpan > 1 // && (newSpan == oldSpan || blockNo + oldSpan == countBlocks()) // && m_sizeInfo[blockNo + oldSpan - 1] == ::modulo(offset + minSize, m_mask)) // { // } else { offset = put(buf); } return offset; }
save::State DatabaseCodec::addGame(ByteStream const& gameData, GameInfo const& info, Allocation allocation) { //M_REQUIRE(isOpen()); if (m_db->size() == maxGameCount()) return save::TooManyGames; if (gameData.size() > maxGameRecordLength() || info.plyCount() > maxGameLength()) return save::GameTooLong; mstl::string whitePlayer; mstl::string blackPlayer; mstl::string event; mstl::string site; mstl::string annotator; if (allocation == Alloc) { namebase(Namebase::Player).copy(whitePlayer, info.playerName(color::White)); namebase(Namebase::Player).copy(blackPlayer, info.playerName(color::Black)); namebase(Namebase::Event).copy(event, info.event()); namebase(Namebase::Site).copy(site, info.site()); namebase(Namebase::Annotator).copy(annotator, info.annotator()); } else { whitePlayer.hook(info.playerName(color::White)); blackPlayer.hook(info.playerName(color::Black)); event.hook(info.event()); site.hook(info.site()); annotator.hook(info.annotator()); } unsigned maxAnnotatorCount = this->maxAnnotatorCount(); NamebasePlayer* whiteEntry; NamebasePlayer* blackEntry; NamebaseSite* siteEntry; NamebaseEvent* eventEntry; NamebaseEntry* annotatorEntry = NamebaseEntry::emptyEntry(); unsigned maxPlayerCount = this->maxPlayerCount(); whiteEntry = namebase(Namebase::Player).insertPlayer( whitePlayer, info.federation(color::White), info.title(color::White), info.playerType(color::White), info.sex(color::White), info.fideID(color::White), maxPlayerCount); blackEntry = namebase(Namebase::Player).insertPlayer( blackPlayer, info.federation(color::Black), info.title(color::Black), info.playerType(color::Black), info.sex(color::Black), info.fideID(color::Black), maxPlayerCount); siteEntry = namebase(Namebase::Site).insertSite( site, info.eventCountry(), maxSiteCount()); eventEntry = namebase(Namebase::Event).insertEvent( event, info.eventDate(), info.eventType(), info.timeMode(), info.eventMode(), maxEventCount(), siteEntry ?siteEntry : NamebaseEvent::emptySite()); if (maxAnnotatorCount) annotatorEntry = namebase(Namebase::Annotator).insert(annotator, maxAnnotatorCount); bool failed = whiteEntry == 0 || blackEntry == 0 || eventEntry == 0 || siteEntry == 0 || annotatorEntry == 0; save::State state = save::Ok; if (!failed && format() != format::Scidb) { } unsigned gameOffset = 0; // shut up compiler if (failed || int(gameOffset = putGame(gameData)) < 0) { namebases().update(); switch (gameOffset) { /*case util::BlockFile::MaxFileSizeExceeded: IO_RAISE(Game, Max_File_Size_Exceeded, "maximal file size (2 GB) exceeded"); case util::BlockFile::SyncFailed: IO_RAISE(Game, Write_Failed, "sync failed"); case util::BlockFile::ReadError: IO_RAISE(Game, Read_Error, "read error"); case util::BlockFile::IllegalOffset: IO_RAISE(Game, Write_Failed, "offset failure (internal error)");*/ } if (!whiteEntry) return save::TooManyPlayerNames; if (!blackEntry) return save::TooManyPlayerNames; if (!eventEntry) return save::TooManyEventNames; if (!siteEntry) return save::TooManySiteNames; return save::TooManyAnnotatorNames; } GameInfo* i = allocGameInfo(); *i = info; i->setup( gameOffset, gameData.size(), whiteEntry, blackEntry, eventEntry, annotatorEntry, m_db->m_namebases); m_db->m_gameInfoList.push_back(i); return state; }
save::State DatabaseCodec::saveGame(ByteStream const& gameData, TagSet const& tags, Provider const& provider) { //M_REQUIRE(isOpen()); typedef Namebase::PlayerEntry* Player; typedef Namebase::EventEntry* Event; typedef Namebase::SiteEntry* Site; typedef Namebase::Entry* Entry; if (gameData.size() > maxGameRecordLength()) return save::GameTooLong; if (provider.plyCount() > maxGameLength()) return save::GameTooLong; GameInfo* info = 0; unsigned index; if (provider.index() >= 0) { index = provider.index(); info = m_db->m_gameInfoList[index]; *m_storedInfo = *info; info->reset(m_db->m_namebases); } else if (m_db->size() == maxGameCount()) { return save::TooManyGames; } else { index = m_db->m_gameInfoList.size(); } unsigned maxAnnotatorCount = this->maxAnnotatorCount(); unsigned maxPlayerCount = this->maxPlayerCount(); InfoData data(tags); Player whiteEntry; Player blackEntry; Site siteEntry; switch (provider.sourceFormat()) { case format::Scid3: case format::Scid4: { mstl::string name; whiteEntry = namebase(Namebase::Player).insertPlayer( ::normalizePlayerName(tags.value(tag::White), name), data.whiteCountry, data.whiteTitle, data.whiteType, data.whiteSex, data.whiteFideID, maxPlayerCount); blackEntry = namebase(Namebase::Player).insertPlayer( ::normalizePlayerName(tags.value(tag::Black), name), data.blackCountry, data.blackTitle, data.blackType, data.blackSex, data.blackFideID, maxPlayerCount); siteEntry = namebase(Namebase::Site).insertSite( ::normalizeSiteName(tags.value(tag::Site), name), data.eventCountry, maxSiteCount()); } break; default: whiteEntry = namebase(Namebase::Player).insertPlayer( tags.value(tag::White), data.whiteCountry, data.whiteTitle, data.whiteType, data.whiteSex, data.whiteFideID, maxPlayerCount); blackEntry = namebase(Namebase::Player).insertPlayer( tags.value(tag::Black), data.blackCountry, data.blackTitle, data.blackType, data.blackSex, data.blackFideID, maxPlayerCount); siteEntry = namebase(Namebase::Site).insertSite( tags.value(tag::Site), data.eventCountry, maxSiteCount()); } Event eventEntry = namebase(Namebase::Event).insertEvent( tags.value(tag::Event), data.eventDate, data.eventType, data.timeMode, data.eventMode, maxEventCount(), siteEntry ? siteEntry : NamebaseEvent::emptySite()); Entry annotatorEntry = NamebaseEntry::emptyEntry(); if (maxAnnotatorCount) { annotatorEntry = namebase(Namebase::Annotator).insert(tags.value(tag::Annotator), maxAnnotatorCount); } save::State state = save::Ok; bool failed = whiteEntry == 0 || blackEntry == 0 || eventEntry == 0 || siteEntry == 0 || annotatorEntry == 0; unsigned gameOffset = 0; // shut up compiler if (!failed) { if (info) gameOffset = putGame(gameData, info->gameOffset(), info->gameRecordLength()); else gameOffset = putGame(gameData); } if (failed || int(gameOffset) < 0) { if (info) info->restore(*m_storedInfo, m_db->m_namebases); namebases().update(); switch (gameOffset) { /*case util::BlockFile::MaxFileSizeExceeded: IO_RAISE(Game, Max_File_Size_Exceeded, "maximal file size (2 GB) exceeded"); case util::BlockFile::SyncFailed: IO_RAISE(Game, Write_Failed, "sync failed"); case util::BlockFile::ReadError: IO_RAISE(Game, Read_Error, "read error"); case util::BlockFile::IllegalOffset: IO_RAISE(Game, Write_Failed, "offset failure (internal error)");*/ } if (!whiteEntry) return save::TooManyPlayerNames; if (!blackEntry) return save::TooManyPlayerNames; if (!eventEntry) return save::TooManyEventNames; if (!siteEntry) return save::TooManySiteNames; return save::TooManyAnnotatorNames; } if (info == 0) { info = allocGameInfo(); m_db->m_gameInfoList.push_back(info); } info->setup(gameOffset, gameData.size(), whiteEntry, blackEntry, eventEntry, annotatorEntry, tags, provider, m_db->m_namebases); return state; }
Decoder::Decoder(ByteStream& strm) :m_strm(strm) ,m_ensuredStreamSize(strm.size()) ,m_currentNode(0) { }
unsigned BlockFile::put(ByteStream const& buf) { //M_REQUIRE(isOpen()); //M_REQUIRE(isReadWrite()); //M_REQUIRE(buf.size() <= MaxSpanSize); size_t nbytes = buf.size(); if (nbytes == 0) return 0; if (m_mode == ReadWriteLength) nbytes += 3; size_t span = countSpans(nbytes); if (m_buffer.m_capacity == 0) { //M_ASSERT(m_buffer.m_number == InvalidBlock); //M_ASSERT(m_buffer.m_size == 0); //M_ASSERT(m_isDirty == false); // create first block resize(span); if (m_sizeInfo.empty()) { if (m_stream == 0) m_cache.push_back(m_buffer.m_data); m_sizeInfo.push_back(0); m_buffer.m_number = 0; } else if ((m_buffer.m_size = m_sizeInfo.back()) + nbytes <= m_blockSize) { if (unsigned rc = fetch(m_sizeInfo.size() - 1, span)) return rc; } } //M_ASSERT(m_buffer.m_data); //M_ASSERT(m_buffer.m_number != InvalidBlock); //M_ASSERT(!m_sizeInfo.empty()); if (m_buffer.m_size + nbytes <= m_blockSize) { // use current block } else if (lastBlockSize() + nbytes <= m_blockSize) { // use last block if (unsigned rc = fetch(countBlocks() - 1)) return rc; } else { // need new block if (fileOffset(countBlocks() + 1) > MaxFileSize) return MaxFileSizeExceeded; if (m_stream) { if (!sync()) return SyncFailed; resize(span); ::zero(m_buffer.m_data, m_buffer.m_capacity); } else { m_buffer.m_size = fileOffset(span); m_buffer.m_data = new Byte[m_buffer.m_size]; m_buffer.m_capacity = mstl::max(m_buffer.m_capacity, m_buffer.m_size); for (unsigned i = 0; i < span; ++i) m_cache.push_back(m_buffer.m_data + fileOffset(i)); } m_buffer.m_number = m_sizeInfo.size(); m_buffer.m_size = 0; if (span >= 2) { m_sizeInfo.push_back(fileOffset(span)); m_sizeInfo.insert(m_sizeInfo.end(), SizeInfo::size_type(span - 2), m_blockSize); } m_sizeInfo.push_back(0); } //M_ASSERT(m_buffer.m_size + nbytes <= m_buffer.m_capacity); //M_ASSERT(m_buffer.m_size + nbytes <= m_blockSize || nbytes > m_blockSize); copy(buf, m_buffer.m_size, nbytes); m_isDirty = true; unsigned offset = fileOffset(m_buffer.m_number) + m_buffer.m_size; //M_ASSERT(offset <= MaxFileSize); m_buffer.m_size += nbytes; m_sizeInfo[m_buffer.m_number + span - 1] = ::modulo(m_buffer.m_size, m_mask); return offset; }