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