Пример #1
0
void dng_memory_stream::DoRead (void *data,
							    uint32 count,
							    uint64 offset)
	{
	
	if (offset + count > fMemoryStreamLength)
		{
		
		ThrowEndOfFile ();
		
		}
		
	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 = fPageList [pageIndex]->Buffer_uint8 () +
						    pageOffset;
		
		uint8 *dPtr = ((uint8 *) data) + (uint32) (offset - baseOffset);
		
		DoCopyBytes (sPtr, dPtr, blockCount);
		
		offset += blockCount;
		count  -= blockCount;
		
		}
	
	}
Пример #2
0
void dng_stream::SetReadPosition (uint64 offset)
	{
	
	fPosition = offset;
	
	if (fPosition > Length ())
		{
		
		ThrowEndOfFile ();

		}
	
	}
Пример #3
0
void dng_memory_stream::CopyToStream (dng_stream &dstStream,
									  uint64 count)
	{
	
	if (count < kBigBufferSize)
		{
	
		dng_stream::CopyToStream (dstStream, count);
		
		}
		
	else
		{
		
		Flush ();
		
		uint64 offset = Position ();
		
		if (offset + count > Length ())
			{
			
			ThrowEndOfFile ();
			
			}
			
		while (count)
			{
			
			uint32 pageIndex  = (uint32) (offset / fPageSize);
			uint32 pageOffset = (uint32) (offset % fPageSize);
			
			uint32 blockCount = (uint32) Min_uint64 (fPageSize - pageOffset, count);
			
			const uint8 *sPtr = fPageList [pageIndex]->Buffer_uint8 () +
								pageOffset;
								
			dstStream.Put (sPtr, blockCount);
			
			offset += blockCount;
			count  -= blockCount;
			
			}
			
		SetReadPosition (offset);
	
		}
	
	}
Пример #4
0
void dng_stream::Get (void *data, uint32 count)
	{
	
	while (count)
		{
		
		// See if the request is totally inside buffer.
		
		if (fPosition >= fBufferStart && fPosition + count <= fBufferEnd)
			{
			
			DoCopyBytes (fBuffer + (uint32) (fPosition - fBufferStart),
						 data,
						 count);
						 
			fPosition += count;
			
			return;
			
			}
			
		// See if first part of request is inside buffer.
		
		if (fPosition >= fBufferStart && fPosition < fBufferEnd)
			{
			
			uint32 block = (uint32) (fBufferEnd - fPosition);
			
			DoCopyBytes (fBuffer + (fPosition - fBufferStart),
						 data,
						 block);
			
			count -= block;
			
			data = (void *) (((char *) data) + block);
			
			fPosition += block;
			
			}
			
		// Flush buffer if dirty.
		
		Flush ();
		
		// Do large reads unbuffered.
		
		if (count > fBufferSize)
			{
			
			if (fPosition + count > Length ())
				{
				
				ThrowEndOfFile ();
				
				}
				
			DoRead (data,
					count,
					fPosition);
					
			fPosition += count;
			
			return;
			
			}
			
		// Figure out new buffer range.
		
		fBufferStart = fPosition;
		
		if (fBufferSize >= 4096)
			{
			
			// Align to a 4K file block.
			
			fBufferStart &= (uint64) ~((int64) 4095);
			
			}
		
		fBufferEnd = Min_uint64 (fBufferStart + fBufferSize, Length ());
		
		if (fBufferEnd <= fPosition)
			{
			
			ThrowEndOfFile ();

			}
			
		// Read data into buffer.
		
		dng_abort_sniffer::SniffForAbort (fSniffer);
		
		DoRead (fBuffer,
				(uint32) (fBufferEnd - fBufferStart),
				fBufferStart);
		
		}

	}