size_t VirtualDiscFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) {
	EntryMap::iterator iter = entries.find(handle);
	if (iter != entries.end())
	{
		// it's the whole iso... it could reference any of the files on the disc.
		// For now let's just open and close the files on demand. Can certainly be done
		// better though
		if (iter->second.type == VFILETYPE_ISO)
		{
			int fileIndex = getFileListIndex(iter->second.curOffset,size*2048,true);
			if (fileIndex == -1)
			{
				ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Reading from unknown address in %08x at %08llx", handle, iter->second.curOffset);
				return 0;
			}

			OpenFileEntry temp;
			if (fileList[fileIndex].handler != NULL) {
				temp.handler = fileList[fileIndex].handler;
			}
			bool success = temp.Open(basePath, fileList[fileIndex].fileName, FILEACCESS_READ);

			if (!success)
			{
				ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Error opening file %s", fileList[fileIndex].fileName.c_str());
				return 0;
			}

			u32 startOffset = (iter->second.curOffset-fileList[fileIndex].firstBlock)*2048;
			size_t bytesRead;

			temp.Seek(startOffset, FILEMOVE_BEGIN);

			u32 remainingSize = fileList[fileIndex].totalSize-startOffset;
			if (remainingSize < size * 2048)
			{
				// the file doesn't fill the whole last sector
				// read what's there and zero fill the rest like on a real disc
				bytesRead = temp.Read(pointer, remainingSize);
				memset(&pointer[bytesRead], 0, size * 2048 - bytesRead);
			} else {
				bytesRead = temp.Read(pointer, size * 2048);
			}

			temp.Close();

			iter->second.curOffset += size;
			return size;
		}

		size_t bytesRead = iter->second.Read(pointer, size);
		iter->second.curOffset += bytesRead;
		return bytesRead;
	} else {
		//This shouldn't happen...
		ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Cannot read file that hasn't been opened: %08x", handle);
		return 0;
	}
}
예제 #2
0
size_t VirtualDiscFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) {
	EntryMap::iterator iter = entries.find(handle);
	if (iter != entries.end()) {
		if (size < 0) {
			ERROR_LOG_REPORT(FILESYS, "Invalid read for %lld bytes from virtual umd", size);
			return 0;
		}

		// it's the whole iso... it could reference any of the files on the disc.
		// For now let's just open and close the files on demand. Can certainly be done
		// better though
		if (iter->second.type == VFILETYPE_ISO)
		{
			int fileIndex = getFileListIndex(iter->second.curOffset,size*2048,true);
			if (fileIndex == -1)
			{
				ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Reading from unknown address in %08x at %08llx", handle, iter->second.curOffset);
				return 0;
			}

			OpenFileEntry temp;
			if (fileList[fileIndex].handler != NULL) {
				temp.handler = fileList[fileIndex].handler;
			}
			bool success = temp.Open(basePath, fileList[fileIndex].fileName, FILEACCESS_READ);

			if (!success)
			{
				ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Error opening file %s", fileList[fileIndex].fileName.c_str());
				return 0;
			}

			u32 startOffset = (iter->second.curOffset-fileList[fileIndex].firstBlock)*2048;
			size_t bytesRead;

			temp.Seek(startOffset, FILEMOVE_BEGIN);

			u32 remainingSize = fileList[fileIndex].totalSize-startOffset;
			if (remainingSize < size * 2048)
			{
				// the file doesn't fill the whole last sector
				// read what's there and zero fill the rest like on a real disc
				bytesRead = temp.Read(pointer, remainingSize);
				memset(&pointer[bytesRead], 0, size * 2048 - bytesRead);
			} else {
				bytesRead = temp.Read(pointer, size * 2048);
			}

			temp.Close();

			iter->second.curOffset += size;
			// TODO: This probably isn't enough...
			if (abs((int)lastReadBlock_ - (int)iter->second.curOffset) > 100) {
				// This is an estimate, sometimes it takes 1+ seconds, but it definitely takes time.
				usec = 100000;
			}
			lastReadBlock_ = iter->second.curOffset;
			return size;
		}

		if (iter->second.type == VFILETYPE_LBN && iter->second.curOffset + size > iter->second.size) {
			// Clamp to the remaining size, but read what we can.
			const s64 newSize = iter->second.size - iter->second.curOffset;
			WARN_LOG(FILESYS, "VirtualDiscFileSystem: Reading beyond end of file, clamping size %lld to %lld", size, newSize);
			size = newSize;
		}

		size_t bytesRead = iter->second.Read(pointer, size);
		iter->second.curOffset += bytesRead;
		return bytesRead;
	} else {
		//This shouldn't happen...
		ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Cannot read file that hasn't been opened: %08x", handle);
		return 0;
	}
}