Esempio n. 1
0
NOXREF void TextMessageParse(unsigned char *pMemFile, int fileSize)
{
	NOXREFCHECK;
	char buf[512];
	char trim[512];
	char *pCurrentText;
	char *pNameHeap;
	char currentName[512];
	char nameHeap[NAME_HEAP_SIZE];
	int lastNamePos;
	int mode;
	int lineNumber;
	int filePos;
	int lastLinePos;
	int messageCount;
	client_textmessage_t textMessages[MAX_MESSAGES];
	int i;
	int nameHeapSize;
	int textHeapSize;
	int messageSize;
	int nameOffset;

	lastNamePos = 0;
	lineNumber = 0;
	filePos = 0;
	lastLinePos = 0;
	messageCount = 0;
	mode = MSGFILE_NAME;

	while (memfgets(pMemFile, fileSize, &filePos, buf, 512) != NULL)
	{
		if(messageCount >= MAX_MESSAGES)
			Sys_Error("%s: messageCount >= MAX_MESSAGES", __func__);

		TrimSpace(buf, trim);
		switch (mode)
		{
			case MSGFILE_NAME:
			{
				if (IsComment(trim))
					break;

				if (ParseDirective(trim))
					break;

				if (IsStartOfText(trim))
				{
					mode = MSGFILE_TEXT;
					pCurrentText = (char *)(pMemFile + filePos);
					break;
				}
				if (IsEndOfText(trim))
				{
					Con_DPrintf("Unexpected '}' found, line %d\n", lineNumber);
					return;
				}
				Q_strncpy(currentName, trim, 511);
				currentName[511] = 0;

				break;
			}
			case MSGFILE_TEXT:
			{
				if (IsEndOfText(trim))
				{
					int length = Q_strlen(currentName);
					if (lastNamePos + length > sizeof(nameHeap))
					{
						Con_DPrintf("Error parsing file!  length > %i bytes\n", sizeof(nameHeap));
						return;
					}

					Q_strcpy(nameHeap + lastNamePos, currentName);

					pMemFile[lastLinePos - 1] = 0;

					textMessages[messageCount] = gMessageParms;
					textMessages[messageCount].pName = nameHeap + lastNamePos;
					lastNamePos += Q_strlen(currentName) + 1;
					textMessages[messageCount].pMessage = pCurrentText;
					messageCount++;

					mode = MSGFILE_NAME;
					break;
				}
				if (IsStartOfText(trim))
				{
					Con_DPrintf("Unexpected '{' found, line %d\n", lineNumber);
					return;
				}
				break;
			}
		}

		lineNumber++;
		lastLinePos = filePos;
	}

	Con_DPrintf("Parsed %d text messages\n", messageCount);
	nameHeapSize = lastNamePos;
	textHeapSize = 0;

	for (i = 0; i < messageCount; i++)
		textHeapSize += Q_strlen(textMessages[i].pMessage) + 1;

	messageSize = (messageCount * sizeof(client_textmessage_t));

	gMessageTable = (client_textmessage_t *)Mem_Malloc(textHeapSize + nameHeapSize + messageSize);

	Q_memcpy(gMessageTable, textMessages, messageSize);

	pNameHeap = ((char *)gMessageTable) + messageSize;
	Q_memcpy(pNameHeap, nameHeap, nameHeapSize);
	nameOffset = pNameHeap - gMessageTable[0].pName;

	pCurrentText = pNameHeap + nameHeapSize;
	for (i = 0; i < messageCount; i++)
	{
		gMessageTable[i].pName += nameOffset;
		Q_strcpy(pCurrentText, gMessageTable[i].pMessage);
		gMessageTable[i].pMessage = pCurrentText;
		pCurrentText += Q_strlen(pCurrentText) + 1;
	}

	gMessageTableCount = messageCount;
}
Esempio n. 2
0
void TextMessageParse( byte *pMemFile, int fileSize )
{
	char		buf[512], trim[512];
	char		*pCurrentText=0, *pNameHeap;
	char		 currentName[512], nameHeap[ NAME_HEAP_SIZE ];
	int			lastNamePos;

	int			mode = MSGFILE_NAME;	// Searching for a message name	
	int			lineNumber, filePos, lastLinePos;
	int			messageCount;

	client_textmessage_t	textMessages[ MAX_MESSAGES ];
	
	int			i, nameHeapSize, textHeapSize, messageSize, nameOffset;

	lastNamePos = 0;
	lineNumber = 0;
	filePos = 0;
	lastLinePos = 0;
	messageCount = 0;

	CharacterSetBuild( &g_WhiteSpace, " \r\n\t" );

	while( memfgets( pMemFile, fileSize, &filePos, buf, 512 ) != NULL )
	{
		if(messageCount>=MAX_MESSAGES)
		{
			Sys_Error("tmessage::TextMessageParse : messageCount>=MAX_MESSAGES");
		}

		TrimSpace( buf, trim );
		switch( mode )
		{
		case MSGFILE_NAME:
			if ( IsComment( trim ) )	// Skip comment lines
				break;
			
			if ( ParseDirective( trim ) )	// Is this a directive "$command"?, if so parse it and break
				break;

			if ( IsStartOfText( trim ) )
			{
				mode = MSGFILE_TEXT;
				pCurrentText = (char*)(pMemFile + filePos);
				break;
			}
			if ( IsEndOfText( trim ) )
			{
				Con_DPrintf("Unexpected '}' found, line %d\n", lineNumber );
				return;
			}
			strcpy( currentName, trim );
			break;
		
		case MSGFILE_TEXT:
			if ( IsEndOfText( trim ) )
			{
				int length = strlen(currentName);

				// Save name on name heap
				if ( lastNamePos + length > 8192 )
				{
					Con_DPrintf("Error parsing file!\n" );
					return;
				}
				strcpy( nameHeap + lastNamePos, currentName );

				// Terminate text in-place in the memory file (it's temporary memory that will be deleted)
				pMemFile[ lastLinePos - 1 ] = 0;

				// Save name/text on heap
				textMessages[ messageCount ] = gMessageParms;
				textMessages[ messageCount ].pName = nameHeap + lastNamePos;
				lastNamePos += strlen(currentName) + 1;
				textMessages[ messageCount ].pMessage = pCurrentText;
				messageCount++;

				// Reset parser to search for names
				mode = MSGFILE_NAME;
				break;
			}
			if ( IsStartOfText( trim ) )
			{
				Con_DPrintf("Unexpected '{' found, line %d\n", lineNumber );
				return;
			}
			break;
		}
		lineNumber++;
		lastLinePos = filePos;

		if ( messageCount >= MAX_MESSAGES )
		{
			Con_Printf("WARNING: TOO MANY MESSAGES IN TITLES.TXT, MAX IS %d\n", MAX_MESSAGES );
			break;
		}
	}

	Con_DPrintf("Parsed %d text messages\n", messageCount );
	nameHeapSize = lastNamePos;
	textHeapSize = 0;
	for ( i = 0; i < messageCount; i++ )
		textHeapSize += strlen( textMessages[i].pMessage ) + 1;


	messageSize = (messageCount * sizeof(client_textmessage_t));

	// Must malloc because we need to be able to clear it after initialization
	gMessageTable = (client_textmessage_t *)malloc( textHeapSize + nameHeapSize + messageSize );
	
	// Copy table over
	memcpy( gMessageTable, textMessages, messageSize );
	
	// Copy Name heap
	pNameHeap = ((char *)gMessageTable) + messageSize;
	memcpy( pNameHeap, nameHeap, nameHeapSize );
	nameOffset = pNameHeap - gMessageTable[0].pName;

	// Copy text & fixup pointers
	pCurrentText = pNameHeap + nameHeapSize;

	for ( i = 0; i < messageCount; i++ )
	{
		gMessageTable[i].pName += nameOffset;		// Adjust name pointer (parallel buffer)
		strcpy( pCurrentText, gMessageTable[i].pMessage );	// Copy text over
		gMessageTable[i].pMessage = pCurrentText;
		pCurrentText += strlen( pCurrentText ) + 1;
	}

#if _DEBUG
	if ( (pCurrentText - (char *)gMessageTable) != (textHeapSize + nameHeapSize + messageSize) )
		Con_Printf("Overflow text message buffer!!!!!\n");
#endif
	gMessageTableCount = messageCount;
}