336 lines
9.7 KiB
C++
Executable File
336 lines
9.7 KiB
C++
Executable File
//
|
|
// STATUS.CPP
|
|
//
|
|
// Source file for ArchiveLib 1.0
|
|
//
|
|
// Copyright (c) 1994 Greenleaf Software, Inc.
|
|
// All Rights Reserved
|
|
//
|
|
// CONTENTS
|
|
//
|
|
// ALStatus::operator new()
|
|
// ALStatus::ALStatus()
|
|
// ALStatus::~ALStatus()
|
|
// ALStatus::SetError()
|
|
// ALStatus::GetStatusString()
|
|
// ALStatus::GetStatusDetail()
|
|
// ALStatus::operator = ()
|
|
//
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// This file contains LibMain() and the WEP() for ArchiveLib DLLs.
|
|
// We don't really do anything exciting in the WEP, it is just
|
|
// here for decoration. LibMain() has to set up memory allocation
|
|
// for Borland.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// May 26, 1994 1.0A : First release
|
|
//
|
|
//
|
|
|
|
#include "arclib.h"
|
|
#pragma hdrstop
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
|
|
//
|
|
// void * ALStatus::operator new( size_t size )
|
|
//
|
|
// ARGUMENTS:
|
|
//
|
|
// size : The number of bytes needed to create a new ALStatus 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 ALStatus::operator new( size_t size )
|
|
{
|
|
return ::new char[ size ];
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// ALStatus::ALStatus()
|
|
//
|
|
// ARGUMENTS:
|
|
//
|
|
// None.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Nothing, this is a constructor.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// This is the only constructor for objects of class ALStatus. It
|
|
// initializes the detail length member to 129, which is a const and
|
|
// won't change. The initial status is AL_SUCCESS, and there is no
|
|
// detail string to start with.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// May 26, 1994 1.0A : First release
|
|
//
|
|
|
|
AL_PROTO ALStatus::ALStatus() : miStatusDetailLength( 129 )
|
|
{
|
|
miStatus = AL_SUCCESS;
|
|
mszStatusDetail = 0;
|
|
}
|
|
|
|
//
|
|
// ALStatus::~ALStatus()
|
|
//
|
|
// ARGUMENTS:
|
|
//
|
|
// None, destructor.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// None, destructor.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// The destructor has to free up any space allocated for the detailed
|
|
// error status string. That's all.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// May 26, 1994 1.0A : First release
|
|
//
|
|
|
|
AL_PROTO ALStatus::~ALStatus()
|
|
{
|
|
if ( mszStatusDetail )
|
|
delete[] mszStatusDetail;
|
|
}
|
|
|
|
//
|
|
// int ALStatus::SetError( int error, const char AL_DLL_FAR *fmt, ... )
|
|
//
|
|
// ARGUMENTS:
|
|
//
|
|
// error : The new error code to set the miStatus member to. A value
|
|
// less than 0 (AL_SUCCESS) will always be interpreted as
|
|
// an error.
|
|
//
|
|
// fmt : A sprintf style formatting string. This is for the
|
|
// message that is going to go into the status detail message.
|
|
//
|
|
// ... : Any additional arguments needed by the formatting string.
|
|
//
|
|
//
|
|
// RETURNS
|
|
//
|
|
// error, the error code that just got passed in.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// I don't know why I did the status detail allocation the way it is
|
|
// done here, it is really stupid. I should just allocate whatever space
|
|
// is necessary after formatting the string. This will probably be
|
|
// fixed in 1.x.
|
|
//
|
|
// This function is used to set the status of an object to an error state.
|
|
// Normally this is done by sending an error code, along with a detailed
|
|
// message explaining what went wrong and why. Note that to clear
|
|
// and error state, you can pass AL_SUCCESS for the error code and
|
|
// 0 for the format. The object will look like it is healthy and happy
|
|
// after that.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// May 26, 1994 1.0A : First release
|
|
//
|
|
|
|
int AL_PROTO ALStatus::SetError( int error, const char AL_DLL_FAR *fmt, ... )
|
|
{
|
|
char detail[ 256 ];
|
|
va_list argptr;
|
|
|
|
miStatus = error;
|
|
if ( fmt == 0 ) {
|
|
if ( mszStatusDetail )
|
|
delete[] mszStatusDetail;
|
|
mszStatusDetail = 0;
|
|
} else {
|
|
va_start( argptr, fmt );
|
|
vsprintf( detail, fmt, argptr );
|
|
va_end( argptr );
|
|
if ( mszStatusDetail == 0 )
|
|
mszStatusDetail = new char[ miStatusDetailLength ];
|
|
if ( mszStatusDetail ) {
|
|
strncpy( mszStatusDetail, detail, miStatusDetailLength - 1 );
|
|
mszStatusDetail[ miStatusDetailLength - 1 ] = '\0';
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
|
|
//
|
|
// const char * ALStatus::GetStatusString()
|
|
//
|
|
// ARGUMENTS:
|
|
//
|
|
// None.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// A short ASCII translation of the current error code.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// Rather than just printing an error code number, it is usually more
|
|
// helpful to translate that number into ASCII text, so a user or
|
|
// programmer can read the description. This function is used to
|
|
// do just that. It translates the current error code into a short
|
|
// ASCII text string. Note that this is not the same as the detail
|
|
// string, which is tailored for each specific occurrence of an error code.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// May 26, 1994 1.0A : First release
|
|
//
|
|
|
|
const char AL_DLL_FAR * AL_PROTO ALStatus::GetStatusString()
|
|
{
|
|
switch ( miStatus ) {
|
|
case AL_SUCCESS : return "Success";
|
|
case AL_END_OF_FILE : return "End of file";
|
|
case AL_CANT_OPEN_BUFFER : return "Can't allocate buffer";
|
|
case AL_CANT_CREATE_ENGINE : return "Can't create compression engine";
|
|
case AL_CANT_CREATE_STORAGE_OBJECT: return "Can't create storage object";
|
|
case AL_CANT_ALLOCATE_MEMORY : return "Memory allocation failure";
|
|
case AL_RENAME_ERROR : return "Error renaming file";
|
|
case AL_CANT_OPEN_FILE : return "Can't open file";
|
|
case AL_SEEK_ERROR : return "Seek error";
|
|
case AL_READ_ERROR : return "Read error";
|
|
case AL_WRITE_ERROR : return "Write error";
|
|
case AL_DELETE_ERROR : return "File deletion error";
|
|
case AL_ILLEGAL_PARAMETER : return "Illegal parameter";
|
|
case AL_INTERNAL_ERROR : return "Internal error";
|
|
case AL_USER_ABORT : return "User abort";
|
|
case AL_SERVER_NOT_PRESENT : return "Server not present";
|
|
case AL_COMPRESSION_TYPE_MISMATCH : return "Mismatch in compression type";
|
|
case AL_NEED_LENGTH : return "Missing length parameter";
|
|
case AL_CRC_ERROR : return "CRC Error";
|
|
case AL_COMPARE_ERROR : return "Comparison error";
|
|
case AL_UNKNOWN_COMPRESSION_TYPE : return "Unknown compression type";
|
|
case AL_UNKNOWN_STORAGE_OBJECT : return "Unknown type of storage object";
|
|
case AL_INVALID_ARCHIVE : return "Invalid archive";
|
|
case AL_LOGIC_ERROR : return "Logic error";
|
|
case AL_BACKUP_FAILURE : return "Could not create backup";
|
|
case AL_GETSEL_ERROR : return "Error getting selections from list box";
|
|
case AL_DUPLICATE_ENTRY : return "Duplicate entry";
|
|
default : return "Unknown error";
|
|
}
|
|
}
|
|
|
|
//
|
|
// const char * ALStatus::GetStatusDetail() const
|
|
//
|
|
// ARGUMENTS:
|
|
//
|
|
// None.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Guaranteed to return a valid character string.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// Whenever we set the error code for an object in ArchiveLib, we
|
|
// call ALStatus::SetError(). At the same time that we set the
|
|
// error code of the object to a non-zero value, we supply a formatted
|
|
// string providing some detail about when and where the error
|
|
// took place, maybe even including some other information provided by the
|
|
// O/S. That information is stored in the detail string, which is a
|
|
// private data member. This function provides the ability to get at
|
|
// that detail string.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// May 26, 1994 1.0A : First release
|
|
//
|
|
|
|
const char AL_DLL_FAR * AL_PROTO ALStatus::GetStatusDetail() const
|
|
{
|
|
if ( mszStatusDetail )
|
|
return mszStatusDetail;
|
|
else if ( miStatus == AL_SUCCESS )
|
|
return "No errors";
|
|
else
|
|
return "Unable to allocate memory for error detail message";
|
|
}
|
|
|
|
//
|
|
// ALStatus & ALStatus::operator = ( ALStatus &rhs )
|
|
//
|
|
// ARGUMENTS:
|
|
//
|
|
// rhs : Another ALStatus object that I want to copy into this object.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// A reference to this.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// Somewhere in ArchiveLib I want to be able to copy one status
|
|
// into another. This function does just that. It has to allocate
|
|
// new space to make a copy of the detail string, and be sure to
|
|
// free up any old space, and all that.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// May 26, 1994 1.0A : First release
|
|
//
|
|
|
|
ALStatus AL_DLL_FAR & AL_PROTO ALStatus::operator = ( ALStatus AL_DLL_FAR &rhs )
|
|
{
|
|
if ( rhs.mszStatusDetail == 0 ) {
|
|
if ( mszStatusDetail ) {
|
|
delete[] mszStatusDetail;
|
|
mszStatusDetail = 0;
|
|
}
|
|
} else {
|
|
if ( mszStatusDetail == 0 )
|
|
mszStatusDetail = new char[ miStatusDetailLength ];
|
|
if ( mszStatusDetail )
|
|
strcpy( mszStatusDetail, rhs.mszStatusDetail );
|
|
}
|
|
miStatus = rhs.miStatus;
|
|
return *this;
|
|
}
|
|
|