552 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			552 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| //
 | |
| // BARGRAPH.CPP
 | |
| //
 | |
| //  Source file for ArchiveLib 2.0
 | |
| //
 | |
| //  Copyright (c) Greenleaf Software, Inc. 1994-1996
 | |
| //  All Rights Reserved
 | |
| //
 | |
| // CONTENTS
 | |
| //
 | |
| //  ALBarGraph::operator new()
 | |
| //  ALBarGraph::ALBarGraph()
 | |
| //  newALBarGraph()
 | |
| //  ALBarGraph::~ALBarGraph()
 | |
| //  ALBarGraph::Progress()
 | |
| //  ALBarGraph::ArchiveOperation()
 | |
| //
 | |
| // DESCRIPTION
 | |
| //
 | |
| //  This file contains all of the member functions from class ALBarGraph.
 | |
| //  ALBarGraph is a monitor class that is only used under MS-DOS
 | |
| //  console operations.  This guy prints out a little graph, then
 | |
| //  fills it in as the progress proceeds from 0 to 100%.
 | |
| //
 | |
| // REVISION HISTORY
 | |
| //
 | |
| //  May 21, 1994  1.0A  : First release
 | |
| //
 | |
| //  July 8, 1994  1.0B  : Changed the default characters under UNIX to
 | |
| //                        normal ASCII, not IBMPC non-printables.  They
 | |
| //                        are defined by the macros FOREGROUND and
 | |
| //                        BACKGROUND.
 | |
| //
 | |
| //  January 9, 1995  1.01A : Made modifications to argument and parameter
 | |
| //                           definitions so that the bargraph could be used
 | |
| //                           as part of a DOS DLL.
 | |
| //
 | |
| //   February 14, 1996  2.0A : New release
 | |
| 
 | |
| #include "arclib.h"
 | |
| #if !defined( AL_IBM )
 | |
| #pragma hdrstop
 | |
| #endif
 | |
| 
 | |
| #include <iostream.h>
 | |
| #include <iomanip.h>
 | |
| 
 | |
| #include "bargraph.h"
 | |
| 
 | |
| #define FOREGROUND '\xb1'
 | |
| #define BACKGROUND '\xb0'
 | |
| 
 | |
| //
 | |
| // NAME
 | |
| //
 | |
| //  ALBarGraph::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 "bargraph.h"
 | |
| //
 | |
| //  void * ALBarGraph::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 ALBarGraph 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
 | |
| ALBarGraph::operator new( size_t size )  /* Tag protected function */
 | |
| {
 | |
|     return ::new char[ size ];
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| //
 | |
| // NAME
 | |
| //
 | |
| //  ALBarGraph::ALBarGraph()
 | |
| //
 | |
| // PLATFORMS/ENVIRONMENTS
 | |
| //
 | |
| //  Console
 | |
| //  C++  C
 | |
| //
 | |
| // SHORT DESCRIPTION
 | |
| //
 | |
| //  Create a new bar graph monitor object.
 | |
| //
 | |
| // C++ SYNOPSIS
 | |
| //
 | |
| //  #include "arclib.h"
 | |
| //  #include "bargraph.h"
 | |
| //
 | |
| //  ALBarGraph::ALBarGraph( ALMonitorType monitor_type,
 | |
| //                          ostream AL_DLL_FAR& stream,
 | |
| //                          int bar_length = 25 );
 | |
| //
 | |
| // C SYNOPSIS
 | |
| //
 | |
| //  #include "arclib.h"
 | |
| //  #include "bargraph.h"
 | |
| //
 | |
| //  hALMonitor newALBarGraph( 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 little graph 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.
 | |
| //
 | |
| //  bar_length    : The length of the bar.  C programmers get no choice here,
 | |
| //                  have to use the default value of 25.
 | |
| //
 | |
| //
 | |
| // DESCRIPTION
 | |
| //
 | |
| //  This constructor initializes things, but it doesn't have any real
 | |
| //  work to do.  It initializes the three local data members for
 | |
| //  the object, and initializes ALMonitor with its data member, and
 | |
| //  that's that.  We don't actually draw the graph yet, that happens
 | |
| //  later when one of the Archive operations takes place.
 | |
| //
 | |
| //  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
 | |
| ALBarGraph::ALBarGraph( ALMonitorType monitor_type,  /* Tag public function */
 | |
|                         ostream AL_DLL_FAR& stream,
 | |
|                         int bar_length /* =25 */ )
 | |
|      : ALMonitor( monitor_type ),
 | |
|         mrStream( stream ),
 | |
|         miBarLength( bar_length )
 | |
| {
 | |
|      miCurrentOffset = 0;
 | |
| }
 | |
| 
 | |
| #if !defined( AL_NO_C )
 | |
| 
 | |
| extern "C" AL_LINKAGE hALMonitor AL_FUNCTION
 | |
| newALBarGraph( enum ALMonitorType monitor_type )  /* Tag public function */
 | |
| {
 | |
|     ALBarGraph *monitor;
 | |
|     monitor = new ALBarGraph( monitor_type, cout );
 | |
|     return (hALMonitor) monitor;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| //
 | |
| // NAME
 | |
| //
 | |
| //  ALBarGraph::~ALBarGraph()
 | |
| //
 | |
| // PLATFORMS/ENVIRONMENTS
 | |
| //
 | |
| //  Console
 | |
| //  C++
 | |
| //
 | |
| // SHORT DESCRIPTION
 | |
| //
 | |
| //  Destroy an ALBarGraph monitor object.
 | |
| //
 | |
| // C++ SYNOPSIS
 | |
| //
 | |
| //  #include "arclib.h"
 | |
| //  #include "bargraph.h"
 | |
| //
 | |
| //  ALBarGraph::~ALBarGraph();
 | |
| //
 | |
| // 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
 | |
| ALBarGraph::~ALBarGraph()  /* Tag public function */
 | |
| {
 | |
|      AL_ASSERT( GoodTag(), "~ALBarGraph: attempt to delete invalid object" );
 | |
| }
 | |
| 
 | |
| //
 | |
| // NAME
 | |
| //
 | |
| //  ALBarGraph::Progress()
 | |
| //
 | |
| // PLATFORMS/ENVIRONMENTS
 | |
| //
 | |
| //  Console
 | |
| //  C++
 | |
| //
 | |
| // SHORT DESCRIPTION
 | |
| //
 | |
| //  The progress routine for the BarGraph monitor.
 | |
| //
 | |
| // C++ SYNOPSIS
 | |
| //
 | |
| //  #include "arclib.h"
 | |
| //  #include "bargraph.h"
 | |
| //
 | |
| //  void ALBarGraph::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 update the position on the bargraph.  Note
 | |
| //  that we can't go backwards!
 | |
| //
 | |
| //  You might notice here that we don't check on whether we are monitoring
 | |
| //  Objects or Jobs, we just go with the value found in miRatio.  There
 | |
| //  is a simple reason for that.  At the start of the function, we call
 | |
| //  ALMonitor::Progress().  The base class function checks to see which
 | |
| //  mode we are in, and calculates the miRatio value according to whatever
 | |
| //  mode we are in.
 | |
| //
 | |
| // RETURNS
 | |
| //
 | |
| //  Nothing.
 | |
| //
 | |
| // EXAMPLE
 | |
| //
 | |
| // SEE ALSO
 | |
| //
 | |
| // REVISION HISTORY
 | |
| //
 | |
| //   February 14, 1996  2.0A : New release
 | |
| //
 | |
| 
 | |
| void AL_PROTO
 | |
| ALBarGraph::Progress( long object_tell,  /* Tag public function */
 | |
|                       ALStorage AL_DLL_FAR & object )
 | |
| {
 | |
|      ALMonitor::Progress( object_tell, object );
 | |
|      if ( miRatio >= 0 ) {
 | |
|           int new_offset = ( miBarLength * miRatio ) / 100;
 | |
|           while ( miCurrentOffset < new_offset ) {
 | |
|                 mrStream << FOREGROUND;
 | |
|                 miCurrentOffset++;
 | |
|           }
 | |
|      }
 | |
|      mrStream << flush;
 | |
| }
 | |
| 
 | |
| //
 | |
| // NAME
 | |
| //
 | |
| //  ALBarGraph::ArchiveOperation()
 | |
| //
 | |
| // PLATFORMS/ENVIRONMENTS
 | |
| //
 | |
| //  Console
 | |
| //  C++
 | |
| //
 | |
| // SHORT DESCRIPTION
 | |
| //
 | |
| //  Update user interface elements after an archiving operation.
 | |
| //
 | |
| // C++ SYNOPSIS
 | |
| //
 | |
| //  #include "arclib.h"
 | |
| //  #include "bargraph.h"
 | |
| //
 | |
| //  void ALBarGraph::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
 | |
| ALBarGraph::ArchiveOperation( ALArchiveOperation operation,  /* Tag public function */
 | |
|                               ALArchive AL_DLL_FAR *archive,
 | |
|                               ALEntry AL_DLL_FAR *job )
 | |
| {
 | |
|     int i;
 | |
| //
 | |
| // Note that I am using character 0xb0 to draw the graph originally,
 | |
| // and 0xb1 to redraw it indicating progress.  Maybe it would be
 | |
| // better to make these data members so people could change their
 | |
| // values...
 | |
| //
 | |
|     switch ( operation ) {
 | |
|         case AL_ARCHIVE_OPEN :
 | |
|             if ( miMonitorType == AL_MONITOR_JOB ) {
 | |
|                 mrStream << archive->GetStorageObject()->mName.GetSafeName()
 | |
|                          << " ";
 | |
|                 for ( i = 0 ; i < miBarLength ; i++ )
 | |
|                     mrStream << BACKGROUND;
 | |
|                 for ( i = 0 ; i < miBarLength ; i++ )
 | |
|                     mrStream << '\b';
 | |
|             }
 | |
|                 break;
 | |
| 
 | |
|         case AL_ARCHIVE_CLOSE :
 | |
|             if ( miMonitorType == AL_MONITOR_JOB ) {
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << '\b';
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << ' ';
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << '\b';
 | |
|                 mrStream << "\n";
 | |
|                 miCurrentOffset = 0;
 | |
|             }
 | |
|                 break;
 | |
|         case AL_EXTRACTION_OPEN :
 | |
|         case AL_COPY_OPEN :
 | |
|         case AL_INSERTION_OPEN :
 | |
|             if ( miMonitorType == AL_MONITOR_OBJECTS ) {
 | |
|                 mrStream << job->mpStorageObject->mName.GetSafeName() << " ";
 | |
|                 for ( i = 0 ; i < miBarLength ; i++ )
 | |
|                     mrStream << BACKGROUND;
 | |
|                 for ( i = 0 ; i < miBarLength ; i++ )
 | |
|                     mrStream << '\b';
 | |
|             }
 | |
|             break;
 | |
|         case AL_EXTRACTION_CLOSE :
 | |
|         case AL_COPY_CLOSE :
 | |
|             if ( miMonitorType == AL_MONITOR_OBJECTS ) {
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << '\b';
 | |
| //
 | |
| // I'm trying an alternative here that was necessitated
 | |
| // by 'extracting' directory entries.
 | |
| //
 | |
| #if 0
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << ' ';
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << '\b';
 | |
| #else
 | |
|                 for ( i = 0 ; i < miBarLength ; i++ )
 | |
|                     mrStream << ' ';
 | |
|                 for ( i = 0 ; i < miBarLength ; i++ )
 | |
|                     mrStream << '\b';
 | |
| #endif
 | |
|                 mrStream << "\n";
 | |
|                 miCurrentOffset = 0;
 | |
|             }
 | |
|             break;
 | |
|         case AL_INSERTION_CLOSE :
 | |
|                 if ( miMonitorType == AL_MONITOR_OBJECTS ) {
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << '\b';
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << ' ';
 | |
|                 for ( i = 0 ; i < miCurrentOffset ; i++ )
 | |
|                     mrStream << '\b';
 | |
|                 mrStream << job->CompressionRatio() << "%\n";
 | |
|                 miCurrentOffset = 0;
 | |
|             }
 | |
|             break;
 | |
| //
 | |
| // I decided the aesthetics were better without these messages.  I am
 | |
| // leaving them here to look at in case we want to try them again
 | |
| // some day.
 | |
| //
 | |
|         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;
 | |
| }
 |