493 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			493 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
//
 | 
						|
// ARCLIST.CPP
 | 
						|
//
 | 
						|
//  Source file for ArchiveLib 2.0
 | 
						|
//
 | 
						|
//  Copyright (c) Greenleaf Software, Inc. 1994-1996
 | 
						|
//  All Rights Reserved
 | 
						|
//
 | 
						|
// CONTENTS
 | 
						|
//
 | 
						|
//  ALEntryList::operator new()
 | 
						|
//  ALEntryList::ALEntryList()
 | 
						|
//  newALEntryList()
 | 
						|
//  ALEntryList::ALEntryList(ALEntryList&)
 | 
						|
//  ALEntryList::~ALEntryList()
 | 
						|
//  deleteALEntryList()
 | 
						|
//  ALEntryList::GetFirstEntry()
 | 
						|
//  ALEntryListGetFirstEntry()
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  ALEntryList is simply a class that is used to keep a linked list of
 | 
						|
//  ALEntry objects together.  ALEntryList objects are passed to the high
 | 
						|
//  level ALArchiveBase functions for common operations, such as Create()
 | 
						|
//  Extract(), and so on.  You get an ALEntryList back when you read the
 | 
						|
//  directory of an archive.  The ALEntryList object tells you everything
 | 
						|
//  there is to know about the object stored in the archive.
 | 
						|
//
 | 
						|
//  In archive lib 2.0, entry lists now contain a toolkit also.  The
 | 
						|
//  toolkit is used when extracting objects from an archive, or when
 | 
						|
//  adding items to the list.  It provides a factory that is used to
 | 
						|
//  create new storage objects and engines.
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
 | 
						|
#include "arclib.h"
 | 
						|
#if !defined( AL_IBM )
 | 
						|
#pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALEntryList::operator new()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Windows
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Memory allocation operator needed with DLL.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include <arclib.h>
 | 
						|
//
 | 
						|
//  void * ALEntryList::operator new( size_t size )
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  size  :  The number of bytes needed to create a new ALEntryList object.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  When using a DLL, it is easy to create 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.
 | 
						|
//
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  A pointer to the newly allocated storage area, or 0 if no storage
 | 
						|
//  was available.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
//  None.
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   May 23, 1994  1.0A  : First release
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
 | 
						|
#if defined( AL_BUILDING_DLL )
 | 
						|
 | 
						|
void AL_DLL_FAR * AL_PROTO
 | 
						|
ALEntryList::operator new( size_t size )  /* Tag internal function */
 | 
						|
{
 | 
						|
    return ::new char[ size ];
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALEntryList::ALEntryList()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Create a new ALEntry list
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  ALEntryList::ALEntryList( ALMonitor * monitor,
 | 
						|
//                            ALToolKit toolkit )
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  hALEntryList newALEntryList( hALMonitor monitor, hALToolkit toolkit );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function newALEntryList Lib "AL20LW"
 | 
						|
//    (ByVal monitor&, ByVal toolkit) As Long
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function newALEntryList( monitor : hALMonitor;
 | 
						|
//                           toolkit : hALTookit ) : hALEntryList;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  monitor : A pointer to a monitor that will be used whenever we are
 | 
						|
//            processing objects in the list.  If no argument is supplied,
 | 
						|
//            (in the C++ version), the default argument value of 0 is used.
 | 
						|
//            When the ctor sees that the value of the monitor pointer is 0,
 | 
						|
//            it assigns the default monitor instead.
 | 
						|
//
 | 
						|
//  toolkit : The toolkit is a collection of storage objects, compressors,
 | 
						|
//            and decompressors.  This toolkit is used whenever the archving
 | 
						|
//            software needs to create one of the three types of objects.
 | 
						|
//            The components you put in your toolkit will determine what sort
 | 
						|
//            of compression and storage your archives will use.
 | 
						|
//
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  Constructing an ALEntryList object doesn't take much work.  I have to
 | 
						|
//  initialize three data members.  The first is the pointer to the monitor
 | 
						|
//  that will be used when processing objects in the list.  The second is
 | 
						|
//  a copy of a toolkit that you plan to use.  The final data element is
 | 
						|
//  the root of the linked list, which is a dummy ALEntry object.  Note
 | 
						|
//  that the root is created as a dummy by setting the storage object pointer
 | 
						|
//  to 0.
 | 
						|
//
 | 
						|
//  The default monitor is defined below.  If you don't specify a real
 | 
						|
//  monitor, you get the default, which is a do nothing function.  Everyone
 | 
						|
//  can share one instance of the default monitor, because it doesn't have
 | 
						|
//  any data members to be concerned about.
 | 
						|
//
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  Nothing in C++.  A handle (pointer) to the newly created list when
 | 
						|
//  called from C, VB, or Delph.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   November 13, 1995  2.00A : First release.
 | 
						|
//   February 14, 1996  2.0A : New release, with the toolkit marking a major
 | 
						|
//                             change.
 | 
						|
//
 | 
						|
 | 
						|
//
 | 
						|
// This default monitor does absolutely nothing.  It's what I
 | 
						|
// use as the monitor if the user doesn't specify one.
 | 
						|
//
 | 
						|
 | 
						|
ALMonitor _ALDefaultMonitor( AL_MONITOR_OBJECTS );
 | 
						|
 | 
						|
AL_PROTO
 | 
						|
ALEntryList::ALEntryList( ALMonitor AL_DLL_FAR * monitor,  /* Tag public function */
 | 
						|
                          ALToolKit toolkit )
 | 
						|
    : mrMonitor( monitor ? *monitor : _ALDefaultMonitor ),
 | 
						|
      mToolKit( toolkit )
 | 
						|
{
 | 
						|
    mpListHead = new ALEntry( *this, 0, 0, 0 );
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
//
 | 
						|
// This fn is defined for C users, but I don't think it
 | 
						|
// does them any good.  It's just too difficult to deal
 | 
						|
// with toolkit issues.  instead, I have a bunch of
 | 
						|
// special constructors that add a specific toolkit.
 | 
						|
//
 | 
						|
 | 
						|
extern "C" AL_LINKAGE hALEntryList AL_FUNCTION
 | 
						|
newALEntryList( hALMonitor monitor, hALToolKit toolkit )  /* Tag public function */
 | 
						|
{
 | 
						|
    if ( monitor != 0 )
 | 
						|
        AL_ASSERT(  ((ALMonitor *) monitor)->GoodTag(),
 | 
						|
                    "monitor argument is not a valid ALMonitor" );
 | 
						|
    AL_ASSERT_OBJECT( toolkit, ALToolKit, "newALEntryList" );
 | 
						|
    ALEntryList *list = new ALEntryList( (ALMonitor *) monitor,
 | 
						|
                                         *( ( ALToolKit *) toolkit ) );
 | 
						|
    return (hALEntryList) list;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALEntryList::ALEntryList()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  The ALEntryList copy constructor
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  ALEntryList::ALEntryList( ALEntryList &rhs );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  rhs    :  A reference to an existing ALEntryList object that is going
 | 
						|
//            to be copied into the new object.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  There are times in ArchiveLib where one entry list needs to be copied
 | 
						|
//  to another.  When this occurs, we don't care about the objects in the
 | 
						|
//  list, we just want to make sure we get a copy of the toolkit!  That's
 | 
						|
//  what this is all about.
 | 
						|
//
 | 
						|
//  Note that even though this is a public function, it isn't ordinarily
 | 
						|
//  something you want to use.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  Nothing.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   November 13, 1995  2.00A : First release.
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
 | 
						|
AL_PROTO
 | 
						|
ALEntryList::ALEntryList( ALEntryList AL_DLL_FAR &rhs )  /* Tag public function */
 | 
						|
    : mrMonitor( rhs.mrMonitor ), mToolKit( rhs.mToolKit )
 | 
						|
{
 | 
						|
    mpListHead = new ALEntry( *this, 0, 0, 0 );
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALEntryList::~ALEntryList()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  The ALEntryList destructor.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  ALEntryList::~ALEntryList();
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  void deleteALEntryList( hALEntryList this_object );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Sub deleteALEntryList Lib "AL20LW" (ByVal this_object&)
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  procedure deleteALEntryList( this_object : hALEntryList );
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALEntryList object that
 | 
						|
//                  is going to be destroyed.  Note that the C++ version
 | 
						|
//                  of this member function call uses 'this' as an implicit
 | 
						|
//                  reference, instead of using this argument.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  The destructor for ALEntryList goes through the list and deletes every
 | 
						|
//  ALEntry object it finds.  Note that this also causes the ALEntry
 | 
						|
//  object to destroy its storage object and compression engine.  Once
 | 
						|
//  the whole list is obliterated, the list head ALEntry object can be
 | 
						|
//  safely deleted.  Then the whole thing is done.
 | 
						|
//
 | 
						|
//  The toolkit destructor is automatically called as part of this process,
 | 
						|
//  since it is a data member of the entry list object.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  None, destructors don't get to return anything.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   November 13, 1995  2.00A : First release.
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
 | 
						|
 | 
						|
AL_PROTO
 | 
						|
ALEntryList::~ALEntryList()  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT( GoodTag(), "~ALEntryList: attempting to delete invalid object" );
 | 
						|
    ALEntry *job = GetFirstEntry();
 | 
						|
    while ( job ) {
 | 
						|
        ALEntry *next_job = job->GetNextEntry();
 | 
						|
        delete job;
 | 
						|
        job = next_job;
 | 
						|
    }
 | 
						|
    if ( mpListHead )
 | 
						|
        delete mpListHead;
 | 
						|
    AL_ASSERT( GoodTag(), "~ALEntryList: attempting to delete invalid object" );
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE void AL_FUNCTION
 | 
						|
deleteALEntryList( hALEntryList this_object )  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALEntryList, "deleteALEntryList" );
 | 
						|
    delete (ALEntryList *) this_object;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALEntryList::GetFirstEntry()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Get the first entry in a list.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include <arclib.h>
 | 
						|
//
 | 
						|
//  ALEntry * ALEntryList::GetFirstEntry()
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include <arclib.h>
 | 
						|
//
 | 
						|
//  hALEntry ALEntryListGetFirstEntry( hALEntryList this_object )
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALEntryListGetFirstEntry Lib "AL20LW" (ByVal tihs_object&) As Long
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALEntryListGetFirstEntry( this_object : hALEntryList ) : hALEntry;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALEntryList object that
 | 
						|
//                  is in use.  Note that the C++ version of this function
 | 
						|
//                  doesn't have an explicit argument to access this_object,
 | 
						|
//                  since it has access to 'this' implicitly.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  If you are going to iterate through the entire list, this function is
 | 
						|
//  used to start you off.  It gets the first entry in the list by calling
 | 
						|
//  GetNextEntry() for the list head.  Don't worry about what happens if
 | 
						|
//  the list is empty, the GetNextEntry() code figures that out with no
 | 
						|
//  problem, and returns a 0.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  A pointer to the first valid ALEntry object in the list, or 0 if there
 | 
						|
//  are no entries.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   May 23, 1994  1.0A  : First release
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
 | 
						|
 | 
						|
ALEntry AL_DLL_FAR * AL_PROTO
 | 
						|
ALEntryList::GetFirstEntry()  /* Tag public function */
 | 
						|
{
 | 
						|
    return mpListHead->GetNextEntry();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE hALEntry AL_FUNCTION
 | 
						|
ALEntryListGetFirstEntry( hALEntryList this_object )  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListGetFirstEntry" );
 | 
						|
    return (hALEntry) ( ((ALEntryList *) this_object )->GetFirstEntry() );
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 |