コード例 #1
0
ファイル: APModuleLoader.cpp プロジェクト: pulkomandy/APlayer
bool APModuleLoader::LoadModule(PString fileName, bool changeType, PString &errorStr)
{
	APAgent_DecrunchFile decrunchInfo;
	APAgent_ConvertModule convInfo;
	APMRSWList<AddOnInfo *> *infoList;
	bool modConverted = false;
	bool foundType = false;
	bool result = false;
	ap_result apResult;

	// Allocate the file object
	file = new PCacheFile();
	if (file == NULL)
		throw PMemoryException();

	try
	{
		// Initialize the converter structure
		convInfo.moduleFile         = NULL;
		convInfo.newModuleFile      = NULL;

		// Initialize the decruncher structure
		decrunchInfo.file           = file;
		decrunchInfo.decrunchedFile = NULL;

		// Open the module
		decrunchInfo.file->Open(fileName, PFile::pModeReadWrite | PFile::pModeShareRead | PFile::pModeNoTruncate);

		// Get the original length of the file
		fileLength = decrunchInfo.file->GetLength();

		// Decrunch the file
		DecrunchFile(&decrunchInfo);

		// Copy the file used for decrunching into the converter structure
		convInfo.moduleFile = decrunchInfo.file;

		// Well, lock the player list
		infoList = &GetApp()->playerInfo;
		infoList->WaitToRead();

		try
		{
			// Check to see if we can find a player via
			// the file type
			if (!FindPlayerViaFileType(convInfo.moduleFile))
			{
				// No player could be found via the file type.
				// Now try to convert the module
				modConverted = ConvertModule(&convInfo);

				// Try all the players to see if we can find
				// one that understand the file format
				if (FindPlayer(convInfo.moduleFile))
					result = true;
			}
			else
			{
				foundType = true;
				result    = true;
			}

			// Did we found a player?
			if (result)
			{
				PString typeString;
				PString playerError;

				// Yap, change the file type
				if (changeType && !foundType)
				{
					try
					{
						// Change the module type on the file
						if (modConverted)
						{
							if (convInfo.fileType.IsEmpty())
								typeString = player->GetModTypeString(playerInfo->index);
							else
								typeString = convInfo.fileType;
						}
						else
							typeString = player->GetModTypeString(playerInfo->index);

						if (!typeString.IsEmpty())
							file->SetFileType(typeString);
					}
					catch(PFileException e)
					{
						// If we can't set the file type, we ignore the error.
						// An error will occure on e.g. CD-ROM disks
						;
					}
				}

				// Yap, load the module
				convInfo.moduleFile->SeekToBegin();
				apResult = player->LoadModule(playerInfo->index, convInfo.moduleFile, playerError);

				if (apResult != AP_OK)
				{
					// Well, something went wrong when loading the file
					//
					// Build the error string
					errorStr.Format_S3(GetApp()->resource, IDS_CMDERR_LOAD_MODULE, fileName, playerInfo->addOnName, playerError);

					// Delete the player
					playerInfo->loader->DeleteInstance(player);
					player     = NULL;
					playerInfo = NULL;

					result = false;
				}
				else
				{
					// Get module information
					playerName = playerInfo->addOnName;

					if (modConverted)
					{
						moduleFormat = convInfo.modKind;
						if (moduleFormat.IsEmpty())
							moduleFormat = playerInfo->addOnName;
					}
					else
						moduleFormat = playerInfo->addOnName;

					// Should the file still be open?
					if (player->GetSupportFlags(playerInfo->index) & appDontCloseFile)
					{
						// Yes, remember the file pointer
						if (modConverted)
						{
							usingFile = convInfo.newModuleFile;
							convInfo.newModuleFile = NULL;
						}
						else
						{
							usingFile = file;
							file      = NULL;
						}
					}
				}
			}
			else
			{
				// Nup, send an error back
				errorStr.Format_S1(GetApp()->resource, IDS_CMDERR_UNKNOWN_MODULE, fileName);
			}
		}
		catch(...)
		{
			infoList->DoneReading();
			throw;
		}

		// Done with the list
		infoList->DoneReading();
	}
	catch(PFileException e)
	{
		PString err;
		char *fileStr, *errStr;

		// Build error message
		err = PSystem::GetErrorString(e.errorNum);
		errorStr.Format(GetApp()->resource, IDS_CMDERR_FILE, (fileStr = fileName.GetString()), e.errorNum, (errStr = err.GetString()));
		err.FreeBuffer(errStr);
		fileName.FreeBuffer(fileStr);
		result = false;
	}
	catch(...)
	{
		;
	}

	// Close the files again
	delete convInfo.newModuleFile;
	delete file;
	file = NULL;

	return (result);
}
コード例 #2
0
ファイル: SIDStil.cpp プロジェクト: pulkomandy/APlayer
bool SIDStil::GetField(PString &result, PString buffer, int32 tuneNo, STILField field)
{
	int32 start, firstTuneNo, temp, temp2 = -1;

	// Clean out the result buffer first
	result.MakeEmpty();

	// Position pointer to the first char beyond the file designation
	start = buffer.Find('\n');
	start++;

	// Check whether this is a NULL entry or not
	if (start == 0)
		return (false);

	// Is this a multitune entry?
	firstTuneNo = buffer.Find("(#", start);

	// This is a tune designation only if the previous char was
	// a newline (ie. if the "(#" is on the beginning of a line).
	if ((firstTuneNo >= 1) && (buffer.GetAt(firstTuneNo - 1) != '\n'))
		firstTuneNo = -1;

	if (firstTuneNo == -1)
	{
		//-------------------//
		// SINGLE TUNE ENTRY //
		//-------------------//
		//
		// Is the first thing in this STIL entry the COMMENT?
		temp = buffer.Find(_COMMENT_STR, start);

		// Search for other potential fields beyond the COMMENT
		if (temp == start)
		{
			temp2 = buffer.Find(_NAME_STR, start);
			if (temp2 == -1)
			{
				temp2 = buffer.Find(_AUTHOR_STR, start);
				if (temp2 == -1)
				{
					temp2 = buffer.Find(_TITLE_STR, start);
					if (temp2 == -1)
						temp2 = buffer.Find(_ARTIST_STR, start);
				}
			}
		}

		if (temp == start)
		{
			// Yes. So it's assumed to be a file-global comment
			if ((tuneNo == 0) && ((field == all) || ((field == comment) && (temp2 == -1))))
			{
				// Simply copy the stuff in
				result = buffer.Mid(start);
				return (true);
			}
			else if ((tuneNo == 0) && (field == comment))
			{
				// Just copy the comment
				result = buffer.Mid(start, temp2 - start);
				return (true);
			}
			else if ((tuneNo == 1) && (temp2 != -1))
			{
				// A specific field was asked for
				return (GetOneField(result, buffer.Mid(temp2), field));
			}
			else
			{
				// Anything else is invalid as of v2.00
				return (false);
			}
		}
		else
		{
			// No. Handle it as a regular entry
			if ((field == all) && ((tuneNo == 0) || (tuneNo == 1)))
			{
				// The complete entry was asked for. Simply copy the stuff in
				result = buffer.Mid(start);
				return (true);
			}
			else if (tuneNo == 1)
			{
				// A specific field was asked for
				return (GetOneField(result, buffer.Mid(start), field));
			}
			else
			{
				// Anything else is invalid as of v2.00
				return (false);
			}
		}
	}
	else
	{
		//-----------------//
		// MULTITUNE ENTRY //
		//-----------------//
		int32 myTuneNo, nextTuneNo;
		PString tuneNoStr;

		// Was the complete entry asked for?
		if (tuneNo == 0)
		{
			switch (field)
			{
				case all:
				{
					// Yes. Simply copy the stuff in
					result = buffer.Mid(start);
					return (true);
				}

				case comment:
				{
					// Only the file-global comment field was asked for
					if (firstTuneNo != start)
						return (GetOneField(result, buffer.Mid(start, firstTuneNo - start), comment));
					else
						return (false);
				}

				default:
				{
					// If a specific field other than a comment is
					// asked for tuneNo=0, this is illegal
					return (false);
				}
			}
		}

		// Search for the requested tune number
		tuneNoStr.Format("(#%d)", tuneNo);
		myTuneNo = buffer.Find(tuneNoStr, start);

		if (myTuneNo != -1)
		{
			// We found the requested tune number.
			// Set the pointer beyond it
			myTuneNo = buffer.Find('\n', myTuneNo) + 1;

			// Where is the next one?
			nextTuneNo = buffer.Find("\n(#", myTuneNo);
			if (nextTuneNo == -1)
			{
				// There is no next one - set pointer to the end of entry
				nextTuneNo = buffer.GetLength();
			}
			else
			{
				// The search included the \n - go beyond it
				nextTuneNo++;
			}

			// Put the desired fields into the result (which may be 'all')
			PString tempResult;
			bool retVal;

			retVal = GetOneField(tempResult, buffer.Mid(myTuneNo, nextTuneNo - myTuneNo), field);
			result += tempResult;
			return (retVal);
		}
		else
			return (false);
	}
}