714dd74636
git-svn-id: svn://10.65.10.50/trunk@5350 c028cbd2-c16b-5b4b-a496-9718f37d4682
794 lines
21 KiB
C++
Executable File
794 lines
21 KiB
C++
Executable File
//
|
|
// GLARC.CPP
|
|
//
|
|
// Source file for ArchiveLib 2.0
|
|
//
|
|
// Copyright (c) Greenleaf Software, Inc. 1994-1996
|
|
// All Rights Reserved
|
|
//
|
|
// CONTENTS
|
|
//
|
|
// ALGlArchive::operator new()
|
|
// ALGlArchive::ALGlArchive()
|
|
// newALGlArchiveFromStorage()
|
|
// ALGlArchive::~ALGlArchive()
|
|
// ALGlArchive::PreWriteDir()
|
|
// ALGlArchive::PostWriteDir()
|
|
// ALGlArchive::WriteDirEntry()
|
|
// ALGlArchive::ReadDirectory()
|
|
// ALGlArchive::PreCreate()
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// This file contains all of the source code for the base class,
|
|
// ALGlArchive. The details on how things get inserted and extracted from an
|
|
// archive will all be found here.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// May 23, 1994 1.0A : First release
|
|
//
|
|
// July 7, 1994 1.0B : Minor change to handle a snag with the sun
|
|
// compilers.
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
#include "arclib.h"
|
|
#if !defined( AL_IBM )
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#include "glarc.h"
|
|
#include "_openf.h"
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALGlArchive::operator new()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Memory allocator used when ArchiveLib resides in a 16 bit DLL.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// void * ALGlArchive::operator new( size_t size )
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// size : The number of bytes that the compiler has decided will be
|
|
// necessary to construct a new ALGlArchive object.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// When using a DLL, it is easy to get into a dangerous situation when
|
|
// creating objects whose ctor and dtor are both in the DLL. The problem
|
|
// arises because when you create an object using new, the memory for
|
|
// the object will be allocated from the EXE. However, when you destroy
|
|
// the object using delete, the memory is freed inside the DLL. Since
|
|
// the DLL doesn't really own that memory, bad things can happen.
|
|
//
|
|
// But, you say, won't the space just go back to the Windows heap regardless
|
|
// of who tries to free it? Maybe, but maybe not. If the DLL is using
|
|
// a subsegment allocation scheme, it might do some sort of local free
|
|
// before returning the space to the windows heap. That is the point where
|
|
// you could conceivably cook your heap.
|
|
//
|
|
// By providing our own version of operator new inside this class, we
|
|
// ensure that all memory allocation for the class will be done from
|
|
// inside the DLL, not the EXE calling the DLL.
|
|
//
|
|
// This function will be called whenever you dynamically create a new
|
|
// ALGlArchive object (using the new operator.)
|
|
//
|
|
// RETURNS
|
|
//
|
|
// A pointer to some memory that should have been pulled out of the
|
|
// heap for the DLL.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
#if defined( AL_BUILDING_DLL )
|
|
|
|
void AL_DLL_FAR * AL_PROTO
|
|
ALGlArchive::operator new( size_t size ) /* Tag internal function */
|
|
{
|
|
return ::new char[ size ];
|
|
}
|
|
|
|
#endif
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALGlArchive::ALGlArchive()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++ C VB Delphi
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// The Greenleaf Archive constructors.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// ALGlArchive::ALGlArchive( ALStorage &storage_object );
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// hALArchive newALGlArchiveFromStorage( hALStorage storage );
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// Declare Function newALGlArchiveFromStorage Lib "AL20LW"
|
|
// (ByVal storage&) As Long
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// function newALGlArchiveFromStorage( storage : hALStorage ) : hALArchive;
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// storage_object : A pointer to the storage object that will/does
|
|
// hold the archive.
|
|
//
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// This function creates a new ALGlArchive object, using a storage object
|
|
// as the underlying physical container. GlArchives are siblings to
|
|
// Pk archives. While they both use the same base class, and support many
|
|
// functions in common, they are essentially incompatible.
|
|
//
|
|
// You call this constructor to manipulate any archive, including ones
|
|
// that haven't even been created yet.
|
|
//
|
|
// Recall that the base class, ALArchive, has a single argument to *its*
|
|
// constructor that determines whether or not it destroys the underlying
|
|
// storage object in its destructor. Since we are using user-specified
|
|
// storage in this case, we pass a 0, indicating that we don't want the
|
|
// destructor to destroy the underlying storage object.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// When called from C/VB/Delphi, the translation function returns a handle
|
|
// to a newly created archive object. When called using the new operator
|
|
// in C++, this function returns a pointer to a newly created archive
|
|
// object.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
AL_PROTO
|
|
ALGlArchive::ALGlArchive( ALStorage AL_DLL_FAR &storage_object ) /* Tag public function */
|
|
: ALArchive( &storage_object, 0)
|
|
{
|
|
miVersion = 0x100;
|
|
}
|
|
|
|
#if !defined( AL_NO_C )
|
|
|
|
extern "C" AL_LINKAGE hALArchive AL_FUNCTION
|
|
newALGlArchiveFromStorage( hALStorage storage ) /* Tag public function */
|
|
{
|
|
AL_ASSERT( ( (ALStorage *) storage)->GoodTag(),
|
|
"storage argument is not a valid ALStorageObject" );
|
|
ALArchive *archive;
|
|
archive = new ALGlArchive( *(ALStorage *) storage );
|
|
return (hALArchive) archive;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALGlArchive::~ALGlArchive()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Destructor for the Greenleaf Archive.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// ALGlArchive::~ALGlArchive()
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, use deleteALArchive();
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, use deleteALArchive();
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, use deleteALArchive();
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// None.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// This is a virtual destructor for the derived class ALGlArchive. It
|
|
// has absolutely nothing to do, since all of the important work is done
|
|
// by the base class destructor, ALArchive::~ALArchive(). Note that
|
|
// there is no translation function for C/VB/Delphi to call this function
|
|
// directly. Instead, they will get here by way of a virtual function
|
|
// call to the base class destructor.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Nothing.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
AL_PROTO
|
|
ALGlArchive::~ALGlArchive() /* Tag public function */
|
|
{
|
|
AL_ASSERT( GoodTag(), "~ALGlArchive(): Attempting to delete invalid ALGlArchive" );
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALGlArchive::PreWriteDir()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Write out the archive data that precedes the directory.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// void ALGlArchive::PreWriteDir()
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, this is an internal function.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, this is an internal function.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, this is an internal function.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// None.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// The base class, ALArchive, is responsible for all the work done when
|
|
// creating an archive. However, since Greenleaf and PKWare archives
|
|
// are fairly different, the base class relies on a few virtual functions
|
|
// to perform archive specific chores.
|
|
//
|
|
// PreWriteDir() is one of those functions. It is called after the
|
|
// file pointer has been positioned to write the directory out, but
|
|
// before any directory entries have been written.
|
|
//
|
|
// Greenleaf archives store three items directly ahead of the
|
|
// directory: the archive version, any customized archive data, and
|
|
// the archive comment. This routine just writes all those out, then
|
|
// returns to the calling routine. The caller is presumably the
|
|
// write directory code in ALArchive, and it should continue by writing
|
|
// out all of its directory entries.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Nothing.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
void AL_PROTO
|
|
ALGlArchive::PreWriteDir() /* Tag protected function */
|
|
{
|
|
mpArchiveStorageObject->WriteGlShort( miVersion );
|
|
WriteArchiveData();
|
|
mpArchiveStorageObject->WriteString( mComment );
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALGlArchive::PostWriteDir()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Write out the archive data that follows the directory.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// void ALGlArchive::PostWriteDir()
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, this is an internal function.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, this is an internal function.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, this is an internal function.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// None.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// The base class, ALArchive, is responsible for all the work done when
|
|
// creating an archive. However, since Greenleaf and PKWare archives
|
|
// are fairly different, the base class relies on a few virtual functions
|
|
// to perform archive specific chores.
|
|
//
|
|
// PostWriteDir() is one of those functions. It is called after the
|
|
// directory entires for the archive have all been written out.
|
|
//
|
|
// Greenleaf archives store three items directly ahead of the
|
|
// directory: the archive version, any customized archive data, and
|
|
// the archive comment. This routine just writes all those out, then
|
|
// returns to the calling routine. The caller is presumably the
|
|
// write directory code in ALArchive, and it should continue by writing
|
|
// out all of its directory entries.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Nothing.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
void AL_PROTO
|
|
ALGlArchive::PostWriteDir() /* Tag protected function */
|
|
{
|
|
long keeper = mpArchiveStorageObject->Tell();
|
|
mpArchiveStorageObject->WriteString( "" );
|
|
mpArchiveStorageObject->Seek( 0L );
|
|
mpArchiveStorageObject->WriteGlLong( mlDirectoryOffset );
|
|
|
|
mpArchiveStorageObject->Seek( keeper );
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALGlArchive::WriteDirEntry()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Write an individual object entry to the archive directory.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// void ALGlArchive::WriteDirEntry( ALEntry &entry );
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, internal support function.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, internal support function.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, internal support function.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// entry : A reference to an entry. This should correspond to an actual
|
|
// object that is present in the archive.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// The base class function, ALArchive::WriteDirectory(), sits in a loop
|
|
// writing out directory entries, one after the other. Since it is in
|
|
// the base class, you can't expect it to know the exact format for an
|
|
// entry. So instead, it relies on this virtual function in derived
|
|
// classes to do the job.
|
|
//
|
|
// This function takes care of writing out a directory entry in the format
|
|
// Greenleaf archives use.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Nothing.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
void AL_PROTO
|
|
ALGlArchive::WriteDirEntry( ALEntry AL_DLL_FAR &entry ) /* Tag protected function */
|
|
{
|
|
mpArchiveStorageObject->WriteString( entry.mpStorageObject->mName.GetSafeName() );
|
|
if ( entry.mpCompressor ) {
|
|
mpArchiveStorageObject->WriteChar( entry.mpCompressor->miCompressionType );
|
|
entry.mpCompressor->WriteEngineData( mpArchiveStorageObject );
|
|
} else if ( entry.mpDecompressor ) {
|
|
mpArchiveStorageObject->WriteChar( entry.mpDecompressor->miCompressionType );
|
|
entry.mpDecompressor->WriteEngineData( mpArchiveStorageObject );
|
|
} else {
|
|
mStatus.SetError( AL_UNKNOWN_COMPRESSION_TYPE,
|
|
"No compressor or decompressor for archive"
|
|
" entry %s",
|
|
entry.mpStorageObject->mName.GetSafeName() );
|
|
return;
|
|
}
|
|
mpArchiveStorageObject->WriteChar( entry.mpStorageObject->miStorageObjectType );
|
|
entry.mpStorageObject->WriteStorageObjectData( mpArchiveStorageObject );
|
|
|
|
mpArchiveStorageObject->WriteGlLong( entry.mpStorageObject->GetSize() );
|
|
mpArchiveStorageObject->WriteGlLong( entry.GetCompressedSize() );
|
|
mpArchiveStorageObject->WriteGlLong( entry.GetCrc32() );
|
|
mpArchiveStorageObject->WriteGlLong( entry.mlCompressedObjectPosition );
|
|
mpArchiveStorageObject->WriteString( entry.GetComment() );
|
|
mpArchiveStorageObject->WriteGlLong( entry.mpStorageObject->mTimeDate.GetUnixTime() );
|
|
mpArchiveStorageObject->WriteGlShort( entry.mpStorageObject->mAttributes.PackedAttributes() );
|
|
if ( mpArchiveStorageObject->mStatus < 0 )
|
|
mStatus = mpArchiveStorageObject->mStatus;
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALGlArchive::ReadDirectory()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Read in the directory for a GL format archive.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// int ALGlArchive::ReadDirectory( ALEntryList &list )
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, internal function.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, internal function.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, internal function.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// list : An ALEntryList object that is going to receive all the
|
|
// new ALEntry objects created from reading the directory.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// During the process of creating ArchiveLib 2.0, the WriteDirectory()
|
|
// function was moved up into the base class. The addition of three
|
|
// virtual helper functions takes care of all the specialized aspects
|
|
// needed to make it happen.
|
|
//
|
|
// Well, I haven't gotten around to that for the ReadDirectory function.
|
|
// Maybe in the final release of 2.0, but more likely in the release
|
|
// of ArchiveLib 3.0. It's not a critical issue, it just helps break
|
|
// the code down into smaller pieces, and is somewhat more efficient by
|
|
// sharing common code.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// AL_SUCCESS or < AL_SUCCESS if things don't work.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
|
|
int AL_PROTO
|
|
ALGlArchive::ReadDirectory( ALEntryList AL_DLL_FAR &list ) /* Tag protected function */
|
|
{
|
|
list.mrMonitor.ArchiveOperation( AL_START_DIRECTORY_READ, this, 0 );
|
|
ALOpenInputFile archive( *mpArchiveStorageObject );
|
|
if ( mpArchiveStorageObject->mStatus < 0 )
|
|
return mStatus = mpArchiveStorageObject->mStatus;
|
|
//
|
|
// First I seek to the start of the directory (offset found at 0), and
|
|
// read in the version. This function only supports the directory
|
|
// structure defined in version 0x100.
|
|
//
|
|
mpArchiveStorageObject->Seek( 0 );
|
|
mpArchiveStorageObject->ReadGlLong( mlDirectoryOffset );
|
|
mpArchiveStorageObject->Seek( mlDirectoryOffset );
|
|
mpArchiveStorageObject->ReadGlShort( miVersion );
|
|
if ( miVersion != 0x100 )
|
|
return mStatus.SetError( AL_INVALID_ARCHIVE,
|
|
"%s is not a valid archive file",
|
|
mpArchiveStorageObject->mName.GetSafeName() );
|
|
//
|
|
// Read in any customized archive data defined by a derived class.
|
|
//
|
|
ReadArchiveData();
|
|
//
|
|
// Read in the comment, deleting the old one if necessary.
|
|
//
|
|
mpArchiveStorageObject->ReadString( mComment );
|
|
//
|
|
// Now, the big loop. I have to read in each entry, one at a time, and
|
|
// add it to the list. If I broke this out into a separate routine it
|
|
// would make the whole thing a lot more manageable.
|
|
//
|
|
for ( ; ; ) {
|
|
if ( mpArchiveStorageObject->mStatus < 0 )
|
|
return mStatus = mpArchiveStorageObject->mStatus;
|
|
ALName name;
|
|
mpArchiveStorageObject->ReadString( name );
|
|
//
|
|
// The directory ends with a blank name.
|
|
//
|
|
if ( strlen( name ) == 0 )
|
|
break;
|
|
//
|
|
// Derived classes are responsible for providing a version of
|
|
// CreateCompressionEngine() that will convert the engine_type
|
|
// integer into a created compression engine. The derived class is
|
|
// then also responsible for reading in the engine data from the archive.
|
|
//
|
|
int engine_type = mpArchiveStorageObject->ReadChar();
|
|
ALCompressor *compressor = 0;
|
|
ALDecompressor *decompressor = list.mToolKit.CreateDecompressor( engine_type );
|
|
if ( decompressor )
|
|
decompressor->ReadEngineData( mpArchiveStorageObject );
|
|
else {
|
|
compressor = list.mToolKit.CreateCompressor( engine_type );
|
|
if ( compressor )
|
|
compressor->ReadEngineData( mpArchiveStorageObject );
|
|
else {
|
|
ALName temp;
|
|
mpArchiveStorageObject->ReadString( temp );
|
|
//
|
|
// I used to treat this as an error, now I don't. The error will come about
|
|
// when you actually try to decompress the object.
|
|
//
|
|
#if 0
|
|
return mStatus.SetError( AL_CANT_CREATE_ENGINE,
|
|
"Failure creating compression engine for object %s",
|
|
(const char *) name );
|
|
#endif
|
|
}
|
|
}
|
|
//
|
|
// Now we go through a nearly identical process to create the storage object.
|
|
// The derived class is responsible for writing a CreateStorageObject()
|
|
// function that converts an object_type integer to a created storage
|
|
// object. The derived class also has to read in the storage object
|
|
// data.
|
|
//
|
|
int object_type = mpArchiveStorageObject->ReadChar();
|
|
ALStorage *storage_object = list.mToolKit.CreateStorageObject( name, object_type );
|
|
if ( storage_object )
|
|
storage_object->ReadStorageObjectData( mpArchiveStorageObject );
|
|
else {
|
|
ALName temp;
|
|
mpArchiveStorageObject->ReadString( temp );
|
|
//
|
|
// I used to treat this as an error, now I don't. The error will come about
|
|
// when you actually try to compress the object.
|
|
//
|
|
#if 0
|
|
return mStatus.SetError( AL_CANT_CREATE_STORAGE_OBJECT,
|
|
"Failure creating storage object for object %s",
|
|
(const char *) name );
|
|
#endif
|
|
}
|
|
//
|
|
// The rest of the stuff in the entry is pretty straightforward.
|
|
//
|
|
mpArchiveStorageObject->ReadGlLong( storage_object->mlSize );
|
|
ALEntry *job = new ALEntry( list, storage_object, compressor, decompressor );
|
|
mpArchiveStorageObject->ReadGlLong( job->mlCompressedSize );
|
|
mpArchiveStorageObject->ReadGlLong( job->mlCrc32 );
|
|
mpArchiveStorageObject->ReadGlLong( job->mlCompressedObjectPosition );
|
|
ALName comment;
|
|
mpArchiveStorageObject->ReadString( comment );
|
|
job->SetComment( comment );
|
|
long unix_time;
|
|
mpArchiveStorageObject->ReadGlLong( unix_time );
|
|
storage_object->mTimeDate.SetTimeDate( unix_time );
|
|
short int packed_attributes;
|
|
mpArchiveStorageObject->ReadGlShort( packed_attributes );
|
|
storage_object->mAttributes.SetFromPackedAttributes( packed_attributes );
|
|
}
|
|
list.mrMonitor.ArchiveOperation( AL_END_DIRECTORY_READ, this, 0 );
|
|
return mStatus;
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALEntryList::ClearError()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Reset the error status for an entry list.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "glarc.h"
|
|
//
|
|
// void ALGlArchive::PreCreate()
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, internal support function.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, internal support function.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, internal support function.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// None.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// The Create() function is found in the base class. It takes care of
|
|
// sticking a bunch of compressed objects into an archive. It gets
|
|
// ready to do this, then class this function first.
|
|
//
|
|
// Since this is a virtual function, the derived class can put any
|
|
// specialized behavior here. For Greenleaf archives, the only
|
|
// specialized behavior needed is to save enough space for a long
|
|
// in the file. After the archive is created, the long at offset 0
|
|
// will get a pointer to the start of the directory.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Nothing.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
void AL_PROTO
|
|
ALGlArchive::PreCreate() /* Tag protected function */
|
|
{
|
|
//
|
|
// The first four bytes in the archive are a long that points to the
|
|
// first byte of the directory. I don't know where the directory is
|
|
// going to be, so I just reserve space at this time with a dummy value.
|
|
//
|
|
mpArchiveStorageObject->WriteGlLong( 0x12345678L );
|
|
}
|
|
|