Ejemplo n.º 1
0
Bool SaveStrings(char *filename)
{
   int write_int;
   DWORD written;

   strfile = CreateFile(filename,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
			FILE_ATTRIBUTE_NORMAL,NULL);
   if (strfile == INVALID_HANDLE_VALUE)
   {
      eprintf("SaveStrings can't open %s to save strings!\n",filename);
      return False;
   }

   write_int = 1; /* version */
   if (!WriteFile(strfile,&write_int,LEN_STR_VERSION,&written,NULL) || 
       written != LEN_STR_VERSION)
      eprintf("SaveStrings 1 error writing to file!\n");
   
   write_int = GetNumStrings();
   if (!WriteFile(strfile,&write_int,LEN_NUM_STRS,&written,NULL) || 
       written != LEN_NUM_STRS)
      eprintf("SaveStrings 2 error writing to file!\n");
   

   ForEachString(SaveEachString);
   CloseHandle(strfile);

   return True;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNetworkStringTable::Dump( void )
{
	ConMsg( "Table %s\n", GetTableName() );
	ConMsg( "  %i/%i items\n", GetNumStrings(), GetMaxStrings() );
	for ( int i = 0; i < GetNumStrings() ; i++ )
	{
		ConMsg( "  %i : %s\n", i, GetString( i ) );
	}
	if ( m_pItemsClientSide )
	{
		for ( int i = 0; i < (int)m_pItemsClientSide->Count() ; i++ )
		{
			ConMsg( "  %i : %s\n", i, m_pItemsClientSide->String( i ) );
		}
	}
	ConMsg( "\n" );
}
bool CNetworkStringTable::WriteBaselines( SVC_CreateStringTable &msg, char *msg_buffer, int msg_buffer_size )
{
	msg.m_DataOut.StartWriting( msg_buffer, msg_buffer_size );

	msg.m_bIsFilenames          = m_bIsFilenames;
	msg.m_szTableName			= GetTableName();
	msg.m_nMaxEntries			= GetMaxStrings();
	msg.m_nNumEntries			= GetNumStrings();
	msg.m_bUserDataFixedSize	= IsUserDataFixedSize();
	msg.m_nUserDataSize			= GetUserDataSize();
	msg.m_nUserDataSizeBits		= GetUserDataSizeBits();

	// tick = -1 ensures that all entries are updated = baseline
	int entries = WriteUpdate( NULL, msg.m_DataOut, -1 );

	return entries == msg.m_nNumEntries;
}
void CNetworkStringTable::WriteStringTable( CUtlBuffer& buf )
{
	int numstrings = GetNumStrings();
	buf.PutInt( numstrings );
	for ( int i = 0 ; i < numstrings; i++ )
	{
		buf.PutString( GetString( i ) );
		int userDataSize;
		const void *pUserData = GetStringUserData( i, &userDataSize );
		if ( userDataSize > 0 )
		{
			buf.PutChar( 1 );
			buf.PutShort( (short)userDataSize );
			buf.Put( pUserData, userDataSize );
		}
		else
		{
			buf.PutChar( 0 );
		}
		
	}
}
//-----------------------------------------------------------------------------
// Purpose: Parse string update
//-----------------------------------------------------------------------------
void CNetworkStringTable::ParseUpdate( bf_read &buf, int entries )
{
	int lastEntry = -1;

	CUtlVector< StringHistoryEntry > history;

	for (int i=0; i<entries; i++)
	{
		int entryIndex = lastEntry + 1;

		if ( !buf.ReadOneBit() )
		{
			entryIndex = buf.ReadUBitLong( GetEntryBits() );
		}

		lastEntry = entryIndex;
		
		if ( entryIndex < 0 || entryIndex >= GetMaxStrings() )
		{
			Host_Error( "Server sent bogus string index %i for table %s\n", entryIndex, GetTableName() );
		}

		const char *pEntry = NULL;
		char entry[ 1024 ]; 
		char substr[ 1024 ];

		if ( buf.ReadOneBit() )
		{
			bool substringcheck = buf.ReadOneBit() ? true : false;

			if ( substringcheck )
			{
				int index = buf.ReadUBitLong( 5 );
				int bytestocopy = buf.ReadUBitLong( SUBSTRING_BITS );
				Q_strncpy( entry, history[ index ].string, bytestocopy + 1 );
				buf.ReadString( substr, sizeof(substr) );
				Q_strncat( entry, substr, sizeof(entry), COPY_ALL_CHARACTERS );
			}
			else
			{
				buf.ReadString( entry, sizeof( entry ) );
			}

			pEntry = entry;
		}
		
		// Read in the user data.
		unsigned char tempbuf[ CNetworkStringTableItem::MAX_USERDATA_SIZE ];
		memset( tempbuf, 0, sizeof( tempbuf ) );
		const void *pUserData = NULL;
		int nBytes = 0;

		if ( buf.ReadOneBit() )
		{
			if ( IsUserDataFixedSize() )
			{
				// Don't need to read length, it's fixed length and the length was networked down already.
				nBytes = GetUserDataSize();
				Assert( nBytes > 0 );
				tempbuf[nBytes-1] = 0; // be safe, clear last byte
				buf.ReadBits( tempbuf, GetUserDataSizeBits() );
			}
			else
			{
				nBytes = buf.ReadUBitLong( CNetworkStringTableItem::MAX_USERDATA_BITS );
				ErrorIfNot( nBytes <= sizeof( tempbuf ),
					("CNetworkStringTableClient::ParseUpdate: message too large (%d bytes).", nBytes)
				);

				buf.ReadBytes( tempbuf, nBytes );
			}

			pUserData = tempbuf;
		}

		// Check if we are updating an old entry or adding a new one
		if ( entryIndex < GetNumStrings() )
		{
			SetStringUserData( entryIndex, nBytes, pUserData );
#ifdef _DEBUG
			if ( pEntry )
			{
				Assert( !Q_strcmp( pEntry, GetString( entryIndex ) ) ); // make sure string didn't change
			}
#endif
			pEntry = GetString( entryIndex ); // string didn't change
		}
		else
		{
			// Grow the table (entryindex must be the next empty slot)
			Assert( (entryIndex == GetNumStrings()) && (pEntry != NULL) );
				
			if ( pEntry == NULL )
			{
				Msg("CNetworkStringTable::ParseUpdate: NULL pEntry, table %s, index %i\n", GetTableName(), entryIndex );
				pEntry = "";// avoid crash because of NULL strings
			}

			AddString( true, pEntry, nBytes, pUserData );
		}

		if ( history.Count() > 31 )
		{
			history.Remove( 0 );
		}

		StringHistoryEntry she;
		Q_strncpy( she.string, pEntry, sizeof( she.string ) );
		history.AddToTail( she );
	}
}