477 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			477 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
//
 | 
						|
// SPINNER.CPP
 | 
						|
//
 | 
						|
//  Source file for ArchiveLib 2.0
 | 
						|
//
 | 
						|
//  Copyright (c) Greenleaf Software, Inc. 1994-1996
 | 
						|
//  All Rights Reserved
 | 
						|
//
 | 
						|
// CONTENTS
 | 
						|
//
 | 
						|
//  ALSpinner::operator new()
 | 
						|
//  ALSpinner::ALSpinner()
 | 
						|
//  newALSpinner()
 | 
						|
//  ALSpinner::~ALSpinner()
 | 
						|
//  ALSpinner::Progress()
 | 
						|
//  ALSpinner::ArchiveOperation()
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  This file contains all of the source code to support the ALSpinner
 | 
						|
//  class.  ALSpinner displays a little propellor that spins around
 | 
						|
//  in order to indicate that something is happening.  So the Progress()
 | 
						|
//  guy here doesn't pay any attention to the numbers that he gets, he
 | 
						|
//  just spins the propellor a little bit each time it gets called.
 | 
						|
//
 | 
						|
//  The ArchiveOperation() function works pretty much like the other
 | 
						|
//  monitors.  It just formats the messages and prints them out.
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//  May 22, 1994  1.0A    : First release
 | 
						|
//
 | 
						|
//  January 9, 1995 1.01A : Made modifications to arguments to member
 | 
						|
//                          functions, so this could be used from inside
 | 
						|
//                          a DLL.
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
//
 | 
						|
 | 
						|
#include "arclib.h"
 | 
						|
#if !defined( AL_IBM )
 | 
						|
#pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#include <iostream.h>
 | 
						|
 | 
						|
#include "spinner.h"
 | 
						|
 | 
						|
//
 | 
						|
// A single static member for the whole class.  At one time I thought
 | 
						|
// this would be a good idea, I don't think so any more.  But it doesn't
 | 
						|
// really matter unless you have multiple processes running multiple
 | 
						|
// monitors.  Since this is MS-DOS only, that doesn't seem likely.
 | 
						|
//
 | 
						|
 | 
						|
int ALSpinner::miSpinIndex;
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALSpinner::operator new()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Memory allocator used when ArchiveLib resides in a 16 bit DLL.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//  #include "spinner.h"
 | 
						|
//
 | 
						|
//  void * ALSpinner::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 ALSpinner 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.
 | 
						|
//
 | 
						|
// 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
 | 
						|
ALSpinner::operator new( size_t size )  /* Tag protected function */
 | 
						|
{
 | 
						|
    return ::new char[ size ];
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALSpinner::ALSpinner()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console
 | 
						|
//  C++  C
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Create a new spinner monitor object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//  #include "spinner.h"
 | 
						|
//
 | 
						|
//  ALSpinner::ALSpinner( ALMonitorType monitor_type,
 | 
						|
//                        ostream &stream );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//  #include "spinner.h"
 | 
						|
//
 | 
						|
//  hALMonitor newALSpinner( enum ALMonitorType monitor_type );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None, no text mode output for VB.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None, no text mode output for Delphi.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  monitor_type  : AL_MONITOR_OBJECTS or AL_MONITOR_JOBS.
 | 
						|
//
 | 
						|
//  stream        : The stream where the spinner is going to be
 | 
						|
//                  printed.  Note that if you are using C, you don't
 | 
						|
//                  get a choice here.  That's because C <stdio.h> isn't
 | 
						|
//                  aware of streams.  We give you cout by default.  Hope
 | 
						|
//                  it all works.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  The constructor for the ALSpinner object just has to initialize
 | 
						|
//  a couple of data members.  The real action doesn't start until the
 | 
						|
//  archive is opened.
 | 
						|
//
 | 
						|
//  In theory, you might be able to use this from outside a DLL, for example,
 | 
						|
//  with PowerPack.  However, there could be complications when trying to
 | 
						|
//  talk to a DLL with a far reference.  Who knows???
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  The C++ constructor has no return type.  The C function returns an
 | 
						|
//  ALMonitor handle which points to the newly constructed monitor object.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
//
 | 
						|
 | 
						|
AL_PROTO
 | 
						|
ALSpinner::ALSpinner( ALMonitorType monitor_type,  /* Tag public function */
 | 
						|
                      ostream AL_DLL_FAR & stream )
 | 
						|
    : ALMonitor( monitor_type ),
 | 
						|
      mrStream( stream )
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE hALMonitor AL_FUNCTION
 | 
						|
newALSpinner( enum ALMonitorType monitor_type )  /* Tag public function */
 | 
						|
{
 | 
						|
    ALSpinner *monitor;
 | 
						|
    monitor = new ALSpinner( monitor_type, cout );
 | 
						|
    return (hALMonitor) monitor;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALSpinner::~ALSpinner()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Destroy an ALSpinner monitor object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//  #include "spinner.h"
 | 
						|
//
 | 
						|
//  ALSpinner::~ALSpinner();
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  C programs must call the base class destructor deleteALMonitor().
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  VB programs must call the base class destructor deleteALMonitor().
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  Delphi programs must call the base class destructor deleteALMonitor().
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  None.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  The destructor does nothing.  If it ever has to do anything serious,
 | 
						|
//  this is where it will happen.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  Nothing.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
//
 | 
						|
 | 
						|
AL_PROTO
 | 
						|
ALSpinner::~ALSpinner()  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT( GoodTag(), "~ALSpinner: attempt to delete invalid object" );
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALSpinner::Progress()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  The progress routine for the spinner monitor.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//  #include "spinner.h"
 | 
						|
//
 | 
						|
//  void ALSpinner::Progress( long object_tell,
 | 
						|
//                            ALStorage &object );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is a protected member function for internal use.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is a protected member function for internal use.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is a protected member function for internal use.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  object_tell  : The current offset within the object being processed.
 | 
						|
//                 Since this function is always called from inside
 | 
						|
//                 ALStorage::Yield(), the location will always be known.
 | 
						|
//
 | 
						|
// object        : The object being compressed, extracted, copied, or
 | 
						|
//                 whatever.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  This function gets called a lot while an object is being processed.
 | 
						|
//  All we do in here is spin the spinner by one position.
 | 
						|
//
 | 
						|
//  You might notice that this monitor doesn't really care at all about
 | 
						|
//  any of the numeric values.  All it does is spin the spinner, regardless
 | 
						|
//  of what's happening.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  Nothing.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
//
 | 
						|
 | 
						|
void AL_PROTO
 | 
						|
ALSpinner::Progress( long object_tell,  /* Tag public function */
 | 
						|
                     ALStorage AL_DLL_FAR & object )
 | 
						|
{
 | 
						|
    ALMonitor::Progress( object_tell, object );
 | 
						|
    mrStream << "|/-\\"[ miSpinIndex++ & 3 ] << '\b' << flush;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALSpinner::ArchiveOperation()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Update user interface elements after an archiving operation.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//  #include "spinner.h"
 | 
						|
//
 | 
						|
//  void ALSpinner::ArchiveOperation( ALArchiveOperation operation,
 | 
						|
//                                    ALArchive *archive,
 | 
						|
//                                    ALEntry *job );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is a protected member function for internal use.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is a protected member function for internal use.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is a protected member function for internal use.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  operation : One of the values from the enumerated type ALArchiveOperation.
 | 
						|
//              It is simply a list of possible operations that the archive
 | 
						|
//              operation might take, such as opening a file, closing a
 | 
						|
//              file, etc.
 | 
						|
//
 | 
						|
//  archive   : A pointer to the archive object currently being worked on.
 | 
						|
//
 | 
						|
//  job       : A pointer to an ALEntry object that defines the ALStorage
 | 
						|
//              object presently being worked on.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  During the course of an Archiving operation, the functions in
 | 
						|
//  ALArchive will get the urge to spit out a message.  They do
 | 
						|
//  so by calling this member function.  All of the messages should
 | 
						|
//  be self-explanatory.
 | 
						|
//
 | 
						|
//  It would make a lot of sense to move the message formatting up into
 | 
						|
//  the base class so I didn't have to duplicate this effort in every
 | 
						|
//  derived class.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  Nothing.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
//
 | 
						|
 | 
						|
void AL_PROTO
 | 
						|
ALSpinner::ArchiveOperation( ALArchiveOperation operation,  /* Tag public function */
 | 
						|
                             ALArchive AL_DLL_FAR *archive,
 | 
						|
                             ALEntry AL_DLL_FAR *job )
 | 
						|
{
 | 
						|
    switch ( operation ) {
 | 
						|
        case AL_ARCHIVE_OPEN :
 | 
						|
            if ( miMonitorType == AL_MONITOR_JOB )
 | 
						|
                mrStream << archive->GetStorageObject()->mName.GetName() << " ";
 | 
						|
            break;
 | 
						|
        case AL_ARCHIVE_CLOSE :
 | 
						|
            if ( miMonitorType == AL_MONITOR_JOB )
 | 
						|
                mrStream << "\n";
 | 
						|
            break;
 | 
						|
        case AL_EXTRACTION_OPEN :
 | 
						|
        case AL_COPY_OPEN :
 | 
						|
        case AL_INSERTION_OPEN :
 | 
						|
            if ( miMonitorType == AL_MONITOR_OBJECTS )
 | 
						|
                mrStream << job->mpStorageObject->mName.GetSafeName() << " ";
 | 
						|
            break;
 | 
						|
        case AL_EXTRACTION_CLOSE :
 | 
						|
        case AL_COPY_CLOSE :
 | 
						|
            if ( miMonitorType == AL_MONITOR_OBJECTS )
 | 
						|
                mrStream << "\n";
 | 
						|
            break;
 | 
						|
        case AL_INSERTION_CLOSE :
 | 
						|
            if ( miMonitorType == AL_MONITOR_OBJECTS )
 | 
						|
                mrStream << job->CompressionRatio() << "%\n";
 | 
						|
            break;
 | 
						|
        case AL_END_DIRECTORY_WRITE :
 | 
						|
        case AL_END_DIRECTORY_READ :
 | 
						|
//            cout << "Done\n";
 | 
						|
            break;
 | 
						|
        case AL_START_DIRECTORY_WRITE :
 | 
						|
//            mrStream << "Writing directory\n";
 | 
						|
            break;
 | 
						|
        case AL_START_DIRECTORY_READ :
 | 
						|
//            mrStream << "Reading directory\n";
 | 
						|
            break;
 | 
						|
    }
 | 
						|
    mrStream << flush;
 | 
						|
}
 |