void dng_memory_stream::DoWrite (const void *data, uint32 count, uint64 offset) { DoSetLength (Max_uint64 (fMemoryStreamLength, offset + count)); uint64 baseOffset = offset; while (count) { uint32 pageIndex = (uint32) (offset / fPageSize); uint32 pageOffset = (uint32) (offset % fPageSize); uint32 blockCount = Min_uint32 (fPageSize - pageOffset, count); const uint8 *sPtr = ((const uint8 *) data) + (uint32) (offset - baseOffset); uint8 *dPtr = fPageList [pageIndex]->Buffer_uint8 () + pageOffset; DoCopyBytes (sPtr, dPtr, blockCount); offset += blockCount; count -= blockCount; } }
void dng_stream::Put (const void *data, uint32 count) { // See if we can replace or append to the existing buffer. uint64 endPosition = fPosition + count; if (fBufferDirty && fPosition >= fBufferStart && fPosition <= fBufferEnd && endPosition <= fBufferLimit) { DoCopyBytes (data, fBuffer + (uint32) (fPosition - fBufferStart), count); if (fBufferEnd < endPosition) fBufferEnd = endPosition; } // Else we need to write to the file. else { // Write existing buffer. Flush (); // Write large blocks unbuffered. if (count >= fBufferSize) { dng_abort_sniffer::SniffForAbort (fSniffer); DoWrite (data, count, fPosition); } // Start a new buffer with small blocks. else { fBufferDirty = true; fBufferStart = fPosition; fBufferEnd = endPosition; fBufferLimit = fBufferStart + fBufferSize; DoCopyBytes (data, fBuffer, count); } } fPosition = endPosition; fLength = Max_uint64 (Length (), fPosition); }