campo-sirio/al/cpp_all/arclist.cpp
alex 714dd74636 Archive Library versione 2.00
git-svn-id: svn://10.65.10.50/trunk@5350 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-10-09 16:09:54 +00:00

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