245 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			245 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| //
 | |
| // MONITOR.CPP
 | |
| //
 | |
| //  Source file for ArchiveLib 1.0
 | |
| //
 | |
| //  Copyright (c) Greenleaf Software, Inc. 1994
 | |
| //  All Rights Reserved
 | |
| //
 | |
| // CONTENTS
 | |
| //
 | |
| //  ALMonitor::operator new()
 | |
| //  ALMonitor::ALMonitor()
 | |
| //  ALMonitor::~ALMonitor()
 | |
| //  ALMonitor::Progress()
 | |
| //  ALMonitor::ArchiveOperation()
 | |
| //
 | |
| // DESCRIPTION
 | |
| //
 | |
| //  This file contains the four functions defined for ALMonitor.  This is
 | |
| //  a base class, and you generally won't use an implementation of it.
 | |
| //  It doesn't have any pure functions, so if you want a do-nothing
 | |
| //  monitor, use this guy.  Other than that, the Progress() function actually
 | |
| //  does a useful calculation for derived classes, so they might call it.
 | |
| //
 | |
| // REVISION HISTORY
 | |
| //
 | |
| //  May 26, 1994  1.0A  : First release
 | |
| //
 | |
| //
 | |
| 
 | |
| #include "arclib.h"
 | |
| #pragma hdrstop
 | |
| 
 | |
| //
 | |
| // void * ALMonitor::operator new( size_t size )
 | |
| //
 | |
| // ARGUMENTS:
 | |
| //
 | |
| //  size  :  The number of bytes needed to create a new ALMonitor object.
 | |
| //
 | |
| // RETURNS
 | |
| //
 | |
| //  A pointer to the newly allocated storage area, or 0 if no storage
 | |
| //  was available.
 | |
| //
 | |
| // 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.
 | |
| //
 | |
| // REVISION HISTORY
 | |
| //
 | |
| //   May 26, 1994  1.0A  : First release
 | |
| //
 | |
| 
 | |
| #if defined( AL_BUILDING_DLL )
 | |
| void AL_DLL_FAR * AL_PROTO ALMonitor::operator new( size_t size )
 | |
| {
 | |
|     return ::new char[ size ];
 | |
| }
 | |
| #endif
 | |
| 
 | |
| //
 | |
| // ALMonitor::ALMonitor( ALMonitorType monitor_type )
 | |
| //
 | |
| // ARGUMENTS:
 | |
| //
 | |
| //  monitor_type : One of the enumerated types from ALDEFS.H.  The only
 | |
| //                 two types supported are AL_MONITOR_OBJECTS and 
 | |
| //                 AL_MONITOR_JOB.
 | |
| // RETURNS
 | |
| //
 | |
| //  Nothing, this is a constructor.
 | |
| //
 | |
| // DESCRIPTION
 | |
| //
 | |
| //  This function is called when one of the derived classes is creating
 | |
| //  a new monitor. (It could be called directly, but you aren't likely
 | |
| //  to instantiate an ALMonitor.)  It has only one thing to do, which
 | |
| //  is to initialize the miMonitorType data member.  This data member
 | |
| //  is a const member, so it has to be initialized in an initializer list.
 | |
| //  It's nice to make it const, because then you can leave it public and
 | |
| //  nobody gets to jack with it.
 | |
| //
 | |
| // REVISION HISTORY
 | |
| //
 | |
| //   May 26, 1994  1.0A  : First release
 | |
| //
 | |
| 
 | |
| AL_PROTO ALMonitor::ALMonitor( ALMonitorType monitor_type )
 | |
|     : miMonitorType( monitor_type )
 | |
| {
 | |
| }
 | |
| 
 | |
| //
 | |
| // ALMonitor::~ALMonitor()
 | |
| //
 | |
| // ARGUMENTS:
 | |
| //
 | |
| //  None, destructor.
 | |
| //
 | |
| // RETURNS
 | |
| //
 | |
| //  Likewise, none for a destructor.
 | |
| //
 | |
| // DESCRIPTION
 | |
| //
 | |
| //  The ALMonitor destructor doesn't have to clean up any dynamic
 | |
| //  storage or anything like that.  As a consequence, all we do is
 | |
| //  check the validity of this in debug mode.
 | |
| //
 | |
| // REVISION HISTORY
 | |
| //
 | |
| //   May 26, 1994  1.0A  : First release
 | |
| //
 | |
| 
 | |
| AL_PROTO ALMonitor::~ALMonitor()
 | |
| {
 | |
|     AL_ASSERT( GoodTag(), "~ALMonitor: attempt to delete invalid object" );
 | |
| }
 | |
| 
 | |
| //
 | |
| // void ALMonitor::Progress( long object_tell,
 | |
| //                           ALStorage & object )
 | |
| //
 | |
| // ARGUMENTS:
 | |
| //
 | |
| //  object_tell  : The current offset withing the object being compressed,
 | |
| //                 expanded, copied, or processed.
 | |
| //
 | |
| //  object       : A reference to the storage object being processed.
 | |
| //
 | |
| // RETURNS
 | |
| //
 | |
| //  None.
 | |
| //
 | |
| // DESCRIPTION
 | |
| //
 | |
| //  This is a virtual function.  ALMonitor::Progress() gets called from
 | |
| //  YieldTime() inside a storage object, which happens pretty
 | |
| //  frequently.  Normally the derived class will have its own version
 | |
| //  of Progress(), so this guy won't get called directly.
 | |
| //
 | |
| //  However, most of the derived versions of Progress() will go ahead and
 | |
| //  call this version anyway.  Why?  Because this guy calculates the values
 | |
| //  of miRatio and mlByteCount for you.
 | |
| //
 | |
| //  The calculated values of miRatio and mlByteCount will differ depending
 | |
| //  on whether the monitor is of type AL_MONITOR_JOB or AL_MONITOR_OBJECTS.
 | |
| //
 | |
| //  In AL_MONITOR_OBJECTS mode, the byte count is going be calculated by
 | |
| //  taking the current offset of the object and subtracting the starting 
 | |
| //  position of the object.  We have to subtract out the starting position,
 | |
| //  because sometimes we are going to be monitoring an object that resides
 | |
| //  in an archive, and its starting position will not be at location 0.
 | |
| //
 | |
| //  If we are in AL_MONITOR_JOB mode, the byte count is going to be the
 | |
| //  same as referred to above, plus the value of mlJobSoFar.  That data
 | |
| //  member contains the total number of bytes processed in previous objects
 | |
| //  in this job.  That figure is updated after each object is processed,
 | |
| //  but not by this class. ALArchiveBase does this for ordinary archiving
 | |
| //  operations, you can look at that code for hints on how to do this
 | |
| //  yourself.
 | |
| //
 | |
| //  Calculating the ratio is pretty easy.  If you are in AL_MONITOR_OBJECTS
 | |
| //  mode, you just divide the byte count by the object size.  If you are
 | |
| //  in AL_MONITOR_JOB mode, you divide the byte count by the job size.  Once
 | |
| //  again, the job size will have been calculated in advance by whatever
 | |
| //  process is performing the compression/expansion operation.
 | |
| //
 | |
| //  Note that there is one tricky bit here.  If the object size was set to
 | |
| //  -1 by the calling program, it means this routine has to go out and
 | |
| //  get the size.  This convenience cuts down on code in the high level
 | |
| //  routine.
 | |
| //
 | |
| // REVISION HISTORY
 | |
| //
 | |
| //   May 26, 1994  1.0A  : First release
 | |
| //
 | |
| 
 | |
| void AL_PROTO ALMonitor::Progress( long object_tell,
 | |
|                                    ALStorage AL_DLL_FAR & object )
 | |
| {
 | |
|     mlByteCount = object_tell - mlObjectStart;
 | |
|     if ( mlObjectSize == -1 )
 | |
|         mlObjectSize = object.GetSize();
 | |
|     if ( miMonitorType == AL_MONITOR_JOB ) {
 | |
|         mlByteCount += mlJobSoFar;
 | |
|         if ( mlJobSize == 0 )
 | |
|             miRatio = -1;
 | |
|         else
 | |
|             miRatio = (int)( 100 * mlByteCount / mlJobSize );
 | |
|     } else {
 | |
|         if ( mlObjectSize == 0 )
 | |
|             miRatio = -1;
 | |
|         else
 | |
|             miRatio = (int)(100 * mlByteCount / mlObjectSize );
 | |
|     }
 | |
| }
 | |
| 
 | |
| //
 | |
| // void ALMonitor::ArchiveOperation( ALArchiveOperation,
 | |
| //                                   ALArchiveBase *,
 | |
| //                                   ALEntry * )
 | |
| //
 | |
| // ARGUMENTS:
 | |
| //
 | |
| //  None.  There are actually three arguments passed to this function,
 | |
| //         but we ignore them here.  Derived classes may do something.
 | |
| //
 | |
| // RETURNS
 | |
| //
 | |
| //  Nothing.
 | |
| //
 | |
| // DESCRIPTION
 | |
| //
 | |
| //  Derived classes override this function to print informative information
 | |
| //  about various archiving operations.  The base class does absolutely
 | |
| //  nothing with this information, it is a do-nothing function.
 | |
| //
 | |
| // REVISION HISTORY
 | |
| //
 | |
| //   May 26, 1994  1.0A  : First release
 | |
| //
 | |
| 
 | |
| void AL_PROTO ALMonitor::ArchiveOperation( ALArchiveOperation,
 | |
|                                            ALArchiveBase AL_DLL_FAR *,
 | |
|                                            ALEntry AL_DLL_FAR * )
 | |
| {
 | |
| }                                              
 |