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