示例#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_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;
		
		}
	
	}
示例#3
0
dng_opcode_MapTable::dng_opcode_MapTable (dng_host &host,
										  const dng_area_spec &areaSpec,
										  const uint16 *table,
										  uint32 count)

	:	dng_inplace_opcode (dngOpcode_MapTable,
							dngVersion_1_3_0_0,
							kFlag_None)

	,	fAreaSpec (areaSpec)
	,	fTable    ()
	,	fCount    (count)

	{

	if (count == 0 || count > 0x10000)
		{
		ThrowProgramError ();
		}

	fTable.Reset (host.Allocate (0x10000 * sizeof (uint16)));

	DoCopyBytes (table,
				 fTable->Buffer (),
				 count * sizeof (uint16));

	ReplicateLastEntry ();

	}
示例#4
0
void dng_memory_stream::DoSetLength (uint64 length)
	{
	
	while (length > fPageCount * (uint64) fPageSize)
		{
		
		if (fPageCount == fPagesAllocated)
			{
			
			uint32 newSize = Max_uint32 (fPagesAllocated + 32,
										 fPagesAllocated * 2);
			
			dng_memory_block **list = (dng_memory_block **)
									  malloc (newSize * sizeof (dng_memory_block *));
			
			if (!list)
				{
				
				ThrowMemoryFull ();
				
				}
			
			if (fPageCount)
				{
				
				DoCopyBytes (fPageList,
							 list,
							 fPageCount * (uint32) sizeof (dng_memory_block *));
				
				}
				
			if (fPageList)
				{
				
				free (fPageList);
				
				}
				
			fPageList = list;
			
			fPagesAllocated = newSize;
			
			}
			
		fPageList [fPageCount] = fAllocator.Allocate (fPageSize);
		
		fPageCount++;
		
		}
		
	fMemoryStreamLength = length;
	
	}
示例#5
0
void dng_string_list::Allocate (uint32 minSize)
	{
	
	if (fAllocated < minSize)
		{
		
		uint32 newSize = Max_uint32 (minSize, fAllocated * 2);
		
		dng_string **list = (dng_string **)
							malloc (newSize * sizeof (dng_string *));
		
		if (!list)
			{
			
			ThrowMemoryFull ();
			
			}
		
		if (fCount)
			{
			
			DoCopyBytes (fList, list, fCount * sizeof (dng_string *));
			
			}
			
		if (fList)
			{
			
			free (fList);
			
			}
			
		fList = list;
		
		fAllocated = newSize;
		
		}
	
	}
示例#6
0
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);
	
	}
示例#7
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);
		
		}

	}