size_t IStream::ReadToStream(size_t size, IStream& dest, size_t bufferSize/*=1024*/)const { RETURN_ZERO_IF_FALSE(CanRead() && dest.CanWrite()); if (dest.IsPtrAvailable())//could directly write { dest.ReserveLeftSize(size); byte* buffer = dest.MutablePtr(); MemoryData destBuffer = MemoryData::FromStatic(buffer, size); return ReadDataTo(destBuffer, DataReadingMode::AlwaysCopy); } else { //should use temp buffer size_t count = 0; size_t realBufferSize = Math::Min(LeftLength(), bufferSize, size); MemoryData tempBuffer = MemoryData::Alloc(realBufferSize); do { size_t readSize = Math::Min(size, realBufferSize); tempBuffer.ForceSetSize(readSize); readSize = ReadDataTo(tempBuffer, DataReadingMode::AlwaysCopy); BREAK_IF_ZERO(readSize); tempBuffer.ForceSetSize(readSize); count += dest.WriteData(tempBuffer); tempBuffer.ForceSetSize(realBufferSize); size -= readSize; } while (size > 0); return count; } }
size_t BufferStream::ReadDataTo(MemoryData& outData, DataReadingMode mode/*=DataReadingMode::AlwaysCopy*/)const { RETURN_ZERO_IF_FALSE(CanRead()); FlushOnReadWrite(StreamDataOperation::Read); size_t outPos = 0; size_t outSize = outData.Size(); //read left buffer data size_t bufferLeftLength = mBufferLength - mBuffer.Position(); if (bufferLeftLength != 0) { size_t readSize = Math::Min(bufferLeftLength, outSize); MemoryData tempData = MemoryData::FromStatic(outData.MutableData() + outPos, readSize); readSize = mBuffer.ReadDataTo(tempData, DataReadingMode::AlwaysCopy); outPos += readSize; outSize -= readSize; } //directly read to out data block per block size_t blockSize = mBuffer.Length(); size_t blockCount = outSize / blockSize; FOR_EACH_SIZE(i, blockCount) { MemoryData tempData = MemoryData::FromStatic(outData.MutableData() + outPos, blockSize); size_t readSize = mSourceStream->ReadDataTo(tempData); outPos += readSize; outSize -= readSize; if (readSize != blockSize) //last block { return outPos; } }
size_t IStream::ReadDataToString(WHeapString& outString, int readCount/*=0*/, bool withNullTermitated /*= false*/)const { RETURN_ZERO_IF_FALSE(CanRead()); uintp readSize = 0; if (readCount == 0) { readSize = Math::Min(outString.LeftLength()*sizeof(wchar_t), LeftLength()); } else if (readCount < 0) { readSize = LeftLength(); outString.ReserveLeftLength(readSize/sizeof(wchar_t)); } else { readSize = Math::Min((size_t)readCount, LeftLength()); outString.ReserveLeftLength(readSize/sizeof(wchar_t)); } MemoryData outData = MemoryData::FromStatic((const byte*)outString.LeftPtr(), readSize*sizeof(wchar_t)); size_t count = ReadDataTo(outData, DataReadingMode::AlwaysCopy); if (withNullTermitated) { count -= sizeof(wchar_t); } outString.ForceAppendLength(count / sizeof(wchar_t)); return count; }
size_t HashStream::WriteString(const WStringRef& str, bool withNullTermitated /*= true*/) { RETURN_ZERO_IF_FALSE(CanWrite()); MemoryData data = str.ToData().Cast<byte>(); size_t size = WriteData(data); if (withNullTermitated) { size += WriteChar(L'\0') ? sizeof(wchar_t) : 0; } return size; }
size_t IStream::CopyTo(IStream& dest, size_t bufferSize/*=1024*/)const { RETURN_ZERO_IF_FALSE(CanRead() && dest.CanWrite()); size_t realBufferSize = Math::Min(LeftLength(), bufferSize); size_t count = 0; MemoryData buffer = MemoryData::Alloc(realBufferSize); do { size_t readSize = ReadDataTo(buffer, DataReadingMode::AlwaysCopy); BREAK_IF_ZERO(readSize); buffer.ForceSetSize(readSize); count += dest.WriteData(buffer); buffer.ForceSetSize(realBufferSize); } while (true); return count; }
size_t BlockWriteStream::WriteData(const MemoryByteData& data, DataReadingMode mode /*= DataReadingMode::AlwaysCopy*/) { RETURN_ZERO_IF_FALSE(CanWrite()); size_t dataPos = 0; size_t dataSize = data.Size(); if (mBuffer.Position() > 0) { size_t bufferLeftLength = mBuffer.LeftLength(); size_t writeSize = Math::Min(bufferLeftLength, dataSize); MemoryByteData tempData = MemoryByteData::FromStatic(data.Data(), writeSize); writeSize = mBuffer.WriteData(tempData, mode); dataPos += writeSize; dataSize -= writeSize; if (mBuffer.IsEnd()) { WriteCurrentBlock(); ++mBlockIndex; } else { //all data write to buffer return dataPos; } } //directly write data block per block size_t blockSize = mBuffer.Length(); size_t blockCount = dataSize / blockSize; FOR_EACH_SIZE(i, blockCount) { MemoryByteData tempData = MemoryByteData::FromStatic(data.Data() + dataPos, blockSize); size_t writeSize = WriteBlock(mBlockIndex, tempData); ++mBlockIndex; dataPos += writeSize; dataSize -= writeSize; }
size_t BlockReadStream::ReadDataTo(MemoryByteData& outData, DataReadingMode mode/*=DataReadingMode::AlwaysCopy*/)const { RETURN_ZERO_IF_FALSE(CanRead()); size_t outPos = 0; size_t outSize = outData.Size(); //read left buffer data size_t bufferLeftLength = mBufferLength - mBuffer.Position(); if (bufferLeftLength != 0) { size_t readSize = Math::Min(bufferLeftLength, outSize); MemoryByteData tempData = MemoryByteData::FromStatic(outData.MutableData(), readSize); readSize = mBuffer.ReadDataTo(tempData, DataReadingMode::AlwaysCopy); outPos += readSize; outSize -= readSize; } if (outSize > 0) { mBuffer.Rewind(); mBufferLength = 0; //directly read to out data block per block size_t blockSize = mBuffer.Length(); size_t blockCount = outSize / blockSize; FOR_EACH_SIZE(i, blockCount) { MemoryByteData tempData = MemoryByteData::FromStatic(outData.MutableData() + outPos, blockSize); MemoryStream tempStream(tempData); ++mBlockIndex; size_t readSize = LoadBlockTo(mBlockIndex, tempStream); outPos += readSize; outSize -= readSize; if (readSize != blockSize) //reach file end { return outPos; } }