⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archive.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	)

	{
   int index;
   pointer_fixup_t *fixup;

	ReadData( ARC_ObjectPointer, &index, sizeof( index ) );

   // Check for a NULL pointer
   assert( ptr );
   if ( !ptr )
      {
      FileError( "NULL pointer in ReadObjectPointer." );
      }

   //
   // see if the variable was NULL
   //
   if ( index == ARCHIVE_NULL_POINTER )
      {
      *ptr = NULL;
      }
   else
      {
      // init the pointer with NULL until we can fix it
      *ptr = NULL;

      fixup = new pointer_fixup_t;
      fixup->ptr = ( void ** )ptr;
      fixup->index = index;
      fixup->type = pointer_fixup_normal;
      fixupList.AddObject( fixup );
      }
	}

void Archiver::ReadSafePointer
	(
   SafePtrBase * ptr
	)

	{
   int index;
   pointer_fixup_t *fixup;

	ReadData( ARC_SafePointer, &index, sizeof( &index ) );

   // Check for a NULL pointer
   assert( ptr );
   if ( !ptr )
      {
      FileError( "NULL pointer in ReadSafePointer." );
      }

   //
   // see if the variable was NULL
   //
   if ( index == ARCHIVE_NULL_POINTER )
      {
      ptr->InitSafePtr( NULL );
      }
   else
      {
      // init the pointer with NULL until we can fix it
      ptr->InitSafePtr( NULL );

      // Add new fixup
      fixup = new pointer_fixup_t;
      fixup->ptr = ( void ** )ptr;
      fixup->index = index;
      fixup->type = pointer_fixup_safe;
      fixupList.AddObject( fixup );
      }
	}

Event Archiver::ReadEvent
	(
	void
	)

	{
   Event ev;

	CheckRead();
	CheckType( ARC_Event );

	if ( !fileerror )
		{
      ev.Unarchive( *this );
		}

	return ev;
	}

void Archiver::ReadEvent
	(
   Event * ev
	)

	{
	CheckRead();
	CheckType( ARC_Event );

	if ( !fileerror )
		{
      ev->Unarchive( *this );
		}
	}

void Archiver::ReadRaw
	(
	void *data,
	size_t size
	)

	{
	ReadData( ARC_Raw, data, size );
	}

str Archiver::ReadString
	(
	void
	)

	{
	size_t	s;
	char		*data;
	str		string;

	CheckRead();
	CheckType( ARC_String );

	if ( !fileerror )
		{
		s = ReadSize();
		if ( !fileerror )
			{
			data = new char[ s + 1 ];
         if ( s )
            {
            readfile.Read( data, s );
            }
			data[ s ] = 0;

			string = data;

			delete [] data;
			}
		}

	return string;
	}

void Archiver::ReadString
	(
	str * string
	)

	{
   *string = ReadString();
	}

Class *Archiver::ReadObject
	(
	void
	)

	{
	ClassDef	*cls;
	Class		*obj;
	str		classname;
	long		objstart;
	long		endpos;
   int      index;
	size_t	size;
   qboolean isent;
   int      type;

	CheckRead();

   type = ReadType();
   if ( ( type != ARC_Object ) && ( type != ARC_Entity ) )
      {
      FileError( "Expecting %s or %s", typenames[ ARC_Object ], typenames[ ARC_Entity ] );
      }

	size = ReadSize();
	classname = ReadString();

   cls = getClass( classname.c_str() );
	if ( !cls )
      {
		FileError( "Invalid class %s.", classname.c_str() );
		}

   isent = checkInheritance( &Entity::ClassInfo, cls );
   if ( type == ARC_Entity )
      {
      if ( !isent )
         {
   		FileError( "Non-Entity class object '%s' saved as an Entity based object.", classname.c_str() );
         }

      game.force_entnum = true;
		game.spawn_entnum = ReadInteger();
      }
   else if ( isent )
      {
      FileError( "Entity class object '%s' saved as non-Entity based object.", classname.c_str() );
      }

	index = ReadInteger();
	objstart = readfile.Pos();

	obj = ( Class * )cls->newInstance();
	if ( !obj )
		{
		FileError( "Failed to on new instance of class %s.", classname.c_str() );
		}
	else
		{
		obj->Unarchive( *this );
		}

   if ( isent )
      {
      game.force_entnum = false;
      }

	if ( !fileerror )
		{
		endpos = readfile.Pos();
		if ( ( endpos - objstart ) > size )
			{
			FileError( "Object read past end of object's data" );
			}
		else if ( ( endpos - objstart ) < size )
			{
			FileError( "Object didn't read entire data from file" );
			}
		}

   //
   // register this pointer with our list
   //
   classpointerList.AddObjectAt( index, obj );

	return obj;
	}
	
Class *Archiver::ReadObject
	(
	Class *obj
	)

	{
	ClassDef	*cls;
	str		classname;
	long		objstart;
	long		endpos;
   int      index;
	size_t	size;
   int      type;
   qboolean isent;

	CheckRead();
   type = ReadType();
   if ( ( type != ARC_Object ) && ( type != ARC_Entity ) )
      {
      FileError( "Expecting %s or %s", typenames[ ARC_Object ], typenames[ ARC_Entity ] );
      }

   size = ReadSize();
	classname = ReadString();

   cls = getClass( classname.c_str() );
	if ( !cls )
      {
		FileError( "Invalid class %s.", classname.c_str() );
		}

	if ( obj->classinfo() != cls )
		{
		FileError( "Archive has a '%s' object, but was expecting a '%s' object.", classname.c_str(), obj->getClassname() );
		}

   isent = obj->isSubclassOf( Entity );
   if ( type == ARC_Entity )
      {
      if ( !isent )
         {
   		FileError( "Non-Entity class object '%s' saved as an Entity based object.", classname.c_str() );
         }

      ( ( Entity * )obj )->SetEntNum( ReadInteger() );
      }
   else if ( isent )
      {
      FileError( "Entity class object '%s' saved as non-Entity based object.", classname.c_str() );
      }

	index = ReadInteger();
	objstart = readfile.Pos();

   obj->Unarchive( *this );

	if ( !fileerror )
		{
		endpos = readfile.Pos();
		if ( ( endpos - objstart ) > size )
			{
			FileError( "Object read past end of object's data" );
			}
		else if ( ( endpos - objstart ) < size )
			{
			FileError( "Object didn't read entire data from file" );
			}
		}

   //
   // register this pointer with our list
   //
   classpointerList.AddObjectAt( index, obj );

	return obj;
	}
	
/****************************************************************************************

  File Write functions

*****************************************************************************************/

void Archiver::Create
	(
	const char *name
	)

	{
   assert( name );
   if ( !name )
      {
      gi.error( "NULL pointer for filename in Archiver::Create.\n" );
      }

	fileerror = false;

	archivemode = ARCHIVE_WRITE;

	filename = name;

	gi.CreatePath( filename.c_str() );
	file = fopen( filename.c_str(), "wb" );
	if ( !file )
		{
		FileError( "Couldn't open file." );
		}

	WriteUnsigned( ArchiveHeader );
	WriteUnsigned( ArchiveVersion );
	WriteString( str( ArchiveInfo ) );

  	numclassespos = ftell( file );
   WriteInteger( 0 );
	}

inline void Archiver::CheckWrite
	(
	void
	)

	{
	assert( archivemode == ARCHIVE_WRITE );
	if ( !fileerror && ( archivemode != ARCHIVE_WRITE ) )
		{
		FileError( "File write during a read operation." );
		}
	}

inline void Archiver::WriteType
	(
	int type
	)

	{
	fwrite( &type, sizeof( type ), 1, file );
	}

inline void Archiver::WriteSize
	(
	size_t size
	)

	{
	fwrite( &size, sizeof( size ), 1, file );
	}

inline void Archiver::WriteData
	(
	int type,
	const void *data,
	size_t size
	)

	{
	CheckWrite();
	WriteType( type );
	WriteSize( size );

	if ( !fileerror && size )
		{
		fwrite( data, size, 1, file );
		}
	}

#define WRITE( func, type )									\
void Archiver::Write##func										\
	(																	\
	type v															\
	)																	\
																		\
	{																	\
	WriteData( ARC_##func, &v, sizeof( type ) );			\
	}

	WRITE( Vector, Vector & );
	WRITE( Quat, Quat & );
	WRITE( Integer, int );
	WRITE( Unsigned, unsigned );
	WRITE( Byte, byte );
	WRITE( Char, char );
	WRITE( Short, short );
	WRITE( UnsignedShort, unsigned short );
	WRITE( Float, float );
	WRITE( Double, double );
	WRITE( Boolean, qboolean );

void Archiver::WriteRaw
	(
	const void *data,
	size_t size
	)

	{
	WriteData( ARC_Raw, data, size );
	}

void Archiver::WriteString
	(
	str &string
	)

	{
	WriteData( ARC_String, string.c_str(), string.length() );
	}

void Archiver::WriteObject
	(
	Class *obj
	)

	{
	str		classname;
	long		sizepos;
	long		objstart;
	long		endpos;
   int      index;
	size_t	size;
   qboolean isent;

	assert( obj );
	if ( !obj )
		{
		FileError( "NULL object in WriteObject" );
		}

   isent = obj->isSubclassOf( Entity );

	CheckWrite();
   if ( isent )
      {
      WriteType( ARC_Entity );
      }
   else
      {
	   WriteType( ARC_Object );
      }

	sizepos = ftell( file );
	size = 0;
	WriteSize( size );

	classname = obj->getClassname();
	WriteString( classname );

   if ( isent )
      {
      // Write out the entity number
      WriteInteger( ( ( Entity * )obj )->entnum );
      }

   // write out pointer index for this class pointer
   index = classpointerList.AddUniqueObject( obj );
   WriteInteger( index );

	if ( !fileerror )
		{
		objstart = ftell( file );
		obj->Archive( *this );
		}
	
	if ( !fileerror )
		{
		endpos = ftell( file );
		size = endpos - objstart;
		fseek( file, sizepos, SEEK_SET );
		WriteSize( size );

		if ( !fileerror )
			{
			fseek( file, endpos, SEEK_SET );
			}
		}
	}

void Archiver::WriteObjectPointer
	(
   Class * ptr
	)

	{
   int index;

   if ( ptr )
      {
      index = classpointerList.AddUniqueObject( ptr );
      }
   else
      {
      index = ARCHIVE_NULL_POINTER;
      }
   WriteData( ARC_ObjectPointer, &index, sizeof( index ) );
	}

void Archiver::WriteSafePointer
	(
   Class * ptr
	)

	{
   int index;

   if ( ptr )
      {
      index = classpointerList.AddUniqueObject( ptr );
      }
   else
      {
      index = ARCHIVE_NULL_POINTER;
      }
	WriteData( ARC_SafePointer, &index, sizeof( index ) );
	}

void Archiver::WriteEvent
	(
   Event &ev
	)

	{
	CheckWrite();
   WriteType( ARC_Event );

   //FIXME!!!! Make this handle null events
   if ( &ev == NULL )
      {
      NullEvent.Archive( *this );
      }
   else
      {
      ev.Archive( *this );
      }
   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -