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
 | |
| 
 |