129 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (C) 2002-2012 Nikolaus Gebhardt
 | |
| // This file is part of the "Irrlicht Engine".
 | |
| // For conditions of distribution and use, see copyright notice in irrlicht.h
 | |
| 
 | |
| #include "CLimitReadFile.h"
 | |
| #include "irrMath.h"
 | |
| #include "irrString.h"
 | |
| 
 | |
| namespace irr
 | |
| {
 | |
| namespace io
 | |
| {
 | |
| 
 | |
| 
 | |
| CLimitReadFile::CLimitReadFile(IReadFile* alreadyOpenedFile, long pos,
 | |
| 		long areaSize, const io::path& name)
 | |
| 	: Filename(name), AreaStart(0), AreaEnd(0), Pos(0),
 | |
| 	File(alreadyOpenedFile)
 | |
| {
 | |
| 	#ifdef _DEBUG
 | |
| 	setDebugName("CLimitReadFile");
 | |
| 	#endif
 | |
| 
 | |
| 	if (File)
 | |
| 	{
 | |
| 		File->grab();
 | |
| 		AreaStart = pos;
 | |
| 		AreaEnd = AreaStart + areaSize;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| CLimitReadFile::~CLimitReadFile()
 | |
| {
 | |
| 	if (File)
 | |
| 		File->drop();
 | |
| }
 | |
| 
 | |
| 
 | |
| //! returns how much was read
 | |
| size_t CLimitReadFile::read(void* buffer, size_t sizeToRead)
 | |
| {
 | |
| 	if (0 == File)
 | |
| 		return 0;
 | |
| 
 | |
| #if 1
 | |
| 	long r = AreaStart + Pos;
 | |
| 	long toRead = core::min_(AreaEnd, r + (long)sizeToRead) - core::max_(AreaStart, r);
 | |
| 	if (toRead < 0)
 | |
| 		return 0;
 | |
| 	File->seek(r);
 | |
| 	r = (long)File->read(buffer, toRead);
 | |
| 	Pos += r;
 | |
| 	return r;
 | |
| #else
 | |
| 	const long pos = File->getPos();
 | |
| 
 | |
| 	if (pos >= AreaEnd)
 | |
| 		return 0;
 | |
| 
 | |
| 	if (pos + (long)sizeToRead >= AreaEnd)
 | |
| 		sizeToRead = AreaEnd - pos;
 | |
| 
 | |
| 	return File->read(buffer, sizeToRead);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| //! changes position in file, returns true if successful
 | |
| bool CLimitReadFile::seek(long finalPos, bool relativeMovement)
 | |
| {
 | |
| #if 1
 | |
| 	Pos = core::s32_clamp(finalPos + (relativeMovement ? Pos : 0 ), 0, AreaEnd - AreaStart);
 | |
| 	return true;
 | |
| #else
 | |
| 	const long pos = File->getPos();
 | |
| 
 | |
| 	if (relativeMovement)
 | |
| 	{
 | |
| 		if (pos + finalPos > AreaEnd)
 | |
| 			finalPos = AreaEnd - pos;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		finalPos += AreaStart;
 | |
| 		if (finalPos > AreaEnd)
 | |
| 			return false;
 | |
| 	}
 | |
| 
 | |
| 	return File->seek(finalPos, relativeMovement);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| //! returns size of file
 | |
| long CLimitReadFile::getSize() const
 | |
| {
 | |
| 	return AreaEnd - AreaStart;
 | |
| }
 | |
| 
 | |
| 
 | |
| //! returns where in the file we are.
 | |
| long CLimitReadFile::getPos() const
 | |
| {
 | |
| #if 1
 | |
| 	return Pos;
 | |
| #else
 | |
| 	return File->getPos() - AreaStart;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| //! returns name of file
 | |
| const io::path& CLimitReadFile::getFileName() const
 | |
| {
 | |
| 	return Filename;
 | |
| }
 | |
| 
 | |
| 
 | |
| IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize)
 | |
| {
 | |
| 	return new CLimitReadFile(alreadyOpenedFile, pos, areaSize, fileName);
 | |
| }
 | |
| 
 | |
| 
 | |
| } // end namespace io
 | |
| } // end namespace irr
 | |
| 
 |