Archive Lib versione 1.0
git-svn-id: svn://10.65.10.50/trunk@5346 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
26e072eb99
commit
8316a950de
136
al/_debug.cpp
Executable file
136
al/_debug.cpp
Executable file
@ -0,0 +1,136 @@
|
||||
//
|
||||
// _DEBUG.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// _ALAssertFailure()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains a support routine used by the assertion macros,
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
//
|
||||
// void _ALAssertFailure( const char *condition,
|
||||
// const char *filename,
|
||||
// int line,
|
||||
// const char *message,
|
||||
// ... )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// condition : A character string containing the condition that failed,
|
||||
// leading to the assertion.
|
||||
//
|
||||
// filename : The name of the file where the assertion error took place.
|
||||
//
|
||||
// line : The line in the file where the assertion error took place.
|
||||
//
|
||||
// message : The error message associated with the assertion error.
|
||||
// This message is a sprintf() style format string.
|
||||
//
|
||||
// ... : Any additional arguments.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The C run time library features an assert() macro, that can be used to
|
||||
// abort a program if a given condition isn't true. It aborts the program
|
||||
// by calling a routine that looks something like this. The AL_ASSERT()
|
||||
// macro that we use is even better, because it includes a comment
|
||||
// that gets displayed when the abort takes place. This routine is
|
||||
// responsible for displaying that comment, along with the file name and
|
||||
// the line number, then aborting the program. It is called by the
|
||||
// AL_ASSERT() macro when the conditional expression argument fails.
|
||||
//
|
||||
// This routine is full of #ifdefs, and looks like a real mess. This
|
||||
// is too bad, because it is really quite simple. Basically it has to
|
||||
// quit with an abort() under MS-DOS, and a FatalAppExit() under
|
||||
// windows. The error message is displayed on the console under MS-DOS,
|
||||
// (hope you're not in graphics mode!) and in a MessageBox under
|
||||
// Windows. Man, it would be great to have just a little bit of control
|
||||
// of the formatting in the message box!
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_CFUNCTION _ALAssertFailure( const char AL_DLL_FAR *condition,
|
||||
const char AL_DLL_FAR *filename,
|
||||
int line,
|
||||
const char AL_DLL_FAR *message,
|
||||
... )
|
||||
{
|
||||
char buf1[ 256 ];
|
||||
char buf2[ 128 ];
|
||||
va_list argptr;
|
||||
|
||||
va_start( argptr, message );
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI )
|
||||
//
|
||||
// Watcom is kind of annoying in that they format their variable arguments
|
||||
// just a little differently than everyone else.
|
||||
//
|
||||
#if defined( AL_WATCOM )
|
||||
wvsprintf( buf2, message, *argptr );
|
||||
#else
|
||||
wvsprintf( buf2, message, argptr );
|
||||
#endif
|
||||
#else
|
||||
vsprintf( buf2, message, argptr );
|
||||
#endif
|
||||
va_end( argptr );
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI )
|
||||
wsprintf
|
||||
#else
|
||||
sprintf
|
||||
#endif
|
||||
( buf1,
|
||||
"Assertion error, ArchiveLib is aborting the application.\n"
|
||||
"Condition = %s\n"
|
||||
"File = %s, line = %d\n"
|
||||
"%s",
|
||||
condition,
|
||||
filename,
|
||||
line,
|
||||
buf2 );
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
#ifdef AL_BUILDING_DLL
|
||||
MessageBox( 0, buf1, " ArchiveLib (DLL) assertion error ", MB_ICONSTOP );
|
||||
#else
|
||||
MessageBox( 0,
|
||||
buf1,
|
||||
" "
|
||||
"ArchiveLib (static) assertion error"
|
||||
" ",
|
||||
MB_ICONSTOP );
|
||||
#endif
|
||||
FatalAppExit( 0, "Application terminated" );
|
||||
#else
|
||||
cerr << buf1 << "\n" << flush;
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
193
al/_debug.h
Executable file
193
al/_debug.h
Executable file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* _DEBUG.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* These macros and types are all used in the debug versions of the
|
||||
* ArchiveLib.
|
||||
*
|
||||
* MACROS
|
||||
*
|
||||
* _ALAssertFailure()
|
||||
* AL_ASSERT()
|
||||
* AL_ASSERT_OBJECT()
|
||||
* AL_CLASS_TAG()
|
||||
*
|
||||
* PROTOTYPES:
|
||||
*
|
||||
* IsBadWritePtr()
|
||||
*
|
||||
* ENUMERATED TYPES:
|
||||
*
|
||||
* _ALClassTags
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DEBUG_H
|
||||
#define __DEBUG_H
|
||||
/*
|
||||
* _ALAssertFailure is the function called by AL_ASSERT() and
|
||||
* AL_ASSERT_OBJECT() when their assertion fails.
|
||||
*/
|
||||
void AL_CFUNCTION _ALAssertFailure( const char AL_DLL_FAR *condition,
|
||||
const char AL_DLL_FAR *filename,
|
||||
int line,
|
||||
const char AL_DLL_FAR *message,
|
||||
... );
|
||||
#ifdef NDEBUG
|
||||
/*
|
||||
* In the non-debug versions, both of these macros basically go away.
|
||||
* The only difficulty is trying to avoid having the compilers generate
|
||||
* error messages when they see this code. Maybe in NDEBUG mode I could
|
||||
* change these to inline functions that do nothing?
|
||||
*/
|
||||
|
||||
#define AL_ASSERT( condition, message ) ((void) 0)
|
||||
#define AL_ASSERT_OBJECT( pointer, class, message ) ((void) 0)
|
||||
|
||||
#else
|
||||
/*
|
||||
* In debug mode, AL_ASSERT() tests the condition, and generates
|
||||
* an abort with an error message when the condition fails.
|
||||
*/
|
||||
#define AL_ASSERT( condition, message ) \
|
||||
( ( condition ) ? \
|
||||
(void) 0 : \
|
||||
_ALAssertFailure( #condition, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
message ) ) \
|
||||
/*
|
||||
* I can only call IsBadWritePtr() if TOOLHELP.DLL is available. As far
|
||||
* as I know, it won't be available with any of the DOS Extenders
|
||||
* The only way we have access to TOOLHELP.DLL is if we are *really*
|
||||
* running under Windows, not some bogus imitation.
|
||||
*/
|
||||
#if !defined( AL_WINDOWS_GUI )
|
||||
#define IsBadWritePtr( p, s ) 0
|
||||
#endif
|
||||
/*
|
||||
* AL_ASSERT_OBJECT() is a great macro. It is used to test the
|
||||
* validity of an object. This is a two step process. First,
|
||||
* we make sure we are dealing with a good pointer. If not, an
|
||||
* asserting error is triggered. This is much better than the
|
||||
* GPF you would normally get from a bad pointer. Next, we
|
||||
* test the GoodTag() macro, which verifies that this is
|
||||
* a properly constructed object from the specified class. Of
|
||||
* course, in NDEBUG mode this all goes away.
|
||||
*
|
||||
*/
|
||||
#define AL_ASSERT_OBJECT( pointer, class, message ) \
|
||||
( pointer == 0 || IsBadWritePtr( pointer, sizeof( class ) ) ) ? \
|
||||
_ALAssertFailure( "IsBadWritePtr()", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
"%s: Bad pointer to object of class %s", \
|
||||
message, \
|
||||
#class ) \
|
||||
: \
|
||||
( ( (class *)pointer)->GoodTag() ? \
|
||||
(void) 0 \
|
||||
: \
|
||||
_ALAssertFailure( #pointer "->GoodTag()", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
"%s: %s is not an object of class %s", \
|
||||
message, \
|
||||
#pointer, \
|
||||
#class ) )
|
||||
#endif
|
||||
/*
|
||||
* The AL_CLASS_TAG() macro assigns a new debug class and data
|
||||
* member to each of the classes in ArchiveLib. Each of these
|
||||
* debug classes uses a special integer tag (stored in the data member)
|
||||
* to uniquely identify itself. These are the integer values of
|
||||
* these integers.
|
||||
*/
|
||||
|
||||
enum _ALClassTags {
|
||||
_ALDeletedObjectTag = 0,
|
||||
_ALStorageTag,
|
||||
_ALFileTag,
|
||||
_ALMemoryTag,
|
||||
_ALEntryTag,
|
||||
_ALEntryListTag,
|
||||
_ALArchiveBaseTag,
|
||||
_ALArchiveTag,
|
||||
_ALMonitorTag,
|
||||
_ALBarGraphTag,
|
||||
_ALSpinnerTag,
|
||||
_ALWindowsMessageTag,
|
||||
_ALCompressionEngineTag,
|
||||
_ALCopyEngineTag,
|
||||
_ALGreenleafEngineTag,
|
||||
_ALCompressedObjectTag,
|
||||
_ALNameTag,
|
||||
_ALWildCardExpanderTag,
|
||||
};
|
||||
|
||||
/*
|
||||
* AL_CLASS_TAG( x ) is a macro that is used to help debug
|
||||
* ArchiveLib. The insertion of this macro in a class definition
|
||||
* adds a new data member and member function to the class. The
|
||||
* data member is an object of a class uniquely created by the
|
||||
* macro. The reason the data member is a class object instead
|
||||
* of a simple integer or character tag is this: By making it a
|
||||
* class object, we can automatically assign it a valid value
|
||||
* when constructed, and an invalid value when destroyed.
|
||||
*
|
||||
* The member function added to the class is called GoodTag().
|
||||
* Once you have added AL_CLASS_TAG( x ) to your class definition,
|
||||
* you can call object.GoodTag() anytime you want. It will return
|
||||
* a true value only if the data member has the correct value,
|
||||
*
|
||||
* We make use of this function in AL_ASSERT_OBJECT(). It
|
||||
* checks the value of this object frequently in member functions
|
||||
* and destructors, generating an assertion failure if the object
|
||||
* doesn't look like the correct type.
|
||||
*
|
||||
* Note that the ASSERT_OBJECT() statements generate no code when the
|
||||
* library is compiled with NDEBUG, so this class will not be
|
||||
* generating much low overhead. However, the data member will
|
||||
* still be taking up a single byte in each instance.
|
||||
*
|
||||
* If you want to eliminate class tags, this line in will do it
|
||||
* You will save one byte per instance. The best way to accomplish this
|
||||
* is to define the macro in ALCUSTOM.H, then rebuild the library with
|
||||
* macro AL_CUSTOM defined in your project. After you build this new
|
||||
* version of the library, you must absolutely, positively, be sure
|
||||
* that you continue to use AL_CUSTOM and ALCUSTOM.H when working
|
||||
* with the library. If you don't, your library and your application
|
||||
* will think that most classes in ArchiveLib are different sizes, and
|
||||
* *nothing* will work.
|
||||
*
|
||||
*#define AL_CLASS_TAG( x ) int GoodTag(){ return 1; }
|
||||
*/
|
||||
|
||||
#if defined( NDEBUG ) && !defined( AL_CLASS_TAG )
|
||||
#define AL_CLASS_TAG( x ) class AL_CLASS_TYPE _ALTag##x { \
|
||||
public : \
|
||||
unsigned char mucTagVal; \
|
||||
} mMyTag; \
|
||||
int AL_PROTO GoodTag(){ return 1; }
|
||||
#endif /* #if defined( NDEBUG ) && !defined( AL_CLASS_TAG ) */
|
||||
|
||||
#if !defined( NDEBUG ) && !defined( AL_CLASS_TAG )
|
||||
#define AL_CLASS_TAG( x ) class AL_CLASS_TYPE _ALTag##x { \
|
||||
public : \
|
||||
AL_PROTO _ALTag##x(){ mucTagVal = x; } \
|
||||
AL_PROTO ~_ALTag##x(){ mucTagVal = _ALDeletedObjectTag; } \
|
||||
unsigned char mucTagVal; \
|
||||
} mMyTag; \
|
||||
int AL_PROTO GoodTag(){ return mMyTag.mucTagVal == x; }
|
||||
#endif /* #if !defined( NDEBUG ) && !defined( AL_CLASS_TAG ) */
|
||||
#endif /* #ifndef __DEBUG_H */
|
||||
623
al/_match.cpp
Executable file
623
al/_match.cpp
Executable file
@ -0,0 +1,623 @@
|
||||
//
|
||||
// _MATCH.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// is_pattern()
|
||||
// is_valid_pattern()
|
||||
// matche()
|
||||
// matche_after_star()
|
||||
// match()
|
||||
// main() (For testing, w/conditional compile)
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Some nice code written by J. Kercheval, in the public domain.
|
||||
// This code provides us with the pattern matching functions used
|
||||
// by the ALName functions. It all seems to work without any trouble
|
||||
// at all.
|
||||
//
|
||||
// I tried to change this file as little as possible. I modified the
|
||||
// name of the file, and removed BOOLEAN, TRUE, and FALSE from the
|
||||
// header file. Other than that, it is just as I found it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
/*
|
||||
EPSHeader
|
||||
|
||||
File: match.c
|
||||
Author: J. Kercheval
|
||||
Created: Sat, 01/05/1991 22:21:49
|
||||
*/
|
||||
|
||||
/*
|
||||
EPSRevision History
|
||||
|
||||
J. Kercheval Wed, 02/20/1991 22:29:01 Released to Public Domain
|
||||
J. Kercheval Fri, 02/22/1991 15:29:01 fix '\' bugs (two :( of them)
|
||||
J. Kercheval Sun, 03/10/1991 19:31:29 add error return to matche()
|
||||
J. Kercheval Sun, 03/10/1991 20:11:11 add is_valid_pattern code
|
||||
J. Kercheval Sun, 03/10/1991 20:37:11 beef up main()
|
||||
J. Kercheval Tue, 03/12/1991 22:25:10 Released as V1.1 to Public Domain
|
||||
J. Kercheval Thu, 03/14/1991 22:22:25 remove '\' for DOS file parsing
|
||||
J. Kercheval Mon, 05/13/1991 21:49:05 ifdef full match code
|
||||
J. Kercheval Mon, 01/06/1992 21:31:44 add match character defines
|
||||
*/
|
||||
|
||||
/*
|
||||
* Wildcard Pattern Matching
|
||||
*/
|
||||
|
||||
#include "arclib.h"
|
||||
#include "_match.h"
|
||||
//
|
||||
// The next five lines used to be in the header file
|
||||
//
|
||||
#ifndef BOOLEAN
|
||||
#define BOOLEAN int
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/* character defines */
|
||||
#define MATCH_CHAR_SINGLE '?'
|
||||
#define MATCH_CHAR_KLEENE_CLOSURE '*'
|
||||
#define MATCH_CHAR_RANGE_OPEN '['
|
||||
#define MATCH_CHAR_RANGE '-'
|
||||
#define MATCH_CHAR_RANGE_CLOSE ']'
|
||||
#define MATCH_CHAR_LITERAL '\\'
|
||||
#define MATCH_CHAR_NULL '\0'
|
||||
#define MATCH_CHAR_CARAT_NEGATE '^'
|
||||
#define MATCH_CHAR_EXCLAMATION_NEGATE '!'
|
||||
|
||||
/* forward function prototypes */
|
||||
int matche_after_star( register const char *pattern, register char *text);
|
||||
int fast_match_after_star(register char *pattern, register char *text);
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* Return TRUE if PATTERN has any special wildcard characters
|
||||
*
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
BOOLEAN is_pattern( const char *p )
|
||||
{
|
||||
while (*p) {
|
||||
switch (*p++) {
|
||||
case MATCH_CHAR_SINGLE:
|
||||
case MATCH_CHAR_KLEENE_CLOSURE:
|
||||
case MATCH_CHAR_RANGE_OPEN:
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
case MATCH_CHAR_LITERAL:
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* Return TRUE if PATTERN has is a well formed regular expression according
|
||||
* to the above syntax
|
||||
*
|
||||
* error_type is a return code based on the type of pattern error. Zero is
|
||||
* returned in error_type if the pattern is a valid one. error_type return
|
||||
* values are as follows:
|
||||
*
|
||||
* PATTERN_VALID - pattern is well formed
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
* PATTERN_ESC - pattern has invalid escape ('\' at end of pattern)
|
||||
#endif
|
||||
|
||||
* PATTERN_RANGE - [..] construct has a no end range in a '-' pair (ie [a-])
|
||||
* PATTERN_CLOSE - [..] construct has no end bracket (ie [abc-g )
|
||||
* PATTERN_EMPTY - [..] construct is empty (ie [])
|
||||
*
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
BOOLEAN is_valid_pattern( const char *p, int *error_type )
|
||||
{
|
||||
|
||||
/* init error_type */
|
||||
*error_type = PATTERN_VALID;
|
||||
|
||||
/* loop through pattern to EOS */
|
||||
while (*p) {
|
||||
|
||||
/* determine pattern type */
|
||||
switch (*p) {
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
/* check literal escape, it cannot be at end of pattern */
|
||||
case MATCH_CHAR_LITERAL:
|
||||
if (!*++p) {
|
||||
*error_type = PATTERN_ESC;
|
||||
return FALSE;
|
||||
}
|
||||
p++;
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* the [..] construct must be well formed */
|
||||
case MATCH_CHAR_RANGE_OPEN:
|
||||
p++;
|
||||
|
||||
/* if the next character is ']' then bad pattern */
|
||||
if (*p == MATCH_CHAR_RANGE_CLOSE) {
|
||||
*error_type = PATTERN_EMPTY;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* if end of pattern here then bad pattern */
|
||||
if (!*p) {
|
||||
*error_type = PATTERN_CLOSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* loop to end of [..] construct */
|
||||
while (*p != MATCH_CHAR_RANGE_CLOSE) {
|
||||
|
||||
/* check for literal escape */
|
||||
if (*p == MATCH_CHAR_LITERAL) {
|
||||
p++;
|
||||
|
||||
/* if end of pattern here then bad pattern */
|
||||
if (!*p++) {
|
||||
*error_type = PATTERN_ESC;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
p++;
|
||||
|
||||
/* if end of pattern here then bad pattern */
|
||||
if (!*p) {
|
||||
*error_type = PATTERN_CLOSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* if this a range */
|
||||
if (*p == MATCH_CHAR_RANGE) {
|
||||
|
||||
/* we must have an end of range */
|
||||
if (!*++p || *p == MATCH_CHAR_RANGE_CLOSE) {
|
||||
*error_type = PATTERN_RANGE;
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
|
||||
/* check for literal escape */
|
||||
if (*p == MATCH_CHAR_LITERAL)
|
||||
p++;
|
||||
|
||||
/* if end of pattern here then bad pattern */
|
||||
if (!*p++) {
|
||||
*error_type = PATTERN_ESC;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* all other characters are valid pattern elements */
|
||||
case MATCH_CHAR_KLEENE_CLOSURE:
|
||||
case MATCH_CHAR_SINGLE:
|
||||
default: /* "normal" character */
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* Match the pattern PATTERN against the string TEXT;
|
||||
*
|
||||
* returns MATCH_VALID if pattern matches, or an errorcode as follows
|
||||
* otherwise:
|
||||
*
|
||||
* MATCH_PATTERN - bad pattern
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
* MATCH_LITERAL - match failure on literal mismatch
|
||||
#endif
|
||||
|
||||
* MATCH_RANGE - match failure on [..] construct
|
||||
* MATCH_ABORT - premature end of text string
|
||||
* MATCH_END - premature end of pattern string
|
||||
* MATCH_VALID - valid match
|
||||
*
|
||||
*
|
||||
* A match means the entire string TEXT is used up in matching.
|
||||
*
|
||||
* In the pattern string:
|
||||
* `*' matches any sequence of characters (zero or more)
|
||||
* `?' matches any character
|
||||
* [SET] matches any character in the specified set,
|
||||
* [!SET] or [^SET] matches any character not in the specified set.
|
||||
* \ is allowed within a set to escape a character like ']' or '-'
|
||||
*
|
||||
* A set is composed of characters or ranges; a range looks like character
|
||||
* hyphen character (as in 0-9 or A-Z). [0-9a-zA-Z_] is the minimal set of
|
||||
* characters allowed in the [..] pattern construct. Other characters are
|
||||
* allowed (ie. 8 bit characters) if your system will support them.
|
||||
*
|
||||
* To suppress the special syntactic significance of any of `[]*?!^-\', and
|
||||
* match the character exactly, precede it with a `\'.
|
||||
*
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
int matche( const char *p, char *t)
|
||||
{
|
||||
register char range_start, range_end; /* start and end in range */
|
||||
|
||||
BOOLEAN invert; /* is this [..] or [!..] */
|
||||
BOOLEAN member_match; /* have I matched the [..] construct? */
|
||||
BOOLEAN loop; /* should I terminate? */
|
||||
|
||||
for (; *p; p++, t++) {
|
||||
|
||||
/* if this is the end of the text then this is the end of the match */
|
||||
if (!*t) {
|
||||
return (*p == MATCH_CHAR_KLEENE_CLOSURE &&
|
||||
*++p == MATCH_CHAR_NULL) ?
|
||||
MATCH_VALID : MATCH_ABORT;
|
||||
}
|
||||
|
||||
/* determine and react to pattern type */
|
||||
switch (*p) {
|
||||
|
||||
/* single any character match */
|
||||
case MATCH_CHAR_SINGLE:
|
||||
break;
|
||||
|
||||
/* multiple any character match */
|
||||
case MATCH_CHAR_KLEENE_CLOSURE:
|
||||
return matche_after_star(p, t);
|
||||
|
||||
/* [..] construct, single member/exclusion character match */
|
||||
case MATCH_CHAR_RANGE_OPEN:{
|
||||
|
||||
/* move to beginning of range */
|
||||
p++;
|
||||
|
||||
/* check if this is a member match or exclusion match */
|
||||
invert = FALSE;
|
||||
if (*p == MATCH_CHAR_EXCLAMATION_NEGATE ||
|
||||
*p == MATCH_CHAR_CARAT_NEGATE) {
|
||||
invert = TRUE;
|
||||
p++;
|
||||
}
|
||||
|
||||
/* if closing bracket here or at range start then we have
|
||||
* a malformed pattern */
|
||||
if (*p == MATCH_CHAR_RANGE_CLOSE) {
|
||||
return MATCH_PATTERN;
|
||||
}
|
||||
|
||||
member_match = FALSE;
|
||||
loop = TRUE;
|
||||
|
||||
while (loop) {
|
||||
|
||||
/* if end of construct then loop is done */
|
||||
if (*p == MATCH_CHAR_RANGE_CLOSE) {
|
||||
loop = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* matching a '!', '^', '-', '\' or a ']' */
|
||||
if (*p == MATCH_CHAR_LITERAL) {
|
||||
range_start = range_end = *++p;
|
||||
}
|
||||
else {
|
||||
range_start = range_end = *p;
|
||||
}
|
||||
|
||||
/* if end of pattern then bad pattern (Missing ']') */
|
||||
if (!*p)
|
||||
return MATCH_PATTERN;
|
||||
|
||||
/* check for range bar */
|
||||
if (*++p == MATCH_CHAR_RANGE) {
|
||||
|
||||
/* get the range end */
|
||||
range_end = *++p;
|
||||
|
||||
/* if end of pattern or construct then bad
|
||||
* pattern */
|
||||
if (range_end == MATCH_CHAR_NULL ||
|
||||
range_end == MATCH_CHAR_RANGE_CLOSE)
|
||||
return MATCH_PATTERN;
|
||||
|
||||
/* special character range end */
|
||||
if (range_end == MATCH_CHAR_LITERAL) {
|
||||
range_end = *++p;
|
||||
|
||||
/* if end of text then we have a bad pattern */
|
||||
if (!range_end)
|
||||
return MATCH_PATTERN;
|
||||
}
|
||||
|
||||
/* move just beyond this range */
|
||||
p++;
|
||||
}
|
||||
|
||||
/* if the text character is in range then match
|
||||
* found. make sure the range letters have the proper
|
||||
* relationship to one another before comparison */
|
||||
if (range_start < range_end) {
|
||||
if (*t >= range_start && *t <= range_end) {
|
||||
member_match = TRUE;
|
||||
loop = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (*t >= range_end && *t <= range_start) {
|
||||
member_match = TRUE;
|
||||
loop = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if there was a match in an exclusion set then no match */
|
||||
/* if there was no match in a member set then no match */
|
||||
if ((invert && member_match) ||
|
||||
!(invert || member_match))
|
||||
return MATCH_RANGE;
|
||||
|
||||
/* if this is not an exclusion then skip the rest of the
|
||||
* [...] construct that already matched. */
|
||||
if (member_match) {
|
||||
while (*p != MATCH_CHAR_RANGE_CLOSE) {
|
||||
|
||||
/* bad pattern (Missing MATCH_CHAR_RANGE_CLOSE) */
|
||||
if (!*p)
|
||||
return MATCH_PATTERN;
|
||||
|
||||
/* skip exact match */
|
||||
if (*p == MATCH_CHAR_LITERAL) {
|
||||
p++;
|
||||
|
||||
/* if end of text then we have a bad pattern */
|
||||
if (!*p)
|
||||
return MATCH_PATTERN;
|
||||
}
|
||||
|
||||
/* move to next pattern char */
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
/* next character is quoted and must match exactly */
|
||||
case MATCH_CHAR_LITERAL:
|
||||
|
||||
/* move pattern pointer to quoted char and fall through */
|
||||
p++;
|
||||
|
||||
/* if end of text then we have a bad pattern */
|
||||
if (!*p)
|
||||
return MATCH_PATTERN;
|
||||
#endif
|
||||
|
||||
/* must match this character exactly */
|
||||
default:
|
||||
if (*p != *t)
|
||||
return MATCH_LITERAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* if end of text not reached then the pattern fails */
|
||||
if (*t)
|
||||
return MATCH_END;
|
||||
else
|
||||
return MATCH_VALID;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* recursively call matche() with final segment of PATTERN and of TEXT.
|
||||
*
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
int matche_after_star( register const char *p, register char *t)
|
||||
{
|
||||
register int match = 0;
|
||||
register nextp;
|
||||
|
||||
/* pass over existing ? and * in pattern */
|
||||
while (*p == MATCH_CHAR_SINGLE ||
|
||||
*p == MATCH_CHAR_KLEENE_CLOSURE) {
|
||||
|
||||
/* take one char for each ? and + */
|
||||
if (*p == MATCH_CHAR_SINGLE) {
|
||||
|
||||
/* if end of text then no match */
|
||||
if (!*t++) {
|
||||
return MATCH_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
/* move to next char in pattern */
|
||||
p++;
|
||||
}
|
||||
|
||||
/* if end of pattern we have matched regardless of text left */
|
||||
if (!*p) {
|
||||
return MATCH_VALID;
|
||||
}
|
||||
|
||||
/* get the next character to match which must be a literal or '[' */
|
||||
nextp = *p;
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
if (nextp == MATCH_CHAR_LITERAL) {
|
||||
nextp = p[1];
|
||||
|
||||
/* if end of text then we have a bad pattern */
|
||||
if (!nextp)
|
||||
return MATCH_PATTERN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Continue until we run out of text or definite result seen */
|
||||
do {
|
||||
|
||||
/* a precondition for matching is that the next character in the
|
||||
* pattern match the next character in the text or that the next
|
||||
* pattern char is the beginning of a range. Increment text pointer
|
||||
* as we go here */
|
||||
if (nextp == *t || nextp == MATCH_CHAR_RANGE_OPEN) {
|
||||
match = matche(p, t);
|
||||
}
|
||||
|
||||
/* if the end of text is reached then no match */
|
||||
if (!*t++)
|
||||
match = MATCH_ABORT;
|
||||
|
||||
} while (match != MATCH_VALID &&
|
||||
match != MATCH_ABORT &&
|
||||
match != MATCH_PATTERN);
|
||||
|
||||
/* return result */
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* match() is a shell to matche() to return only BOOLEAN values.
|
||||
*
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
BOOLEAN match( char *p, char *t)
|
||||
{
|
||||
int error_type;
|
||||
|
||||
error_type = matche(p, t);
|
||||
return (error_type == MATCH_VALID) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/*
|
||||
* This test main expects as first arg the pattern and as second arg
|
||||
* the match string. Output is yaeh or nay on match. If nay on
|
||||
* match then the error code is parsed and written.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int error;
|
||||
int is_valid_error;
|
||||
|
||||
if (argc != 3) {
|
||||
printf("Usage: MATCH Pattern Text\n");
|
||||
}
|
||||
else {
|
||||
printf("Pattern: %s\n", argv[1]);
|
||||
printf("Text : %s\n", argv[2]);
|
||||
|
||||
if ( !is_pattern(argv[1])) {
|
||||
printf(" First Argument Is Not A Pattern\n");
|
||||
}
|
||||
else {
|
||||
|
||||
#ifdef FILE_MATCH
|
||||
match(argv[1], argv[2]) ? printf("TRUE") : printf("FALSE");
|
||||
#endif
|
||||
|
||||
error = matche(argv[1], argv[2]);
|
||||
is_valid_pattern(argv[1], &is_valid_error);
|
||||
|
||||
switch (error) {
|
||||
case MATCH_VALID:
|
||||
printf(" Match Successful");
|
||||
if (is_valid_error != PATTERN_VALID)
|
||||
printf(" -- is_valid_pattern() is complaining\n");
|
||||
else
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
case MATCH_LITERAL:
|
||||
printf(" Match Failed on Literal\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MATCH_RANGE:
|
||||
printf(" Match Failed on [..]\n");
|
||||
break;
|
||||
case MATCH_ABORT:
|
||||
printf(" Match Failed on Early Text Termination\n");
|
||||
break;
|
||||
case MATCH_END:
|
||||
printf(" Match Failed on Early Pattern Termination\n");
|
||||
break;
|
||||
case MATCH_PATTERN:
|
||||
switch (is_valid_error) {
|
||||
case PATTERN_VALID:
|
||||
printf(" Internal Disagreement On Pattern\n");
|
||||
break;
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
case PATTERN_ESC:
|
||||
printf(" Literal Escape at End of Pattern\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PATTERN_RANGE:
|
||||
printf(" No End of Range in [..] Construct\n");
|
||||
break;
|
||||
case PATTERN_CLOSE:
|
||||
printf(" [..] Construct is Open\n");
|
||||
break;
|
||||
case PATTERN_EMPTY:
|
||||
printf(" [..] Construct is Empty\n");
|
||||
break;
|
||||
default:
|
||||
printf(" Internal Error in is_valid_pattern()\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf(" Internal Error in matche()\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif
|
||||
158
al/_match.h
Executable file
158
al/_match.h
Executable file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* _MATCH.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file is for the internal support routines
|
||||
* that perform wild card matching. This code is public domain
|
||||
* code that I lifted. It will not be documented!
|
||||
*
|
||||
* I tried to change this file as little as possible. I modified the
|
||||
* name of the file, and removed BOOLEAN, TRUE, and FALSE from the
|
||||
* header file. Other than that, it is unchanged.
|
||||
*
|
||||
* MACROS
|
||||
*
|
||||
* All of the MATCH_xxx macros are defined in this header file.
|
||||
*
|
||||
* PROTOTYPES:
|
||||
*
|
||||
* match()
|
||||
* matche()
|
||||
* is_pattern()
|
||||
* is_valid_pattern()
|
||||
*
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
EPSHeader
|
||||
|
||||
File: match.h
|
||||
Author: J. Kercheval
|
||||
Created: Sat, 01/05/1991 22:27:18
|
||||
*/
|
||||
|
||||
/*
|
||||
EPSRevision History
|
||||
|
||||
J. Kercheval Wed, 02/20/1991 22:28:37 Released to Public Domain
|
||||
J. Kercheval Sun, 03/10/1991 18:02:56 add is_valid_pattern
|
||||
J. Kercheval Sun, 03/10/1991 18:25:48 add error_type in is_valid_pattern
|
||||
J. Kercheval Sun, 03/10/1991 18:47:47 error return from matche()
|
||||
J. Kercheval Tue, 03/12/1991 22:24:49 Released as V1.1 to Public Domain
|
||||
J. Kercheval Thu, 03/14/1991 22:25:00 remove '\' for DOS file matching
|
||||
J. Kercheval Thu, 03/28/1991 21:03:59 add in PATTERN_ESC & MATCH_LITERAL
|
||||
J. Kercheval Mon, 05/13/1991 21:34:02 ifdef the full match code
|
||||
*/
|
||||
|
||||
/*
|
||||
* Wildcard Pattern Matching
|
||||
*/
|
||||
|
||||
/*
|
||||
* if FILE_MATCH is defined then the match routine will compile without
|
||||
* allowing the literal escape character in the pattern string except within
|
||||
* the [..] construct. The literal escape character '\' is an MSDOS special
|
||||
* character and thus is not allowed for file globbing except as a path
|
||||
* follow.
|
||||
*/
|
||||
|
||||
#define FILE_MATCH
|
||||
|
||||
/* match defines */
|
||||
#define MATCH_PATTERN 6 /* bad pattern */
|
||||
#define MATCH_LITERAL 5 /* match failure on literal match */
|
||||
#define MATCH_RANGE 4 /* match failure on [..] construct */
|
||||
#define MATCH_ABORT 3 /* premature end of text string */
|
||||
#define MATCH_END 2 /* premature end of pattern string */
|
||||
#define MATCH_VALID 1 /* valid match */
|
||||
|
||||
/* pattern defines */
|
||||
#define PATTERN_VALID 0 /* valid pattern */
|
||||
#define PATTERN_ESC -1 /* literal escape at end of pattern */
|
||||
#define PATTERN_RANGE -2 /* malformed range in [..] construct */
|
||||
#define PATTERN_CLOSE -3 /* no end bracket in [..] construct */
|
||||
#define PATTERN_EMPTY -4 /* [..] contstruct is empty */
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* Match the pattern PATTERN against the string TEXT;
|
||||
*
|
||||
* match() returns TRUE if pattern matches, FALSE otherwise.
|
||||
* matche() returns MATCH_VALID if pattern matches, or an errorcode
|
||||
* as follows otherwise:
|
||||
*
|
||||
* MATCH_PATTERN - bad pattern
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
* MATCH_LITERAL - match failure on literal mismatch
|
||||
#endif
|
||||
|
||||
* MATCH_RANGE - match failure on [..] construct
|
||||
* MATCH_ABORT - premature end of text string
|
||||
* MATCH_END - premature end of pattern string
|
||||
* MATCH_VALID - valid match
|
||||
*
|
||||
*
|
||||
* A match means the entire string TEXT is used up in matching.
|
||||
*
|
||||
* In the pattern string:
|
||||
* `*' matches any sequence of characters (zero or more)
|
||||
* `?' matches any character
|
||||
* [SET] matches any character in the specified set,
|
||||
* [!SET] or [^SET] matches any character not in the specified set.
|
||||
*
|
||||
* A set is composed of characters or ranges; a range looks like character
|
||||
* hyphen character (as in 0-9 or A-Z). [0-9a-zA-Z_] is the minimal set of
|
||||
* characters allowed in the [..] pattern construct. Other characters are
|
||||
* allowed (ie. 8 bit characters) if your system will support them.
|
||||
*
|
||||
* To suppress the special syntactic significance of any of `[]*?!^-\', and
|
||||
* match the character exactly, precede it with a `\'.
|
||||
*
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
int match(char *pattern, char *text);
|
||||
|
||||
int matche( const char *pattern, char *text );
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* Return TRUE if PATTERN has any special wildcard characters
|
||||
*
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
int is_pattern( const char *pattern);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* Return TRUE if PATTERN has is a well formed regular expression according
|
||||
* to the above syntax
|
||||
*
|
||||
* error_type is a return code based on the type of pattern error. Zero is
|
||||
* returned in error_type if the pattern is a valid one. error_type return
|
||||
* values are as follows:
|
||||
*
|
||||
* PATTERN_VALID - pattern is well formed
|
||||
|
||||
#ifndef FILE_MATCH
|
||||
* PATTERN_ESC - pattern has invalid escape ('\' at end of pattern)
|
||||
#endif
|
||||
|
||||
* PATTERN_RANGE - [..] construct has a no end range in a '-' pair (ie [a-])
|
||||
* PATTERN_CLOSE - [..] construct has no end bracket (ie [abc-g )
|
||||
* PATTERN_EMPTY - [..] construct is empty (ie [])
|
||||
*
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
int is_valid_pattern( const char *pattern, int *error_type );
|
||||
367
al/_new.cpp
Executable file
367
al/_new.cpp
Executable file
@ -0,0 +1,367 @@
|
||||
//
|
||||
// _NEW.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// PointerInHeap()
|
||||
// operator new()
|
||||
// operator delete()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// One of the defensive programming measures we have taken in this
|
||||
// library is to provide versions of ::new and ::delete that do a
|
||||
// little extra work. Of course, these all go away if _DEBUG isn't
|
||||
// defined.
|
||||
//
|
||||
// Basically, there are a couple of things at work here. First, we
|
||||
// have taken over the new operator and delete operator, so we are
|
||||
// guaranteed that all C++ memory allocation will take place through
|
||||
// these routines. Therefore, we can take certain liberties with
|
||||
// them.
|
||||
//
|
||||
// The most important thing we do when someone wants to allocate
|
||||
// memory is to allocate an extra 12 bytes of data beyond what has
|
||||
// been requested. We use 8 bytes at the start of the block and
|
||||
// 4 bytes at the end of the block for our own purposes. The pointer
|
||||
// we return to the requester is actually at the start of the block
|
||||
// plus eight bytes.
|
||||
//
|
||||
// The first four bytes at the start of the block are used to store
|
||||
// the size of the block. The next four bytes hold a long word containing
|
||||
// a leading picket, which is just a special word four bytes long.
|
||||
// If the user underwrites the block of data for some reason, one of
|
||||
// those four bytes will probably be corrupted. At the end of the block,
|
||||
// we store a trailing picket that has the same purpose. It holds
|
||||
// a special pattern of four bytes. If the user overwrites the block
|
||||
// of data, those four bytes will be corrupted.
|
||||
//
|
||||
// We check the pickets when the ::delete operator is called. That way,
|
||||
// when an object is going to be freed, we can instantly detect if it
|
||||
// has been abused in some fashion.
|
||||
//
|
||||
// The ::delete operator here also attempts to make sure that the pointer
|
||||
// being deleted points to a block that is actually in the heap. This
|
||||
// isn't always possible, but it works under most MS-DOS models, and
|
||||
// works under Windows small and medium models. Under Windows large
|
||||
// memory models, we can walk the global heap to look for pointers,
|
||||
// but we might not find them, since the RTL might be using a subsegment
|
||||
// allocation scheme.
|
||||
//
|
||||
// In addition to checking the heap, under Windows the ::delete function
|
||||
// can also call the IsBadWritePtr() function to see if this is just
|
||||
// a completely hosed up pointer.
|
||||
//
|
||||
// Note that it is kind of obtrusive to redefine ::new and ::delete. There
|
||||
// is an excellent chance that this will interfere with other libraries,
|
||||
// such as MFC. Fortunately, we have made it easy to get around this.
|
||||
// First, it is relatively simple to just delete this module from your
|
||||
// library, using: LIB ALXX-_NEW; If you don't want to go to that
|
||||
// trouble, you can also define AL_DISABLE_NEW and rebuild this module,
|
||||
// which should also make it go away. But if you don't need to make
|
||||
// this code disappear, you ought to leave it in, it might save you a lot
|
||||
// of trouble some day.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
//
|
||||
// The MS-DOS heapwalk functions are in different header files depending
|
||||
// on who you are. Note that I don't walk the heap under MS-DOS with
|
||||
// Symantec or Watcom. Not sure if I can.
|
||||
//
|
||||
#if defined( AL_BORLAND )
|
||||
#include <alloc.h>
|
||||
#elif defined( AL_MICROSOFT )
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
//
|
||||
// Walking the Windows heap requires TOOLHELP.DLL. It would be great
|
||||
// if Borland provided the TOOLHELP API under their DPMI extenders, but
|
||||
// I don't think they do. I don't think the heap walk functions are
|
||||
// available under Win 32s either.
|
||||
//
|
||||
#if defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
#include <toolhelp.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To completely eliminate this stuff, all you have to do is define
|
||||
* AL_DISABLE_NEW before rebuilding the library.
|
||||
*/
|
||||
#ifndef AL_DISABLE_NEW
|
||||
//
|
||||
// When I pop up an error message, it sometimes helps to know where it came
|
||||
// from. This definition is used to create the message box.
|
||||
//
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
#define LIB_TYPE "DLL"
|
||||
#else
|
||||
#define LIB_TYPE "Static"
|
||||
#endif
|
||||
|
||||
//
|
||||
// If Debug is not turned on, none of this stuff happens. I also don't
|
||||
// work with Microsoft huge model, things get nasty in there.
|
||||
//
|
||||
#if defined( _DEBUG ) && !( defined( AL_MICROSOFT ) && defined( _M_I86HM ) )
|
||||
|
||||
//
|
||||
// int PointerInHeap( void *p )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// p : The pointer under test.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An integer, true or false.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is called by ::delete() to see if the pointer we are
|
||||
// trying to delete is in fact in the heap. If it isn't, we could cause
|
||||
// quite a bit of trouble if we try to delete it.
|
||||
//
|
||||
// Under MS-DOS, this function just executes the normal heapwalk functions
|
||||
// supported by Microsoft and Borland. Under Windows small memory
|
||||
// models, we use the Toohelp API to walk the local heap. Under all
|
||||
// other circumstances, we just give up and always return a true value.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
//
|
||||
// This is the Microsoft MS-DOS version. It also looks like it is set
|
||||
// up to work with Win 32s, but I'm not sure why, since we haven't
|
||||
// released support for it yet. I think that is a typo.
|
||||
//
|
||||
// This function just uses the heapwalk RTL function to check for the
|
||||
// presence of the pointer in the heap.
|
||||
//
|
||||
#if defined( AL_MICROSOFT ) && ( !defined( AL_WINDOWS_MEMORY ) || defined( AL_FLAT_MODEL ) )
|
||||
|
||||
int PointerInHeap( void *p )
|
||||
{
|
||||
AL_ASSERT( _heapchk() == _HEAPOK, "Heap fails internal consistency check" );
|
||||
_HEAPINFO heapinfo;
|
||||
heapinfo._pentry = 0;
|
||||
while ( _heapwalk( &heapinfo ) == _HEAPOK )
|
||||
if ( heapinfo._pentry == (int __far *) p )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// This is the Borland MS-DOS version. It looks like it also works under
|
||||
// Win 32s, which might be more reasonable, since we do support Borland
|
||||
// in that mode.
|
||||
//
|
||||
// Like the previous function, this guy just uses the heapwalk API to
|
||||
// check the local heap for the presence of the pointer.
|
||||
//
|
||||
#elif defined( AL_BORLAND ) && ( !defined( AL_WINDOWS_MEMORY ) || defined( AL_FLAT_MODEL ) )
|
||||
|
||||
int PointerInHeap( void *p )
|
||||
{
|
||||
AL_ASSERT( heapcheck() == _HEAPOK,
|
||||
LIB_TYPE " heap fails internal consistency check" );
|
||||
struct heapinfo info;
|
||||
info.ptr = 0;
|
||||
while ( heapwalk( &info ) == _HEAPOK )
|
||||
#if defined( AL_LARGE_DATA ) && !defined( AL_FLAT_MODEL )
|
||||
if ( info.ptr == (void huge *) p )
|
||||
return 1;
|
||||
#else
|
||||
if ( info.ptr == p )
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Microsoft is nice enough to support the heapwalk API under Windows
|
||||
// large memory models also. This is good, since the TOOLHELP API would
|
||||
// flounder when confronted with a subsegment allocation strategy.
|
||||
//
|
||||
#elif defined( AL_MICROSOFT ) && defined( AL_WINDOWS_MEMORY ) && defined( AL_LARGE_DATA )
|
||||
|
||||
int PointerInHeap( void *p )
|
||||
{
|
||||
AL_ASSERT( _fheapchk() == _HEAPOK,
|
||||
LIB_TYPE " heap fails internal consistency check" );
|
||||
_HEAPINFO heapinfo;
|
||||
heapinfo._pentry = 0;
|
||||
while ( _fheapwalk( &heapinfo ) == _HEAPOK )
|
||||
if ( heapinfo._pentry == p )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Under Windows small and medium memory models, the TOOLHELP API lets
|
||||
// us walk the local heap, looking for an entry. No subsegment allocation
|
||||
// scheme will get in the way.
|
||||
//
|
||||
// I should be able to use this with Watcom, but I am using a little bit of
|
||||
// inline assembly to get my data segment. This inline assembly won't
|
||||
// work with Watcom, so someday I will have to add a little code to
|
||||
// get things working right with them also.
|
||||
//
|
||||
#elif defined( AL_WINDOWS_MEMORY ) && !defined( AL_FLAT_MODEL ) && !defined( AL_LARGE_DATA ) && !defined( AL_WATCOM )
|
||||
|
||||
int PointerInHeap( void *p )
|
||||
{
|
||||
LOCALENTRY LEntry;
|
||||
WORD wHeap;
|
||||
//
|
||||
// I need to search the local heap that is in my data segment.
|
||||
//
|
||||
_asm mov ax,ds
|
||||
_asm mov wHeap,ax
|
||||
LEntry.dwSize = sizeof( LOCALENTRY );
|
||||
if ( LocalFirst( &LEntry, (HGLOBAL) wHeap ) ) {
|
||||
do {
|
||||
if ( LEntry.wAddress == (WORD) p )
|
||||
return 1;
|
||||
} while ( LocalNext( &LEntry ) );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// When all else fails, give up!
|
||||
//
|
||||
#else
|
||||
int PointerInHeap( void * ){ return 1; }
|
||||
#endif
|
||||
|
||||
//
|
||||
// void *operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The amount of memory being requested.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the newly allocated storage area, or a 0 in the event
|
||||
// of failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This version of ::new() does what I described at the top of the file.
|
||||
// It allocates a block of memory as requested, and includes eight
|
||||
// extra bytes. Four bytes are reserved at the start and end of the memory
|
||||
// block for our "pickets". These pickets hold a fixed pattern in memory
|
||||
// that can be tested for accidental modification. When ::delete() is
|
||||
// called, we check the area to see if the caller munged it, and
|
||||
// cause an assertion error if they did. The other four bytes are needed
|
||||
// to keep the size of the block on hand. Otherwise I wouldn't know how
|
||||
// to get to the end of the block to check the trailing picket.
|
||||
//
|
||||
// Note that if you are using set_new_handler() or exceptions, this stuff
|
||||
// is probably going to hose you up badly.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void *operator new( size_t size )
|
||||
{
|
||||
if ( ( (long) size + 12 ) > 65535L )
|
||||
return 0;
|
||||
char *p = (char *) malloc( size + 12 );
|
||||
if ( !p )
|
||||
return 0;
|
||||
( (long *) p)[ 0 ] = (long) size;
|
||||
( (long *) p)[ 1 ] = 0x12345678L;
|
||||
( (long *)(p + 8 + size))[ 0 ] = 0xfedcba98L;
|
||||
return p + 8;
|
||||
}
|
||||
|
||||
//
|
||||
// void operator delete( void *ptr )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// ptr : A pointer to the memory block the user wishes to delete.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// After the user has had the chance to muck with this memory block for
|
||||
// a while, he or she will want to return it to the heap. We do a bunch
|
||||
// of checks here before that happens, to see if any serious mistakes have
|
||||
// been made. If we detect any serious mistakes, we just abort the
|
||||
// program with an assertion error.
|
||||
//
|
||||
// First we check to see if Windows thinks it is even a valid pointer. If
|
||||
// we don't do this, some of the other code here will GPF if you call delete
|
||||
// with a really bad pointer. Those GPFs are a lot less informative than
|
||||
// our nice assertion failures.
|
||||
//
|
||||
// If it looks like it is a valid pointer, the next thing we do is try to
|
||||
// see if the pointer is in our heap. A common mistake is trying to free
|
||||
// a pointer twice, or freeing a pointer that has been incremented or
|
||||
// decremented. Either of these can royally foul the heap.
|
||||
//
|
||||
// If it looks like the pointer really is in the heap, there is still one
|
||||
// last thing to check. I take a quick glance at both the leading and
|
||||
// trailing pickets to see if either of them have been mangled. A simple
|
||||
// overwrite or underwrite by just one byte can be catastrophic, but we
|
||||
// detect it easily here.
|
||||
//
|
||||
// If all of that goes as expected, we are free to finally return the
|
||||
// storage to the heap. Just for good luck, I clear it out first. That
|
||||
// way if anyone is foolish enough to try and use the data after it has
|
||||
// been deleted, they will at least see that there is nothing intelligent
|
||||
// store there.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void operator delete( void *ptr )
|
||||
{
|
||||
#if defined( AL_WINDOWS_MEMORY ) && !defined( AL_FLAT_MODEL )
|
||||
AL_ASSERT( !IsBadWritePtr( ptr, 1 ), "delete: delete called for ptr Windows doesn't like" );
|
||||
#endif
|
||||
char *p = (char *) ptr;
|
||||
AL_ASSERT( PointerInHeap( p - 8 ),
|
||||
"delete: delete called for pointer not found in the " LIB_TYPE " heap" );
|
||||
AL_ASSERT( ( (long *) p )[ -1 ] == 0x12345678L,
|
||||
"delete : Data corrupted in object's leading picket in the " LIB_TYPE " heap" );
|
||||
size_t size = (size_t) ( (long *) p )[ -2 ];
|
||||
char *ep = p + size;
|
||||
AL_ASSERT( ( (long *) ep )[ 0 ] == 0xfedcba98L,
|
||||
"delete : Data corrupted in object's trailing picket in the " LIB_TYPE " heap" );
|
||||
memset( p - 8, size + 12, 0 ); //Clear it before freeing it
|
||||
free( ((char *) p - 8 ) );
|
||||
}
|
||||
|
||||
#endif //#ifdef _DEBUG etc.
|
||||
|
||||
#endif // #ifdef AL_DISABLE_NEW
|
||||
|
||||
314
al/_openf.cpp
Executable file
314
al/_openf.cpp
Executable file
@ -0,0 +1,314 @@
|
||||
//
|
||||
// _OPENF.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALOpenInputFile::operator new()
|
||||
// ALOpenOutputFile::operator new()
|
||||
// ALOpenFiles::operator new()
|
||||
// ALOpenInputFile::ALOpenInputFile()
|
||||
// ALOpenInputFile::~ALOpenInputFile()
|
||||
// ALOpenOutputFile::ALOpenOutputFile()
|
||||
// ALOpenOutputFile::~ALOpenOutputFile()
|
||||
// ALOpenFiles::ALOpenFiles()
|
||||
// ALOpenFiles::~ALOpenFiles()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The ALOpenInputFile, ALOpenOutputFile, and ALOpenFiles objects
|
||||
// are all just simple little devices I use in functions to open files,
|
||||
// then automatically close them when the function exits. Even better,
|
||||
// if the storage object was already open when we enter the function,
|
||||
// when we exit, we leave it open!
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "_openf.h"
|
||||
|
||||
//
|
||||
// void * ALOpenInputFile::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The size of the object being created.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the storage allocated for the object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When we construct an object when using the DLL, trouble can arise.
|
||||
// The main bad thing is that when we call the constructor from an
|
||||
// EXE, we allocate the storage for the new object from inside our EXE.
|
||||
// When we destroy the same object, the destructor frees up the memory
|
||||
// inside the DLL. This is bad, because you can mangle the heap inside
|
||||
// the DLL by trying to free an object that doesn't belong to it.
|
||||
//
|
||||
// The fix to this conundrum is to allocate the object inside the DLL,
|
||||
// and we can make this happen by overloading the new operator. We don't
|
||||
// bother unless it's a DLL deal.
|
||||
//
|
||||
// This lecture will be repeated at times throughout the source in this
|
||||
// project.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALOpenInputFile::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// void * ALOpenOutputFile::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The size of the object being created.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the storage allocated for the object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// See the function directly above.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALOpenOutputFile::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// void * ALOpenFiles::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The size of the object being created.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the storage allocated for the object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// See the function directly above.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALOpenFiles::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// ALOpenInputFile::ALOpenInputFile( ALStorage &file )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// file : The storage object that has to opened.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// You can stick this constructor at the start of a function, and it
|
||||
// opens up an ALStorage object for you. You can then take it for
|
||||
// granted that it is open. You can also take it for granted that
|
||||
// the storage object will be closed by the destructor when the
|
||||
// function exits. All of this saves a lot of repetitive code.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALOpenInputFile::ALOpenInputFile( ALStorage AL_DLL_FAR &file )
|
||||
{
|
||||
mpFile = &file;
|
||||
miFileWasOpen = file.IsOpen();
|
||||
if ( !miFileWasOpen )
|
||||
file.Open();
|
||||
}
|
||||
|
||||
//
|
||||
// ALOpenInputFile::~ALOpenInputFile()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None, it is a destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// At the end of the function, it is time to close the storage object.
|
||||
// But only if it wasn't open when the constructor was called.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALOpenInputFile::~ALOpenInputFile()
|
||||
{
|
||||
if ( !miFileWasOpen )
|
||||
mpFile->Close();
|
||||
}
|
||||
|
||||
//
|
||||
// ALOpenOutputFile::ALOpenOutputFile( ALStorage &file )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// file : The ALStorage object that needs to be created.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, it is a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is just like ALOpenInputFile, except instead of calling
|
||||
// ALStorage::Open(), it calls ALStorage::Create(). Note that if
|
||||
// the file is already open, we keep track of the fact and leave it
|
||||
// alone.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALOpenOutputFile::ALOpenOutputFile( ALStorage AL_DLL_FAR &file )
|
||||
{
|
||||
mpFile = &file;
|
||||
miFileWasOpen = file.IsOpen();
|
||||
if ( !miFileWasOpen )
|
||||
file.Create();
|
||||
}
|
||||
|
||||
//
|
||||
// ALOpenOutputFile::~ALOpenOutputFile()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// If the file was closed when the constructor was called, we close
|
||||
// it in the constructor.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALOpenOutputFile::~ALOpenOutputFile()
|
||||
{
|
||||
if ( !miFileWasOpen )
|
||||
mpFile->Close();
|
||||
}
|
||||
|
||||
//
|
||||
// ALOpenFiles::ALOpenFiles( ALStorage &input,
|
||||
// ALStorage &output )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// input : The storage object that needs to be opened, maybe.
|
||||
//
|
||||
// output : The storage object that needs to be created, maybe.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is just a combination of the ALOpenOutputFile() and
|
||||
// ALOpenInputFile() guys rolled into one. To combine them, we
|
||||
// just create this object that contains one of both objects.
|
||||
//
|
||||
// So this guy takes care of opening an input file and an output
|
||||
// file right there at the same time. The most exciting part of it
|
||||
// is that they both get closed up in the destructor.
|
||||
//
|
||||
// So all the constructor has to do here is call the other two
|
||||
// constructors in an initializer list.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALOpenFiles::ALOpenFiles( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output )
|
||||
: mInputFile( input ), mOutputFile( output )
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// ALOpenFiles::~ALOpenFiles()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This guy closes the two files, if they were closed when the constructor
|
||||
// was called. We don't have to do anything explicitly, because the
|
||||
// two data members of this object do so in their destructors.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALOpenFiles::~ALOpenFiles()
|
||||
{
|
||||
}
|
||||
|
||||
196
al/_openf.h
Executable file
196
al/_openf.h
Executable file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* _OPENF.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* These three classes are utility classes used inside ArchiveLib.
|
||||
* All they do is let me open a file(s) at the start of a routine and
|
||||
* then automatically close it when I exit. It gets closed when
|
||||
* the destructor for this class gets called. If the file was
|
||||
* already open when the routine was entered, this class leave
|
||||
* it open when the destructor gets called. These classes will generally
|
||||
* get used like this:
|
||||
*
|
||||
* int foo( ALStorage &input_file )
|
||||
* {
|
||||
* ALOpenInputFile file( input_file )
|
||||
* ...
|
||||
* do stuff with input file
|
||||
* ...
|
||||
* } The destructor gets called here and the file is closed.
|
||||
*
|
||||
* This may seem like a lot of work, creating a class just to make
|
||||
* sure files get closed, but it replaces a *lot* of code. Every
|
||||
* routine that uses a file can use one of these classes.
|
||||
*
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALOpenInputFile
|
||||
* ALOpenOutputFile
|
||||
* ALOpenFiles
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OPENF_H
|
||||
#define __OPENF_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
/*
|
||||
* class ALOpenInputFile
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is a utility class. The constructor opens a file for input,
|
||||
* and keeps track of whether it was already open or not. The destructor
|
||||
* will automatically close the file if it was closed when the
|
||||
* ctor was invoked.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miFileWasOpen : The flag that keeps track of the file's state
|
||||
* at the start of the routine.
|
||||
*
|
||||
* mpFile : A pointer to the file, so we can close it in the dtor.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALOpenInputFile : The constructor, opens the file.
|
||||
* ~ALOpenInputFile : The destructor, can close the file.
|
||||
* operator new : This operator is used in the Win16
|
||||
* DLL version of ArchiveLib.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALOpenInputFile {
|
||||
public :
|
||||
AL_PROTO ALOpenInputFile( ALStorage AL_DLL_FAR &file );
|
||||
AL_PROTO ~ALOpenInputFile();
|
||||
#if defined( AL_BUILDING_DLL ) || defined( AL_USING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Prevent the compiler from generating these members.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALOpenInputFile( ALOpenInputFile AL_DLL_FAR &);
|
||||
ALOpenInputFile AL_DLL_FAR & operator=( ALOpenInputFile AL_DLL_FAR & );
|
||||
protected :
|
||||
int miFileWasOpen;
|
||||
ALStorage AL_DLL_FAR *mpFile;
|
||||
};
|
||||
|
||||
/*
|
||||
* class ALOpenOutputFile
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is a utility class. The constructor opens a file for output,
|
||||
* and keeps track of whether it was already open or not. The destructor
|
||||
* will automatically close the file if it was closed when the
|
||||
* ctor was invoked.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miFileWasOpen : The flag that keeps track of the file's state
|
||||
* at the start of the routine.
|
||||
*
|
||||
* mpFile : A pointer to the file, so we can close it in the dtor.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALOpenOutputFile : The constructor, opens the file.
|
||||
* ~ALOpenOutputFile : The destructor, can close the file.
|
||||
* operator new : This operator is used in the Win16
|
||||
* DLL version of ArchiveLib.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALOpenOutputFile {
|
||||
public :
|
||||
AL_PROTO ALOpenOutputFile( ALStorage AL_DLL_FAR &file );
|
||||
AL_PROTO ~ALOpenOutputFile();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Prevent the compiler from generating these members.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALOpenOutputFile( ALOpenOutputFile AL_DLL_FAR &);
|
||||
ALOpenOutputFile AL_DLL_FAR & operator=( ALOpenOutputFile AL_DLL_FAR & );
|
||||
protected :
|
||||
int miFileWasOpen;
|
||||
ALStorage AL_DLL_FAR *mpFile;
|
||||
};
|
||||
|
||||
/*
|
||||
* class ALOpenFiles
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is a utility class. The constructor opens the first file for
|
||||
* input, and the second for output. It does so using the previous
|
||||
* two classes, so it doesn't have to keep track of anything.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mInputFile : The input file open object. It does all the work
|
||||
* related to the input file.
|
||||
*
|
||||
* mOutputFile : The output file open object. It does all the work
|
||||
* related to the output file.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALOpenFiles : The constructor, opens both files.
|
||||
*
|
||||
* ~ALOpenFiles : The destructor, can close one or both files.
|
||||
*
|
||||
* operator new : This operator is used in the Win16
|
||||
* DLL version of ArchiveLib.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALOpenFiles {
|
||||
public :
|
||||
AL_PROTO ALOpenFiles( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output );
|
||||
AL_PROTO ~ALOpenFiles();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Prevent the compiler from generating these members.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALOpenFiles( ALOpenFiles AL_DLL_FAR & );
|
||||
ALOpenFiles AL_DLL_FAR & operator=( ALOpenFiles AL_DLL_FAR & );
|
||||
protected :
|
||||
ALOpenInputFile mInputFile;
|
||||
ALOpenOutputFile mOutputFile;
|
||||
};
|
||||
|
||||
#endif /* #ifndef __OPENF_H */
|
||||
93
al/_r.h
Executable file
93
al/_r.h
Executable file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* _R.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This source code is shrouded.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
#ifndef _60
|
||||
#define _60
|
||||
#include <limits.h>
|
||||
#include "arclib.h"
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned int uint;
|
||||
#define _132 (CHAR_BIT * sizeof(ushort))
|
||||
#define _133 16
|
||||
#define _134 '\0'
|
||||
#define _135 3
|
||||
#define _136 16384
|
||||
#define _137 14
|
||||
#define _138 10
|
||||
#define _139 8
|
||||
#define _140 256
|
||||
#define _141 (UCHAR_MAX + 1 + _140 - _135 + 1 + 1)
|
||||
#define _142 (_137 + 1)
|
||||
#define _143 9
|
||||
#define _144 (_140 + 1)
|
||||
#define _145 (_133 + 3)
|
||||
#define _146 5
|
||||
#define _147 5
|
||||
#define _148 4096
|
||||
#define _149 256
|
||||
#if (1U << _146) <= _142
|
||||
#error _146 _150 _151
|
||||
#endif
|
||||
#if (1U << _147) <= _145
|
||||
#error _147 _150 _151
|
||||
#endif
|
||||
#if _145 > _142
|
||||
#define _152 _145
|
||||
#else
|
||||
#define _152 _142
|
||||
#endif
|
||||
#define _153 4096
|
||||
#define _154 4
|
||||
#define _155 8192
|
||||
#define _156 512
|
||||
#define _157 (-1)
|
||||
#define _158 128
|
||||
#define _159 512
|
||||
class RCompress{ private: ALStorage *_161;ALStorage *_162;
|
||||
#if defined( AL_LARGE_DATA ) || defined( AL_FLAT_MODEL )
|
||||
short *_163;short *_164;uchar *_165;
|
||||
#else
|
||||
short _far *_163;short _far *_164;uchar _far *_165;
|
||||
#endif
|
||||
uchar *_166;ushort _167[ 17 ];short _168;short _169;short _170;short _171;
|
||||
short _172;short _173;short _174;short _175;short _176;short *_177;uchar *_178;
|
||||
uchar *_179;uchar *_180;uchar *_181;ushort _182;ushort _183;ushort _184;
|
||||
ushort _185;ushort _186;ushort *_187;ushort *_188;ushort *_189;ushort *_190;
|
||||
ushort *_191;ushort *_192;ushort *_193;ushort *_194;int _531;private :
|
||||
void _196();void _197();void _198();void _199( short _200, short _201 );
|
||||
void _202( ushort _203, ushort _204 );void _205();void _206();void _207();
|
||||
void _208( int _209, ushort _203 );void _210();int _211( int _212,
|
||||
ushort *_213,uchar *_214,ushort *_215 );void _216( ushort *_217 );
|
||||
void _218( short _219, short _220, short _221 );void _222();
|
||||
void _223( short _203 );void _224( ushort _204 );void _225( int _226,
|
||||
ushort *_187, short *_177, short _227 );void _228( int _229 );void _230(
|
||||
int _219, uchar *_209, ushort *_231 );void _232( int _226 );public :
|
||||
RCompress( ALStorage& _233,ALStorage& _202,int _234,int _235 );~RCompress();
|
||||
int Compress();ALStatus mStatus;protected :RCompress( RCompress & );
|
||||
RCompress & operator=(RCompress&);};class RExpand {private :ALStorage *_161;
|
||||
ALStorage *_162;short _175;short _176;uchar *_166;ushort *_240;ushort *_241;
|
||||
uchar *_242;ushort *_189;ushort *_190;uchar *_180;uchar *_181;short _243;
|
||||
ushort _244;ushort _182;short _172;uchar _245;short _246;uchar *_247;
|
||||
long _248;ushort _249();ushort _250();void _251();ushort _252( int _219 );
|
||||
void _253( short _254, short _220, short _221 );void _255();void _256( int
|
||||
_219 );void _257();void _258( int _259,uchar *_260,int _261,ushort *_262,
|
||||
ushort _263 );public :RExpand( ALStorage& _233,ALStorage& _202,long _264,
|
||||
int _234 );~RExpand();int Expand();ALStatus mStatus;protected :RExpand(
|
||||
RExpand &);RExpand& operator=(RExpand&);};
|
||||
|
||||
#endif
|
||||
190
al/_rc.cpp
Executable file
190
al/_rc.cpp
Executable file
@ -0,0 +1,190 @@
|
||||
//
|
||||
// _RC.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// All shrouded.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
#ifdef AL_SYMANTEC
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "_r.h"
|
||||
#define _519 "Incorrect compression level parameter passed to compressor. Compression level = %d"
|
||||
#define _520 "Memory allocation failure in compression startup"
|
||||
#define _445( _200, _446 ) ((short) ( (_446 << _154 ) ^ ( _278[ _200 + 2 ] ) ) & ( _153 - 1 ))
|
||||
#define _447( _200, _201 ){short _204;if ((_204=_163[_201])!=_157)_164[_204]\
|
||||
=_200;_164[_200]=_201;_163[_200]=_204;_163[_201]=_200;}
|
||||
#define _448(s){short _204;if((_204=_164[s])!=_157){_164[s]=_157;_163[_204]\
|
||||
=_157;}}
|
||||
RCompress::RCompress(ALStorage&_266, ALStorage&_267, int _269, int _235) {
|
||||
_161=&_266; _162=&_267; _531=_235;if(_269>_137||_269<_138){
|
||||
mStatus.SetError(AL_ILLEGAL_PARAMETER,_519,_269-10); _175=2; }else
|
||||
_175=(short)(1<<_269); _176=(short)(_175-1); if((_166=new
|
||||
uchar[_175+_140+2])!=0) memset(_166,0,(_175+_140+2)*sizeof(uchar));
|
||||
#if defined(AL_LARGE_DATA)||defined(AL_FLAT_MODEL)
|
||||
if((_163=new short[_175+_153])!=0) memset(_163,0,(_175+_153)*sizeof(short));
|
||||
if((_164=new short[_175])!=0) memset(_164,0,_175*sizeof(short)); _165=new
|
||||
uchar[_155];
|
||||
#else
|
||||
_163=(short _far*)_fcalloc(_175+_153,sizeof(short )); _164=(short
|
||||
_far*)_fcalloc(_175,sizeof(short)); _165=(uchar
|
||||
_far*)_fcalloc(_155,sizeof(uchar));
|
||||
#endif
|
||||
_179=new uchar[_156]; if((_189=new ushort[2*_141-1])!=0)
|
||||
memset(_189,0,(2*_141-1)*sizeof(ushort)); if((_190=new ushort[2*_141-1])!=0)
|
||||
memset(_190,0,(2*_141-1)*sizeof(ushort)); if((_177=new short[_141+1])!=0)
|
||||
memset(_177,0,(_141+1)*sizeof(short)); _180=new uchar[_141]; if((_191=new
|
||||
ushort[2*_141-1])!=0) memset(_191,0,(2*_141-1)*sizeof(ushort)); if((_192=new
|
||||
ushort[_141])!=0) memset(_192,0,_141*sizeof(ushort)); _181=new uchar[_152];
|
||||
if((_193=new ushort[2*_142-1])!=0) memset(_193,0,(2*_142-1)*sizeof(ushort));
|
||||
if((_194=new ushort[_152])!=0) memset(_194,0,_152*sizeof(ushort)); if(!_166||
|
||||
!_163|| !_164|| !_165|| !_179|| !_189|| !_190|| !_177|| !_180|| !_191||
|
||||
!_192|| !_181|| !_193|| !_194){
|
||||
mStatus.SetError(AL_CANT_ALLOCATE_MEMORY,_520); } }RCompress::~RCompress() {
|
||||
if(_166) delete[]_166;
|
||||
#if defined(AL_LARGE_DATA)||defined(AL_FLAT_MODEL)
|
||||
if(_163) delete[]_163; if(_164) delete[]_164; if(_165) delete[]_165;
|
||||
#else
|
||||
_ffree(_163); _ffree(_164); _ffree(_165);
|
||||
#endif
|
||||
if(_179) delete[]_179;
|
||||
if(_189) delete[]_189; if(_190) delete[]_190; if(_177) delete[]_177; if(_180)
|
||||
delete[]_180; if(_191) delete[]_191; if(_192) delete[]_192; if(_181)
|
||||
delete[]_181; if(_193) delete[]_193; if(_194) delete[]_194; }inline void
|
||||
RCompress::_223(short _203) { _208(_180[_203],_192[_203]); }int
|
||||
RCompress::Compress() { short _209; short _201; short _200; short s; int
|
||||
_231; uchar *_278; short _280; short _279;_278=_166; _280=_176;
|
||||
_279=_175;_231=0; _196(); _198();_200=0;
|
||||
s=0;_209=(short)_161->ReadBuffer(_278,_279); s=(short)(_209&_280); _169=0;
|
||||
_168=0;_201=(short)(((_278[_200]<<_154)^(_278[_200+1]))&(_153-1));
|
||||
_201=(short)(_445(_200,_201)+_279);while(_209>_140+4&&!_170){
|
||||
_199(_200,_201); if(_168<_135){ _202(_278[_200],0); _447(_200,_201); _200++;
|
||||
_201=(short)(_445(_200,_201)+_279); _209--; }else{ _209-=_168;
|
||||
_202((ushort)(_168+(UCHAR_MAX+1-_135)),_169); while(--_168>=0){
|
||||
_447(_200,_201); _200++; _201=(short)(_445(_200,_201)+_279); } }
|
||||
}for(;_209<_140;_209++){ int _203=_161->ReadChar(); if(_203<0) break;
|
||||
_278[s]=(unsigned char)_203; if(s<_140-1) _278[s+_279]=_278[s]; _448(s);
|
||||
s=(short)((s+1)&(_280)); }while(_209>0&&!_170){ _199(_200,_201);
|
||||
if(_168>_209) _168=_209; if(_168<_135){ _168=1; _202(_278[_200],0); }else
|
||||
_202((ushort)(_168+(UCHAR_MAX+1-_135)), _169); while(--_168>=0){ int
|
||||
_203=_161->ReadChar(); if(_203<0) break; else _278[s]=(unsigned char)_203;
|
||||
if(s<_140-1) _278[s+_279]=_278[s]; _448(s);
|
||||
s=(short)((s+1)&(_280));_447(_200,_201); _200=(short)((_200+1)&(_280));
|
||||
_201=(short)(_445(_200,_201)+_279); } while(_168-->=0){ _447(_200,_201);
|
||||
_200=(short)((_200+1)&_280); _201=(short)(_445(_200,_201)+_279); _209--; }
|
||||
if(_162->mStatus<0) return 1; }if(!_170) _202(_144+(UCHAR_MAX+1-_135),0);
|
||||
_197(); if(_170) _231=1;return _231; }void RCompress::_196() { int
|
||||
_226;for(_226=0;_226<_141;_226++) _191[_226]=0; for(_226=0;_226<_142;_226++)
|
||||
_193[_226]=0; _173=0; _205(); _170=0; _185=1; _184=0; _186=0; _165[0]=0;
|
||||
_183=_155; _183-=(ushort)((3*CHAR_BIT)+6); }void RCompress::_197() {
|
||||
if(!_170) _207(); _206(); _183=0; _184=0; }void RCompress::_198() {
|
||||
#if defined(AL_FLAT_MODEL)
|
||||
register short *_450;
|
||||
#else
|
||||
register short
|
||||
_far*_450;
|
||||
#endif
|
||||
register short _226;_450=&_163[_175];
|
||||
for(_226=_153;_226>0;_226--) *_450++=_157; _450=_164;
|
||||
for(_226=_175;_226>0;_226--) *_450++=_157; }void RCompress::_199(short
|
||||
_200,short _201) { register uchar *_451; register uchar *_278; short
|
||||
_226,_452,_204,_453;_452=_158; _168=0; _451=&_166[_200]; _204=_201;
|
||||
while((_204=_163[_204])!=_157){ if(--_452<0) break; _278=&_166[_204];
|
||||
if(_451[_168]!=_278[_168]) continue; if(_451[0]!=_278[0]) continue;
|
||||
if(_451[1]!=_278[1]) continue; if(_451[2]!=_278[2]) continue;
|
||||
for(_226=3;_226<_140;_226++) if(_451[_226]!=_278[_226]) break; if(_226>_168){
|
||||
_453=(short)(_200-_204-1); if(_453<0) _453+=_175; if(_453>=_175){ break; }
|
||||
_169=_453; if((_168=_226)>=_140) break; } } }void RCompress::_202(ushort
|
||||
_203,ushort _204) { if((_185>>=1)==0){ _185=1U<<(CHAR_BIT-1); if(_184>=_183){
|
||||
_207(); if(_170) return; _184=0; } _186=_184++; _165[_186]=0; }
|
||||
_165[_184++]=(uchar)_203; _191[_203]++; if(_203>=(1U<<CHAR_BIT)){
|
||||
_165[_186]|=(uchar)_185; _165[_184++]=(uchar)_204;
|
||||
_165[_184++]=(uchar)(_204>>CHAR_BIT); _203=0; while(_204){ _203++; _204>>=1;
|
||||
} _193[_203]++; } }void RCompress::_205() { _172=0; _182=0; _171=0; }void
|
||||
RCompress::_206() { if(!_170){ _208(CHAR_BIT-1,0); if(_171) _210(); } _171=0;
|
||||
}void RCompress::_207() { uint _226,_289,_229,_454,_455; uint _456=0; ushort
|
||||
_217[2*_145-1];_229=_211(_141,_191,_180,_192); _455=_191[_229];
|
||||
_208(16,(ushort)_455); if(_229>=_141){ _216(_217);
|
||||
_229=_211(_145,_217,_181,_194); if(_229>=_145){ _218(_145,_147,3); }else{
|
||||
_208(_147,0); _208(_147,(ushort)_229); } _222(); }else{ _208(_147,0);
|
||||
_208(_147,0); _208(_143,0); _208(_143,(ushort)_229); }
|
||||
_229=_211(_142,_193,_181,_194); if(_229>=_142){ _218(_142,_146,-1); }else{
|
||||
_208(_146,0); _208(_146,(ushort)_229); } _454=0;
|
||||
for(_226=0;_226<_455;_226++){ if(_226%CHAR_BIT==0) _456=_165[_454++]; else
|
||||
_456<<=1; if(_456&(1U<<(CHAR_BIT-1))){
|
||||
_223((short)(_165[_454++]+(1U<<CHAR_BIT))); _289=_165[_454++];
|
||||
_289+=_165[_454++]<<CHAR_BIT; _224((short)_289); }else _223(_165[_454++]);
|
||||
if(_170) return; } for(_226=0;_226<_141;_226++) _191[_226]=0;
|
||||
for(_226=0;_226<_142;_226++) _193[_226]=0; }void RCompress::_208(int
|
||||
_209,ushort _203) { _203<<=_133-_209; _182|=(ushort)(_203>>_172);
|
||||
if((_172+=(short)_209)>=8){ if(_171>=_156) _210();
|
||||
_179[_171++]=(uchar)(_182>>CHAR_BIT);
|
||||
if((_172=(ushort)(_172-CHAR_BIT))<CHAR_BIT) _182<<=CHAR_BIT; else{
|
||||
if(_171>=_156) _210(); _179[_171++]=(uchar)_182;
|
||||
_172=(ushort)(_172-CHAR_BIT); _182=(ushort)(_203<<(_209-_172)); } } }void
|
||||
RCompress::_210() { if(_171<=0) return; _162->WriteBuffer(_179,_171); _171=0;
|
||||
}int RCompress::_211(int _212, ushort *_213, uchar *_214, ushort *_215) { int
|
||||
_226,_276,_289,_292; short _227;_174=(short)_212; _187=_213; _178=_214;
|
||||
_292=_174; _227=0; _177[1]=0; for(_226=0;_226<_174;_226++){ _178[_226]=0;
|
||||
if(_187[_226]) _177[++_227]=(short)_226; } if(_227<2){ _215[_177[1]]=0;
|
||||
return _177[1]; } for(_226=_227/2;_226>=1;_226--) _225(_226,_187,_177,_227);
|
||||
_188=_215; do{ _226=_177[1]; if(_226<_174) *_188++=(ushort)_226;
|
||||
_177[1]=_177[_227--]; _225(1,_187,_177,_227); _276=_177[1]; if(_276<_174)
|
||||
*_188++=(ushort)_276; _289=_292++;
|
||||
_187[_289]=(ushort)(_187[_226]+_187[_276]); _177[1]=(short)_289;
|
||||
_225(1,_187,_177,_227); _189[_289]=(ushort)_226; _190[_289]=(ushort)_276;
|
||||
}while(_227>1); _188=_215; _228(_289); _230(_212,_214,_215); return _289;
|
||||
}void RCompress::_216(ushort *_217) { short
|
||||
_226,_289,_219,_277;for(_226=0;_226<_145;_226++) _217[_226]=0; _219=_141;
|
||||
while(_219>0&&_180[_219-1]==0) _219--; _226=0; while(_226<_219){
|
||||
_289=_180[_226++]; if(_289==0){ _277=1; while(_226<_219&&_180[_226]==0){
|
||||
_226++; _277++; } if(_277<=2) _217[0]+=_277; else if(_277<=18) _217[1]++;
|
||||
else if(_277==19){ _217[0]++; _217[1]++; }else _217[2]++; }else
|
||||
_217[_289+2]++; } }void RCompress::_218(short _219,short _220,short _221) {
|
||||
short _226,_289;while(_219>0&&_181[_219-1]==0) _219--; _208(_220,_219);
|
||||
_226=0; while(_226<_219){ _289=_181[_226++]; if(_289<=6){ _208(3,_289); }else
|
||||
_208(_289-3,(ushort)(USHRT_MAX<<1)); if(_226==_221){
|
||||
while(_226<6&&_181[_226]==0) _226++; _208(2,(ushort)(_226-3)); } } }void
|
||||
RCompress::_222() { short _226,_289,_219,_277;_219=_141;
|
||||
while(_219>0&&_180[_219-1]==0) _219--; _208(_143,_219); _226=0;
|
||||
while(_226<_219){ _289=_180[_226++]; if(_289==0){ _277=1;
|
||||
while(_226<_219&&_180[_226]==0){ _226++; _277++; } if(_277<=2){
|
||||
for(_289=0;_289<_277;_289++) _208(_181[0],_194[0]); }else if(_277<=18){
|
||||
_208(_181[1],_194[1]); _208(4,(ushort)(_277-3)); }else if(_277==19){
|
||||
_208(_181[0],_194[0]); _208(_181[1],_194[1]); _208(4,15); }else{
|
||||
_208(_181[2],_194[2]); _208(_143,(ushort)(_277-20)); } }else
|
||||
_208(_181[_289+2],_194[_289+2]); } }void RCompress::_224(ushort _204) {
|
||||
ushort _203,_457;_203=0; _457=_204; while(_457){ _203++; _457>>=1; }
|
||||
_208(_181[_203],_194[_203]); if(_203>1) _208(_203-1,_204); }void
|
||||
RCompress::_225(int _226,ushort *_187,short *_177,short _227){int
|
||||
_276,_289;_289=_177[_226]; while((_276=2*_226)<=_227){
|
||||
if(_276<_227&&_187[_177[_276]]>_187[_177[_276+1]]) _276++;
|
||||
if(_187[_289]<=_187[_177[_276]]) break; _177[_226]=_177[_276]; _226=_276; }
|
||||
_177[_226]=(ushort)_289; }void RCompress::_228(int _229) { int _226,_289;
|
||||
uint _458;for(_226=0;_226<=16;_226++) _167[_226]=0; _232(_229); _458=0;
|
||||
for(_226=16;_226>0;_226--) _458+=_167[_226]<<(16-_226);
|
||||
while(_458!=(1U<<16)){ _167[16]--; for(_226=15;_226>0;_226--){
|
||||
if(_167[_226]!=0){ _167[_226]--; _167[_226+1]=(ushort)(_167[_226+1]+2);
|
||||
break; } } _458--; } for(_226=16;_226>0;_226--){ _289=_167[_226];
|
||||
while(--_289>=0) _178[*_188++]=(uchar)_226; } }void RCompress::_230(int
|
||||
_219,uchar *_209,ushort *_231) { int _226; ushort _288[18];_288[1]=0;
|
||||
for(_226=1;_226<=16;_226++)
|
||||
_288[_226+1]=(ushort)((_288[_226]+_167[_226])<<1);
|
||||
for(_226=0;_226<_219;_226++) _231[_226]=_288[_209[_226]]++; }void
|
||||
RCompress::_232(int _226){ if(_226<_174) _167[(_173<16)?_173:16]++; else{
|
||||
_173++; _232(_189[_226]); _232(_190[_226]); _173--; } }
|
||||
113
al/_re.cpp
Executable file
113
al/_re.cpp
Executable file
@ -0,0 +1,113 @@
|
||||
//
|
||||
// _RE.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// All shrouded.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
#include "_r.h"
|
||||
#define _519 "Incorrect compression level parameter passed to compressor. Compression level = %d"
|
||||
#define _520 "Memory allocation failure in expansion startup"
|
||||
#define _521 "Internal 1 error in Greenleaf Decompression routine"
|
||||
#define _522 "Internal 2 error in Greenleaf Decompression routine"
|
||||
RExpand::RExpand(ALStorage&_266, ALStorage&_267, long _268, int _269) {
|
||||
_161=&_266; _162=&_267; _248=_268;;if(_269>_137||_269<_138){
|
||||
mStatus.SetError(AL_ILLEGAL_PARAMETER, _519, _269-10); _175=2; }else
|
||||
_175=(short)(1<<_269); _176=(short)(_175-1);_166=new uchar[_175+2];
|
||||
if(_166) memset(_166,0,(_175+2)*sizeof(uchar)); _240=new ushort[_148];
|
||||
if(_240) memset(_240,0,_148*sizeof(ushort)); _241=new ushort[_149];
|
||||
if(_241) memset(_241,0,_149*sizeof(ushort)); _242=new uchar[_159];
|
||||
if(_242) memset(_242,0,_159*sizeof(uchar)); _189=new ushort[2*_141-1];
|
||||
if(_189) memset(_189,0,(2*_141-1)*sizeof(ushort)); _190=new
|
||||
ushort[2*_141-1]; if(_190) memset(_190,0,(2*_141-1)*sizeof(ushort));
|
||||
_180=new uchar[_141]; _181=new uchar[_152]; if(!_166|| !_240|| !_241||
|
||||
!_242|| !_189|| !_190|| !_180|| !_181){
|
||||
mStatus.SetError(AL_CANT_ALLOCATE_MEMORY,_520); } }RExpand::~RExpand() {
|
||||
if(_166) delete[]_166; if(_240) delete[]_240; if(_241) delete[]_241;
|
||||
if(_242) delete[]_242; if(_189) delete[]_189; if(_190) delete[]_190;
|
||||
if(_180) delete[]_180; if(_181) delete[]_181; }int RExpand::Expand() {
|
||||
int _231; short _226; short _276; short _203; short _200; long _277;
|
||||
uchar *_278; short _279; short _280;_278=_166; _279=_175;
|
||||
_280=_176;_231=0; _243=0;_251();_277=0; _200=0;while(_243<5){
|
||||
if((_203=_249())<=UCHAR_MAX){ _278[_200]=(uchar)_203; _277++;
|
||||
if(++_200>=_279){ _200=0; if((short)_162->WriteBuffer(_278,_279)!=_279)
|
||||
goto _282; } }else{ _276=(short)(_203-(UCHAR_MAX+1-_135));
|
||||
if(_276==_144) break; _277+=_276; _226=(short)((_200-_250()-1)&_280);
|
||||
if(_226<_279-_140-1&&_200<_279-_140-1){ while(--_276>=0)
|
||||
_278[_200++]=_278[_226++]; }else{ while(--_276>=0){
|
||||
_278[_200]=_278[_226]; if(++_200>=_279){ _200=0;
|
||||
if((short)_162->WriteBuffer(_278,_279)!=_279) goto _282; }
|
||||
_226=(short)((_226+1)&_280); } } } } if(_200!=0)
|
||||
_162->WriteBuffer(_278,_200); _282: return _231; }ushort RExpand::_249()
|
||||
{ ushort _276,_283;if(_244==0){ _244=_252(16); _253(_145,_147,3);
|
||||
_255(); _253(_142,_146,-1); if(mStatus<0) return 0; } _244--;
|
||||
_276=_240[_182>>4]; if(_276>=_141){ _283=1U<<3; do{ if(_182&_283)
|
||||
_276=_190[_276]; else _276=_189[_276]; _283>>=1; }while(_276>=_141); }
|
||||
_256(_180[_276]); return _276; }ushort RExpand::_250() { ushort
|
||||
_276,_283;_276=_241[_182>>8]; if(_276>=_142){ _283=1U<<7; do{
|
||||
if(_182&_283) _276=_190[_276]; else _276=_189[_276]; _283>>=1;
|
||||
}while(_276>=_142); } _256(_181[_276]); if(_276!=0){ _276--;
|
||||
_276=(short)((1U<<_276)+_252(_276)); } return _276; }void
|
||||
RExpand::_251() { _244=0; _257(); }ushort RExpand::_252(int _219) {
|
||||
ushort _284;_284=(ushort)(_182>>(2*CHAR_BIT-_219)); _256(_219); return
|
||||
_284; }void RExpand::_253(short _254,short _220,short _221) { short
|
||||
_226,_203,_219; ushort _283;_219=_252(_220); if(_219==0){
|
||||
_203=_252(_220); for(_226=0;_226<_254;_226++) _181[_226]=0;
|
||||
for(_226=0;_226<256;_226++) _241[_226]=_203; }else{ _226=0;
|
||||
while(_226<_219){ _203=(short)(_182>>13); if(_203==7){ _283=1U<<12;
|
||||
while(_283&_182){ _283>>=1; _203++; } } _256((_203<7)?3:_203-3);
|
||||
_181[_226++]=(uchar)_203; if(_226==_221){ _203=_252(2); while(--_203>=0)
|
||||
_181[_226++]=0; } } while(_226<_254) _181[_226++]=0;
|
||||
_258(_254,_181,8,_241,_149); } }void RExpand::_255() { short
|
||||
_226,_203,_219; ushort _283;_219=_252(_143); if(_219==0){
|
||||
_203=_252(_143); for(_226=0;_226<_141;_226++) _180[_226]=0;
|
||||
for(_226=0;_226<_148;_226++) _240[_226]=_203; }else{ _226=0;
|
||||
while(_226<_219){ _203=_241[_182>>8]; if(_203>=_145){ _283=1U<<7; do{
|
||||
if(_182&_283) _203=_190[_203]; else _203=_189[_203]; _283>>=1;
|
||||
}while(_203>=_145); } _256(_181[_203]); if(_203<=2){ if(_203==0) _203=1;
|
||||
else if(_203==1) _203=(short)(_252(4)+3); else
|
||||
_203=(short)(_252(_143)+20); while(--_203>=0) _180[_226++]=0; }else
|
||||
_180[_226++]=(uchar)(_203-2); } while(_226<_141) _180[_226++]=0;
|
||||
_258(_141,_180,12,_240,_148); } }void RExpand::_256(int _219){
|
||||
while(_219>_172){ _219-=_172;
|
||||
_182=(ushort)((_182<<_172)+(_245>>(CHAR_BIT-_172))); if(_246<=0){
|
||||
_247=_242; if(_248>=0&&_248<_159){
|
||||
_246=(short)_161->ReadBuffer(_242,(size_t)_248); _248-=_246; }else
|
||||
_246=(short)_161->ReadBuffer(_242,_159); if(_246<=0) _243++; }
|
||||
_245=*_247++; _246--; _172=CHAR_BIT; } _172=(short)(_172-_219);
|
||||
_182=(ushort)((_182<<_219)+(_245>>(CHAR_BIT-_219))); _245<<=_219; }void
|
||||
RExpand::_257() { _182=0; _245=0; _172=0; _246=0; _256(2*CHAR_BIT);
|
||||
}void RExpand::_258(int _259, uchar *_260, int _261, ushort *_262,
|
||||
ushort _263) { ushort _277[17],_287[17],_288[18],*_204; uint
|
||||
_226,_289,_209,_290,_291,_292,_293,_283;for(_226=1;_226<=16;_226++)
|
||||
_277[_226]=0; for(_226=0;(int)_226<_259;_226++)
|
||||
_277[_260[_226]]++;_288[1]=0; for(_226=1;_226<=16;_226++)
|
||||
_288[_226+1]=(ushort)(_288[_226]+(_277[_226]<<(16-_226)));
|
||||
if(_288[17]!=(ushort)(1U<<16)){
|
||||
mStatus.SetError(AL_INTERNAL_ERROR,_521); _243=10; return;
|
||||
}_291=16-_261; for(_226=1;(int)_226<=_261;_226++){ _288[_226]>>=_291;
|
||||
_287[_226]=(ushort)(1U<<(_261-_226)); } while(_226<=16){
|
||||
_287[_226]=(ushort)(1U<<(16-_226)); _226++; }_226=_288[_261+1]>>_291;
|
||||
if(_226!=(ushort)(1U<<16)){ _289=1U<<_261; while(_226!=_289)
|
||||
_262[_226++]=0; }_292=_259; _283=1U<<(15-_261);
|
||||
for(_290=0;(int)_290<_259;_290++){ if((_209=_260[_290])==0) continue;
|
||||
_293=_288[_209]+_287[_209]; if((int)_209<=_261){ if(_293>_263){
|
||||
mStatus.SetError(AL_INTERNAL_ERROR,_522); _243=10; return; }
|
||||
for(_226=_288[_209];_226<_293;_226++) _262[_226]=(ushort)_290; }else{
|
||||
_289=_288[_209]; _204=&_262[_289>>_291]; _226=_209-_261; while(_226!=0){
|
||||
if(*_204==0){ _190[_292]=_189[_292]=0; *_204=(ushort)_292++; }
|
||||
if(_289&_283) _204=&_190[*_204]; else _204=&_189[*_204]; _289<<=1;
|
||||
_226--; } *_204=(ushort)_290; } _288[_209]=(ushort)_293; } }
|
||||
55
al/al.h
Executable file
55
al/al.h
Executable file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* AL.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is the master file that you can use to include
|
||||
* all of the ArchiveLib headers. If you are using precompiled
|
||||
* headers with your compiler, this might be the file you want
|
||||
* included first in all your source files.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AL_H
|
||||
#define _AL_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
/*
|
||||
* Derived classes
|
||||
*/
|
||||
|
||||
#include "filestor.h"
|
||||
#include "memstore.h"
|
||||
#include "copyengn.h"
|
||||
#include "grenengn.h"
|
||||
#include "archive.h"
|
||||
|
||||
/*
|
||||
* Demo classes and functions
|
||||
*/
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
#include "winmon.h"
|
||||
#include "algauge.h"
|
||||
#include "alstream.h"
|
||||
#else
|
||||
#include "bargraph.h"
|
||||
#include "spinner.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Additional classes
|
||||
*/
|
||||
#include "wildcard.h"
|
||||
|
||||
#endif /* #ifdef _AL_H */
|
||||
489
al/alcxl.h
Executable file
489
al/alcxl.h
Executable file
@ -0,0 +1,489 @@
|
||||
/*
|
||||
* ALCXL.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is the header file that C programmers need to include
|
||||
* to have access to all of the C and VB translation functions.
|
||||
*
|
||||
* MACROS
|
||||
*
|
||||
* DECLARE_AL_HANDLE()
|
||||
*
|
||||
* PROTOTYPES:
|
||||
*
|
||||
* All C and VB translation functions.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ALCXL_H
|
||||
#define _ALCXL_H
|
||||
|
||||
#include <time.h>
|
||||
#include "aldefs.h"
|
||||
|
||||
/*
|
||||
* The deal with these bogus structures is simply a convoluted way
|
||||
* to provide some type checking when using these handles. As far
|
||||
* as the C compiler can be concerned, they might as well all be
|
||||
* void*, but then we wouldn't have as much type safety. This
|
||||
* method is a lot like that used with STRICT in <windows.h>
|
||||
* All we are doing is creating a purely arbitrary pointer type
|
||||
* that will be used to communicate with C++ functions in ArchiveLib.
|
||||
* As soon as we get inside ArchiveLib, we cast it to a more
|
||||
* useful type.
|
||||
*/
|
||||
|
||||
#define DECLARE_AL_HANDLE( x ) \
|
||||
struct x##_bogus_struct { \
|
||||
int x##_bogus_unused_member; \
|
||||
}; \
|
||||
typedef struct x##_bogus_struct AL_DLL_FAR * x
|
||||
|
||||
DECLARE_AL_HANDLE( hALArchive );
|
||||
DECLARE_AL_HANDLE( hALMonitor );
|
||||
DECLARE_AL_HANDLE( hALEntryList );
|
||||
DECLARE_AL_HANDLE( hALEntry );
|
||||
DECLARE_AL_HANDLE( hALStorage );
|
||||
DECLARE_AL_HANDLE( hALExpander );
|
||||
DECLARE_AL_HANDLE( hALEngine );
|
||||
DECLARE_AL_HANDLE( hALCompressed );
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALEngine functions
|
||||
*/
|
||||
void AL_FUNCTION deleteALEngine( hALEngine this_object );
|
||||
int AL_FUNCTION ALEngineCompress( hALEngine this_object,
|
||||
hALStorage input_object,
|
||||
hALStorage output_object );
|
||||
int AL_FUNCTION ALEngineDecompress( hALEngine this_object,
|
||||
hALStorage input_object,
|
||||
hALStorage output_object,
|
||||
long compressed_length );
|
||||
int AL_FUNCTION ALEngineGetTypeCode( hALEngine this_object );
|
||||
char AL_DLL_FAR * AL_FUNCTION ALEngineGetTypeString( hALEngine this_object );
|
||||
int AL_FUNCTION ALEngineGetStatusCode( hALEngine this_object );
|
||||
int AL_FUNCTION ALEngineSetError( hALEngine this_object,
|
||||
int error_code,
|
||||
char AL_DLL_FAR *text );
|
||||
char AL_DLL_FAR * AL_FUNCTION ALEngineGetStatusString( hALEngine this_object );
|
||||
char AL_DLL_FAR * AL_FUNCTION ALEngineGetStatusDetail( hALEngine this_object );
|
||||
|
||||
/*
|
||||
* ALEngine functions for Visual Basic only.
|
||||
*/
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
long AL_FUNCTION ALEngineGetTypeStringVB( hALEngine this_object );
|
||||
long AL_FUNCTION ALEngineGetStatusStringVB( hALEngine this_object );
|
||||
long AL_FUNCTION ALEngineGetStatusDetailVB( hALEngine this_object );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALCopyEngine
|
||||
*/
|
||||
hALEngine AL_FUNCTION newALCopyEngine( void );
|
||||
|
||||
/*
|
||||
* ALGreenleafEngine
|
||||
*/
|
||||
hALEngine AL_FUNCTION newALGreenleafEngine( int level );
|
||||
|
||||
/*
|
||||
* ALStorage functions
|
||||
*/
|
||||
void AL_FUNCTION deleteALStorage( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageCompare( hALStorage this_object,
|
||||
hALStorage test_object );
|
||||
int AL_FUNCTION ALStorageIsOpen( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageReadChar( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageReadShort( hALStorage this_object,
|
||||
short int AL_DLL_FAR *short_data );
|
||||
int AL_FUNCTION ALStorageReadLong( hALStorage this_object,
|
||||
long AL_DLL_FAR *long_data );
|
||||
int AL_FUNCTION ALStorageWriteLong( hALStorage this_object, long long_data );
|
||||
int AL_FUNCTION ALStorageWriteShort( hALStorage this_object,
|
||||
short int short_data );
|
||||
int AL_FUNCTION ALStorageWriteString( hALStorage this_object,
|
||||
char AL_DLL_FAR *string_data );
|
||||
long AL_FUNCTION ALStorageGetCrc32( hALStorage this_object );
|
||||
long AL_FUNCTION ALStorageGetSize( hALStorage this_object );
|
||||
long AL_FUNCTION ALStorageTell( hALStorage this_object );
|
||||
size_t AL_FUNCTION ALStorageReadBuffer( hALStorage this_object,
|
||||
unsigned char AL_DLL_FAR *buffer,
|
||||
size_t length );
|
||||
size_t AL_FUNCTION ALStorageWriteBuffer( hALStorage this_object,
|
||||
unsigned char AL_DLL_FAR *buffer,
|
||||
size_t length );
|
||||
void AL_FUNCTION ALStorageInitCrc32( hALStorage this_object, long seed );
|
||||
int AL_FUNCTION ALStorageClose( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageCreate( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageDelete( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageFlushBuffer( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageLoadBuffer( hALStorage this_object, long address );
|
||||
int AL_FUNCTION ALStorageOpen( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageRename( hALStorage this_object,
|
||||
char *new_name,
|
||||
int delete_on_clash );
|
||||
int AL_FUNCTION ALStorageRenameToBackup( hALStorage this_object,
|
||||
int delete_on_clash );
|
||||
int AL_FUNCTION ALStorageSeek( hALStorage this_object, long address );
|
||||
int AL_FUNCTION ALStorageUnRename( hALStorage this_object,
|
||||
int delete_on_clash );
|
||||
int AL_FUNCTION ALStorageWriteChar( hALStorage this_object, int c );
|
||||
int AL_FUNCTION ALStorageGetType( hALStorage this_object );
|
||||
void AL_FUNCTION ALStorageSetMonitor( hALStorage this_object,
|
||||
hALMonitor monitor );
|
||||
long AL_FUNCTION ALStorageGetUnixTime( hALStorage this_object );
|
||||
long AL_FUNCTION ALStorageToJulian( hALStorage this_object );
|
||||
void AL_FUNCTION ALStorageFromJulian( hALStorage this_object, long jdn );
|
||||
void AL_FUNCTION
|
||||
ALStorageSetTimeDateFromStruc( hALStorage this_object,
|
||||
struct tm AL_DLL_FAR * time_struct );
|
||||
void AL_FUNCTION ALStorageSetTimeDateFromUnix( hALStorage this_object,
|
||||
long unix_time );
|
||||
void AL_FUNCTION
|
||||
ALStorageGetStrucFromTimeDate( hALStorage this_object,
|
||||
struct tm AL_DLL_FAR * time_struct );
|
||||
unsigned short int AL_FUNCTION
|
||||
ALStoragePackedAttributes( hALStorage this_object );
|
||||
void AL_FUNCTION
|
||||
ALStorageSetFromDosAttributes( hALStorage this_object,
|
||||
unsigned short int dos_attributes );
|
||||
void AL_FUNCTION
|
||||
ALStorageSetFromPackedAtts( hALStorage this_object,
|
||||
unsigned short int packed_attributes );
|
||||
char AL_DLL_FAR * AL_FUNCTION ALStorageGetName( hALStorage this_object );
|
||||
void AL_FUNCTION ALStorageSetName( hALStorage this_object,
|
||||
char AL_DLL_FAR *object_name );
|
||||
int AL_FUNCTION ALStorageWildCardMatch( hALStorage this_object,
|
||||
char AL_DLL_FAR *pattern );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALStorageChangeExtension( hALStorage this_object,
|
||||
char AL_DLL_FAR *new_extension );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALStorageChangeTrailingChar( hALStorage this_object,
|
||||
char new_char );
|
||||
char AL_DLL_FAR * AL_FUNCTION ALStorageGetOldName( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageGetStatusCode( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageSetError( hALStorage this_object,
|
||||
int error_code,
|
||||
char AL_DLL_FAR * text );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALStorageGetStatusString( hALStorage this_object );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALStorageGetStatusDetail( hALStorage this_object );
|
||||
unsigned short int AL_FUNCTION ALStorageGetDosTime( hALStorage this_object );
|
||||
unsigned short int AL_FUNCTION ALStorageGetDosDate( hALStorage this_object );
|
||||
int AL_FUNCTION ALStorageValidTimeDate( hALStorage this_object );
|
||||
#if defined( AL_WIN32S )
|
||||
DWORD AL_FUNCTION ALStorageGetWin32Attributes( hALStorage this_object );
|
||||
#endif
|
||||
#if !defined( AL_WIN32S )
|
||||
unsigned short int AL_FUNCTION ALStorageGetDosAttributes( hALStorage this_object );
|
||||
#endif
|
||||
/*
|
||||
* ALStorage functions for Visual Basic only.
|
||||
*/
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
long AL_FUNCTION
|
||||
ALStorageChangeExtensionVB( hALStorage this_object,
|
||||
char AL_DLL_FAR *new_extension );
|
||||
long AL_FUNCTION
|
||||
ALStorageChangeTrailingCharVB( hALStorage this_object,
|
||||
char new_char );
|
||||
long AL_FUNCTION ALStorageGetNameVB( hALStorage this_object );
|
||||
long AL_FUNCTION ALStorageGetOldNameVB( hALStorage this_object );
|
||||
long AL_FUNCTION ALStorageGetStatusStringVB( hALStorage this_object );
|
||||
long AL_FUNCTION ALStorageGetStatusDetailVB( hALStorage this_object );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALFile functions
|
||||
*/
|
||||
hALStorage AL_FUNCTION newALFile( char AL_DLL_FAR *file_name );
|
||||
|
||||
/*
|
||||
* ALMemory Functions
|
||||
*/
|
||||
#ifdef AL_WINDOWS_MEMORY
|
||||
hALStorage AL_FUNCTION newALMemory( char AL_DLL_FAR *buffer_name,
|
||||
char AL_HUGE *user_buffer,
|
||||
DWORD user_buffer_size );
|
||||
UINT AL_FUNCTION ALMemoryGetHandle( hALStorage this_object );
|
||||
long AL_FUNCTION ALMemoryGetBufferSize( hALStorage this_object );
|
||||
char AL_HUGE *AL_FUNCTION ALMemoryGetBuffer( hALStorage this_object );
|
||||
#else
|
||||
hALStorage AL_FUNCTION newALMemory( char AL_DLL_FAR *buffer_name,
|
||||
char AL_DLL_FAR *user_buffer,
|
||||
int user_buffer_size );
|
||||
size_t AL_FUNCTION ALMemoryGetBufferSize( hALStorage this_object );
|
||||
char AL_DLL_FAR *AL_FUNCTION ALMemoryGetBuffer( hALStorage this_object );
|
||||
#endif
|
||||
int AL_FUNCTION ALMemoryGetBufferOwner( hALStorage this_object );
|
||||
void AL_FUNCTION ALMemorySetBufferOwner( hALStorage this_object,
|
||||
int user_owns_buffer );
|
||||
/*
|
||||
* ALMonitor functions
|
||||
*/
|
||||
void AL_FUNCTION deleteALMonitor( hALMonitor this_object );
|
||||
long AL_FUNCTION ALMonitorSetObjectSize( hALMonitor this_object,
|
||||
long object_size );
|
||||
long AL_FUNCTION ALMonitorSetObjectStart( hALMonitor this_object,
|
||||
long object_start );
|
||||
long AL_FUNCTION ALMonitorSetJobSize( hALMonitor this_object, long job_size );
|
||||
long AL_FUNCTION ALMonitorSetJobSoFar( hALMonitor this_object,
|
||||
long job_so_far );
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
hALMonitor AL_FUNCTION
|
||||
newALWindowsMessage( enum ALMonitorType monitor_type,
|
||||
HWND progress_text_window,
|
||||
enum ALWindowsMessageType message_type,
|
||||
HWND progress_number_window,
|
||||
UINT windows_message );
|
||||
#else
|
||||
hALMonitor newALBarGraph( enum ALMonitorType monitor_type );
|
||||
hALMonitor newALSpinner( enum ALMonitorType );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALEntry functions
|
||||
*/
|
||||
|
||||
hALEntry AL_FUNCTION newALEntry( hALEntryList list,
|
||||
hALStorage storage,
|
||||
hALEngine engine );
|
||||
void AL_FUNCTION deleteALEntry( hALEntry this_object );
|
||||
int AL_FUNCTION ALEntryDuplicate( hALEntry this_object, hALEntryList list );
|
||||
int AL_FUNCTION ALEntryCompressionRatio( hALEntry this_object );
|
||||
int AL_FUNCTION ALEntryGetMark( hALEntry this_object );
|
||||
int AL_FUNCTION ALEntrySetComment( hALEntry this_object,
|
||||
char AL_DLL_FAR *comment );
|
||||
long AL_FUNCTION ALEntryGetCompressedSize( hALEntry this_object );
|
||||
long AL_FUNCTION ALEntryGetCrc32( hALEntry this_object );
|
||||
hALEntry AL_FUNCTION ALEntryGetNextEntry( hALEntry this_object );
|
||||
char AL_DLL_FAR *AL_FUNCTION ALEntryGetComment( hALEntry this_object );
|
||||
void AL_FUNCTION ALEntryClearMark( hALEntry this_object );
|
||||
void AL_FUNCTION ALEntrySetMark( hALEntry this_object );
|
||||
void AL_FUNCTION ALEntrySetMarkState( hALEntry this_object,
|
||||
short int new_state );
|
||||
hALStorage AL_FUNCTION ALEntryGetStorage( hALEntry this_object );
|
||||
void AL_FUNCTION ALEntrySetStorage( hALEntry this_object,
|
||||
hALStorage storage_object );
|
||||
hALEngine AL_FUNCTION ALEntryGetEngine( hALEntry this_object );
|
||||
void AL_FUNCTION ALEntrySetEngine( hALEntry this_object, hALEngine engine );
|
||||
|
||||
/*
|
||||
* ALEntry functions for Visual Basic only.
|
||||
*/
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
long AL_FUNCTION ALEntryGetCommentVB( hALEntry this_object );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALEntryList functions
|
||||
*/
|
||||
|
||||
hALEntryList AL_FUNCTION newALEntryList( hALMonitor monitor );
|
||||
void AL_FUNCTION deleteALEntryList( hALEntryList this_object );
|
||||
int AL_FUNCTION ALEntryListClearMarks( hALEntryList this_object,
|
||||
char AL_DLL_FAR *pattern );
|
||||
int AL_FUNCTION ALEntryListDeleteUnmarked( hALEntryList this_object );
|
||||
int AL_FUNCTION ALEntryListSetMarks( hALEntryList this_object,
|
||||
char AL_DLL_FAR *pattern );
|
||||
int AL_FUNCTION ALEntryListToggleMarks( hALEntryList this_object );
|
||||
void AL_FUNCTION ALEntryListUnmarkDuplicates( hALEntryList this_object,
|
||||
hALEntryList list, char
|
||||
AL_DLL_FAR *error_message );
|
||||
hALEntry AL_FUNCTION ALEntryListGetFirstEntry( hALEntryList this_object );
|
||||
int AL_FUNCTION ALEntryListGetStatusCode( hALEntryList this_object );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALEntryListGetStatusString( hALEntryList this_object );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALEntryListGetStatusDetail( hALEntryList this_object );
|
||||
int AL_FUNCTION ALEntryListAddWildCardFiles( hALEntryList this_object,
|
||||
char AL_DLL_FAR *pattern,
|
||||
int traverse );
|
||||
/*
|
||||
* ALEntry functions for Visual Basic only.
|
||||
*/
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
long AL_FUNCTION ALEntryLisGetStatusStringVB( hALEntryList this_object );
|
||||
long AL_FUNCTION ALEntryListGetStatusDetailVB( hALEntryList this_object );
|
||||
#endif
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
int AL_FUNCTION ALEntryListAddFromDialog( hALEntryList this_object,
|
||||
HWND hWnd,
|
||||
int list_box_id );
|
||||
int AL_FUNCTION ALEntryListAddFromWindow( hALEntryList this_object,
|
||||
HWND hWnd );
|
||||
int AL_FUNCTION ALEntryListSetMarksFromDialog( hALEntryList this_object,
|
||||
HWND hWnd,
|
||||
int id );
|
||||
int AL_FUNCTION ALEntryListSetMarksFromWindow( hALEntryList this_object,
|
||||
HWND hWnd );
|
||||
int AL_FUNCTION ALEntryListFillListBoxWindow( hALEntryList this_object,
|
||||
HWND hWnd );
|
||||
int AL_FUNCTION ALEntryListFillListBoxDialog( hALEntryList this_object,
|
||||
HWND hDlg,
|
||||
int list_box_id );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALArchiveBase Functions
|
||||
*/
|
||||
void AL_FUNCTION deleteALArchive( hALArchive this_object );
|
||||
int AL_FUNCTION ALArchiveCreate( hALArchive this_object, hALEntryList list );
|
||||
int AL_FUNCTION ALArchiveCreateFromArchive( hALArchive this_object,
|
||||
hALArchive source_archive,
|
||||
hALEntryList source_list );
|
||||
int AL_FUNCTION ALArchiveAppend( hALArchive this_object, hALEntryList list );
|
||||
int AL_FUNCTION ALArchiveAppendFromArchive( hALArchive this_object,
|
||||
hALArchive source_archive,
|
||||
hALEntryList source_list );
|
||||
int AL_FUNCTION ALArchiveExtract( hALArchive this_object, hALEntryList list );
|
||||
int AL_FUNCTION ALArchiveDelete( hALArchive this_object,
|
||||
hALEntryList list,
|
||||
hALArchive destination_archive );
|
||||
char AL_DLL_FAR * AL_FUNCTION ALArchiveGetComment( hALArchive this_object );
|
||||
int AL_FUNCTION ALArchiveSetComment( hALArchive this_object,
|
||||
char AL_DLL_FAR *comment );
|
||||
int AL_FUNCTION ALArchiveReadDirectory( hALArchive this_object,
|
||||
hALEntryList list );
|
||||
int AL_FUNCTION ALArchiveWriteDirectory( hALArchive this_object,
|
||||
hALEntryList list );
|
||||
int AL_FUNCTION ALArchiveGetVersion( hALArchive this_object );
|
||||
hALStorage AL_FUNCTION ALArchiveGetStorage( hALArchive this_object );
|
||||
int AL_FUNCTION ALArchiveGetStatusCode( hALArchive this_object );
|
||||
int AL_FUNCTION ALArchiveSetError( hALArchive this_object,
|
||||
int error_code,
|
||||
char AL_DLL_FAR *text );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALArchiveGetStatusString( hALArchive this_object );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALArchiveGetStatusDetail( hALArchive this_object );
|
||||
|
||||
/*
|
||||
* ALArchiveBase functions for Visual Basic only.
|
||||
*/
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
long AL_FUNCTION ALArchiveGetCommentVB( hALArchive this_object );
|
||||
long AL_FUNCTION ALArchiveGetStatusStringVB( hALArchive this_object );
|
||||
long AL_FUNCTION ALArchiveGetStatusDetailVB( hALArchive this_object );
|
||||
#endif
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
int AL_FUNCTION ALArchiveFillListBoxDialog( hALArchive this_object,
|
||||
HWND hDlg,
|
||||
int list_box);
|
||||
int AL_FUNCTION ALArchiveFillListBoxWindow( hALArchive this_object,
|
||||
HWND hWnd );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALArchive functions
|
||||
*/
|
||||
|
||||
hALArchive AL_FUNCTION newALArchive( char AL_DLL_FAR *file_name );
|
||||
hALArchive AL_FUNCTION newALArchiveFromStorage( hALStorage object );
|
||||
/*
|
||||
* Note: this function has been replaced by the more properly
|
||||
* named ALEntryListAddWildCardFiles. Calls the same C++ member fn.
|
||||
*/
|
||||
int AL_FUNCTION ALArchiveAddFilesToList( hALArchive this_object,
|
||||
hALEntryList list,
|
||||
char AL_DLL_FAR * pattern,
|
||||
int traverse_flag );
|
||||
|
||||
/*
|
||||
* ALCompressed functions
|
||||
*/
|
||||
|
||||
hALCompressed AL_FUNCTION newALCompressed( hALStorage storage,
|
||||
hALEngine engine );
|
||||
void AL_FUNCTION deleteALCompressed( hALCompressed this_object );
|
||||
int AL_FUNCTION ALCompressedExtract( hALCompressed this_object,
|
||||
hALStorage output_object );
|
||||
int AL_FUNCTION ALCompressedInsert( hALCompressed this_object,
|
||||
hALStorage input_object );
|
||||
int AL_FUNCTION ALCompressedGetStatusCode( hALCompressed this_object );
|
||||
int AL_FUNCTION ALCompressedSetError( hALCompressed this_object,
|
||||
int error_code,
|
||||
char AL_DLL_FAR *text );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALCompressedGetStatusString( hALCompressed this_object );
|
||||
char AL_DLL_FAR * AL_FUNCTION
|
||||
ALCompressedGetStatusDetail( hALCompressed this_object );
|
||||
|
||||
/*
|
||||
* ALCompressed functions for Visual Basic only.
|
||||
*/
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
long AL_FUNCTION ALCompressedGetStatusStringVB( hALCompressed this_object );
|
||||
long AL_FUNCTION ALCompressedGetStatusDetailVB( hALCompressed this_object );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALWildCardExpander functions
|
||||
*/
|
||||
|
||||
hALExpander AL_FUNCTION newALExpander( char AL_DLL_FAR *file_list,
|
||||
int traverse_flag,
|
||||
enum ALCase name_case );
|
||||
void AL_FUNCTION deleteALExpander( hALExpander this_object );
|
||||
char AL_DLL_FAR * AL_FUNCTION ALExpanderGetNextFile( hALExpander this_object );
|
||||
|
||||
/*
|
||||
* ALWildCardExpander functions for Visual Basic only.
|
||||
*/
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
long AL_FUNCTION ALExpanderGetNextFileVB( hALExpander this_object );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Utility
|
||||
*/
|
||||
|
||||
char AL_DLL_FAR * AL_FUNCTION StripFileName( char AL_DLL_FAR *file_name );
|
||||
char AL_DLL_FAR * AL_FUNCTION StripPath( char AL_DLL_FAR *file_name );
|
||||
|
||||
/*
|
||||
* Utility functions for Visual Basic only
|
||||
*/
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
long AL_FUNCTION StripFileNameVB( char AL_DLL_FAR *file_name );
|
||||
long AL_FUNCTION StripPathVB( char AL_DLL_FAR *file_name );
|
||||
#endif
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
void AL_CFUNCTION EditDisplay( HWND hDlg, int id, char AL_DLL_FAR *fmt, ... );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internal use for VB only
|
||||
*/
|
||||
#if defined( AL_BUILDING_DLL ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long _far _pascal ALCreateVBString( const char _far *string, unsigned short int length );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef _ALCXL_H */
|
||||
427
al/aldefs.h
Executable file
427
al/aldefs.h
Executable file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* ALDEFS.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is the setup file for ArchiveLib. Everyone else has to include
|
||||
* it, because all of the macros defined in here help to control
|
||||
* how the library operates. Normally you will never have to include
|
||||
* this header file, because it is included by ARCLIB.H, and consequently,
|
||||
* everyone else.
|
||||
*
|
||||
* MACROS
|
||||
*
|
||||
* These are all calculated automatically for supported compilers.
|
||||
*
|
||||
* AL_WINDOWS_GUI : This library uses the Windows GUI API
|
||||
* AL_WINDOWS_MEMORY : This library uses the Windows Memory API
|
||||
* AL_FLAT_MODEL : This library uses 386 Flat Model
|
||||
* AL_LARGE_DATA : Data uses 16:16 data pointer
|
||||
* AL_OS2 : Some day.
|
||||
* AL_UNIX : Some day.
|
||||
*
|
||||
* AL_BUILDING_DLL : Building the Windows DLL
|
||||
* AL_USING_DLL : Linking to the Windows DLL
|
||||
*
|
||||
* AL_SYMANTEC : Compiler selection
|
||||
* AL_BORLAND : Compiler selection
|
||||
* AL_MICROSOFT : Compiler selection
|
||||
* AL_WATCOM : Compiler selection
|
||||
*
|
||||
* Based on those settings, we can set this:
|
||||
*
|
||||
* AL_WIN32S : This is NT or Win32s
|
||||
*
|
||||
* AL_WINDOWS_GUI AL_WINDOWS_MEMORY AL_FLAT_MODEL
|
||||
* Vanilla DOS NO NO NO
|
||||
* Borland DPMI16 NO YES NO
|
||||
* Borland DPMI32 NO YES YES
|
||||
* Symantec DOSX NO NO YES
|
||||
* Win32s YES YES YES
|
||||
* Vanilla Windows YES YES NO
|
||||
*
|
||||
* Finally, we use those to create these things used in prototypes:
|
||||
*
|
||||
* AL_CLASS_TYPE : Sometimes "export", for classes in DLLs
|
||||
* AL_PROTO : Sometimes "export", for functions in DLLs
|
||||
* AL_DLL_FAR : Sometimes "far", for arguments being passed to DLLs
|
||||
* AL_FUNCTION : Vanilla exported functions are "_export pascal"
|
||||
* AL_CFUNCTION : Variable argument export functions are "_export cdecl"
|
||||
*
|
||||
* PROTOTYPES:
|
||||
*
|
||||
*
|
||||
* ENUMERATED TYPES:
|
||||
*
|
||||
* ALMonitorType : Used to indicate whether a monitor
|
||||
* is watching objects or an entire job.
|
||||
*
|
||||
* ALWindowsMessageType : To indicate whether an object of
|
||||
* class ALMonitor is supposed to be
|
||||
* sending total byte counts or
|
||||
* percentage complete ratios.
|
||||
*
|
||||
* ALErrors : The global list of errors.
|
||||
*
|
||||
* ALCase : Used by ALName to indicate case
|
||||
* sensitivity/handling
|
||||
*
|
||||
* ALGreenleafCompressionLevels : The five levels used by ALGreenleafEngine.
|
||||
*
|
||||
* ALTraverseSetting : Used to indicate whether class
|
||||
* ALWildCardExpander will traverse
|
||||
* subdirectories when searching.
|
||||
*
|
||||
* ALStorageType : The type of a storage engine.
|
||||
*
|
||||
* ALCompressionType : The type of a compression engine.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
#ifndef _ALDEFS_H
|
||||
#define _ALDEFS_H
|
||||
/*
|
||||
* The next long set of definitions and tests are all here simply to
|
||||
* determine which compiler we are using, and what sort of target
|
||||
* configuration we are trying to build/use.
|
||||
*/
|
||||
#if defined(__BORLANDC__) || defined(__TURBOC__)
|
||||
#if defined( __WIN32__ )
|
||||
#define AL_FLAT_MODEL
|
||||
#endif
|
||||
#if !defined( __BORLANDC__ )
|
||||
#define AL_BORLAND __TURBOC__
|
||||
#else
|
||||
#define AL_BORLAND __BORLANDC__
|
||||
#endif
|
||||
#if sizeof( void * ) == 4
|
||||
#define AL_LARGE_DATA
|
||||
#endif
|
||||
#if defined( _Windows )
|
||||
#define AL_WINDOWS_MEMORY
|
||||
#ifdef __DLL__
|
||||
#define AL_BUILDING_DLL
|
||||
#endif
|
||||
#if !defined( __DPMI16__ ) && !defined( __CONSOLE__ )
|
||||
#define AL_WINDOWS_GUI
|
||||
#endif
|
||||
#endif
|
||||
#elif defined( __SC__ )
|
||||
#define AL_SYMANTEC _MSC_VER
|
||||
#if defined( __NT__ )
|
||||
#define AL_FLAT_MODEL
|
||||
#define AL_WINDOWS_MEMORY
|
||||
#define AL_WINDOWS_GUI
|
||||
#endif
|
||||
#if defined( _M_I86HM ) || defined( _M_I86CM ) || defined( _M_I86LM )
|
||||
#define AL_LARGE_DATA
|
||||
#endif
|
||||
/*
|
||||
* The _WINDOWS and _WINDLL macros are only documented in LIBRARY.TXT
|
||||
*/
|
||||
#ifdef _WINDOWS
|
||||
#define AL_WINDOWS_MEMORY
|
||||
#define AL_WINDOWS_GUI
|
||||
#ifdef _WINDLL
|
||||
#define AL_BUILDING_DLL
|
||||
#ifndef M_I86LM
|
||||
#error All DLLs must be built using Large Model!
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#elif defined( _MSC_VER )
|
||||
#define AL_MICROSOFT _MSC_VER
|
||||
#if defined( _M_I86HM ) || defined( _M_I86CM ) || defined( _M_I86LM )
|
||||
#define AL_LARGE_DATA
|
||||
#endif
|
||||
#if ( AL_MICROSOFT >= 800 )
|
||||
/*
|
||||
* I really don't want MSC to tell me when it is using a precompiled
|
||||
* header file. What is really dumb is that I probably do want it
|
||||
* to tell me when it is creating one, but they generate the same
|
||||
* warning!
|
||||
*/
|
||||
#pragma warning( disable : 4699 )
|
||||
/*
|
||||
* This error occurs if you have inline functions in a header file and
|
||||
* they don't get used in a particular file. Bogus.
|
||||
*/
|
||||
#pragma warning( disable : 4505 )
|
||||
/*
|
||||
* This warning occurs if you are using assert() macros with NDEBUG and /Ox
|
||||
* it is bogus
|
||||
*/
|
||||
#pragma warning( disable : 4705 )
|
||||
/*
|
||||
* This gives a warning for cout << setw( x )
|
||||
*/
|
||||
#pragma warning( disable : 4270 )
|
||||
/*
|
||||
* This is informational, it tells me when a function has been
|
||||
* chosen for inlining.
|
||||
*/
|
||||
#pragma warning( disable : 4711 )
|
||||
/*
|
||||
* This is informational, it tells me when a function has been
|
||||
* rejected for inlining. The funny part is that it gives
|
||||
* me this message even if I don't select inlining for that
|
||||
* particular function???
|
||||
*/
|
||||
#pragma warning( disable : 4710 )
|
||||
#else /*#if ( AL_MICROSOFT >= 800 ) */
|
||||
/*
|
||||
* Microsoft C 7.0 has a major linker problems if a symbol exceeds
|
||||
* 64 characters. Unfortunately, with full decoration, we have
|
||||
* a couple of functions that hit that wall. So I have to redefine
|
||||
* a couple of innocuous class names. I am trying to use similar
|
||||
* names so that if you hit them in the debugger you will be able
|
||||
* to understand what they mean.
|
||||
*
|
||||
* #if defined( _WINDLL )
|
||||
* #define ALWindowsMessage ALWinMsg_
|
||||
* #define ALCompressionEngine ALEngine_
|
||||
* #endif NOTE: Fixing problem with /H64 in BUILD.INI! */
|
||||
#endif /*#if ( AL_MICROSOFT >= 800 ) ... #else */
|
||||
#ifdef _WINDOWS
|
||||
#define AL_WINDOWS_MEMORY
|
||||
#define AL_WINDOWS_GUI
|
||||
#ifdef _WINDLL
|
||||
#define AL_BUILDING_DLL
|
||||
#ifndef M_I86LM
|
||||
#error All DLLs must be built using Large Model!
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#elif defined( __WATCOMC__ ) && defined( __386__ )
|
||||
#define AL_FLAT_MODEL
|
||||
#ifdef __WINDOWS__
|
||||
#define AL_WINDOWS_MEMORY
|
||||
#define AL_WINDOWS_GUI
|
||||
#endif
|
||||
#pragma warning 690 9 /* Warning for AL_ASSERT() at /w3 */
|
||||
#pragma warning 549 9 /* Warning for sizeof() on class */
|
||||
#elif defined( __GNUC__ )
|
||||
#define AL_FLAT_MODEL
|
||||
#ifdef __WINDOWS__
|
||||
#define AL_WINDOWS_MEMORY
|
||||
#define AL_WINDOWS_GUI
|
||||
#endif
|
||||
#elif defined( __WATCOMC__ ) && !defined( __386__ )
|
||||
#define AL_WATCOM
|
||||
#ifdef __WINDOWS__
|
||||
#define AL_WINDOWS_MEMORY
|
||||
#define AL_WINDOWS_GUI
|
||||
#ifdef __SW_ZU
|
||||
#define AL_BUILDING_DLL
|
||||
#ifndef M_I86LM
|
||||
#error All DLLs must be built using Large Model!
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined( _M_I86HM ) || defined( _M_I86CM ) || defined( _M_I86LM )
|
||||
#define AL_LARGE_DATA
|
||||
#endif
|
||||
#pragma warning 549 9 /* Warning for sizeof() on class */
|
||||
#elif defined( __IBMC__ ) || defined( __IBMCPP__ )
|
||||
#define AL_IBM
|
||||
#define AL_OS2
|
||||
#define AL_FLAT_MODEL
|
||||
#else
|
||||
#error "Unknown compiler!"
|
||||
#endif
|
||||
|
||||
#if defined( AL_WINDOWS_MEMORY ) || defined( AL_WINDOWS_GUI )
|
||||
#define STRICT
|
||||
#include <windows.h>
|
||||
#ifdef AL_FLAT_MODEL
|
||||
#define AL_HUGE
|
||||
#else
|
||||
#define AL_HUGE _huge
|
||||
#endif
|
||||
#else
|
||||
#define WORD unsigned int
|
||||
#define DWORD unsigned long
|
||||
#endif
|
||||
|
||||
#if defined( AL_WINDOWS_GUI ) && defined( AL_WINDOWS_MEMORY ) && defined( AL_FLAT_MODEL )
|
||||
#define AL_WIN32S
|
||||
#endif
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
#if defined( AL_FLAT_MODEL )
|
||||
#define AL_CLASS_TYPE _export
|
||||
#define AL_PROTO _export
|
||||
#define AL_DLL_FAR
|
||||
#define AL_FUNCTION _export pascal
|
||||
#define AL_CFUNCTION _export cdecl
|
||||
#elif defined( AL_WATCOM )
|
||||
#define AL_CLASS_TYPE
|
||||
#define AL_PROTO _export
|
||||
#define AL_DLL_FAR
|
||||
#define AL_FUNCTION _export _far pascal
|
||||
#define AL_CFUNCTION _export _far cdecl
|
||||
#else
|
||||
#define AL_CLASS_TYPE _export
|
||||
#define AL_PROTO _far
|
||||
#define AL_DLL_FAR _far
|
||||
#define AL_FUNCTION _export _far pascal
|
||||
#define AL_CFUNCTION _export _far cdecl
|
||||
#endif
|
||||
#elif defined( AL_USING_DLL )
|
||||
#if defined( AL_FLAT_MODEL ) && defined( AL_BORLAND )
|
||||
#define AL_CLASS_TYPE _import
|
||||
#define AL_PROTO _import
|
||||
#define AL_DLL_FAR
|
||||
#define AL_FUNCTION _import pascal
|
||||
#define AL_CFUNCTION _import cdecl
|
||||
#elif defined( AL_FLAT_MODEL ) && defined( AL_SYMANTEC )
|
||||
#define AL_CLASS_TYPE _export
|
||||
#define AL_PROTO _export
|
||||
#define AL_DLL_FAR
|
||||
#define AL_FUNCTION _export pascal
|
||||
#define AL_CFUNCTION _export cdecl
|
||||
#elif defined( AL_WATCOM )
|
||||
#define AL_PROTO
|
||||
#define AL_DLL_FAR
|
||||
#define AL_CLASS_TYPE
|
||||
#define AL_FUNCTION _far _pascal
|
||||
#define AL_CFUNCTION _far cdecl
|
||||
#else
|
||||
#define AL_PROTO _far
|
||||
#define AL_DLL_FAR _far
|
||||
#ifdef AL_BORLAND
|
||||
#if ( AL_BORLAND >= 0x450 )
|
||||
#define AL_CLASS_TYPE _import
|
||||
#else
|
||||
#define AL_CLASS_TYPE _huge
|
||||
#endif
|
||||
#else
|
||||
#define AL_CLASS_TYPE _export
|
||||
#endif
|
||||
#define AL_FUNCTION _export _far _pascal
|
||||
#define AL_CFUNCTION _export _far cdecl
|
||||
#endif
|
||||
#else
|
||||
#define AL_PROTO
|
||||
#define AL_CLASS_TYPE
|
||||
#define AL_DLL_FAR
|
||||
#define AL_FUNCTION
|
||||
#define AL_CFUNCTION
|
||||
#endif
|
||||
|
||||
/*
|
||||
* All objects of type ALMonitor are set up to monitor jobs or objects.
|
||||
* This enum is passed to the constructor to select which one is desired.
|
||||
*/
|
||||
enum ALMonitorType {
|
||||
AL_MONITOR_OBJECTS,
|
||||
AL_MONITOR_JOB
|
||||
};
|
||||
|
||||
/*
|
||||
* An ALMonitor object can either send out byte counts or percentage
|
||||
* complete ratios. When constructing the object, this enum indicates
|
||||
* which strategy is going to be used.
|
||||
*/
|
||||
enum ALWindowsMessageType {
|
||||
AL_SEND_BYTE_COUNT,
|
||||
AL_SEND_RATIO,
|
||||
};
|
||||
|
||||
/*
|
||||
* Global enumerated error codes
|
||||
*/
|
||||
enum ALErrors {
|
||||
AL_CANT_OPEN_BUFFER = -1200,
|
||||
AL_CANT_ALLOCATE_MEMORY,
|
||||
AL_CANT_CREATE_ENGINE,
|
||||
AL_CANT_CREATE_STORAGE_OBJECT,
|
||||
AL_RENAME_ERROR,
|
||||
AL_CANT_OPEN_FILE,
|
||||
AL_SEEK_ERROR,
|
||||
AL_READ_ERROR,
|
||||
AL_WRITE_ERROR,
|
||||
AL_DELETE_ERROR,
|
||||
AL_ILLEGAL_PARAMETER,
|
||||
AL_INTERNAL_ERROR,
|
||||
AL_USER_ABORT,
|
||||
AL_SERVER_NOT_PRESENT,
|
||||
AL_COMPRESSION_TYPE_MISMATCH,
|
||||
AL_NEED_LENGTH,
|
||||
AL_CRC_ERROR,
|
||||
AL_COMPARE_ERROR,
|
||||
AL_UNKNOWN_COMPRESSION_TYPE,
|
||||
AL_UNKNOWN_STORAGE_OBJECT,
|
||||
AL_INVALID_ARCHIVE,
|
||||
AL_LOGIC_ERROR,
|
||||
AL_BACKUP_FAILURE,
|
||||
AL_GETSEL_ERROR,
|
||||
AL_DUPLICATE_ENTRY,
|
||||
AL_END_OF_FILE = -1,
|
||||
AL_SUCCESS = 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Enum used by ALName guys. Names can either be forced to upper
|
||||
* or lower case, or support normal mixed case representations. Objects
|
||||
* like MS-DOS file names should be forced to upper or lower, since the
|
||||
* O/S keeps the names as case insensitive.
|
||||
*/
|
||||
|
||||
enum ALCase {
|
||||
AL_UPPER,
|
||||
AL_LOWER,
|
||||
AL_MIXED
|
||||
};
|
||||
|
||||
/*
|
||||
* Compressing levels used by the Greenleaf Engine. In the archive, this
|
||||
* ratio is stored in the engine private data.
|
||||
*/
|
||||
enum ALGreenleafCompressionLevels {
|
||||
AL_GREENLEAF_COPY = -1,
|
||||
AL_GREENLEAF_LEVEL_0 = 0,
|
||||
AL_GREENLEAF_LEVEL_1,
|
||||
AL_GREENLEAF_LEVEL_2,
|
||||
AL_GREENLEAF_LEVEL_3,
|
||||
AL_GREENLEAF_LEVEL_4,
|
||||
};
|
||||
|
||||
/*
|
||||
* Used when constructing ALWildCardExpander objects. It decides whether
|
||||
* the expander will traverse the entire subdirectory tree, or just stay
|
||||
* on the current level.
|
||||
*/
|
||||
|
||||
enum ALTraverseSetting {
|
||||
AL_TRAVERSE = 1,
|
||||
AL_DONT_TRAVERSE = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* The type of storage object. This is stored in the base class, ALStorage,
|
||||
* and is initialized in the constructor.
|
||||
*/
|
||||
enum ALStorageType {
|
||||
AL_UNDEFINED = -1,
|
||||
AL_MEMORY_OBJECT = 0,
|
||||
AL_FILE_OBJECT = 1 };
|
||||
|
||||
/*
|
||||
* The type of compression engine. This is stored in the base class,
|
||||
* ALEngine, and is initialized in the constructor.
|
||||
*/
|
||||
enum ALCompressionType {
|
||||
AL_COMPRESSION_COPY = 0,
|
||||
AL_COMPRESSION_GREENLEAF = 1
|
||||
};
|
||||
|
||||
#endif
|
||||
91
al/algauge.h
Executable file
91
al/algauge.h
Executable file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* ALGAUGE.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file and ALGauge.CPP are derived from Microsoft's zYzGauge
|
||||
* file posted on CompuServe.
|
||||
*
|
||||
* You have to include this header file if you are going to use the
|
||||
* percentage gauge file. The percentage gauge is not a C++ class, it
|
||||
* is some straight C Windows code that Microsoft posted on Compuserve.
|
||||
* The end user has to create a control and assign it class "ALGauge"
|
||||
* in Resource Workshop or App Studio. The initialization function
|
||||
* defined in this header file then has to be called to set up the
|
||||
* control. After that, it is simply a matter of sending a number
|
||||
* between 0 and 100 to the control, using the ALGaugeSetPosition
|
||||
* command. The actual format used for this control is:
|
||||
*
|
||||
* SendMessage( window_handle, ALGaugeSetPosition, ratio, 0 )
|
||||
*
|
||||
* PROTOTYPES:
|
||||
*
|
||||
* ALGaugeInit() : Public initialization for the entire class
|
||||
* of gauge objects.
|
||||
*
|
||||
* ENUMERATED TYPES:
|
||||
*
|
||||
* typedef ALGaugeMessages : Messages that you can send to a
|
||||
* gauge control.
|
||||
*
|
||||
* typedef ALGaugeOrientation : The physical orientation of the
|
||||
* gauge on your screen. I like left
|
||||
* to right best.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ALGAUGE_H
|
||||
#define _ALGAUGE_H
|
||||
|
||||
/*
|
||||
* These are all the different messages you can send to
|
||||
* an ALGauge object. Our demo programs don't use any of these
|
||||
* except ALGaugeSetPosition, so most of these aren't even tested.
|
||||
*/
|
||||
typedef enum {
|
||||
ALGaugeSetRange = WM_USER,
|
||||
ALGaugeGetRange,
|
||||
ALGaugeSetPosition,
|
||||
ALGaugeGetPosition,
|
||||
ALGaugeSetOrientation,
|
||||
ALGaugeGetOrientation,
|
||||
ALGaugeSetForegroundColor,
|
||||
ALGaugeGetForegroundColor,
|
||||
ALGaugeSetBackgroundColor,
|
||||
ALGaugeGetBackgroundColor,
|
||||
ALGaugeSetDeltaPosition,
|
||||
} ALGaugeMessages;
|
||||
|
||||
/*
|
||||
* Send one of these with ALGaugeSetOrientation, to determined which
|
||||
* direction the flood fill progresses.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ALGaugeOrientLeftToRight,
|
||||
ALGaugeOrientRightToLeft,
|
||||
ALGaugeOrientBottomToTop,
|
||||
ALGaugeOrientTopToBottom,
|
||||
} ALGaugeOrientation;
|
||||
|
||||
|
||||
/*
|
||||
* public function prototypes
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int AL_FUNCTION ALGaugeInit( HINSTANCE hInstance, HINSTANCE hPrevInstance );
|
||||
|
||||
#endif /* #ifdef _ALGAUGE_H */
|
||||
|
||||
193
al/alstream.h
Executable file
193
al/alstream.h
Executable file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* ALSTREAM.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* These macros and types are all used in the debug versions of the
|
||||
* ArchiveLib.
|
||||
|
||||
* This is a utility class that is used in some of the demos.
|
||||
* It is a simple implementation of a C++ iostream that writes
|
||||
* to a multiline edit control. The constructor wants a window
|
||||
* handle and a control ID. In the implementations in the demos,
|
||||
* the window handle is that of the dialog box, and the control
|
||||
* ID is that of the multiline edit control. This class
|
||||
* works pretty well, but it is by no means bulletproof. For one
|
||||
* thing, it won't work from inside a DLL, because of far/near
|
||||
* problems. So if you link to the DLL, you are still going to
|
||||
* have to link to the static library to get this class. That
|
||||
* is why the class isn't defined with the usual AL_CLASS_TYPE
|
||||
* and AL_PROTO macros.
|
||||
*
|
||||
* Note that _ALControlStream is used internally as a helper.
|
||||
* ALEditControlStream is what the programmer uses, but when
|
||||
* creating an ALEditControlStream, we have to create an
|
||||
* _ALControlStream object to do some of the work.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* _ALControlStream : The streambuf used by ALEditControlStream
|
||||
*
|
||||
* ALEditControlStream : The ostream that writes to multiline edit
|
||||
* controls.
|
||||
* PROTOTYPES:
|
||||
*
|
||||
* ostream& gfendl( ostream &s ) : Used to generate a newline and
|
||||
* a flush for ALEditControlStream.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ALSTREAM_H
|
||||
#define _ALSTREAM_H
|
||||
|
||||
#define STRICT
|
||||
#include <windows.h>
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/* Won't work in a DLL! */
|
||||
|
||||
#if !defined( AL_BUILDING_DLL )
|
||||
|
||||
#include <iostream.h>
|
||||
|
||||
/*
|
||||
* class _ALControlStream
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is a class derived from streambuf. We attach this to an
|
||||
* ALEditControlStream, and it will write to the edit control
|
||||
* specified in the constructor.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* hWindow : The handle of the edit control.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* _ALControlStream() : The constructor, called by the ALEditControlStream
|
||||
* constructor.
|
||||
*
|
||||
* ~_ALControlStream() : The virtual destructor.
|
||||
*
|
||||
* overflow() : Called by the base class when the buffer is about
|
||||
* to overflow. This is our cue to send bytes out
|
||||
* to the edit control.
|
||||
*
|
||||
* underflow() : Called by the base class when the more data is
|
||||
* needed by the buffer for reading. We don't
|
||||
* supply any data, this is a stub.
|
||||
*
|
||||
* sync() : Base class calls this when it feels like flushing
|
||||
* the buffers.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class _ALControlStream : public streambuf {
|
||||
/*
|
||||
* Constructors, destructors, friend declarations
|
||||
*/
|
||||
friend class ALEditControlStream;
|
||||
|
||||
public :
|
||||
_ALControlStream( HWND hwnd, int control );
|
||||
virtual ~_ALControlStream();
|
||||
/*
|
||||
* The copy constructor and assignment operator are not supported. I
|
||||
* declare them here because I don't want the compiler to generate
|
||||
* default versions for me.
|
||||
*/
|
||||
protected :
|
||||
operator=( _ALControlStream& );
|
||||
_ALControlStream( _ALControlStream& );
|
||||
/*
|
||||
* Member functions and overloaded operators
|
||||
*/
|
||||
protected :
|
||||
virtual int overflow( int );
|
||||
virtual int underflow();
|
||||
virtual int sync();
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
HWND hWindow;
|
||||
};
|
||||
|
||||
/*
|
||||
* class ALEditControlStream
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is the demo class that actually performs output to the
|
||||
* edit control. It doesn't really have to do anything other than
|
||||
* create itself and then create the streambuf derivative, because
|
||||
* the streambuf does al the work.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mpControlStream : A pointer to the streambuf object we create,
|
||||
* because without him I am nothing.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALEditControlStream() : The constructor.
|
||||
* ~ALEditControlStream() : The destructor.
|
||||
*
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class ALEditControlStream : public ostream
|
||||
{
|
||||
/*
|
||||
* Constructors, destructors, and friends
|
||||
*/
|
||||
public :
|
||||
ALEditControlStream( HWND handle, int control_id = -1 );
|
||||
~ALEditControlStream();
|
||||
/*
|
||||
* The copy constructor and assignment operator are not supported. I
|
||||
* declare them here because I don't want the compiler to generate
|
||||
* default versions for me.
|
||||
*/
|
||||
protected :
|
||||
operator=( ALEditControlStream& );
|
||||
ALEditControlStream( ALEditControlStream& );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
_ALControlStream mpControlStream;
|
||||
};
|
||||
|
||||
/*
|
||||
* The gfendl manipulator is used to send an eol and flush the buffer
|
||||
* when writing to an ALEditControlStream. It serves the same purpose
|
||||
* as an endl written to a normal stream. The difference is that an
|
||||
* eol on a regular stream has a "/n/r" pair, and this guy doesn't.
|
||||
*/
|
||||
ostream& gfendl( ostream &s );
|
||||
|
||||
#endif /* #if !defined( AL_BUILDING_DLL ) */
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifdef _ALSTREAM_H */
|
||||
913
al/arcentry.cpp
Executable file
913
al/arcentry.cpp
Executable file
@ -0,0 +1,913 @@
|
||||
//
|
||||
// ARCENTRY.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALEntry::operator new()
|
||||
// ALEntryList::operator new()
|
||||
// ALEntry::ALEntry()
|
||||
// ALEntry::~ALEntry()
|
||||
// ALEntry::Duplicate()
|
||||
// ALEntry::InsertBefore()
|
||||
// ALEntry::SetComment()
|
||||
// ALEntry::CompressionRatio()
|
||||
// ALEntryList::ALEntryList()
|
||||
// ALEntryList::~ALEntryList()
|
||||
// ALEntryList::SetMarkState()
|
||||
// ALEntryList::ToggleMarks()
|
||||
// ALEntry::GetNextEntry()
|
||||
// ALEntryList::UnmarkDuplicates()
|
||||
// ALEntryList::DeleteUnmarked()
|
||||
// ALEntryList::FillListBox() //Windows GUI only
|
||||
// ALEntryList::SetMarksFromListBox() //Windows GUI only
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the source code for two class, ALEntry and
|
||||
// ALEntryList. They are so tightly bound together that it made
|
||||
// sense to go ahead and stick them both in the same file.
|
||||
//
|
||||
// Class ALEntry describes the state of an object that is in an archive.
|
||||
// It contains a pointer to a storage object and a compression engine,
|
||||
// which define what goes in the archive and how it is put there. It
|
||||
// also defines how to extract it. The ALEntry object also contains
|
||||
// miscellaneous items that go with the object in the archive, such
|
||||
// as its time/date stamp, its CRC, and its comment.
|
||||
//
|
||||
// You have to create an ALEntry *before* you put an object into an
|
||||
// archive. The archiving class member function figure out what you want
|
||||
// to do by looking at objects of the ALEntry. You also have to read
|
||||
// the contents of the archive into a list of ALEntry objects before you
|
||||
// can extract anything.
|
||||
//
|
||||
// ALEntryList is simply a class that is used to keep a linked list of
|
||||
// ALEntry objects together. ALEntryList objects are passed to the high
|
||||
// level ALArchiveBase functions for common operations, such as Create()
|
||||
// Extract(), and so on. You get an ALEntryList back when you read the
|
||||
// directory of an archive. The ALEntryList object tells you everything
|
||||
// there is to know about the object stored in the archive.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//
|
||||
// void * ALEntry::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALEntry 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 create 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 schemed, 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 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALEntry::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// void * ALEntryList::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes that are going to need to be allocated
|
||||
// to create a new ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the newly allocated storage area. A 0 is returned if no
|
||||
// storage could be found.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Look at the explanation for ALEntry::operator new(), directly above
|
||||
// this guy. The description is identical.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALEntryList::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALEntry::ALEntry( ALEntryList &list,
|
||||
// ALStorage *object,
|
||||
// ALCompressionEngine *engine )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// list : A reference to the list the ALEntry object is going to
|
||||
// be linked into. ALEntry objects aren't allowed to exist
|
||||
// without being in a list.
|
||||
//
|
||||
// object : A pointer to the storage object that is attached to this
|
||||
// entry. Remember, this is an unopened storage object,
|
||||
// so it is not consuming very much space. It is okay
|
||||
// to have a zillion or so of these just lying around.
|
||||
// Don't forget that the ALEntry dtor is going to destroy
|
||||
// this guy for you, don't you dare try it!.
|
||||
//
|
||||
// engine : A pointer to the compression engine that is going to
|
||||
// be used to create/insert/extract the storage object
|
||||
// to/from the archive. Just like with the compression
|
||||
// engine, it is a low cost object, and you can keep lots
|
||||
// of them on hand. This engine will be destroyed in the
|
||||
// ALEntry dtor, so be sure to give up any claim you might
|
||||
// have on this guy.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a ctor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This ctor creates a new ALEntry object. You can do this by hand, but
|
||||
// frequently you will ask ArchiveLib to create ALEntry objects for you,
|
||||
// maybe by pulling them out of a list box, or reading them in from and
|
||||
// archive. Note that ALEntry objects aren't allowed to ever exist
|
||||
// outside a list, each entry absolutely has to appear in a list.
|
||||
//
|
||||
// dtor issues relating to the ALEntry object are very important. Since
|
||||
// ALEntry objects always are part of a list, it made sense for the
|
||||
// ALEntryList destructor to clean up all the entries in its list. So
|
||||
// even though you might have created this ALEntry object, you don't get to
|
||||
// delete it, that will be done for you.
|
||||
//
|
||||
// Also, the storage object and compression engine in the ALEntry object
|
||||
// are going to be automatically destroyed by the ALEntry dtor. Don't
|
||||
// even think about trying it yourself!
|
||||
//
|
||||
// You can think of an ALEntryList as a directory of an archive, and each
|
||||
// ALEntry object in the list is a single entry in that directory.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALEntry::ALEntry( ALEntryList &list,
|
||||
ALStorage *object,
|
||||
ALCompressionEngine *engine )
|
||||
: mrList( list ) // Initialize our own pointer to the list we will
|
||||
// be a member of.
|
||||
{
|
||||
mpNextItem = this;
|
||||
mpPreviousItem = this;
|
||||
mpStorageObject = object;
|
||||
mpCompressionEngine = engine;
|
||||
mlCompressedSize = -1;
|
||||
mlCompressedObjectPosition = -1;
|
||||
miMark = 1; //Always construct with the mark turned on
|
||||
mszComment = 0;
|
||||
//
|
||||
// I check for the object member to be non-zero because of a clunky design
|
||||
// choice I made a while back. Each ALEntryList has an ALEntry member that
|
||||
// points to the first and last members of the list. I could have (and
|
||||
// probably should have) made the root of the list just be a pair of pointers,
|
||||
// instead of a dummy ALEntry. Anyway, I can tell that dummy entry apart
|
||||
// from the valid entries by virtue of the fact that it has a null
|
||||
// pointer in its object pointer.
|
||||
//
|
||||
// So anyway, when I create this dummy object, I don't want to try to add
|
||||
// it to the list, because by definition it is already in the list. So
|
||||
// I do a check before adding any ALEntry to the list.
|
||||
//
|
||||
if ( object )
|
||||
InsertBefore( *list.mpListHead );
|
||||
}
|
||||
|
||||
//
|
||||
// ALEntry::~ALEntry()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This destructor should normally be called by the ALEntryList dtor. The
|
||||
// list that owns an entry will always try to delete it when the list
|
||||
// is deleted.
|
||||
//
|
||||
// The ALEntry object tries to delete three dynamically allocated objects
|
||||
// that it has control over: the storage object, the compression engine,
|
||||
// and the comment. In each case it won't do it if the object pointer
|
||||
// is 0. This provides a convenient mechanism for you to steal a storage
|
||||
// object from an ALEntry. All you have to do is take the pointer, and
|
||||
// then sent ALEntry::mpStorageObject to 0. This is an especially useful
|
||||
// thing to do for ALMemory objects.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALEntry::~ALEntry()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALEntry: Attempting to delete invalid object" );
|
||||
if ( mszComment )
|
||||
delete[] mszComment;
|
||||
if ( mpStorageObject != 0 )
|
||||
delete mpStorageObject;
|
||||
if ( mpCompressionEngine != 0 )
|
||||
delete mpCompressionEngine;
|
||||
AL_ASSERT( mpNextItem != 0 ,"~ALEntry: next item is null" );
|
||||
AL_ASSERT( mpPreviousItem != 0, "~ALEntry: previous item is null" );
|
||||
|
||||
ALEntry *next_job = mpNextItem;
|
||||
ALEntry *previous_job = mpPreviousItem;
|
||||
|
||||
if ( next_job != this ) {
|
||||
next_job->mpPreviousItem = previous_job;
|
||||
previous_job->mpNextItem = next_job;
|
||||
}
|
||||
//
|
||||
// Note that I check the object twice, one at the start of the dtor, and
|
||||
// once again at the end. With all the linked list and dynamic deletion
|
||||
// being done here, it seems like it would be really easy to hose things
|
||||
// up if any mistakes were made.
|
||||
//
|
||||
AL_ASSERT( GoodTag(), "~ALEntry: Attempting to delete invalid object" );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALEntry::Duplicate( ALEntryList &list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// list : A list of ALEntry objects to scan.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// 0 if the entry is not duplicated, 1 if it is.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to scan a list of ALEntry objects to see if
|
||||
// any of them have the same name as this. Unmarked objects are ignored.
|
||||
// All the function does is zip through the ALEntryList, checking each
|
||||
// marked member for an ASCII match with the name of the storage object
|
||||
// pointed to by this. You can see that the case sensitivity of this
|
||||
// is observed when making the comparison.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALEntry::Duplicate( ALEntryList &list )
|
||||
{
|
||||
char *name = mpStorageObject->mName;
|
||||
int case_sensitive = mpStorageObject->mName.mCase == AL_MIXED;
|
||||
ALEntry *job = list.GetFirstEntry();
|
||||
while ( job ) {
|
||||
if ( job->GetMark() && job != this ) {
|
||||
if ( case_sensitive ) {
|
||||
if ( strcmp( name, job->mpStorageObject->mName ) == 0 )
|
||||
return 1;
|
||||
} else {
|
||||
if ( stricmp( name, job->mpStorageObject->mName ) == 0 )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
job = job->GetNextEntry();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// PROTECTED FUNCTION
|
||||
//
|
||||
// void ALEntry::InsertBefore( ALEntry &job )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// job : A reference to another job in the target list.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used inside the ALEntryList class to add a new ALEntry
|
||||
// object to an ALEntryList. Since the list is a doubly linked list, the
|
||||
// code to do the job is pretty simple. It would have been a little more
|
||||
// complicated if I used a pair of pointers in the ALEntryList to start
|
||||
// the list, instead of a dummy ALEntry object.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALEntry::InsertBefore( ALEntry &job )
|
||||
{
|
||||
mpNextItem = &job;
|
||||
mpPreviousItem = job.mpPreviousItem;
|
||||
(job.mpPreviousItem)->mpNextItem = this;
|
||||
job.mpPreviousItem = this;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALEntry::SetComment( const char *comment )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// comment : The new comment that is going to be associated with the
|
||||
// ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if the new comment was set, < 0 if an error occurred.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Before adding an object to an archive, you may want to change or set
|
||||
// its comment. You do so by calling this function before performing any
|
||||
// operation that will write the directory, such as Create() or
|
||||
// WriteDirectory(). It has to dynamically allocate the space in the
|
||||
// ALEntry object in order to store the new comment. This is good for
|
||||
// you, because it means you don't have to worry about who owns the comment
|
||||
// you just passed in.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALEntry::SetComment( const char AL_DLL_FAR *comment )
|
||||
{
|
||||
if ( mszComment )
|
||||
delete[] mszComment;
|
||||
if ( comment ) {
|
||||
mszComment = new char[ strlen( comment ) + 1 ];
|
||||
if ( mszComment )
|
||||
strcpy( mszComment, comment );
|
||||
else
|
||||
return mrList.mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Failed to allocate memory when "
|
||||
"adding comment to storage object %s",
|
||||
(char *) mpStorageObject->mName );
|
||||
} else
|
||||
mszComment = 0;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALEntry::CompressionRatio()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The integer representing the compression ratio. The ration is a number
|
||||
// from 0 to 100 (or maybe more) with 0 being perfect compression.
|
||||
//
|
||||
// It is possible to get a -1 back from this routine if the compression
|
||||
// ratio is not presently known. This will be the case if you have
|
||||
// not created the archive yet, or have a new object that hasn't been
|
||||
// inserted yet.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This calculates and returns the compression ratio. We don't store the
|
||||
// ratio in ALEntry, because it is so darned easy to calculate when
|
||||
// we need it. However, there are going to be times when we don't have
|
||||
// it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALEntry::CompressionRatio()
|
||||
{
|
||||
long uncompressed_size = mpStorageObject->GetSize();
|
||||
|
||||
if ( uncompressed_size <= 0 )
|
||||
return -1;
|
||||
if ( mlCompressedSize <= 0 )
|
||||
return -1;
|
||||
return (int) ( 100 * mlCompressedSize / uncompressed_size );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ALEntryList::ALEntryList( ALMonitor * monitor = 0 )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// monitor : A pointer to a monitor that will be used whenever we are
|
||||
// processing objects in the list. If no argument is supplied,
|
||||
// the default argument value of 0 is used. When the ctor sees
|
||||
// that the value of the monitor pointer is 0, it assigns the
|
||||
// default monitor instead.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// No returns from constructors.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Constructing an ALEntryList object doesn't take much work. I have to
|
||||
// initialize two data members. The first is the pointer to the monitor
|
||||
// that will be used when processing objects in the list. The second is
|
||||
// the root of the linked list, which is a dummy ALEntry object. Note
|
||||
// that the root is created as a dummy by setting the storage object pointer
|
||||
// to 0.
|
||||
//
|
||||
// The default monitor is defined below. If you don't specify a real
|
||||
// monitor, you get the default, which is a do nothing function. Everyone
|
||||
// can share one instance of the default monitor, because it doesn't have
|
||||
// any data members to be concerned about.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALMonitor ALDefaultMonitor( AL_MONITOR_OBJECTS );
|
||||
|
||||
AL_PROTO ALEntryList::ALEntryList( ALMonitor AL_DLL_FAR * monitor /* = 0 */ )
|
||||
: mrMonitor( monitor ? *monitor : ALDefaultMonitor )
|
||||
{
|
||||
mpListHead = new ALEntry( *this, 0, 0 );
|
||||
}
|
||||
|
||||
//
|
||||
// ALEntryList::~ALEntryList()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None, destructors don't get to return anything.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The destructor for ALEntryList goes through the list and deletes every
|
||||
// ALEntry object it finds. Note that this also causes the ALEntry
|
||||
// object to destroy its storage object and compression engine. Once
|
||||
// the whole list is obliterated, the list head ALEntry object can be
|
||||
// safely deleted. Then the whole thing is done.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALEntryList::~ALEntryList()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALEntryList: attempting to delete invalid object" );
|
||||
ALEntry *job = GetFirstEntry();
|
||||
while ( job ) {
|
||||
ALEntry *next_job = job->GetNextEntry();
|
||||
delete job;
|
||||
job = next_job;
|
||||
}
|
||||
if ( mpListHead )
|
||||
delete mpListHead;
|
||||
AL_ASSERT( GoodTag(), "~ALEntryList: attempting to delete invalid object" );
|
||||
}
|
||||
|
||||
// PROTECTED FUNCTION
|
||||
//
|
||||
// int ALEntryList::SetMarkState( const char *name,
|
||||
// short int new_state )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// name : The object name, specifying which storage objects are
|
||||
// to have their state set. This name can include
|
||||
// wild card characters. Note that passing a null
|
||||
// pointer here will cause a match to *every* object name.
|
||||
//
|
||||
// new_state : The new state that the ALEntry mark should be set to.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A count of the number of ALEntry objects whose state was changed.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This protected function is used internally to help out a couple of the
|
||||
// public functions. It rips through every entry of the list, checks to
|
||||
// see if storage object associate with the entry has a name that matches
|
||||
// the wildcard specification, and sets the mark if it does.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALEntryList::SetMarkState( const char AL_DLL_FAR *name,
|
||||
short int new_state )
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
ALEntry *job = GetFirstEntry();
|
||||
while ( job ) {
|
||||
if ( name ) {
|
||||
if ( job->mpStorageObject->mName.WildCardMatch( name ) ) {
|
||||
job->SetMarkState( new_state );
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
job->SetMarkState( new_state );
|
||||
count++;
|
||||
}
|
||||
job = job->GetNextEntry();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALEntryList::ToggleMarks()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A count of the number of entries whose mark was changed.
|
||||
// (Just the total number of entries.)
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This simple member function just goes through the entire list,
|
||||
// toggling the mark state of every entry. In other words, if the mark
|
||||
// was previously set, it will now be cleared, and vice versa.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALEntryList::ToggleMarks()
|
||||
{
|
||||
int count = 0;
|
||||
ALEntry *job = GetFirstEntry();
|
||||
while ( job ) {
|
||||
job->SetMarkState( (short int) !job->GetMark() );
|
||||
job = job->GetNextEntry();
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
// ALEntry * ALEntry::GetNextEntry()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the next entry in the list. If the next entry is the
|
||||
// list head, it means we have reached the end of the list, and a value
|
||||
// of 0 is returned.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to iterate through the list. Each entry has
|
||||
// a pointer to the next and previous entries, so this function is really
|
||||
// simple. The only complications comes from trying to detect the end of
|
||||
// the list, which is denoted by the list head instance of ALEntry. We
|
||||
// can tell it apart from all the legitimate entries by the fact that
|
||||
// its storage object is 0.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALEntry AL_DLL_FAR * AL_PROTO ALEntry::GetNextEntry()
|
||||
{
|
||||
ALEntry *next_entry = this->mpNextItem;
|
||||
//
|
||||
// The list head has the special case where both the compression engine
|
||||
// and storage object pointers are 0, and that makes the end of the list.
|
||||
//
|
||||
if ( mpNextItem->mpStorageObject == 0 )
|
||||
return 0;
|
||||
else
|
||||
return next_entry;
|
||||
}
|
||||
|
||||
//
|
||||
// ALEntry * ALEntryList::GetFirstEntry()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the first valid ALEntry object in the list, or 0 if there
|
||||
// are no entries.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// If you are going to iterate through the entire list, this function is
|
||||
// used to start you off. It gets the first entry in the list by call
|
||||
// GetNextEntry() for the list head. Don't worry about what happens if
|
||||
// the list is empty, the GetNextEntry() code figures that out with no
|
||||
// problem, and returns a 0.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALEntry AL_DLL_FAR * AL_PROTO ALEntryList::GetFirstEntry()
|
||||
{
|
||||
return mpListHead->GetNextEntry();
|
||||
}
|
||||
|
||||
//
|
||||
// void ALEntryList::UnmarkDuplicates( ALEntryList &list,
|
||||
// const char *error_message = 0 )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// list : The list that is going to be compared to this.
|
||||
//
|
||||
// error_message : Each entry in this that turns out to have a duplicate
|
||||
// entry in the list argument will not only be unmarked,
|
||||
// it will also have its error status set, if an error
|
||||
// message is provide.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// I think this function is a little confusing. At first blush, you would
|
||||
// probably expect this function to scan all the items in a single list,
|
||||
// and unmark any object that turn out to have duplicates elsewhere
|
||||
// in the list. Unfortunately, it doesn't work that way.
|
||||
//
|
||||
// Instead, this function goes through the list specified by this, and
|
||||
// checks to see if each entry in this appears in the list specified by
|
||||
// the list parameter. This means that we are working with two different
|
||||
// lists, which certainly offers plenty of chances to get confused.
|
||||
//
|
||||
// Anyway, each entry in this that turns out to have a duplicate gets its
|
||||
// mark cleared. If the calling program specifies and error message,
|
||||
// the entry also gets its mStatus error member set to flag this as an
|
||||
// error.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALEntryList::UnmarkDuplicates( ALEntryList &list,
|
||||
const char *error_message /* = 0 */ )
|
||||
{
|
||||
ALEntry *job = GetFirstEntry();
|
||||
while ( job ) {
|
||||
if ( job->GetMark() ) {
|
||||
if ( job->Duplicate( list ) ) {
|
||||
job->ClearMark();
|
||||
if ( error_message && error_message[ 0 ] != '\0' )
|
||||
job->mpStorageObject->mStatus.SetError(
|
||||
AL_DUPLICATE_ENTRY,
|
||||
error_message );
|
||||
}
|
||||
}
|
||||
job = job->GetNextEntry();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// int ALEntryList::DeleteUnmarked()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries that are deleted.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Sometimes you may have a list with a whole bunch of unmarked entries.
|
||||
// Those unmarked entries are just sitting there taking up space, so it
|
||||
// would be handle to be able to just delete them. That is what this
|
||||
// function does.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALEntryList::DeleteUnmarked()
|
||||
{
|
||||
ALEntry *job;
|
||||
int count = 0;
|
||||
|
||||
job = GetFirstEntry();
|
||||
while ( job ) {
|
||||
ALEntry *next_job = job->GetNextEntry();
|
||||
if ( job->GetMark() == 0 ) {
|
||||
count++;
|
||||
delete job;
|
||||
}
|
||||
job = next_job;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
// in ALEntryList::FillListBox( HWND hDlg, int list_box = -1 )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// hDlg : The handle of the dialog box that contains the list box
|
||||
// control. If the list box is not a control in a dialog,
|
||||
// set the next parameter to -1, and just pass the handle
|
||||
// of the list box in this argument.
|
||||
//
|
||||
// list_box : The ID of the list box, if and only if the list box is
|
||||
// in a dialog box specified by by the hDlg argument.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries that were stuffed into the list box.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is a handy helper when using the Windows GUI. It goes
|
||||
// through an ALEntryList, and finds all the marked entries. For every
|
||||
// marked entry, it stuffs the name of the storage object into the list box.
|
||||
// This means that if you are planning on letting the user select a list
|
||||
// of storage objects, you can initialize the list with just one
|
||||
// function call.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
int AL_PROTO ALEntryList::FillListBox( HWND hDlg, int list_box /* = -1 */ )
|
||||
{
|
||||
HWND window;
|
||||
|
||||
if ( list_box != -1 )
|
||||
window = GetDlgItem( hDlg, (short int) list_box );
|
||||
else
|
||||
window = hDlg;
|
||||
SendMessage( window, LB_RESETCONTENT, 0, 0 );
|
||||
ALEntry *job = GetFirstEntry();
|
||||
int count = 0;
|
||||
while ( job ) {
|
||||
if ( job->GetMark() ) {
|
||||
count++;
|
||||
SendMessage( window,
|
||||
LB_ADDSTRING,
|
||||
0,
|
||||
(LPARAM)( (LPSTR) job->mpStorageObject->mName ) );
|
||||
}
|
||||
job = job->GetNextEntry();
|
||||
}
|
||||
if ( count == 0 )
|
||||
SendMessage( window,
|
||||
LB_ADDSTRING,
|
||||
0,
|
||||
(LPARAM)( (LPSTR) "<none>" ) );
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// int ALEntryList::SetMarksFromListBox( HWND hDlg, int list_box = - 1 )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// hDlg : The handle of the dialog box that contains the list box.
|
||||
// If the list box control is standalone window, this parameter
|
||||
// can be its handle, if the list_box argument is set to -1.
|
||||
//
|
||||
// list_box : The ID of the list box, if and only if it is contained in
|
||||
// a dialog box whose handle is specified in the hDlg param.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A count of the number of items whose marks were set.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is called after you have given a user the opportunity
|
||||
// to set and clear items in a multiselection list box. Once the user
|
||||
// has done so, you can call this function, which will go through the
|
||||
// list and set all the marks that have been set in the list box by the
|
||||
// user. Note that it will not clear the marks on any of the ALEntry
|
||||
// objects in the list, you might want to do that first.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALEntryList::SetMarksFromListBox( HWND hDlg, int list_box /* = -1 */ )
|
||||
{
|
||||
HWND window;
|
||||
|
||||
if ( list_box != -1 )
|
||||
window = GetDlgItem( hDlg, (short int) list_box );
|
||||
else
|
||||
window = hDlg;
|
||||
|
||||
WORD count = (WORD) SendMessage( window, LB_GETSELCOUNT, 0, 0L );
|
||||
int *items = new int[ count ];
|
||||
if ( items == 0 )
|
||||
return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Memory allocation failure in SetMarksFromListBox()" );
|
||||
#ifdef AL_FLAT_MODEL
|
||||
if ( count != (WORD) SendMessage( window, LB_GETSELITEMS, count, (LPARAM) ( items ) ) ) {
|
||||
#else
|
||||
if ( count != (WORD) SendMessage( window, LB_GETSELITEMS, count, (LPARAM) ( (int _far * ) items ) ) ) {
|
||||
#endif
|
||||
mStatus.SetError( AL_LOGIC_ERROR,
|
||||
"Logic error in SetMarksFromListBox()."
|
||||
"Mismatch in select count from list box." );
|
||||
delete[] items;
|
||||
return AL_LOGIC_ERROR;
|
||||
}
|
||||
for ( WORD i = 0 ; i < count ; i++ ) {
|
||||
WORD length = (WORD) SendMessage( window, LB_GETTEXTLEN, (short int) items[ i ], 0L );
|
||||
AL_ASSERT( length != (WORD) LB_ERR, "SetMarksFromListBox: LB_ERR returned from list box" );
|
||||
if ( length > 0 ) {
|
||||
char *name = new char[ length + 1 ];
|
||||
if ( name ) {
|
||||
if ( SendMessage( window, LB_GETTEXT, (short int) items[ i ], (LPARAM)( (LPSTR) name ) ) >= 0 )
|
||||
SetMarks( name );
|
||||
delete[] name;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] items;
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
352
al/arcentry.h
Executable file
352
al/arcentry.h
Executable file
@ -0,0 +1,352 @@
|
||||
/*
|
||||
* ARCENTRY.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the definitions for two closely related
|
||||
* classes, ALEntry and ALEntryList. An ALEntry
|
||||
* object describes a storage object found in an archive. These
|
||||
* objects are always carried around in a list. These lists are
|
||||
* what get passed to archive member functions such as Create,
|
||||
* Delete, and Append. They are also what comes back
|
||||
* from ReadDirectory.
|
||||
*
|
||||
* In addition to the information about a file that is either in an
|
||||
* archive or is going to go into an archive, the job entry also
|
||||
* has a special mark. Each job entry is created in the marked state.
|
||||
* All of the archive functions that accept a list as an argument only
|
||||
* work on marked files, they ignore items in the list that aren't marked.
|
||||
* Various member functions can be used to clear or set marks on files.
|
||||
* There are several criteria you might use to clear or set marks,
|
||||
* such as matching a wild card specification, being older than a
|
||||
* certain date, or being a certain size.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALEntry : A description of an entry in an Archive.
|
||||
*
|
||||
* ALEntryList : A list of ALEntry objects.
|
||||
*
|
||||
* FUNCTIONS
|
||||
*
|
||||
* ALEntryList::SetMarks()
|
||||
* ALEntryList::ClearMarks()
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ARCENTRY_H
|
||||
#define _ARCENTRY_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALEntryList;
|
||||
class AL_CLASS_TYPE ALArchiveBase;
|
||||
class AL_CLASS_TYPE ALMonitor;
|
||||
|
||||
/*
|
||||
* class ALEntry
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ALEntry objects describe an entry in an archive. When you read in
|
||||
* the directory from an archive, it consists of a list of ALEntry
|
||||
* objects. The description can also refer to objects that you
|
||||
* want to put in an archive.
|
||||
*
|
||||
* An ALEntry object has pointers to both a compression engine and
|
||||
* a storage object. It also has the position of an object in an archive,
|
||||
* its CRC-32, and more. Some of this data will not be filled in when
|
||||
* you pass a list of these objects as an argument to an Archive command
|
||||
* like Create().
|
||||
*
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mszComment : The comment stored with the archive.
|
||||
*
|
||||
* mpNextItem : A pointer to the next ALEntry object in
|
||||
* the list. (Note that ALEntry items are
|
||||
* always in a list.)
|
||||
*
|
||||
* mpPreviousItem : A pointer to the previous item in the list.
|
||||
*
|
||||
* mrList : A reference to the list that the ALEntry
|
||||
* guy is a member of.
|
||||
*
|
||||
* mlCompressedSize : How big the object is after it is compressed.
|
||||
* If you are inserting an object for the first
|
||||
* time, you will have to wait for the ALArchiveBase
|
||||
* member function to fill this guy in after
|
||||
* the insertion takes place.
|
||||
*
|
||||
* mlCompressedObjectPosition : Where the object is found in the archive.
|
||||
* Another field that gets filled in during
|
||||
* insertion.
|
||||
*
|
||||
* mlCrc32 : The CRC-32 of the uncompressed object. This
|
||||
* gets filled in during compression.
|
||||
*
|
||||
* miMark : The object's mark. If the mark is not set,
|
||||
* most of the archive commands will ignore
|
||||
* this entry.
|
||||
*
|
||||
*
|
||||
* mpStorageObject : A pointer to the storage object associated
|
||||
* with this entry. This is a public member,
|
||||
* so you can dink with it. It will be destroyed
|
||||
* by the ALEntry destructor!
|
||||
*
|
||||
* mpCompressionEngine : A pointer to the compression engine associated
|
||||
* with this archive entry.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALEntry() : The constructor.
|
||||
* ~ALEntry() : The destructor.
|
||||
* operator new() : Memory allocation operator, only used when the
|
||||
* constructor is inside the DLL.
|
||||
* InsertBefore() : A private function used when updating an
|
||||
* ALEntrylist
|
||||
* GetNextEntry() : A routine used when interating an ALEntrylist.
|
||||
* GetCompressedSize() : An access routine to get a protected member.
|
||||
* GetCrc32() : An access routine to get a protected member.
|
||||
* GetComment() : An access routine to get a protected member.
|
||||
* SetMark() : Set the mark for an ALEntry, the default state is set.
|
||||
* ClearMark() : Clear the mark for an ALEntry.
|
||||
* SetMarkState() : Private function to set or clear the mark.
|
||||
* SetComment() : Set the comment for an entry.
|
||||
* GetMark() : Get the current state of the mark.
|
||||
* CompressionRatio() : Calculate the compression ratio for an object.
|
||||
* Duplicate() : Test to see if an entry is found in a list.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALEntry {
|
||||
/*
|
||||
* Constructors, destructors, friends
|
||||
*/
|
||||
friend class AL_CLASS_TYPE ALArchiveBase;
|
||||
|
||||
public :
|
||||
AL_PROTO ALEntry( ALEntryList AL_DLL_FAR &,
|
||||
ALStorage AL_DLL_FAR *,
|
||||
ALCompressionEngine AL_DLL_FAR * );
|
||||
AL_PROTO ~ALEntry();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* The copy constructor and assignment operator are not supported. I
|
||||
* declare them here because I don't want the compiler to generate
|
||||
* default versions for me.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO operator=( ALEntry AL_DLL_FAR & );
|
||||
AL_PROTO ALEntry( ALEntry AL_DLL_FAR & );
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
protected :
|
||||
void AL_PROTO InsertBefore( ALEntry AL_DLL_FAR & );
|
||||
|
||||
public :
|
||||
ALEntry AL_DLL_FAR * AL_PROTO GetNextEntry();
|
||||
long AL_PROTO GetCompressedSize() const { return mlCompressedSize; }
|
||||
long AL_PROTO GetCrc32() const { return mlCrc32; }
|
||||
const char AL_DLL_FAR * AL_PROTO GetComment(){ return mszComment; }
|
||||
void AL_PROTO SetMark(){ miMark = 1; }
|
||||
void AL_PROTO ClearMark(){ miMark = 0; }
|
||||
void AL_PROTO SetMarkState( short int new_state ){ miMark = new_state; }
|
||||
int AL_PROTO SetComment( const char AL_DLL_FAR *comment );
|
||||
int AL_PROTO GetMark(){ return miMark; }
|
||||
int AL_PROTO CompressionRatio();
|
||||
int AL_PROTO Duplicate( ALEntryList AL_DLL_FAR &list );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
char AL_DLL_FAR *mszComment;
|
||||
ALEntry AL_DLL_FAR *mpNextItem;
|
||||
ALEntry AL_DLL_FAR *mpPreviousItem;
|
||||
ALEntryList AL_DLL_FAR &mrList;
|
||||
long mlCompressedSize;
|
||||
long mlCompressedObjectPosition;
|
||||
long mlCrc32;
|
||||
short int miMark;
|
||||
|
||||
public :
|
||||
ALStorage AL_DLL_FAR *mpStorageObject;
|
||||
ALCompressionEngine AL_DLL_FAR *mpCompressionEngine;
|
||||
AL_CLASS_TAG( _ALEntryTag );
|
||||
};
|
||||
|
||||
/*
|
||||
* class ALEntryList
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This class is simply a list of ALEntry objects. There are
|
||||
* quite a few member functions that operate on this list.
|
||||
* ALEntryList objects are passed as arguments to many of the
|
||||
* archive functions, such as ReadDirectory(), Create(), Extract(),
|
||||
* and more.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mpListHead : The head of the list is a dummy entry that is a
|
||||
* placeholder.
|
||||
*
|
||||
* &mrMonitor : A reference to the monitor associated with this list.
|
||||
* The monitor will take care of generating all the
|
||||
* user interface activity to go with this list.
|
||||
*
|
||||
* mStatus : A standard status member, the status of the whole list.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALEntryList() : The constructor
|
||||
* ~ALEntryList() : The destructor.
|
||||
* operator new() : Memory allocation for the class, only used
|
||||
* when the ctor is in a DLL.
|
||||
* SetMarkState() : Set the marks of items in the list to 1 or 0
|
||||
* GetFirstEntry() : A list iterator function, starts the iteration
|
||||
* SetMarks() : Set some of the marks in the list
|
||||
* ClearMarks( : Clear some of the marks in the list
|
||||
* DeleteUnmarked() : Delete list entries that aren't marked
|
||||
* ToggleMarks() : Toggle every mark in the list
|
||||
* UnmarkDuplicates() : Use this to avoid processing duplicates
|
||||
* FillListBox() : Fill a list box up with a list
|
||||
* SetMarksFromListBox() : Use list feedback to set marks
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALEntryList {
|
||||
/*
|
||||
* Constructors, destructors, friends
|
||||
*/
|
||||
friend class AL_CLASS_TYPE ALEntry;
|
||||
|
||||
public :
|
||||
AL_PROTO ALEntryList( ALMonitor AL_DLL_FAR * = 0 );
|
||||
AL_PROTO ~ALEntryList();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* The copy constructor and assignment operator are not supported. I
|
||||
* declare them here because I don't want the compiler to generate
|
||||
* default versions for me.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO operator=( ALEntryList AL_DLL_FAR & );
|
||||
AL_PROTO ALEntryList( ALEntryList AL_DLL_FAR & );
|
||||
/*
|
||||
* Member Functions
|
||||
*/
|
||||
protected :
|
||||
int AL_PROTO SetMarkState( const char AL_DLL_FAR *name, short int state );
|
||||
|
||||
public :
|
||||
ALEntry AL_DLL_FAR * AL_PROTO GetFirstEntry();
|
||||
int AL_PROTO SetMarks( const char AL_DLL_FAR *pattern = 0 );
|
||||
int AL_PROTO ClearMarks( const char AL_DLL_FAR *pattern = 0 );
|
||||
int AL_PROTO DeleteUnmarked();
|
||||
int AL_PROTO ToggleMarks();
|
||||
void AL_PROTO UnmarkDuplicates( ALEntryList AL_DLL_FAR &list,
|
||||
const char AL_DLL_FAR *error_message = 0 );
|
||||
/*
|
||||
* A windows utility function
|
||||
*/
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
int AL_PROTO FillListBox( HWND hDlg, int list_box = -1 );
|
||||
int AL_PROTO SetMarksFromListBox( HWND hDlg, int list_box = -1 );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
ALEntry *mpListHead; /* The head is never used */
|
||||
|
||||
public :
|
||||
ALMonitor AL_DLL_FAR &mrMonitor;
|
||||
ALStatus mStatus;
|
||||
AL_CLASS_TAG( _ALEntryListTag );
|
||||
};
|
||||
|
||||
/*
|
||||
* inline int ALEntryList::SetMarks( const char *name )
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* name : A wild care file spec.
|
||||
*
|
||||
* RETURNS
|
||||
*
|
||||
* The number of entries that matched the wild card.
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This function sets the mark for every entry in the list object
|
||||
* that matches the wild card specification.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*/
|
||||
|
||||
inline int AL_PROTO ALEntryList::SetMarks( const char AL_DLL_FAR *name )
|
||||
{
|
||||
return SetMarkState( name, 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* inline int ALEntryList::ClearMarks( const char *name )
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* name : A wild care file spec.
|
||||
*
|
||||
* RETURNS
|
||||
*
|
||||
* The number of entries that matched the wild card.
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This function clears the mark for every entry in the list object
|
||||
* that matches the wild card specification.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*/
|
||||
|
||||
inline int AL_PROTO ALEntryList::ClearMarks( const char AL_DLL_FAR *name )
|
||||
{
|
||||
return SetMarkState( name, 0 );
|
||||
}
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
#endif /* #ifdef _ARCENTRY_H */
|
||||
|
||||
433
al/archive.cpp
Executable file
433
al/archive.cpp
Executable file
@ -0,0 +1,433 @@
|
||||
//
|
||||
// ARCHIVE.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALArchive::operator new()
|
||||
// ALArchive::ALArchive()
|
||||
// ALArchive::~ALArchive()
|
||||
// ALArchive::CreateCompressionEngine()
|
||||
// ALArchive::CreateStorageObject()
|
||||
// ALArchive::AddWildCardFiles()
|
||||
// ALArchive::MakeEntriesFromListBox()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the source code for class ALArchive. ALArchive
|
||||
// is a class derived from ALArchiveBase that knows how to create ALFile
|
||||
// and ALMemory objects. Remember that ALArchiveBase doesn't know how
|
||||
// to create any kind of storage object, so we need derived classes to
|
||||
// bind ourselves to certain types of objects.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "archive.h"
|
||||
#include "grenengn.h"
|
||||
#include "copyengn.h"
|
||||
#include "filestor.h"
|
||||
#include "memstore.h"
|
||||
#include "wildcard.h"
|
||||
|
||||
//
|
||||
// void * ALArchive::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALArchive 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 create 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 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALArchive::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALArchive::ALArchive( const char *file_name )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// name : The name of the ALFile object that is going to hold the
|
||||
// ALArchive.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is one of two constructors for ALArchive. (The other one
|
||||
// follows immediately in this source file.) It is used
|
||||
// when the archive you are working with or are going to create will
|
||||
// reside in an ALFile object, which should be often. It simply
|
||||
// calls the constructor for the base class with the appropriately
|
||||
// created ALFile object and returns. It doesn't have to initialize
|
||||
// any data members of its own, so life is really simple.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALArchive::ALArchive( const char AL_DLL_FAR *file_name )
|
||||
: ALArchiveBase( new ALFile( file_name ), 1 )
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// ALArchive::ALArchive( ALStorage &so )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// so : A storage object that will used as the storage for the archive.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is one of two constructors for ALArchive. (The other one
|
||||
// immediately precedes this function in the same source file.) It is used
|
||||
// when the archive you are working with or are going to create will
|
||||
// reside in an object that you have already constructed.
|
||||
// It doesn't have to initialize any data members of its own, so
|
||||
// all it does is call the base class constructor from an
|
||||
// initializer list, and then return.
|
||||
//
|
||||
// The storage object used for this archive is your responsibility to delete.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALArchive::ALArchive( ALStorage AL_DLL_FAR &so )
|
||||
: ALArchiveBase( &so, 0 )
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// ALArchive::~ALArchive()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This destructor has an easy life of it, since it has no data
|
||||
// members to clean up after. Instead, it leaves all of the heavy
|
||||
// lifting to the base class destructor. In debug mode we at least
|
||||
// do *something*, which is just to verify that this is the correct
|
||||
// type of object.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALArchive::~ALArchive()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALArchive: attempt to delete invalid object" );
|
||||
}
|
||||
|
||||
//
|
||||
// ALCompressionEngine *ALArchive::CreateCompressionEngine( int engine_type )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// engine_type : An integer from ALDEFS.H that defines the type of compression
|
||||
// to be created.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to a newly created compression engine. If things go bad,
|
||||
// a value of 0 is possible.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// ALArchiveBase doesn't know how to create compression engines or
|
||||
// storage objects. That knowledge is left up to derived classes like
|
||||
// this one. When extracting objects from an archive, this class has
|
||||
// to be able to create a compression engine with no more information
|
||||
// than the integer engine type stored in the archive directory.
|
||||
// This is where we do it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALCompressionEngine AL_DLL_FAR *
|
||||
AL_PROTO ALArchive::CreateCompressionEngine( int engine_type )
|
||||
{
|
||||
switch ( engine_type ) {
|
||||
case AL_COMPRESSION_COPY :
|
||||
return new ALCopyEngine();
|
||||
case AL_COMPRESSION_GREENLEAF :
|
||||
return new ALGreenleafEngine();
|
||||
default :
|
||||
mStatus.SetError( AL_UNKNOWN_COMPRESSION_TYPE,
|
||||
"Unknown compression type (%d) found in archive",
|
||||
engine_type );
|
||||
break; //Break instead of return because of bogus warnings
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ALStorage * ALArchive::CreateStorageObject( const char *name,
|
||||
// int object_type )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// name : The name of the storage object to be created.
|
||||
//
|
||||
// object_type : The object type, from ALStorageType in STORAGE.H.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to a newly storage object. If things go bad,
|
||||
// a value of 0 is possible.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// ALArchiveBase doesn't know how to create compression engines or
|
||||
// storage objects. That knowledge is left up to derived classes like
|
||||
// this one. When extracting objects from an archive, this class has
|
||||
// to be able to create a storage object with no more information
|
||||
// than the integer object type stored in the archive directory.
|
||||
// This is where we do it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALStorage AL_DLL_FAR * AL_PROTO
|
||||
ALArchive::CreateStorageObject( const char AL_DLL_FAR *name,
|
||||
int object_type )
|
||||
{
|
||||
switch ( object_type ) {
|
||||
case AL_MEMORY_OBJECT :
|
||||
return new ALMemory( name );
|
||||
case AL_FILE_OBJECT :
|
||||
return new ALFile( name );
|
||||
default :
|
||||
mStatus.SetError( AL_UNKNOWN_STORAGE_OBJECT,
|
||||
"Unknown storage object type (%d) "
|
||||
"found in archive",
|
||||
object_type );
|
||||
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// STATIC MEMBER FUNCTION
|
||||
//
|
||||
// int ALArchive::AddWildCardFiles(
|
||||
// ALEntryList & list,
|
||||
// const char *wild_spec = "*.*",
|
||||
// int traverse_flag = 0,
|
||||
// short int compression_level = AL_GREENLEAF_LEVEL_2 )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// list : The list that is going to receive the newly created
|
||||
// ALEntry objects.
|
||||
//
|
||||
// wild_spec : The wild card file spec to expand into a list of
|
||||
// files. Note that this string can contain multiple
|
||||
// file specs, separated by commas or spaces.
|
||||
//
|
||||
// traverse_flag : A flag to indicate whether wild card expansion
|
||||
// should traverse subdirectories.
|
||||
//
|
||||
// compression_level : The compression level that will be used to create
|
||||
// compression engines for the new entries.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries created by the wild card expansion.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// It is handy to have a function that will create a bunch of ALEntry
|
||||
// objects and add them to a list of your choosing. We can't do this
|
||||
// in the base class of ALArchiveBase, because it doesn't know anything
|
||||
// about specific storage objects or compression engines. So the
|
||||
// logical place to turn is to this derived class, which does know about
|
||||
// ALFile and ALMemory.
|
||||
//
|
||||
// The only bad thing here is that this is a static public functions,
|
||||
// so it is kind of confusing. You might think that this ought to be
|
||||
// a member function of ALEntryList. The problem is, we don't want
|
||||
// ALEntryList to know about specific engines or compression classes,
|
||||
// because then they would get linked in to any application created
|
||||
// with ArchiveLib.
|
||||
//
|
||||
// So anyway, this function creates a bunch of new ALEntry objects,
|
||||
// with the storage object being an instance of class ALFile, and the
|
||||
// compression engine being an object of class ALGreenleafEngine. It
|
||||
// then adds the new ALEntry to the specified ALEntryList, so you don't
|
||||
// have to do any work at all.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO
|
||||
ALArchive::AddWildCardFiles( ALEntryList AL_DLL_FAR & list,
|
||||
const char AL_DLL_FAR *wild_spec /* = "*.*" */,
|
||||
int traverse_flag /* = 0 */,
|
||||
short int compression_level /* = AL_GREENLEAF_LEVEL_2 */ )
|
||||
{
|
||||
AL_ASSERT( wild_spec != 0, "AddWildCardFiles: null parameter for wild_spec" );
|
||||
ALWildCardExpander files( wild_spec, traverse_flag );
|
||||
int count = 0;
|
||||
|
||||
char *new_name;
|
||||
while ( ( new_name = files.GetNextFile() ) != 0 ) {
|
||||
new ALEntry( list,
|
||||
new ALFile( new_name ),
|
||||
new ALGreenleafEngine( compression_level ) );
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALArchive::MakeEntriesFromListBox( ALEntryList &list,
|
||||
// HWND hDlg,
|
||||
// int list_box /* = -1 */ )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// list : The list that is going to get the new entries.
|
||||
//
|
||||
// hDlg : The handle of the dialog box that contains the list box
|
||||
// control. If you aren't using a dialog box, you can pass
|
||||
// the handle of the list box control directly, and set
|
||||
// the list_box parameter to -1.
|
||||
//
|
||||
// list_box : The id of the list box control in the dialog box. If this
|
||||
// parameter is set to -1, it means that hDlg doesn't refer
|
||||
// to a dialog, it refers to the actual handle of a list box
|
||||
// control.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of new entries created from the list box.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function goes through a list box, and picks out all the
|
||||
// highlighted entries. It creates a new ALEntry object for each
|
||||
// of the marked entires, using ALFile and ALGreenleafEngine objects.
|
||||
// For purposes of orthogonality, I probably should have had a
|
||||
// compression_level parameter here, but I neglected to include that.
|
||||
// We could do it in the next release using a default parameter and
|
||||
// nobody would even notice.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
|
||||
int AL_PROTO ALArchive::
|
||||
MakeEntriesFromListBox( ALEntryList AL_DLL_FAR &list,
|
||||
HWND hDlg,
|
||||
int list_box /* = -1 */ )
|
||||
{
|
||||
HWND window;
|
||||
|
||||
if ( list_box != -1 )
|
||||
window = GetDlgItem( hDlg, (short int) list_box );
|
||||
else
|
||||
window = hDlg;
|
||||
int count = (WORD) SendMessage( window, LB_GETSELCOUNT, 0, 0L );
|
||||
if ( count == LB_ERR )
|
||||
return AL_GETSEL_ERROR;
|
||||
int *items = new int[ count ];
|
||||
if ( items == 0 )
|
||||
return AL_CANT_ALLOCATE_MEMORY;
|
||||
#ifdef AL_FLAT_MODEL
|
||||
if ( count != SendMessage( window, LB_GETSELITEMS, (short int) count, (LPARAM) items ) ) {
|
||||
#else
|
||||
if ( count != SendMessage( window, LB_GETSELITEMS, (short int) count, (LPARAM)(int _far *) items ) ) {
|
||||
#endif
|
||||
delete items;
|
||||
return AL_GETSEL_ERROR;
|
||||
}
|
||||
for ( WORD i = 0 ; i < (WORD) count ; i++ ) {
|
||||
WORD length = (WORD) SendMessage( window, LB_GETTEXTLEN, (short int) items[ i ], 0L );
|
||||
if ( length > 0 ) {
|
||||
char *name = new char[ length + 1 ];
|
||||
if ( name ) {
|
||||
if ( SendMessage( window, LB_GETTEXT, (short int) items[ i ], (LPARAM)( (LPSTR) name ) ) >= 0 ) {
|
||||
new ALEntry( list,
|
||||
new ALFile( name ),
|
||||
new ALGreenleafEngine() );
|
||||
}
|
||||
delete name;
|
||||
SendMessage( window,
|
||||
LB_SETSEL,
|
||||
0,
|
||||
items[ i ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
delete items;
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif //#ifdef AL_WINDOWS_GUI
|
||||
135
al/archive.h
Executable file
135
al/archive.h
Executable file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* ARCHIVE.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class definition for ALArchive, the
|
||||
* standard archiving class derived from ALArchiveBase.
|
||||
*
|
||||
* ALArchive is the default archive class used in the
|
||||
* library. The base class, ALArchiveBase, doesn't know which storage
|
||||
* objects and compression engines to use when extracting files. (This is so
|
||||
* you don't have to link in *every* storage and compression class if
|
||||
* you want to create your own archive class). This derived class
|
||||
* takes care of creating two different storage types, ALFile and
|
||||
* ALMemory. It knows how to create two different types of
|
||||
* compression engines also: ALGreenleafEngine and ALCopyEngine. All
|
||||
* of this is the result of the two virtual functions that override
|
||||
* the base class: CreateCompressionEngine() and CreateStorageObject().
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* class ALArchive
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ARCHIVE_H
|
||||
#define _ARCHIVE_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
#include "filestor.h"
|
||||
#include "grenengn.h"
|
||||
|
||||
/*
|
||||
* class ALArchive : public ALArchiveBase
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ALArchive is a class derived from ALArchiveBase. It is the
|
||||
* class we use most often for standard archiving use.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALArchive(char *) : A constructor that creates the storage
|
||||
* object for you.
|
||||
* ALArchive(ALStorage&) : Constructor using a storage object that
|
||||
* you have created.
|
||||
* ~ALArchive() : Virtual destructor.
|
||||
* operator new() : Memory allocation when inside a DLL.
|
||||
* CreateCompressionEngine() : Virtual function that knows how to make
|
||||
* ALCopyEngine and ALGreenleafEngine engines.
|
||||
* CreateStorageObject() : Virtual function that knows how to make
|
||||
* ALFile and ALMemory objects.
|
||||
* AddWildCardFiles() : A static function used to create
|
||||
* new ALEntry objects, and add them to an
|
||||
* ALEntryList object.
|
||||
* MakeEntriesFromListBox() : A second static function used to create
|
||||
* new ALEntry objects and add them to an
|
||||
* ALEntryList object.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALArchive : public ALArchiveBase {
|
||||
/*
|
||||
* Constructors, destructors, declarations
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALArchive( const char AL_DLL_FAR *file_name );
|
||||
AL_PROTO ALArchive( ALStorage AL_DLL_FAR &object );
|
||||
virtual AL_PROTO ~ALArchive();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* As usual, I prohibit the copy constructor and assignment operator.
|
||||
* They are declared here but they don't exist.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALArchive( ALArchive AL_DLL_FAR & );
|
||||
ALArchive AL_DLL_FAR & AL_PROTO operator=( ALArchive AL_DLL_FAR & );
|
||||
/*
|
||||
* Member Functions
|
||||
*
|
||||
* Note, these guys are used inside the Archive class for extraction.
|
||||
* The may be better off protected.
|
||||
*/
|
||||
public :
|
||||
virtual ALCompressionEngine AL_DLL_FAR * AL_PROTO CreateCompressionEngine( int engine_type );
|
||||
virtual ALStorage AL_DLL_FAR * AL_PROTO CreateStorageObject( const char AL_DLL_FAR *name, int object_type );
|
||||
|
||||
public :
|
||||
/*
|
||||
* These two member functions are both static. They are in this class
|
||||
* to take advantage of this classes knowledge of how to create
|
||||
* ALFile and ALGreenleafEngine objects. They are used to create
|
||||
* new ALEntry objects. It would be good in a future release to
|
||||
* change their names to be more uniform.
|
||||
*/
|
||||
static int AL_PROTO
|
||||
AddWildCardFiles( ALEntryList AL_DLL_FAR & list,
|
||||
const char AL_DLL_FAR *pattern = "*.*",
|
||||
int traverse_flag = 0,
|
||||
short int compression_level = AL_GREENLEAF_LEVEL_2 );
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
static int AL_PROTO MakeEntriesFromListBox( ALEntryList AL_DLL_FAR &list, HWND hDlg, int list_box = -1 );
|
||||
#endif
|
||||
/*
|
||||
* Data members, hey there aren't any!
|
||||
*/
|
||||
public :
|
||||
AL_CLASS_TAG( _ALArchiveTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifndef _ARCHIVE_H */
|
||||
1456
al/archiveb.cpp
Executable file
1456
al/archiveb.cpp
Executable file
File diff suppressed because it is too large
Load Diff
226
al/archiveb.h
Executable file
226
al/archiveb.h
Executable file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* ARCHIVEB.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class definition for class
|
||||
* ALArchiveBase.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALArchiveBase
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ARCHIVEB_H
|
||||
#define _ARCHIVEB_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
/*
|
||||
* class ALArchiveBase
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is the most important class definition in the library.
|
||||
* ALArchiveBase defines the interface to archive objects, on disk,
|
||||
* memory, or whatever. This class is a pure base class, so you
|
||||
* won't ever create an instance of an ALArchiveBase object.
|
||||
*
|
||||
* The derived class for a given archive type has several very important
|
||||
* virtual functions it has to provide. The most important two are
|
||||
* CreateCompressionEngine() and CreateStorageObject(). These
|
||||
* two functions are called when the directory is being read from
|
||||
* a given archive. In the directory, the type of a storage object
|
||||
* and the compression engine used to create it are defined as just
|
||||
* plain integers. Somewhere, somebody has to look at these integers
|
||||
* and create real objects based on their contents, and then maybe
|
||||
* perform some initialization as well.
|
||||
*
|
||||
* At first glance it might seem like there is no reason the base class
|
||||
* shouldn't just do all this work itself. However, there is a good reason
|
||||
* not to do it this way. If the base class is designed to be a completely
|
||||
* general purpose class, it would need to know how to create a Greenleaf
|
||||
* compression engine, a Microsoft compression engine, and so on. It
|
||||
* would also need to know how to create all different kinds of storage
|
||||
* objects, probably including our demo storage objects. This would mean
|
||||
* that the base ALArchiveBase class would basically have to link in our
|
||||
* entire library. What is worse, if someone created a lean and mean
|
||||
* derived class that only supported one storage type and one compression
|
||||
* engine, they would still have to link in all that other code because
|
||||
* it was referenced in the base class.
|
||||
*
|
||||
* So the compromise is the current hierarchy. We have a base class that
|
||||
* has no links to any engines or storage objects. A user can derive
|
||||
* a lean and mean class from the base class and not have to worry as much
|
||||
* about code bloat. On the other hand, we have a relatively full
|
||||
* featured derived class one level down, called ALArchive. It
|
||||
* has the built in links to the "ordinary" object types. This way, you
|
||||
* have a ready-built class that will do lots of ordinary jobs without a
|
||||
* lot of fuss.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mpArchiveStorageObject : Pointer to the Archive's storage object.
|
||||
* This is the ALFile, or whatever, that
|
||||
* actually contains (or will contain) the
|
||||
* archive.
|
||||
*
|
||||
* mszComment : The comment associated with this archive.
|
||||
* This comment is stored on disk along with
|
||||
* the archive directory.
|
||||
*
|
||||
* mlDirectoryOffset : The offset in the storage object to the
|
||||
* archive's directory. All of the compressed
|
||||
* objects in the archive are stored sequentially
|
||||
* at the start of the file. The directory
|
||||
* and other information starts after all of
|
||||
* the objects. This data member tells us
|
||||
* how to get there. Not filled in until
|
||||
* an archive has actually been created.
|
||||
*
|
||||
* miVersion : The archive version. This version field
|
||||
* refers to the format version of the archive,
|
||||
* which won't necessarily be the save as
|
||||
* the format of ArchiveLib.
|
||||
*
|
||||
* miDeleteStorageObject : If this flag is set, the storage object
|
||||
* associated with the archive object will
|
||||
* have its object destroyed in the
|
||||
* archive destructor. This saves you
|
||||
* from having to do the job explicitly
|
||||
* in your code.
|
||||
*
|
||||
* mStatus : The only public data member, this is a
|
||||
* standard ArchiveLib status object.
|
||||
*
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALArchiveBase() : The only constructor.
|
||||
* ~ALArchiveBase() : The virtual destructor.
|
||||
* operator new() : Memory allocation operator used when
|
||||
* the library is in a DLL
|
||||
* AddJobs() : Protected function used to create
|
||||
* CopyJobs() : Protected function used to create
|
||||
* AddDirectoryEntries() : Protected function used to create, append
|
||||
* CalculateJobSize() : Protected function to help monitor
|
||||
* CalculateCompressedJobSize() : Protected function to help monitor
|
||||
* ScanStatus() : Protected function to update status
|
||||
* CreateCompressionEngine() : Virtual fn used when extracting
|
||||
* CreateStorageObject() : Virtual fn used when extracting
|
||||
* WriteArchiveData() : Protected fn to write part of directory
|
||||
* ReadArchiveData() : Protected fn to read part of directory
|
||||
* Create(ALEntryList&) : Create a new archive
|
||||
* Create(ALArchiveBase&, : Create a new archive from another
|
||||
* ALEntryList&)
|
||||
* Append(ALEntryList&) : Add objects to archive
|
||||
* Append(ALArchiveBase&, : Add objects to archive from another one
|
||||
* ALEntryList&)
|
||||
* Extract() : Extract objects from an archive
|
||||
* Delete() : Delete objects from an archive
|
||||
* GetComment() : Get the comment stored in the archive
|
||||
* SetComment() : Set the comment that will be stored
|
||||
* ReadDirectory() : Read the directory into an ALEntryList
|
||||
* WriteDirectory() : Write the directory back out.
|
||||
* GetVersion() : Get the archive's version
|
||||
* GetStorageObject() : Get pointer to the archive's storage object
|
||||
* FillListBox() : Fill a list box with the archive's entries
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALArchiveBase {
|
||||
/*
|
||||
* Constructors, destructors, declarations, and friends
|
||||
*/
|
||||
protected :
|
||||
public :
|
||||
AL_PROTO ALArchiveBase( ALStorage AL_DLL_FAR *, short int delete_in_dtor );
|
||||
virtual AL_PROTO ~ALArchiveBase();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
|
||||
/* The copy constructor and assignment operator do not exist. */
|
||||
protected :
|
||||
AL_PROTO ALArchiveBase( const ALArchiveBase AL_DLL_FAR & );
|
||||
ALArchiveBase AL_DLL_FAR & AL_PROTO operator=( ALArchiveBase AL_DLL_FAR &rhs );
|
||||
|
||||
/*
|
||||
* Member functions
|
||||
*
|
||||
*
|
||||
* Used internally, not for public access
|
||||
*/
|
||||
private :
|
||||
int AL_PROTO AddJobs( ALEntryList AL_DLL_FAR & list );
|
||||
int AL_PROTO CopyJobs( ALArchiveBase AL_DLL_FAR & source_archive,
|
||||
ALEntryList AL_DLL_FAR & list );
|
||||
int AL_PROTO AddDirectoryEntries( ALEntryList AL_DLL_FAR &list );
|
||||
long AL_PROTO CalculateJobSize( ALEntryList AL_DLL_FAR &list );
|
||||
long AL_PROTO CalculateCompressedJobSize( ALEntryList AL_DLL_FAR &list );
|
||||
void AL_PROTO ScanStatus( ALEntryList AL_DLL_FAR &list );
|
||||
/*
|
||||
* This batch of functions are the ones that have to be created by a derived
|
||||
* class. The first four are simple U/I functions that are normally used
|
||||
* to print stuff on the screen when starting or finishing a compression
|
||||
* or extraction. The final two provide the very important function of
|
||||
* binding compression engines and object types to the archive.
|
||||
*/
|
||||
protected :
|
||||
virtual ALCompressionEngine AL_DLL_FAR * AL_PROTO CreateCompressionEngine( int engine_type ) = 0;
|
||||
virtual ALStorage AL_DLL_FAR * AL_PROTO CreateStorageObject( const char AL_DLL_FAR *name, int object_type ) = 0;
|
||||
virtual int AL_PROTO WriteArchiveData();
|
||||
virtual int AL_PROTO ReadArchiveData();
|
||||
/*
|
||||
* These functions provide the public API to an archive
|
||||
*/
|
||||
public :
|
||||
int AL_PROTO Create( ALEntryList AL_DLL_FAR &list );
|
||||
int AL_PROTO Create( ALArchiveBase AL_DLL_FAR &source_archive,
|
||||
ALEntryList AL_DLL_FAR &source_list );
|
||||
int AL_PROTO Append( ALEntryList AL_DLL_FAR &list );
|
||||
int AL_PROTO Append( ALArchiveBase AL_DLL_FAR &source_archive,
|
||||
ALEntryList AL_DLL_FAR &source_list );
|
||||
int AL_PROTO Extract( ALEntryList AL_DLL_FAR &list );
|
||||
int AL_PROTO Delete( ALEntryList AL_DLL_FAR &list,
|
||||
ALArchiveBase AL_DLL_FAR & destination_archive );
|
||||
const char AL_DLL_FAR * AL_PROTO GetComment(){ return mszComment; }
|
||||
int AL_PROTO SetComment( char AL_DLL_FAR *comment );
|
||||
int AL_PROTO ReadDirectory( ALEntryList AL_DLL_FAR &list );
|
||||
int AL_PROTO WriteDirectory( ALEntryList AL_DLL_FAR &list );
|
||||
short AL_PROTO GetVersion(){ return miVersion; }
|
||||
ALStorage AL_DLL_FAR *GetStorageObject(){ return mpArchiveStorageObject; }
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
int AL_PROTO FillListBox( HWND hWnd, int list_box_id = -1 );
|
||||
#endif
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
ALStorage AL_DLL_FAR *mpArchiveStorageObject;
|
||||
char AL_DLL_FAR *mszComment;
|
||||
long mlDirectoryOffset;
|
||||
short miVersion;
|
||||
const short int miDeleteStorageObject;
|
||||
|
||||
public :
|
||||
ALStatus mStatus;
|
||||
AL_CLASS_TAG( _ALArchiveBaseTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifndef _ARCHIVEB_H */
|
||||
85
al/arclib.h
Executable file
85
al/arclib.h
Executable file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* ARCLIB.H
|
||||
*
|
||||
* Master header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is the master header file for Archive Library. It will include
|
||||
* all header files that define base classes, but no derived classes. For
|
||||
* people who don't want the massive flood of include files provided by
|
||||
* AL.H, this is the answer. However, you will have to include some
|
||||
* other headers, leading to some extra work.
|
||||
*
|
||||
* This file must be included by any module that is either a part of
|
||||
* Archive Library, or part of a project that uses archive library.
|
||||
*
|
||||
* Defines that you should be creating in your program when using this
|
||||
* product include:
|
||||
*
|
||||
* #define AL_USING_DLL Every module calling the AL DLL *must*
|
||||
* have this defined
|
||||
* #define NDEBUG Turns off assertions. Note that assertions
|
||||
* defined in the debug version of the library
|
||||
* won't go away just because you define this
|
||||
* #define _DEBUG Turn this on to turn on some of the debugging
|
||||
* features of the library. Doesn't do much
|
||||
* at this time.
|
||||
*
|
||||
* We set up the rest of the definitions in ALDEFS.H, based on compiler
|
||||
* settings that can be detected using your compiler's predefined
|
||||
* macros.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ARCLIB_H
|
||||
#define _ARCLIB_H
|
||||
|
||||
/*
|
||||
* Want to customize the workings of our library? Just define AL_CUSTOM,
|
||||
* and then create your own personal version of ALCUSTOM.H. (No, we don't
|
||||
* ship a copy of this header file with the library, it is for you to
|
||||
* define. This is a really good way to use products like MEMCHECK or
|
||||
* SmartHeap that want to insert an included file in every one of
|
||||
* our source files.
|
||||
*/
|
||||
|
||||
#if defined( AL_CUSTOM )
|
||||
#include "alcustom.h"
|
||||
#endif
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/* All these includes needed for various library features */
|
||||
|
||||
#include "iostream.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "aldefs.h"
|
||||
#include "_debug.h"
|
||||
|
||||
/* Base classes */
|
||||
|
||||
#include "status.h"
|
||||
#include "objname.h"
|
||||
#include "storage.h"
|
||||
#include "cmpengn.h"
|
||||
#include "monitor.h"
|
||||
#include "arcentry.h"
|
||||
#include "cmpobj.h"
|
||||
#include "archiveb.h"
|
||||
|
||||
#else /* #if defined( __cplusplus ) */
|
||||
|
||||
#include "alcxl.h" /* Included only if we are compiling C code, not C++ */
|
||||
|
||||
#endif /* #if defined( __cplusplus ) ... #else */
|
||||
|
||||
#endif /* ARCLIB_H */
|
||||
107
al/bargraph.h
Executable file
107
al/bargraph.h
Executable file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* BARGRAPH.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* The class definition for ALBarGraph is found here.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* class ALBarGraph
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _BARGRAPH_H
|
||||
#define _BARGRAPH_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/*
|
||||
* class ALBarGraph : public ALMonitor
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is a utility class. The constructor opens a file for input,
|
||||
* and keeps track of whether it was already open or not. The destructor
|
||||
* will automatically close the file if it was closed when the
|
||||
* ctor was invoked.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miCurrentOffset : The current offset of the bargraph, in screen
|
||||
* units. Usually the bar itself is 20 characters
|
||||
* long, in which case this value will be somewhere
|
||||
* between 0 and 19.
|
||||
*
|
||||
* miBarLength : The length of the bar, defined when the
|
||||
* constructor is called. This is a const member,
|
||||
* which means we can leave it public.
|
||||
*
|
||||
* mrStream : Reference to an output stream. This is the
|
||||
* stream where the bargraph gets drawn.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALBarGraph() : The constructor.
|
||||
* ~ALBarGraph() : Virtual destructor.
|
||||
* Progress() : The progress routine, where the bargraph
|
||||
* gets updated.
|
||||
* ArchiveOperation() : The routine that gets called when files
|
||||
* are opened, closed, etc.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALBarGraph : public ALMonitor {
|
||||
/*
|
||||
* Constructors, destructors, and friend classes
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALBarGraph( ALMonitorType monitor_type,
|
||||
ostream& stream = cout,
|
||||
int bar_length = 25 );
|
||||
virtual AL_PROTO ~ALBarGraph();
|
||||
/*
|
||||
* The copy constructor and assignment operator do not exist.
|
||||
*/
|
||||
protected :
|
||||
ALBarGraph( const ALBarGraph& );
|
||||
ALBarGraph& operator=( const ALBarGraph& );
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
protected :
|
||||
virtual void AL_PROTO Progress( long object_so_far,
|
||||
ALStorage& object );
|
||||
virtual void AL_PROTO
|
||||
ArchiveOperation( ALArchiveOperation operation,
|
||||
ALArchiveBase *archive,
|
||||
ALEntry *job );
|
||||
/*
|
||||
* Data Members
|
||||
*/
|
||||
protected :
|
||||
int miCurrentOffset;
|
||||
const int miBarLength;
|
||||
ostream& mrStream;
|
||||
public :
|
||||
AL_CLASS_TAG( _ALBarGraphTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifdef _BARGRAP_H */
|
||||
204
al/cmpengn.cpp
Executable file
204
al/cmpengn.cpp
Executable file
@ -0,0 +1,204 @@
|
||||
//
|
||||
// CMPENGN.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALCompressionEngine::operator new()
|
||||
// ALCompressionEngine::ALCompressionEngine()
|
||||
// ALCompressionEngine::WriteEngineData()
|
||||
// ALCompressionEngine::ReadEngineData()
|
||||
// ALCompressionEngine::~ALCompressionEngine()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the functions for the base class
|
||||
// ALCompressionEngine. Since the base class doesn't do much,
|
||||
// this is a pretty small file. See derived classes for
|
||||
// excitement.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//
|
||||
// void * ALCompressionEngine::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALCompressionEngine
|
||||
// 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 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALCompressionEngine::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALCompressionEngine::
|
||||
// ALCompressionEngine( ALCompressionType compression_type_int,
|
||||
// const char *compression_type_string )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// compression_type_int : The enumerated constant for the compression
|
||||
// type supported by this compression engine.
|
||||
//
|
||||
// compression_type_string : The string describing the compression engine.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This constructor can only be called by derived classes, and all they
|
||||
// do with it is call it to set up the compression type and integer
|
||||
// members. This class has a couple of pure virtual functions, so
|
||||
// you can't instantiate a freestanding object.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO
|
||||
ALCompressionEngine::ALCompressionEngine( ALCompressionType compression_type_int,
|
||||
const char *compression_type_string )
|
||||
: miCompressionType( compression_type_int ),
|
||||
mszCompressionType( compression_type_string )
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// int ALCompressionEngine::WriteEngineData( ALStorage *archive )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// archive : The storage object where the engine specific data is
|
||||
// going to be written.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, or < AL_SUCCESS if something bad happens.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Compression engines can write private data out to the archive
|
||||
// directory to provide customization information. For example, the
|
||||
// Greenleaf compression engine writes its compression level
|
||||
// using this function. By default, there is no data, which is what
|
||||
// this function writes out, a 0 length string.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO
|
||||
ALCompressionEngine::WriteEngineData( ALStorage AL_DLL_FAR * archive )
|
||||
{
|
||||
return archive->WritePortableShort( 0 );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALCompressionEngine::ReadEngineData( ALStorage * archive )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// archive : The storage object where the engine specific data is
|
||||
// going to be read in from.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, or < AL_SUCCESS if something bad happened.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Compression engines can write private data out to the archive
|
||||
// directory to provide customization information. For example, the
|
||||
// Greenleaf compression engine writes its compression level
|
||||
// using this function. By default, no data is written out. This
|
||||
// function expects to find a zero length string, and complains
|
||||
// with a fatal error if it doesn't.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO
|
||||
ALCompressionEngine::ReadEngineData( ALStorage AL_DLL_FAR * archive )
|
||||
{
|
||||
short temp;
|
||||
int status = archive->ReadPortableShort( temp );
|
||||
AL_ASSERT( temp == 0, "ReadEngineData: engine data not 0 length" );
|
||||
return status;
|
||||
}
|
||||
|
||||
//
|
||||
// ALCompressionEngine::~ALCompressionEngine()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None, destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This guy doesn't have anything to do. In the debug version of
|
||||
// the library, it at least checks to be sure the object type is correct.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALCompressionEngine::~ALCompressionEngine()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALCompressionEngine: attempt to delete invalid object" );
|
||||
}
|
||||
|
||||
130
al/cmpengn.h
Executable file
130
al/cmpengn.h
Executable file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* CPMENGN.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class declaration for ALCompressionEngine,
|
||||
* the base class used by all ArchiveLib compression engines.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALCompressionEngine
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CMPENGN_H
|
||||
#define _CMPENGN_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
|
||||
/*
|
||||
* class ALOpenInputFile
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file defines the ALCompressionEngine class. It is a base
|
||||
* class with pure virtual functions, so it cannot be instantiated.
|
||||
* The two derived classes supplied with Archive Library at this time are
|
||||
* ALGreenleafEngine, which implements a Greenleaf proprietary compression
|
||||
* engine, and ALCopyEngine, which just performs straight copying.
|
||||
*
|
||||
* ALCompressionEngine has two public virtual functions, Compress()
|
||||
* and Decompress(), which are pure here. It also provides two
|
||||
* virtual protected functions which are used to store configuration
|
||||
* in the archive directory.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miCompressionType : The compression type integer is what gets stored
|
||||
* in the archive directory, and what the archive
|
||||
* class looks at when extracting so it can figure
|
||||
* out what type of compression engine to construct
|
||||
* for a specific type of object.
|
||||
*
|
||||
* mszCompressionType : This string just describes the compression type
|
||||
* in ASCII format suitable for printing or display.
|
||||
*
|
||||
* mStatus : A standard ArchiveLib status object, stored
|
||||
* with the compression engine. Check this after
|
||||
* completing a compression or decompression to
|
||||
* see how things went.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALCompressionEngine() : The constructor. Only called by the ctors for
|
||||
* derived classes.
|
||||
* ~ALCompressionEngine() : The virtual destructor.
|
||||
* operator new() : Memory allocation operator, only gets used
|
||||
* when the library is in a DLL.
|
||||
* WriteEngineData() : Private virtual function used to store engine
|
||||
* specific data.
|
||||
* ReadEngineData() : Private virtual function used to read back
|
||||
* engine specific data.
|
||||
* Compress() : The compression routine. Derived classes
|
||||
* have to provide their own versions of this
|
||||
* function. Wouldn't be much good without it.
|
||||
* Decompress() : The inverse, has to know how to undo the
|
||||
* Compress() output.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALCompressionEngine {
|
||||
/*
|
||||
* Constructors, destructors, declarations, and friends
|
||||
*/
|
||||
friend class AL_CLASS_TYPE ALArchiveBase;
|
||||
|
||||
public :
|
||||
AL_PROTO ALCompressionEngine( ALCompressionType compression_type_int,
|
||||
const char AL_DLL_FAR *compression_type_string );
|
||||
virtual AL_PROTO ~ALCompressionEngine();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* The copy constructor and assignment operator do not exist. I define
|
||||
* them here to prevent the compiler from creating default versions.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALCompressionEngine( ALCompressionEngine AL_DLL_FAR & );
|
||||
ALCompressionEngine AL_DLL_FAR & AL_PROTO operator=( ALCompressionEngine AL_DLL_FAR & rhs );
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
protected :
|
||||
virtual int AL_PROTO WriteEngineData( ALStorage AL_DLL_FAR * archive );
|
||||
virtual int AL_PROTO ReadEngineData( ALStorage AL_DLL_FAR * archive );
|
||||
|
||||
public :
|
||||
virtual int AL_PROTO Compress( ALStorage AL_DLL_FAR &input_object,
|
||||
ALStorage AL_DLL_FAR &output_object ) = 0;
|
||||
virtual int AL_PROTO Decompress( ALStorage AL_DLL_FAR &input_object,
|
||||
ALStorage AL_DLL_FAR &output_object,
|
||||
long compressed_length = -1 ) = 0;
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
public :
|
||||
const ALCompressionType miCompressionType;
|
||||
const char AL_DLL_FAR *mszCompressionType;
|
||||
ALStatus mStatus;
|
||||
AL_CLASS_TAG( _ALCompressionEngineTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifndef _CMPENGN_H */
|
||||
361
al/cmpobj.cpp
Executable file
361
al/cmpobj.cpp
Executable file
@ -0,0 +1,361 @@
|
||||
//
|
||||
// CMPOBJ.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALCompressedObject::operator new()
|
||||
// ALCompressedObject::ALCompressedObject()
|
||||
// ALCompressedObject::~ALCompressedObject()
|
||||
// ALCompressedObject::Insert()
|
||||
// ALCompressedObject::Extract()
|
||||
// ALCompressedObject::WriteHeaderData()
|
||||
// ALCompressedObject::ReadHeaderData()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the support code for the ALCompressedObject
|
||||
// class. This class is sort of a poor-man's archive, with just one
|
||||
// file, no flexibility, and super-low overhead.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "_openf.h"
|
||||
|
||||
//
|
||||
// void * ALCompressedObject::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALCompressedObject
|
||||
// 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 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALCompressedObject::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALCompressedObject::
|
||||
// ALCompressedObject( ALStorage AL_DLL_FAR & storage_object,
|
||||
// ALCompressionEngine AL_DLL_FAR & compression_engine )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// storage_object : A reference to the storage object that is going
|
||||
// to get the compressed data.
|
||||
//
|
||||
// compression_engine : A reference to the compression engine that will
|
||||
// be used to insert an object or extract an object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A constructor, you don't get a return.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// A compressed object is a storage object that gets a single compressed
|
||||
// object packed into it. You get to call Insert() or Extract(), to
|
||||
// put the object in or take it out. Compressed objects don't get all
|
||||
// the fancy options that Archives do. For example, you have to know in
|
||||
// advance what sort of compression engine and storage object you are
|
||||
// going to use to put things in and take things out. You don't get to
|
||||
// store comments or time date stamps, or anything like that.
|
||||
//
|
||||
// The one piece of flexibility you do get the ALCompressedObject is
|
||||
// the ability to derive a new class from this base, then use the
|
||||
// new class to write some custom data out to the object.
|
||||
//
|
||||
// This constructor stores references to the object being used to hold the
|
||||
// compressed data, and the engine being used to pack and unpack it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALCompressedObject::
|
||||
ALCompressedObject( ALStorage AL_DLL_FAR & storage_object,
|
||||
ALCompressionEngine AL_DLL_FAR & compression_engine )
|
||||
{
|
||||
mpCompressionEngine = &compression_engine;
|
||||
mpStorageObject = &storage_object;
|
||||
}
|
||||
|
||||
//
|
||||
// ALCompressedObject::~ALCompressedObject()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None, destructor.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None, destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This destructor has nothing important to do. The debug version
|
||||
// checks the object type for validity, but that's it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALCompressedObject::~ALCompressedObject()
|
||||
{
|
||||
AL_ASSERT_OBJECT( this, ALCompressedObject, "~ALCompressedObject" );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALCompressedObject::Insert( ALStorage &input_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// input_object : A storage object that is going to be inserted into
|
||||
// the compressed object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if everything worked properly, or < AL_SUCCESS if an
|
||||
// error was encountered.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The compressed object has this format:
|
||||
//
|
||||
// long uncompressed_size
|
||||
// long compressed_size
|
||||
// DWORD crc_32
|
||||
// Any data from derived classes
|
||||
// unsigned char data[]
|
||||
//
|
||||
// Writing all this out is pretty straightforward, although you might
|
||||
// note that it is going to require at least one seek() back to the
|
||||
// start of the compressed object after the compression is done.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
|
||||
int AL_PROTO ALCompressedObject::Insert( ALStorage AL_DLL_FAR &input_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this, ALCompressedObject, "Insert" );
|
||||
AL_ASSERT_OBJECT( &input_object, ALStorage, "Insert" );
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
//
|
||||
// Here is where we open the input and the output.
|
||||
//
|
||||
ALOpenFiles files( input_object, *mpStorageObject );
|
||||
//
|
||||
// We first write out the uncompressed size, which we already know. We
|
||||
// then save the current position, and write placeholder longs out for
|
||||
// what will become the compressed size and the CRC-32.
|
||||
//
|
||||
mpStorageObject->WritePortableLong( input_object.GetSize() );
|
||||
long saved_pos = mpStorageObject->Tell();
|
||||
mpStorageObject->WritePortableLong( 0xfedcba98L ); //Temporary
|
||||
mpStorageObject->WritePortableLong( 0x01234567L ); //Temporary
|
||||
//
|
||||
// If a derived class has any header data to write out, this is where it
|
||||
// will be performed. The base class writes 0 bytes here.
|
||||
//
|
||||
WriteHeaderData();
|
||||
long start = mpStorageObject->Tell();
|
||||
//
|
||||
// Next, perform the compression. Once that is done we can calculate
|
||||
// the compressed size. The CRC-32 will have been calculated on the fly
|
||||
// as the compression was performed.
|
||||
//
|
||||
mpCompressionEngine->Compress( input_object, *mpStorageObject );
|
||||
long compressed_size = mpStorageObject->Tell() - start;
|
||||
if ( mpCompressionEngine->mStatus < 0 )
|
||||
return mStatus = mpCompressionEngine->mStatus;
|
||||
//
|
||||
// Go back to the spot we remembered, and write out the compressed
|
||||
// size and the CRC. At that point, the compressed object is complete.
|
||||
//
|
||||
mpStorageObject->Seek( saved_pos );
|
||||
mpStorageObject->WritePortableLong( compressed_size );
|
||||
mpStorageObject->WritePortableLong( ~input_object.GetCrc32() );
|
||||
if ( mpStorageObject->mStatus < 0 )
|
||||
return mStatus = mpStorageObject->mStatus;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALCompressedObject::Extract( ALStorage &output_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// output_object : The storage object that is going to receive the
|
||||
// extracted data from the compressed object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, or < AL_SUCCESS if an error occurs.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Extracting the data to a new storage object is easy. We read in
|
||||
// all the data so that we can do a little error checking along the
|
||||
// way, but that's all.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALCompressedObject::Extract( ALStorage AL_DLL_FAR &output_object )
|
||||
{
|
||||
long compressed_length;
|
||||
long crc32;
|
||||
|
||||
AL_ASSERT_OBJECT( this, ALCompressedObject, "Extract" );
|
||||
AL_ASSERT_OBJECT( &output_object, ALStorage, "Extract" );
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
//
|
||||
// Open the input and output files.
|
||||
//
|
||||
ALOpenFiles files( *mpStorageObject, output_object );
|
||||
//
|
||||
// Now read in all the data stored at the start of the object,
|
||||
// including any header data created by derived classes. If we are
|
||||
// using the base class, there won't be any additional data bytes there.
|
||||
//
|
||||
mpStorageObject->ReadPortableLong( output_object.mlSize );
|
||||
mpStorageObject->ReadPortableLong( compressed_length );
|
||||
mpStorageObject->ReadPortableLong( crc32 );
|
||||
ReadHeaderData();
|
||||
if ( mpStorageObject->mStatus < 0 )
|
||||
return mStatus = mpStorageObject->mStatus;
|
||||
//
|
||||
// Extract the data and store it in the storage object specified
|
||||
// as an argument.
|
||||
//
|
||||
if ( mpCompressionEngine->Decompress( *mpStorageObject,
|
||||
output_object,
|
||||
compressed_length ) < 0 )
|
||||
return mStatus = mpCompressionEngine->mStatus;
|
||||
//
|
||||
// A little error checking leads to an error return if things didn't
|
||||
// go well, or AL_SUCCESS if things did.
|
||||
//
|
||||
if ( mpStorageObject->mStatus < 0 )
|
||||
return mStatus = mpStorageObject->mStatus;
|
||||
if ( crc32 != ~output_object.GetCrc32() )
|
||||
return mStatus.SetError( AL_CRC_ERROR,
|
||||
"CRC32 differs between %s and %s",
|
||||
mpStorageObject->mName.GetName(),
|
||||
output_object.mName.GetName() );
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALCompressedObject::WriteHeaderData()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, always.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Derived classes can override this function and use it to add
|
||||
// additional data bytes to the header of a compressed object. Note
|
||||
// that this data does not have to be written out in any particular
|
||||
// format, we have no portability concerns here. It is up to the
|
||||
// derived class to insure that the data is written in an internally
|
||||
// consistent format so that ReadHeaderData() can always position the
|
||||
// file pointer to the correct start of data.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALCompressedObject::WriteHeaderData()
|
||||
{
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALCompressedObject::ReadHeaderData()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, always.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Derived classes can override this function and use it to read
|
||||
// additional data bytes from the header of a compressed object. Note
|
||||
// that this data does not have to be written out in any particular
|
||||
// format, we have no portability concerns here. It is up to the
|
||||
// derived class to insure that the data is written in an internally
|
||||
// consistent format so that ReadHeaderData() can always position the
|
||||
// file pointer to the correct start of data.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 23, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALCompressedObject::ReadHeaderData()
|
||||
{
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
120
al/cmpobj.h
Executable file
120
al/cmpobj.h
Executable file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* CMPOBJ.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class definition for ALCompressedObject.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALCompressedObject
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CMPOBJ_H
|
||||
#define _CMPOBJ_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/*
|
||||
* class ALCompressedObject
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is the class definition for ALCompressedObject. A compressed
|
||||
* object is a very simple artifact that contains some compressed data,
|
||||
* a checksum, and a couple of length variables. No comments, no engine
|
||||
* data, no archive data, nothing else. This give this type of object
|
||||
* a very low overhead. It also assumes that when you create a compressed
|
||||
* object using a storage object and a compression engine that you will
|
||||
* know what type of storage object and compression engine to use when
|
||||
* expanding it.
|
||||
*
|
||||
* If you decide you want to add some private data to your compressed
|
||||
* object, it isn't hard. Just derive a new class, and implement the
|
||||
* two virtual functions defined here to read and write your own private
|
||||
* data during compression and decompression.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mpCompressionEngine : A pointer to the compression engine that will
|
||||
* be used by this object. This is assigned when
|
||||
* the object is created, and used to insert or
|
||||
* extract objects.
|
||||
*
|
||||
* mpStorageObject : A pointer to the storage object where this
|
||||
* object will live.
|
||||
*
|
||||
* mStatus : A standard ArchiveLib status object.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALCompressedObject() : The only constructor for ALCompressedObject.
|
||||
* ~ALCompressedObject() : The virtual destructor.
|
||||
* operator new() : Memory allocation operator, used in DLL only.
|
||||
* WriteHeaderData() : Virtual function to allow for storage of
|
||||
* customized data in the object header.
|
||||
* ReadHeaderData() : The virtual complement to the previous function,
|
||||
* lets you read in some customized data.
|
||||
* Insert() : Insert a single storage object into the Compressed
|
||||
* object.
|
||||
* Extract() : Extract the storage object from the Compressed
|
||||
* object.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALCompressedObject {
|
||||
/*
|
||||
* Constructors, destructors, declarations, friends
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALCompressedObject( ALStorage AL_DLL_FAR & storage_object,
|
||||
ALCompressionEngine AL_DLL_FAR & engine );
|
||||
virtual AL_PROTO ~ALCompressedObject();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Define the copy constructor and assignment operator here, that way
|
||||
* the compiler won't attempt to.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALCompressedObject( ALCompressedObject AL_DLL_FAR & );
|
||||
ALCompressedObject AL_DLL_FAR & AL_PROTO operator = ( ALCompressedObject AL_DLL_FAR & );
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
protected :
|
||||
virtual int AL_PROTO WriteHeaderData();
|
||||
virtual int AL_PROTO ReadHeaderData();
|
||||
public :
|
||||
int AL_PROTO Insert( ALStorage AL_DLL_FAR &input_object );
|
||||
int AL_PROTO Extract( ALStorage AL_DLL_FAR &output_object );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
ALCompressionEngine AL_DLL_FAR *mpCompressionEngine;
|
||||
ALStorage AL_DLL_FAR *mpStorageObject;
|
||||
|
||||
public :
|
||||
ALStatus mStatus;
|
||||
AL_CLASS_TAG( _ALCompressedObjectTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifdef _CMPOBJ_H */
|
||||
241
al/copyengn.cpp
Executable file
241
al/copyengn.cpp
Executable file
@ -0,0 +1,241 @@
|
||||
//
|
||||
// COPYENGN.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALCopyEngine::operator new()
|
||||
// ALCopyEngine::ALCopyEngine()
|
||||
// ALCopyEngine::~ALCopyEngine()
|
||||
// ALCopyEngine::Compress()
|
||||
// ALCopyEngine::Decompress()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the source code for the class ALCopyEngine.
|
||||
// The copy engine just does a straight binary copy, so it is pretty
|
||||
// simple. Note that it doesn't have to overload the routines to
|
||||
// read and write the engine data in the archive directory. This is
|
||||
// because it has nothing to write.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "copyengn.h"
|
||||
#include "_openf.h"
|
||||
|
||||
//
|
||||
// void * ALCopyEngine::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The amount of storage that needs to be allocated for
|
||||
// this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the storage.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When using the DLL version of ArchiveLib, it is a good idea to
|
||||
// allocate the storage for objects from inside the DLL, since they
|
||||
// will be freed inside the DLL. If we don't have the new operator
|
||||
// for a class, its storage will be allocated from the EXE before
|
||||
// the constructor code is called. Then, when it is time to free
|
||||
// the storage, the delete operator will be called inside the DLL.
|
||||
// Not good, right?
|
||||
//
|
||||
// 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 21, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALCopyEngine::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALCopyEngine::ALCopyEngine()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None, constructor.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The copy engine doesn't have to store any data, because it just
|
||||
// performs a straight binary copy, without any frills. Because of
|
||||
// this simplicity, it doesn't have any data members to initialize.
|
||||
// The only thing it does initialize is the base class, with the
|
||||
// appropriate enum value and string identifier.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALCopyEngine::ALCopyEngine()
|
||||
: ALCompressionEngine( AL_COMPRESSION_COPY, "Binary copy" )
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// ALCopyEngine::~ALCopyEngine()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None, destructor.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The destructor has absolutely nothing to do. In the debug
|
||||
// versions of the library, the dtor checks to be sure that it
|
||||
// is operating on the right type of object.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALCopyEngine::~ALCopyEngine()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALCopyEngine: Attempt to delete invalid object" );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALCopyEngine::Compress( ALStorage &input, ALStorage &output )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// input : A reference to the input storage object.
|
||||
//
|
||||
// output : A reference to the output storage object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, or < AL_SUCCESS if something bad happens.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is ostensibly a compression engine, but really all it does
|
||||
// is copy input directly to the output. The most exciting thing it
|
||||
// does during the entire process is initialize CRC checking.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALCopyEngine::Compress( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output )
|
||||
{
|
||||
//
|
||||
// Open the input and output files, and initialize CRC 32 checking.
|
||||
//
|
||||
ALOpenFiles files( input, output );
|
||||
input.InitCrc32();
|
||||
//
|
||||
// Now read all the data from the input file, and write it to the
|
||||
// output file.
|
||||
//
|
||||
int c;
|
||||
for ( ; ; ) {
|
||||
c = input.ReadChar();
|
||||
if ( c < 0 )
|
||||
break;
|
||||
output.WriteChar( c );
|
||||
}
|
||||
//
|
||||
// Finally, check on the error status codes, then return.
|
||||
//
|
||||
if ( input.mStatus < AL_SUCCESS )
|
||||
return mStatus = input.mStatus;
|
||||
if ( output.mStatus < AL_SUCCESS )
|
||||
return mStatus = output.mStatus;
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALCopyEngine::Decompress( ALStorage &input,
|
||||
// ALStorage &output,
|
||||
// long length )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// input : A reference to the storage object containing the
|
||||
// compressed data.
|
||||
//
|
||||
// output : A reference to the storage object that is going to receive
|
||||
// the uncompressed data.
|
||||
//
|
||||
// length : The number of byte in the uncompressed image.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if things went properly, error code < AL_SUCCESS if
|
||||
// a problem occurred.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is a decompression routine, but really it just performs a
|
||||
// straight binary copy of input to output. This is the copy engine you
|
||||
// use when you just want to copy/archive files, and aren't worried
|
||||
// about saving disk space.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALCopyEngine::Decompress( ALStorage AL_DLL_FAR & input,
|
||||
ALStorage AL_DLL_FAR & output,
|
||||
long length )
|
||||
{
|
||||
ALOpenFiles files( input, output );
|
||||
output.InitCrc32();
|
||||
|
||||
int c;
|
||||
// if ( length == -1 )
|
||||
// return SetError( NEED_LENGTH,
|
||||
// "The copy engine requires a length parameter when "
|
||||
// "decompressing" );
|
||||
for ( ; length != 0 ; length-- ) {
|
||||
c = input.ReadChar();
|
||||
if ( c < 0 )
|
||||
break;
|
||||
output.WriteChar( c );
|
||||
}
|
||||
if ( input.mStatus < AL_SUCCESS )
|
||||
return mStatus = input.mStatus;
|
||||
if ( output.mStatus < AL_SUCCESS )
|
||||
return mStatus = output.mStatus;
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
|
||||
93
al/copyengn.h
Executable file
93
al/copyengn.h
Executable file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* COPYENGN.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class definition for the derived
|
||||
* class ALCopyEngine.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALCopyEngine
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _COPYENG_H
|
||||
#define _COPYENG_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
#include "cmpengn.h"
|
||||
#include "storage.h"
|
||||
|
||||
/*
|
||||
* class ALOpenInputFile
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ALCopyEngine is a full fledged compression engine. It just
|
||||
* copies files from input to output, instead of doing something
|
||||
* exciting like making them smaller. Its principal virtue is that it
|
||||
* is very fast. If you are packing a bunch of files into an archive,
|
||||
* and don't particularly need to compress them, you can use an instance of
|
||||
* ALCopyEngine and get your work done quickly.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALCopyEngine() : The one and only constructor.
|
||||
* ~ALCopyEngine() : The virtual destructor.
|
||||
* operator new() : Memory allocation operator, only used when the
|
||||
* library is in a DLL.
|
||||
* Compress() : The virtual compression function.
|
||||
* Decompress() : The virtual decompression function.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALCopyEngine : public ALCompressionEngine {
|
||||
/*
|
||||
* Constructors, destructors, declarations, friends
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALCopyEngine();
|
||||
virtual AL_PROTO ~ALCopyEngine();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
public :
|
||||
virtual int AL_PROTO Compress( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output );
|
||||
virtual int AL_PROTO Decompress( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output,
|
||||
long compressed_length = -1 );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
public :
|
||||
AL_CLASS_TAG( _ALCompressedObjectTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifndef _COPYENG_H */
|
||||
956
al/cxl_arch.cpp
Executable file
956
al/cxl_arch.cpp
Executable file
@ -0,0 +1,956 @@
|
||||
//
|
||||
// CXL_ARCH.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALArchiveExtract()
|
||||
// ALArchiveCreate()
|
||||
// ALArchiveCreateFromArchive()
|
||||
// ALArchiveAppend()
|
||||
// ALArchiveAppendFromArchive()
|
||||
// ALArchiveReadDirectory()
|
||||
// ALArchiveWriteDirectory()
|
||||
// ALArchiveDelete()
|
||||
// ALArchiveSetComment()
|
||||
// ALArchiveGetComment()
|
||||
// ALArchiveGetCommentVB()
|
||||
// ALArchiveGetStorage()
|
||||
// ALArchiveFillListBoxWindow()
|
||||
// ALArchiveFillListBoxDialog()
|
||||
// deleteALArchive()
|
||||
// ALArchiveSetError()
|
||||
// ALArchiveGetStatusCode()
|
||||
// ALArchiveGetStatusString()
|
||||
// ALArchiveGetStatusStringVB()
|
||||
// ALArchiveGetStatusDetail()
|
||||
// ALArchiveGetStatusDetailVB()
|
||||
// ALArchiveGetVersion()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the C translation layer routines for the
|
||||
// member functions in ALArchiveBase. Note that we shorten the name
|
||||
// of the base class to ALArchive here.
|
||||
//
|
||||
// Most of the descriptions in this file of the routines are going
|
||||
// to be pretty skimpy. After all, there isn't much code to look
|
||||
// at here anyway. For detailed descriptions, you will want to
|
||||
// look in ARCHIVEB.CPP for the C++ archive base class member functions.
|
||||
//
|
||||
// The one thing all these functions do have in common is that they
|
||||
// perform type checking on the arguments passed from C or VB.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 2.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveExtract( hALArchive this_object,
|
||||
// hALEntryList list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : The handle of (pointer to) an ALArchiveBase object.
|
||||
//
|
||||
// list : The handle of (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A status code, AL_SUCCESS or < AL_SUCCESS in case of an error.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the wrapper function for ALArchiveBase::Extract(). See the
|
||||
// function in ARCHIVEB.CPP for more details.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 2.0A : First release
|
||||
//
|
||||
extern "C" int AL_FUNCTION ALArchiveExtract( hALArchive this_object, hALEntryList list )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveExtract" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALArchiveExtract" );
|
||||
return ((ALArchiveBase *) this_object )->Extract( *( (ALEntryList *) list ) );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveCreate( hALArchive this_object,
|
||||
// hALEntryList list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : The handle of (pointer to) an ALArchiveBase object.
|
||||
//
|
||||
// list : The handle of (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for successful creation, < AL_SUCCESS for a failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function that supports the
|
||||
// ALArchiveBase::Create(ALEntryList&) function. For details on the
|
||||
// internals, see ARCHIVEB.CPP. Note that the two arguments
|
||||
// are checked for correct type. The second version of
|
||||
// ALArchiveBase::Create() is found below.
|
||||
//
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveCreate( hALArchive this_object, hALEntryList list )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveCreate" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALArchiveCreate" );
|
||||
return ((ALArchiveBase *) this_object )->Create( *( (ALEntryList *) list ) );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveCreateFromArchive( hALArchive this_object,
|
||||
// hALArchive input_archive,
|
||||
// hALEntryList list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// This is the archive that is going to be created.
|
||||
//
|
||||
// input_archive : A handle for (pointer to) an ALArchiveBase object.
|
||||
// This is the archive that contains the compressed
|
||||
// objects that are going to be inserted.
|
||||
//
|
||||
// list : A handle for (pointer to) an ALEntryList object.
|
||||
// It will contains descriptions of all the compressed
|
||||
// objects in input_archive that are going to be inserted
|
||||
// into this_object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for successful creation, < AL_SUCCESS for a failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::Create(ALArchiveBase&,ALEntrylist&).
|
||||
// For details on how the member function actually works, take a
|
||||
// gander at ARCHIVEB.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveCreateFromArchive( hALArchive this_object, hALArchive input_archive, hALEntryList list )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveCreateFromArchive" );
|
||||
AL_ASSERT_OBJECT( input_archive, ALArchiveBase, "ALArchiveCreateFromArchive" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALArchiveCreateFromArchive" );
|
||||
return ((ALArchiveBase *) this_object )->Create( *(ALArchiveBase *)input_archive, *( (ALEntryList *) list ) );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveAppend( hALArchive this_object,
|
||||
// hALEntryList list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// This is the archive that is going to have new objects
|
||||
// appended to it.
|
||||
//
|
||||
// list : A handle for (pointer to) an ALEntryList object.
|
||||
// It will contains descriptions of all the standalone
|
||||
// objects that are going to be inserted into this_object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for a successful append, < AL_SUCCESS for a failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::Append(ALEntrylist&). For details on how the member
|
||||
// function actually works, see ARCHIVEB.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveAppend( hALArchive this_object, hALEntryList list )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveAppend" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALArchiveAppend" );
|
||||
return ((ALArchiveBase *) this_object )->Append( *( (ALEntryList *) list ) );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveAppendFromArchive( hALArchive this_object,
|
||||
// hALArchive input_archive,
|
||||
// hALEntryList list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// This is the archive that is going to get new stuff
|
||||
// appended to it.
|
||||
//
|
||||
// input_archive : A handle for (pointer to) an ALArchiveBase object.
|
||||
// This is the archive that contains the compressed
|
||||
// objects that are going to be added to this_object.
|
||||
//
|
||||
// list : A handle for (pointer to) an ALEntryList object.
|
||||
// It will contains descriptions of all the compressed
|
||||
// objects in input_archive that are going to be added
|
||||
// to this_object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for a successful append, < AL_SUCCESS for a failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::Append(ALArchiveBase&,ALEntrylist&).
|
||||
// For details on how the member function actually works, take a
|
||||
// look at ARCHIVEB.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveAppendFromArchive( hALArchive this_object, hALArchive input_archive, hALEntryList list )
|
||||
{
|
||||
AL_ASSERT( ((ALArchiveBase *) this_object)->GoodTag(),
|
||||
"archive argument is not a valid ALArchiveBase" );
|
||||
AL_ASSERT( ((ALArchiveBase *) input_archive)->GoodTag(),
|
||||
"input archive argument is not a valid ALArchiveBase" );
|
||||
AL_ASSERT( ((ALEntryList *) list)->GoodTag(),
|
||||
"list argument is not a valid ALEntryList" );
|
||||
return ((ALArchiveBase *) this_object )->Append( *(ALArchiveBase *) input_archive, *( (ALEntryList *) list ) );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveReadDirectory( hALArchive this_object,
|
||||
// hALEntryList list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// This is the archive that is going to have its directory
|
||||
// read into the list.
|
||||
//
|
||||
// list : A handle for (pointer to) an ALEntryList object.
|
||||
// The list is going to receive descriptions for all
|
||||
// of the compressed objects stored in the archive.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for a successful read, < AL_SUCCESS for a failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::ReadDirectory(ALEntrylist&). For details on how
|
||||
// the member function actually works, take a look at ARCHIVEB.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveReadDirectory( hALArchive this_object, hALEntryList list )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveReadDirectory" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALArchiveReadDirectory" );
|
||||
return ((ALArchiveBase *) this_object )->ReadDirectory( *( (ALEntryList *) list ) );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveWriteDirectory( hALArchive this_object,
|
||||
// hALEntryList list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// This is the archive that is going to get the new copy
|
||||
// of the directory written out to it.
|
||||
//
|
||||
// list : A handle for (pointer to) an ALEntryList object.
|
||||
// The list contains descriptions for all
|
||||
// of the compressed objects stored in the archive.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for a successful write, < AL_SUCCESS for a failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::WriteDirectory(ALEntrylist&). For details on how
|
||||
// the member function actually works, take a look at ARCHIVEB.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveWriteDirectory( hALArchive this_object, hALEntryList list )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveWriteDirectory" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALArchiveWriteDirectory" );
|
||||
return ( (ALArchiveBase *) this_object )->WriteDirectory( *( (ALEntryList *) list ) );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveDelete( hALArchive this_object,
|
||||
// hALEntryList list,
|
||||
// hALArchive output_archive )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// This archive will have some of its compressed
|
||||
// objects copied to the output archive. It will
|
||||
// then be renamed to a backup name, with its contents
|
||||
// unchanged.
|
||||
//
|
||||
// list : A handle for (pointer to) an ALEntryList object.
|
||||
// All of the marked objects in the list will be
|
||||
// deleted (by not copying) from the output_archive.
|
||||
//
|
||||
// output_archive: This archive will get some of the files from
|
||||
// this_object. It will then be renamed to have the
|
||||
// original name of this_object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for a successful deletion, < AL_SUCCESS for a failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::Delete(). For details on how the member function
|
||||
// actually works, take a look at ARCHIVEB.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveDelete( hALArchive this_object,
|
||||
hALEntryList list,
|
||||
hALArchive output_archive )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveDelete" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALArchiveDelete" );
|
||||
AL_ASSERT_OBJECT( output_archive, ALArchiveBase, "IALArchiveDelete" );
|
||||
return ((ALArchiveBase *) this_object )->Delete( *( (ALEntryList *) list ), *( (ALArchiveBase *) output_archive ) );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveSetComment( hALArchive this_object,
|
||||
// char *comment )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We are going to change the comment in archive, although
|
||||
// the new comment won't be stored in the archive until
|
||||
// we do a WriteDirectory().
|
||||
//
|
||||
// comment : An ASCII string that will be the new comment. Note
|
||||
// that this gets passed properly from both C and VB.
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for a successful update, < AL_SUCCESS for a failure.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::SetComment(). For details on how the member function
|
||||
// actually works, take a look at ARCHIVEB.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveSetComment( hALArchive this_object, char *comment )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveSetComment" );
|
||||
if ( comment == 0 )
|
||||
comment = "";
|
||||
return ( (ALArchiveBase *) this_object )->SetComment( comment );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char * ALArchiveGetComment( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We are going to get the comment from this archive.
|
||||
// Note that there won't be any comment here until
|
||||
// you have performed a ReadDirectory().
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the new string, which is stored in the ArchiveBase
|
||||
// object. You can print it, copy it, or whatever, but don't you
|
||||
// dare change it.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C wrapper function for the C++ function
|
||||
// ALArchiveBase::GetComment(). For details on how the member function
|
||||
// actually works, take a look at ARCHIVEB.CPP. Very important
|
||||
// to note that this is for C ONLY! VB strings take a special
|
||||
// return type, see the next function.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char * AL_FUNCTION ALArchiveGetComment( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveGetComment" );
|
||||
return (char *) ( (ALArchiveBase *) this_object )->GetComment();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALArchiveGetCommentVB( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We are going to get the comment from this archive.
|
||||
// Note that there won't be any comment here until
|
||||
// you have performed a ReadDirectory().
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer (or something, I'm not really sure) to a VB string.
|
||||
// The string is created inside VB.EXE (I think), by the
|
||||
// special string creation function.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the VB wrapper function for the C++ function
|
||||
// ALArchiveBase::GetComment(). For details on how the member function
|
||||
// actually works, take a look at ARCHIVEB.CPP. Very important
|
||||
// to note that this is for VB ONLY! We have to do something
|
||||
// special to translate a C character string to a VB native string
|
||||
// type, and the two are not interchangeable!!!
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting. The return result from the
|
||||
// function has to get ground through the VB string maker before we
|
||||
// have something good to return.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION ALArchiveGetCommentVB( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveGetCommentVB" );
|
||||
const char _far *status = ( (ALArchiveBase *) this_object )->GetComment();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" hALStorage ALArchiveGetStorage( hALArchive hArchive )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// we are going to get the handle for (pointer to)
|
||||
// the underlying storage object that contains the
|
||||
// archive.
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) an ALStorage object. I think in theory
|
||||
// it isn't possible for this guy to return a 0.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::GetStorageObject(). For details on how the member
|
||||
// function actually works, take a look at ARCHIVEB.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALStorage AL_FUNCTION ALArchiveGetStorage( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT( ((ALArchiveBase *) this_object)->GoodTag(),
|
||||
"archive argument is not a valid ALArchiveBase" );
|
||||
ALStorage *obj = ((ALArchiveBase *) this_object)->GetStorageObject();
|
||||
return (hALStorage) obj;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveFillListBoxWindow( hALArchive this_object,
|
||||
// HWND window )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We are going to fill a list box with the names
|
||||
// of the storage objects in this archive.
|
||||
//
|
||||
// window : The window handle (not the ID!!!) of a list box.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for good things, <AL_SUCCESS for bad things.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::FillListBox(). For details on how the member
|
||||
// function actually works, take a look at ARCHIVEB.CPP. Note that
|
||||
// even though there is only a single C++ function, we have two
|
||||
// different incarnations for the wrapper function. One that uses
|
||||
// a window handle by itself, and another that uses a dialog handle
|
||||
// /list box id combo to identify the list box.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
extern "C" int AL_FUNCTION ALArchiveFillListBoxWindow( hALArchive this_object,
|
||||
HWND window )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveFillListBoxWindow" );
|
||||
return ((ALArchiveBase *) this_object)->FillListBox( window );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveFillListBoxDialog( hALArchive this_object,
|
||||
// HWND dialog,
|
||||
// int id );
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We are going to fill a list box with the names
|
||||
// of the storage objects in this archive.
|
||||
//
|
||||
// window : The window handle of a dialog box that contains
|
||||
// the list box that will be filled.
|
||||
//
|
||||
// id : The id of the list box control in the dialog.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for good things, <AL_SUCCESS for bad things.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::FillListBox(). For details on how the member
|
||||
// function actually works, take a look at ARCHIVEB.CPP. Note that
|
||||
// even though there is only a single C++ function, we have two
|
||||
// different incarnations for the wrapper function. One that uses
|
||||
// a window handle by itself, and another that uses a dialog handle
|
||||
// /list box id combo to identify the list box.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveFillListBoxDialog( hALArchive this_object,
|
||||
HWND dialog,
|
||||
int id )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveFillListBoxDialog" );
|
||||
return ((ALArchiveBase *) this_object )->FillListBox( dialog, id );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" void deleteALArchive( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We destroy it in this function.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// No returns from destructors.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALArchiveBase::~ALArchiveBase(). For details on how the member
|
||||
// function actually works, take a look at ARCHIVEB.CPP.
|
||||
//
|
||||
// Note that this destructor function is virtual, and should be called
|
||||
// to destroy any derived classes as well.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION deleteALArchive( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "deleteALArchive()" );
|
||||
delete (ALArchiveBase *) this_object;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveSetError( hALArchive this_object,
|
||||
// int error,
|
||||
// char *text )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We are going to set the archive's status member
|
||||
// so that it is in an error state.
|
||||
//
|
||||
// error : The error code to apply to the object. Values from
|
||||
// ALDEFS.H are good, but it really doesn't matter as
|
||||
// long as you use a negative number.
|
||||
//
|
||||
// text : The text of the error message you want to associate with
|
||||
// this error.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Returns the error code that you passed it.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ member function
|
||||
// ALName::SetError(), as applied to an ALArchive object. For more
|
||||
// details on how the function actually works, check out OBJNAME.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveSetError( hALArchive this_object,
|
||||
int error,
|
||||
char AL_DLL_FAR *text )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchive, "ALArchiveSetError" );
|
||||
( (ALArchive *) this_object )->mStatus.SetError( error, text );
|
||||
return error;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveGetStatusCode( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An integer that contains the current status code for the object.
|
||||
// Note that values of < 0 always indicate an error conditions.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALName::GetStatusCode() as implemented for objects of type
|
||||
// ALArchiveBase. For details on how the member
|
||||
// function actually works, take a look at OBJNAME.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveGetStatusCode( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase , "ALArchiveGetStatusCode" );
|
||||
return ( (ALArchiveBase *) this_object )->mStatus.GetStatusCode();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char *ALArchiveGetStatusString( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We want to get the string translation of the error
|
||||
// code for this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a pointer to a short string translation of the
|
||||
// current error code.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C wrapper function for the C++ function
|
||||
// ALName::GetStatusString(), as implemented for class ALArchiveBase.
|
||||
// Note that we need a completely different function return strings
|
||||
// to VB programmers.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
ALArchiveGetStatusString( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveGetStatusString" );
|
||||
const char *status = ( (ALArchiveBase *) this_object )->mStatus.GetStatusString();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return (char AL_DLL_FAR *) status;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALArchiveGetStatusStringVB( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We want to get the string translation of the error
|
||||
// code for this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a VB handle (pointer?) to a short string translation of
|
||||
// the current error code for the ALArchiveBase object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the VB wrapper function for the C++ function
|
||||
// ALName::GetStatusString(), as implemented for class ALArchiveBase.
|
||||
// Note that we need a completely different function to return strings
|
||||
// to C programmers. In this case, we use a special VB translation routine
|
||||
// to convert a C string to one that is nice and easy for VB to use.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION ALArchiveGetStatusStringVB( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveGetStatusStringVB" );
|
||||
const char _far *status = ( (ALArchiveBase *) this_object )->mStatus.GetStatusString();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// extern "C" char * ALArchiveGetStatusDetail( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We want to get the detailed string describing this
|
||||
// object's current status.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a pointer to a status detail message.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C wrapper function for the C++ function
|
||||
// ALName::GetStatusDetail(), as implemented for class ALArchiveBase.
|
||||
// Note that we need a completely different function to return strings
|
||||
// to VB programmers.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
ALArchiveGetStatusDetail( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveGetStatusDetail" );
|
||||
const char *status = ( (ALArchiveBase *) this_object )->mStatus.GetStatusDetail();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return (char AL_DLL_FAR *) status;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALArchiveGetStatusDetailVB( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We want to get the detailed status message for
|
||||
// this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a VB handle (pointer?) to a translation of
|
||||
// the current status detail for the ALArchiveBase object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the VB wrapper function for the C++ function
|
||||
// ALName::GetStatusDetail(), as implemented for class ALArchiveBase.
|
||||
// Note that we need a completely different function to return strings
|
||||
// to C programmers. In this case, we use a special VB translation routine
|
||||
// to convert a C string to one that is nice and easy for VB to use.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION ALArchiveGetStatusDetailVB( hALArchive archive )
|
||||
{
|
||||
AL_ASSERT_OBJECT( archive, ALArchiveBase, "ALArchiveGetStatusDetailVB" );
|
||||
const char _far *status = ( (ALArchiveBase *) archive)->mStatus.GetStatusDetail();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" int ALArchiveGetVersion( hALArchive this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALArchiveBase object.
|
||||
// We want to get the version of this archive.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns the integer version of the object. The current version
|
||||
// is 0x100. Note that this is the version of the Archive, not of the
|
||||
// library.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the VB/C wrapper function for the C++ function
|
||||
// ALArchiveBase::GetVersion(). For details on this function,
|
||||
// take a look at source file ARCHIVEB.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveGetVersion( hALArchive this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALArchiveBase, "ALArchiveGetVersion" );
|
||||
return ( (ALArchiveBase *) this_object )->GetVersion();
|
||||
}
|
||||
442
al/cxl_cmpo.cpp
Executable file
442
al/cxl_cmpo.cpp
Executable file
@ -0,0 +1,442 @@
|
||||
//
|
||||
// CXL_CMPO.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// newALCompressed()
|
||||
// deleteALCompressed()
|
||||
// ALCompressedInsert()
|
||||
// ALCompressedExtract()
|
||||
// ALCompresssedGetStatusCode()
|
||||
// ALCompressedSetError()
|
||||
// ALCompressedGetStatusString()
|
||||
// ALCompressedGetStatusStringVB()
|
||||
// ALCompressedGetStatusDetail()
|
||||
// ALCompressedGetStatusDetailVB()
|
||||
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the C/VB translation routines to support
|
||||
// operations on ALCompressedObject objects. These routines are all
|
||||
// going to be short and sweet, so don't expect too much explanation.
|
||||
// The meat can all be found in CMPOBJ.CPP
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" hALCompressed newALCompressed( hALStorage storage,
|
||||
// hALEngine engine )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// storage : A handle for (pointer to) an ALStorage object that is
|
||||
// going to hold the compressed object.
|
||||
//
|
||||
// engine : A handle for (pointer to) an ALCompressionEngine that will
|
||||
// be used to insert and extract objects from the the storage
|
||||
// object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) a newly created ALCompressedObject, or 0 if
|
||||
// the constructor failed.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation function for the C++ constructor
|
||||
// ALCompressedObject::ALCompressedObject(). See CMPOBJ.CPP for
|
||||
// details on what happens in the member function.
|
||||
//
|
||||
// In the translation function, we just check the arguments for
|
||||
// correct type (in the debug version) and call the function, returning
|
||||
// the result to the calling function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALCompressed AL_FUNCTION
|
||||
newALCompressed( hALStorage storage,
|
||||
hALEngine engine )
|
||||
{
|
||||
AL_ASSERT_OBJECT( storage, ALStorage, "newALCompressed" );
|
||||
AL_ASSERT_OBJECT( engine, ALCompressionEngine, "newALCompressed" );
|
||||
return (hALCompressed) new ALCompressedObject( *(ALStorage *) storage, *(ALCompressionEngine *) engine );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void deleteALCompressed( hALCompressed this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedObject
|
||||
// that is going to be destroyed.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation function for the C++ destructor
|
||||
// ALCompressedObject::~ALCompressedObject(). See CMPOBJ.CPP for
|
||||
// details on what happens in the member function.
|
||||
//
|
||||
// In the translation function, we just check the arguments for
|
||||
// correct type (in the debug version) and call the function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION deleteALCompressed( hALCompressed this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "deleteALCompressed" );
|
||||
delete (ALCompressedObject *) this_object;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALCompressedInsert( hALCompressed this_object,
|
||||
// hALStorage input_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedObject
|
||||
// that is going to have a storage object inserted
|
||||
// int it.
|
||||
//
|
||||
// input_object : A handle for (pointer to) a storage object that is
|
||||
// going to get compressed into this_object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for success, or < AL_SUCCESS for one of many failures
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation function for the C++ function
|
||||
// ALCompressedObject::Insert(). See CMPOBJ.CPP for more details
|
||||
// on what happens in the member function.
|
||||
//
|
||||
// In the translation function, we just check the arguments for
|
||||
// correct type (in the debug version) and call the function. We
|
||||
// return the integer result of the function directly to the calling
|
||||
// function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALCompressedInsert( hALCompressed this_object,
|
||||
hALStorage input_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "ALCompressedInsert" );
|
||||
AL_ASSERT_OBJECT( input_object, ALStorage, "ALCompressedInsert" );
|
||||
return ( (ALCompressedObject *) this_object )->Insert( * (ALStorage *) input_object );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALCompressedExtract( hALCompressed this_object,
|
||||
// hALStorage output_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedObject
|
||||
// that is going to have a storage object extracted
|
||||
// from it.
|
||||
//
|
||||
// output_object: A handle for (pointer to) a storage object that is
|
||||
// going to receive the uncompressed object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS for success, or < AL_SUCCESS for one of many failures
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation function for the C++ function
|
||||
// ALCompressedObject::Extract(). See CMPOBJ.CPP for more details
|
||||
// on what happens in the member function.
|
||||
//
|
||||
// In the translation function, we just check the arguments for
|
||||
// correct type (in the debug version) and call the function. We
|
||||
// return the integer result of the function directly to the calling
|
||||
// function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALCompressedExtract( hALCompressed this_object,
|
||||
hALStorage output_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "ALCompressedExtract" );
|
||||
AL_ASSERT_OBJECT( output_object, ALStorage, "ALCompressedExtract" );
|
||||
return ( (ALCompressedObject *) this_object )->Extract( * (ALStorage *) output_object );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALCompressedGetStatusCode( hALCompressed this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedObject.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An integer that contains the current status code for the object.
|
||||
// Note that values of < 0 always indicate an error conditions.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALName::GetStatusCode() as implemented for objects of type
|
||||
// ALCompressedObject. For details on how the member
|
||||
// function actually works, take a look at OBJNAME.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALCompressedGetStatusCode( hALCompressed this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "ALCompressedGetStatusCode" );
|
||||
return ( (ALCompressedObject *) this_object )->mStatus.GetStatusCode();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALCompressedSetError( hALCompressed this_object,
|
||||
// int error,
|
||||
// char *text )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedObject.
|
||||
// We are going to set the object's status member
|
||||
// so that it is in an error state.
|
||||
//
|
||||
// error : The error code to apply to the object. Values from
|
||||
// ALDEFS.H are good, but it really doesn't matter as
|
||||
// long as you use a negative number.
|
||||
//
|
||||
// text : The text of the error message you want to associate with
|
||||
// this error.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Returns the error code that you passed it.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ member function
|
||||
// ALName::SetError(), as applied to an ALCompressedObject. For more
|
||||
// details on how the function actually works, check out OBJNAME.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALCompressedSetError( hALCompressed this_object,
|
||||
int error_code,
|
||||
char AL_DLL_FAR *text )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "ALCompressedSetError" );
|
||||
( (ALCompressedObject *) this_object )->mStatus.SetError( error_code, text );
|
||||
return error_code;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char *ALCompressedGetStatusString( hALCompressed this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedObject.
|
||||
// We want to get the string translation of the error
|
||||
// code for this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a pointer to a short string translation of the
|
||||
// current error code.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C wrapper function for the C++ function
|
||||
// ALName::GetStatusString(), as implemented for class ALCompressedObject.
|
||||
// Note that we need a completely different function in order to
|
||||
// return strings to VB programmers, this function is only good for C!
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
ALCompressedGetStatusString( hALCompressed this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "ALCompressedGetStatusString" );
|
||||
const char *status = ( (ALCompressedObject *) this_object )->mStatus.GetStatusString();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return (char AL_DLL_FAR *) status;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALCompressedGetStatusStringVB( hALCompressed this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedObject.
|
||||
// We want to get the string translation of the error
|
||||
// code for this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a VB handle (pointer?) to a short string translation of
|
||||
// the current error code for the ALCompressedObject.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the VB wrapper function for the C++ function
|
||||
// ALName::GetStatusString(), as implemented for class ALCompressedObject.
|
||||
// Note that we need a completely different function to return strings
|
||||
// to C programmers. In this case, we use a special VB translation routine
|
||||
// to convert a C string to one that is nice and easy for VB to use.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION ALCompressedGetStatusStringVB( hALCompressed this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "ALCompressedGetStatusStringVB" );
|
||||
const char _far *status = ( (ALCompressedObject *) this_object )->mStatus.GetStatusString();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" char *ALCompressedGetStatusDetail( hALCompressed this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedObject.
|
||||
// We want to get the detailed string describing this
|
||||
// object's current status.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a pointer to a status detail message.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C wrapper function for the C++ function
|
||||
// ALName::GetStatusDetail(), as implemented for class ALCompressedObject.
|
||||
// Note that we need a completely different function in order to
|
||||
// return strings to VB programmers.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
ALCompressedGetStatusDetail( hALCompressed this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "ALCompressedGetStatusDetail" );
|
||||
const char *status = ( (ALCompressedObject *) this_object )->mStatus.GetStatusDetail();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return (char AL_DLL_FAR *) status;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALCompressedGetStatusDetailVB( hALCompressed this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressedobject.
|
||||
// We want to get the detailed status message for
|
||||
// this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a VB handle (pointer?) to a translation of
|
||||
// the current status detail for the ALCompressedObject.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the VB wrapper function for the C++ function
|
||||
// ALName::GetStatusDetail(), as implemented for class ALCompressedObject.
|
||||
// Note that we need a completely different function to return strings
|
||||
// to C programmers. In this case, we use a special VB translation routine
|
||||
// to convert a C string to one that is nice and easy for VB to use.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION
|
||||
ALCompressedGetStatusDetailVB( hALCompressed this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressedObject, "ALCompressedGetStatusDetailVB" );
|
||||
const char _far *status = ( (ALCompressedObject *) this_object )->mStatus.GetStatusDetail();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
586
al/cxl_engn.cpp
Executable file
586
al/cxl_engn.cpp
Executable file
@ -0,0 +1,586 @@
|
||||
//
|
||||
// CXL_ENGN.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// newALCopyEngine()
|
||||
// newALGreenleafEngine()
|
||||
// ALEngineGetStatusCode()
|
||||
// ALEngineSetError()
|
||||
// ALEngineGetStatusString()
|
||||
// ALEngineGetStatusStringVB()
|
||||
// ALEngineGetStatusDetail()
|
||||
// ALEngineGetStatusDetailVB()
|
||||
// deleteALEngine()
|
||||
// ALEngineCompress()
|
||||
// ALEngineDecompress()
|
||||
// ALEngineGetTypeCode()
|
||||
// ALEngineGetTypeString()
|
||||
// ALEngineGetTypeStringVB()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all of the C/VB translation functions for all
|
||||
// of the Compression enging classes: ALEngine, ALCopyEngine, and
|
||||
// ALGreenleafEngine. You won't get much good information out of this
|
||||
// file, since there really isn't much code in the translation layer.
|
||||
// For detailed information, see CMPENGN.CPP, COPYENGN.CPP, and
|
||||
// GRENENGN.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" hALEngine newALCopyEngine( void )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) a newly create ALCopyEngine object.
|
||||
// If for some reason the constructor failed this function might
|
||||
// just return a 0.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation layer function for the C++ constructor
|
||||
// ALCopyEngine::ALCopyEngine(). It simply calls the constructor
|
||||
// and returns the resulting value. For more information on what
|
||||
// actually happens inside the constructor, see COPYENGN.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALEngine AL_FUNCTION newALCopyEngine( void )
|
||||
{
|
||||
return (hALEngine) new ALCopyEngine();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" hALEngine newALGreenleafEngine( void )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) a newly create ALGreenleafEngine object.
|
||||
// If for some reason the constructor failed this function might
|
||||
// just return a 0.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation layer function for the C++ constructor
|
||||
// ALGreenleafEngine::ALGreenleafEngine(). It simply calls the constructor
|
||||
// and returns the resulting value. For more information on what
|
||||
// actually happens inside the constructor, see GRENENGN.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALEngine AL_FUNCTION newALGreenleafEngine( int level )
|
||||
{
|
||||
return (hALEngine) new ALGreenleafEngine( (short int) level );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEngineGetStatusCode( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressionEngine object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An integer that contains the current status code for the object.
|
||||
// Note that values of < 0 always indicate an error conditions.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ function
|
||||
// ALName::GetStatusCode() as implemented for objects of type
|
||||
// ALCompressionEngine. For details on how the member
|
||||
// function actually works, take a look at OBJNAME.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALEngineGetStatusCode( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineGetStatusCode" );
|
||||
return ( (ALCompressionEngine *) this_object )->mStatus.GetStatusCode();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEngineSetError( hALEngine this_object,
|
||||
// int error,
|
||||
// char *text )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressionEngine object.
|
||||
// We are going to set the engine's status member
|
||||
// so that it is in an error state.
|
||||
//
|
||||
// error : The error code to apply to the object. Values from
|
||||
// ALDEFS.H are good, but it really doesn't matter as
|
||||
// long as you use a negative number.
|
||||
//
|
||||
// text : The text of the error message you want to associate with
|
||||
// this error.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Returns the error code that you passed it.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ member function
|
||||
// ALName::SetError(), as applied to an ALCompressionEngine object.
|
||||
// For more details on how the function actually works, check out
|
||||
// OBJNAME.CPP.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
extern "C" int AL_FUNCTION ALEngineSetError( hALEngine this_object,
|
||||
int error,
|
||||
char AL_DLL_FAR *text )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineSetError" );
|
||||
( (ALCompressionEngine *) this_object )->mStatus.SetError( error, text );
|
||||
return error;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char *ALEngineGetStatusString( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressionEngine object.
|
||||
// We want to get the string translation of the error
|
||||
// code for this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a pointer to a short string translation of the
|
||||
// current error code.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C wrapper function for the C++ function
|
||||
// ALName::GetStatusString(), as implemented for class ALCompressionEngine.
|
||||
// Note that we need a completely different function return strings
|
||||
// to VB programmers.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
ALEngineGetStatusString( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineGetStatusString" );
|
||||
const char *status = ( (ALCompressionEngine *) this_object )->mStatus.GetStatusString();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return (char AL_DLL_FAR *) status;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALEngineGetStatusStringVB( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressionEngine object.
|
||||
// We want to get the string translation of the error
|
||||
// code for this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a VB handle (pointer?) to a short string translation of
|
||||
// the current error code for the ALCompressionEngine object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the VB wrapper function for the C++ function
|
||||
// ALName::GetStatusString(), as implemented for class ALCompressionEngine.
|
||||
// Note that we need a completely different function to return strings
|
||||
// to C programmers. In this case, we use a special VB translation routine
|
||||
// to convert a C string to one that is nice and easy for VB to use.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION ALEngineGetStatusStringVB( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object , ALCompressionEngine, "ALEngineGetStatusStringVB" );
|
||||
const char _far *status = ( (ALCompressionEngine *) this_object )->mStatus.GetStatusString();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" char * ALEngineGetStatusDetail( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressionEngine object.
|
||||
// We want to get the detailed string describing this
|
||||
// object's current status.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a pointer to a status detail message.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C wrapper function for the C++ function
|
||||
// ALName::GetStatusDetail(), as implemented for class ALCompressionEngine.
|
||||
// Note that we need a completely different function to return strings
|
||||
// to VB programmers.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
ALEngineGetStatusDetail( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineGetStatusDetail" );
|
||||
const char *status = ( (ALCompressionEngine *) this_object )->mStatus.GetStatusDetail();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return (char AL_DLL_FAR *) status;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALEngineGetStatusDetailVB( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressionEngine object.
|
||||
// We want to get the detailed status message for
|
||||
// this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns a VB handle (pointer?) to a translation of
|
||||
// the current status detail for the ALCompressionEngine object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the VB wrapper function for the C++ function
|
||||
// ALName::GetStatusDetail(), as implemented for class ALCompressionEngine.
|
||||
// Note that we need a completely different function to return strings
|
||||
// to C programmers. In this case, we use a special VB translation routine
|
||||
// to convert a C string to one that is nice and easy for VB to use.
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION ALEngineGetStatusDetailVB( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineGetStatusDetailVB" );
|
||||
const char _far *status = ( (ALCompressionEngine *) this_object )->mStatus.GetStatusDetail();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" void deleteALEngine( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALCompressionEngine object.
|
||||
// We destroy it in this function.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// No returns from destructors.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function for the C++ destructor
|
||||
// ALCompressionEngine::~ALCompressionEngine()). For details
|
||||
// on what the member function actually works, take a look at
|
||||
// CMPENGN.CPP.
|
||||
//
|
||||
// Note that this destructor function is virtual, and should be called
|
||||
// to destroy any derived classes (ALCopyEngine and ALGreenleafEngine).
|
||||
//
|
||||
// All that happens here is that the arguments are checked for correct
|
||||
// type (when in debug mode), and a call is made to the appropriate
|
||||
// member function, with lots of casting.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION deleteALEngine( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "deleteALEngine" );
|
||||
delete (ALCompressionEngine *) this_object;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEngineCompress( hALEngine this_object,
|
||||
// hALStorage input,
|
||||
// hALStorage output )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an object of type
|
||||
// ALCompressionEngine. The engine contains
|
||||
// the code that will perform the compression.
|
||||
//
|
||||
// input : A handle for (pointer to) an object of type
|
||||
// ALStorage that contains the input data that will
|
||||
// be fed to the compression engine.
|
||||
//
|
||||
// output : A handle for (pointer to) an object of type
|
||||
// ALStorage that will receive the compressed output
|
||||
// from the engine.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if everything worked, code < AL_SUCCESS if not.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is the C/VB translation function for the C++ member
|
||||
// function ALCompressionEngine::Compress(). For details on what
|
||||
// this function does, you will need to look at the source code
|
||||
// in the appropriate module, such as COPYENGN.CPP or GRENENGN.CPP.
|
||||
//
|
||||
// All the wrapper function does is check the type of the arguments
|
||||
// (if in debug mode), then call the C++ member function, returning
|
||||
// the result to the calling routine.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALEngineCompress( hALEngine this_object,
|
||||
hALStorage input,
|
||||
hALStorage output )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineCompress" );
|
||||
AL_ASSERT_OBJECT( input, ALStorage, "ALEngineCompress" );
|
||||
AL_ASSERT_OBJECT( output, ALStorage, "ALEngineCompress" );
|
||||
return ( (ALCompressionEngine *) this_object )->Compress( *(ALStorage *) input, *(ALStorage *) output );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEngineDecompress( hALEngine this_object,
|
||||
// hALStorage input,
|
||||
// hALStorage output )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an object of type
|
||||
// ALCompressionEngine. The engine contains
|
||||
// the code that will perform the expansion.
|
||||
//
|
||||
// input : A handle for (pointer to) an object of type
|
||||
// ALStorage that contains a stream of compressed
|
||||
// data that was previously created using Compress().
|
||||
//
|
||||
// output : A handle for (pointer to) an object of type
|
||||
// ALStorage that will receive the plain text output
|
||||
// from the compression engine.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if everything worked, code < AL_SUCCESS if not.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is the C/VB translation function for the C++ member
|
||||
// function ALCompressionEngine::Decompress(). For details on what
|
||||
// this function does, you will need to look at the source code
|
||||
// in the appropriate module, such as COPYENGN.CPP or GRENENGN.CPP.
|
||||
//
|
||||
// All the wrapper function does is check the type of the arguments
|
||||
// (if in debug mode), then call the C++ member function, returning
|
||||
// the result to the calling routine.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEngineDecompress( hALEngine this_object,
|
||||
hALStorage input,
|
||||
hALStorage output,
|
||||
long compressed_length )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineDecompress" );
|
||||
AL_ASSERT_OBJECT( input, ALStorage, "ALEngineDecompress" );
|
||||
AL_ASSERT_OBJECT( output, ALStorage, "ALEngineDecompress" );
|
||||
return ( (ALCompressionEngine *) this_object )->Decompress( *(ALStorage *) input, *(ALStorage *) output, compressed_length );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEngineGetTypeCode( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an object of type
|
||||
// ALCompressionEngine.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The compression engine type, found in enum ALCompressionType in
|
||||
// ALDEFS.H.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is the C/VB translation function that provides access
|
||||
// to the C++ data member ALCompressionEngine::miCompressionType. Since
|
||||
// C and VB can't access the class object directly, they have to go through
|
||||
// this function as an intermediary.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALEngineGetTypeCode( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineGetTypeCode" );
|
||||
return ( (ALCompressionEngine *) this_object )->miCompressionType;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char *ALEngineGetTypeString( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an object of type
|
||||
// ALCompressionEngine.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The string describing the engine type. The description string is always
|
||||
// provided by the derived class.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is the C translation function that provides access
|
||||
// to the C++ data member ALCompressionEngine::mszCompressionType. Since
|
||||
// C can't access the class object directly, it has to go through
|
||||
// this function as an intermediary. Note that there is a special
|
||||
// function to return the compression type string to a VB program.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION ALEngineGetTypeString( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineGetTypeString" );
|
||||
return (char AL_DLL_FAR *) ( (ALCompressionEngine *) this_object )->mszCompressionType;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char *ALEngineGetTypeStringVB( hALEngine this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an object of type
|
||||
// ALCompressionEngine.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A VB string describing the engine type. The description string is
|
||||
// always provided by the derived class.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is the VB translation function that provides access
|
||||
// to the C++ data member ALCompressionEngine::mszCompressionType. Since
|
||||
// VB can't access the class object directly, it has to go through
|
||||
// this function as an intermediary. Note that this is a special
|
||||
// function that knows how to convert a standard C string to one that
|
||||
// VB likes.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION ALEngineGetTypeStringVB( hALEngine this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALCompressionEngine, "ALEngineGetTypeStringVB" );
|
||||
const char _far *status = ( (ALCompressionEngine *) this_object )->mszCompressionType;
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
704
al/cxl_entr.cpp
Executable file
704
al/cxl_entr.cpp
Executable file
@ -0,0 +1,704 @@
|
||||
//
|
||||
// CXL_ENTR.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// newALEntry()
|
||||
// deleteALEntry()
|
||||
// ALEntryDuplicate()
|
||||
// ALEntryGetNextEntry()
|
||||
// ALEntrySetMark()
|
||||
// ALEntryClearMark()
|
||||
// ALEntrySetMarkState()
|
||||
// ALEntryGetStorage()
|
||||
// ALEntrySetStorage()
|
||||
// ALEntrySetComment()
|
||||
// ALEntryGetCompressedSize()
|
||||
// ALEntryGetCrc32()
|
||||
// ALEntryGetMark()
|
||||
// ALEntryCompressionRatio()
|
||||
// ALEntryGetComment()
|
||||
// ALEntryGetCommentVB()
|
||||
// ALEntryGetEngine()
|
||||
// ALEntrySetEngine()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the C/VB translation layer for the ALEntry class.
|
||||
// These functions all provide mapping to equivalent member functions
|
||||
// or data members in class ALEntry. Since there isn't much code
|
||||
// involved in the translation, it is recommended that you look in
|
||||
// ARCENTRY.CPP for details on how the ALEntry class really works.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" hALEntry newALEntry( hALEntryList list,
|
||||
// hALStorage storage,
|
||||
// hALEngine engine )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// list : A handle for (pointer to) the ALEntryList that is
|
||||
// going get this ALEntry.
|
||||
//
|
||||
// storage : A handle for (pointer to) the storage object that is
|
||||
// being described in this ALEntry object.
|
||||
//
|
||||
// engine : A handle for (pointer to) the compression engine that
|
||||
// will be/was used to compress/expand the storage object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) a freshly constructed ALEntry object. In the
|
||||
// case of a really horrible error, this might be a 0.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB function provides a translation layer so that those two
|
||||
// languages can access the C++ constructor ALEntry::ALEntry().
|
||||
// For details on what exactly happens in the ALEntry ctor, check out
|
||||
// the source module in ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation layer functions, this guy works by simply
|
||||
// performing type checking on the arguments (in debug mode), and calling
|
||||
// the function. The result is then cast properly and returned to the
|
||||
// calling routine.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALEntry AL_FUNCTION newALEntry( hALEntryList list,
|
||||
hALStorage storage,
|
||||
hALEngine engine )
|
||||
{
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "newALEntry" );
|
||||
AL_ASSERT_OBJECT( storage, ALStorage, "newALEntry" );
|
||||
AL_ASSERT_OBJECT( engine, ALCompressionEngine, "newALEntry" );
|
||||
return (hALEntry) new ALEntry( *( (ALEntryList *) list ),
|
||||
(ALStorage * ) storage,
|
||||
(ALCompressionEngine *) engine );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void deleteALEntry( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) a valid ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB function provides a translation layer so that those two
|
||||
// languages can access the C++ destructor ALEntry::~ALEntry().
|
||||
// For details on what exactly happens in the ALEntry dtor, check out
|
||||
// the source module in ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation layer functions, this guy works by simply
|
||||
// performing type checking on the arguments (in debug mode), and calling
|
||||
// the function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION deleteALEntry( hALEntry entry )
|
||||
{
|
||||
AL_ASSERT_OBJECT( entry, ALEntry, "deleteALEntry" );
|
||||
delete (ALEntry *) entry;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryDuplicate( hALEntry this_object, hALEntryList list )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// list : A handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// 1 if the entry is duplicated somewhere in the list, 0 if not.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member function ALEntry::Duplicate(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function. The return
|
||||
// from the member function is passed right back to the calling routine.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntryDuplicate( hALEntry this_object, hALEntryList list )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryDuplicate" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALEntryDuplicate" );
|
||||
return ( (ALEntry *) this_object )->Duplicate( * (ALEntryList *) list );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// extern "C" hALEntry ALEntryGetNextEntry( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A valid handle for (pointer to) an ALEntry if there are more
|
||||
// objects in the list. If not, 0.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member function ALEntry::GetNextEntry(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function. The return
|
||||
// from the member function is passed right back to the calling routine
|
||||
// after being cast to the appropriate C/VB type.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALEntry AL_FUNCTION ALEntryGetNextEntry( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryGetNextEntry" );
|
||||
return (hALEntry) ( ((ALEntry *) this_object )->GetNextEntry() );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void ALEntrySetMark( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member function ALEntry::SetMark(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION ALEntrySetMark( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntrySetMark" );
|
||||
((ALEntry *) this_object )->SetMark();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void ALEntryClearMark( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member function ALEntry::ClearMark(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION ALEntryClearMark( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryClearMark" );
|
||||
((ALEntry *) this_object )->ClearMark();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void ALEntrySetMarkState( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member function ALEntry::SetMarkState(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION ALEntrySetMarkState( hALEntry this_object,
|
||||
short int new_state )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntrySetMarkState" );
|
||||
((ALEntry *) this_object )->SetMarkState( new_state );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" hALStorage ALEntryGetStorage( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A valid handle for (pointer to) an ALStorage object. It is possible
|
||||
// to get a return value of 0, since an ALEntry is not required to have
|
||||
// a valid ALStorage object attached to it.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ data member ALEntry::mpStorageObject. For more information on
|
||||
// what this data member actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and gets the data member. The data member
|
||||
// is passed right back to the calling routine after being cast to the
|
||||
// appropriate C/VB type.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALStorage AL_FUNCTION ALEntryGetStorage( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryGetStorage" );
|
||||
return (hALStorage) ( (ALEntry *) this_object )->mpStorageObject;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void ALEntrySetStorage( hALEntry this_object,
|
||||
// hALStorage storage )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// storage : A handle for (pointer to) an ALStorage object that
|
||||
// will now be attached to the ALEntry object. Note
|
||||
// that a value of 0 is acceptable.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ data member ALEntry::mpStorageObject. For more information on
|
||||
// what this data member actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and accesses the data member.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION ALEntrySetStorage( hALEntry this_object,
|
||||
hALStorage storage )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntrySetStorage" );
|
||||
if ( storage != 0 )
|
||||
AL_ASSERT_OBJECT( storage, ALStorage, "ALEntrySetStorage" );
|
||||
( (ALEntry *) this_object )->mpStorageObject = (ALStorage *) storage;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntrySetComment( hALEntry this_object, char *comment )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// comment : A pointer to a character string that is going to be
|
||||
// copied into the ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if things went okay, or a code < AL_SUCCESS if not.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ data member ALEntry::mpStorageObject. For more information on
|
||||
// what this data member actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and accesses the data member.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntrySetComment( hALEntry this_object, char *comment )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntrySetComment" );
|
||||
if ( comment == 0 )
|
||||
comment = "";
|
||||
return ( (ALEntry *) this_object )->SetComment( comment );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALEntryGetCompressedSize( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A long value, indicating the compressed size. Note that this information
|
||||
// will only be available after reading a directory, or performing an
|
||||
// operation that compresses the file.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member ALEntry::GetCompressedSize. For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function. The return data
|
||||
// from the member function is passed back directly to the calling module.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" long AL_FUNCTION ALEntryGetCompressedSize( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryGetCompressedSize" );
|
||||
return ( (ALEntry *) this_object )->GetCompressedSize();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALEntryGetCrc32( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A long value, indicating the object's CRC. Note that this information
|
||||
// will only be available after reading a directory, or performing an
|
||||
// operation that compresses the file.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member function ALEntry::GetCrc32(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function. The return data
|
||||
// from the member function is passed back directly to the calling module.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" long AL_FUNCTION ALEntryGetCrc32( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryGetCrc32" );
|
||||
return ( (ALEntry *) this_object )->GetCrc32();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryGetMark( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A 1 or 0, indicating the object's mark state.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member function ALEntry::GetMark(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function. The return data
|
||||
// from the member function is passed back directly to the calling module.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALEntryGetMark( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryGetMark" );
|
||||
return ( (ALEntry *) this_object )->GetMark();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryCompressionRatio( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A number usually ranging from 0 to 100. Less than 0 indicates
|
||||
// an error.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ member function ALEntry::CompressionRatio(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function. The return data
|
||||
// from the member function is passed back directly to the calling module.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALEntryCompressionRatio( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryCompressionRatio" );
|
||||
return ( (ALEntry *) this_object )->CompressionRatio();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char *ALEntryGetComment( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to a C character string. The pointer is the value of the
|
||||
// string pointer embedded in the class object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C to access the
|
||||
// C++ member function ALEntry::GetComment(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function. The return data
|
||||
// from the member function is passed back directly to the calling module.
|
||||
//
|
||||
// C strings aren't happy in VB, so there is a special function just to
|
||||
// convert strings to vB format. Don't call this function from
|
||||
// Visual Basic, there is an easier way!
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char *AL_FUNCTION ALEntryGetComment( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryGetComment" );
|
||||
return (char *) ( (ALEntry *) this_object )->GetComment();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALEntryGetCommentVB( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A Visual Basic character string. The string is a copy of the
|
||||
// string pointer embedded in the class object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for VB to access the
|
||||
// C++ member function ALEntry::GetComment(). For more information on
|
||||
// what this member function actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and calls the member function. The return data
|
||||
// from the member function is passed back directly to the calling module.
|
||||
//
|
||||
// C strings aren't happy in VB, so this function converts the C
|
||||
// character pointer to a super-special VB string.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
extern "C" long AL_FUNCTION ALEntryGetCommentVB( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryGetComment" );
|
||||
char _far *p = (char _far *) ( (ALEntry *) this_object )->GetComment();
|
||||
return ALCreateVBString( p, (unsigned short int) _fstrlen( p ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" hALEngine ALEntryGetEngine( hALEntry this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A valid handle for (pointer to) an ALCompressionEngine object. It is
|
||||
// possible to get a return value of 0, since an ALEntry is not required to
|
||||
// have a valid ALCompressionEngine object attached to it.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ data member ALEntry::mpCompressionEngine. For more information on
|
||||
// what this data member actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and gets the data member. The data member
|
||||
// is passed right back to the calling routine after being cast to the
|
||||
// appropriate C/VB type.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALEngine AL_FUNCTION ALEntryGetEngine( hALEntry this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntryGetEngine" );
|
||||
return (hALEngine) ( (ALEntry *) this_object )->mpCompressionEngine;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void ALEntrySetEngine( hALEntry this_object, hALEngine engine )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntry object.
|
||||
//
|
||||
// engine : A handle for (pointer to) an ALcompressionEngine
|
||||
// will now be attached to the ALEntry object. Note
|
||||
// that a value of 0 is acceptable.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a translation layer for C and VB to access the
|
||||
// C++ data member ALEntry::mpCompressionEngine. For more information on
|
||||
// what this data member actually does, see ARCENTRY.CPP.
|
||||
//
|
||||
// Like most of the translation functions, this routine checks the
|
||||
// arguments for correct type (in debug mode), then casts this_object
|
||||
// to the desired class, and accesses the data member.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION ALEntrySetEngine( hALEntry this_object, hALEngine engine )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntry, "ALEntrySetEngine" );
|
||||
if ( engine != 0 )
|
||||
AL_ASSERT_OBJECT( engine, ALCompressionEngine, "ALEntrySetEngine" );
|
||||
( (ALEntry *) this_object )->mpCompressionEngine = (ALCompressionEngine *) engine;
|
||||
}
|
||||
64
al/cxl_file.cpp
Executable file
64
al/cxl_file.cpp
Executable file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// CXL_FILE.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// newALFile()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the one and only source file to support
|
||||
// the C and VB translation layer for ALFile objects. Everything
|
||||
// else you might want to do with a file after constructing it is done
|
||||
// via the base class.
|
||||
//
|
||||
// If you want to learn more about ALFile, (and who wouldn't) look in
|
||||
// FILESTOR.CPP for the juicy C++ code.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" hALStorage newALFile( char *file_name )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// file_name : The name of the file to construct.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) a newly constructed ALFile object. It is
|
||||
// possible to get a 0 back if the file could not be constructed for
|
||||
// some reason.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C and VB translation function that provides access to
|
||||
// ALFile::ALFile(). It calls the constructor, then casts the result
|
||||
// to a type C will be happy with and returns it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALStorage AL_FUNCTION newALFile( char AL_DLL_FAR *file_name )
|
||||
{
|
||||
return (hALStorage) new ALFile( file_name );
|
||||
}
|
||||
|
||||
|
||||
319
al/cxl_garc.cpp
Executable file
319
al/cxl_garc.cpp
Executable file
@ -0,0 +1,319 @@
|
||||
//
|
||||
// CXL_GARC.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// newALArchive()
|
||||
// newALArchiveFromStorage()
|
||||
// ALArchiveAddFilesToList() /* OBSOLETE!!! */
|
||||
// ALEntryListAddFromDialog()
|
||||
// ALEntryListAddFromWindow()
|
||||
// ALEntryListAddWildCardFiles() /* Replacement for the obsolete fn */
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the source code for the C and VB translation
|
||||
// layer modules to support class ALArchive. The source file
|
||||
// has "GARC" because once upon a time class ALArchive was called
|
||||
// ALGreenleafArchive.
|
||||
//
|
||||
// There isn't too much to learn by looking at the translation layers, so
|
||||
// if you really want to see some exciting C++ code, check out ARCHIVE.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" hALArchive newALArchive( char *name )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// name : This constructor automatically creates an ALFile object
|
||||
// for the archive. This is the name of the ALFile object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) a newly created ALArchive, or 0 if
|
||||
// the constructor failed for some reason.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation function for the C++ constructor
|
||||
// ALArchive::ALArchive(char *). See ARCHIVE.CPP for details on what
|
||||
// happens in the constructor.
|
||||
//
|
||||
// Unlike most translation functions, this constructor doesn't have to check
|
||||
// or cast any arguments before calling its C++ code. It does however have
|
||||
// to cast the result to the correct type before giving it back to the
|
||||
// C or VB calling module.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALArchive AL_FUNCTION newALArchive( char *name )
|
||||
{
|
||||
ALArchive *archive;
|
||||
|
||||
archive = new ALArchive( name );
|
||||
return (hALArchive) archive;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" hALArchive newALArchiveFromStorage( hALStorage storage )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// storage : A handle for (pointer to) a preconstructed storage object.
|
||||
// This storage object will be where the archive keeps all of
|
||||
// its stuff. Note that you have to create and destroy this
|
||||
// storage object yourself, unlike the previous constructor.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) a newly created ALArchive, or 0 if
|
||||
// the constructor failed for some reason.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation function for the C++ constructor
|
||||
// ALArchive::ALArchive(ALStorage&). See ARCHIVE.CPP for details on what
|
||||
// happens in the constructor.
|
||||
//
|
||||
// Like most translation functions, this one checks the type off its single
|
||||
// argument (in debug mode), before casting and calling the C++ function.
|
||||
// It takes the result from the C++ constructor and casts it back to
|
||||
// correct type before giving it back to the C or VB calling module.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALArchive AL_FUNCTION newALArchiveFromStorage( hALStorage storage )
|
||||
{
|
||||
AL_ASSERT( ( (ALStorage *) storage)->GoodTag(),
|
||||
"storage argument is not a valid ALStorageObject" );
|
||||
ALArchive *archive;
|
||||
archive = new ALArchive( *(ALStorage *) storage );
|
||||
return (hALArchive) archive;
|
||||
}
|
||||
|
||||
// OBSOLETE FUNCTION
|
||||
//
|
||||
// extern "C" int ALArchiveAddFilesToList( hALArchive this_object,
|
||||
// hALEntryList list,
|
||||
// char *pattern,
|
||||
// int traverse )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) a valid ALArchive object.
|
||||
// It isn't used since we are calling a static function.
|
||||
//
|
||||
// list : A handle for (pointer to) an ALEntryList. This list
|
||||
// is going to get a bunch of new entries, like it or not.
|
||||
//
|
||||
// pattern : A list of wild-card file specs, separated by spaces,
|
||||
// commas, or semicolons.
|
||||
//
|
||||
// traverse : A flag to indicate whether the search engine should
|
||||
// traverse subdirectories when expanding file specs.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An integer indicating how many entries were added to the list.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function has been replaced by the more appropriately named
|
||||
// ALEntryListAddWildCardFiles().
|
||||
//
|
||||
// This function is the C/VB translation function to access the C++
|
||||
// member function ALArchive::AddWildCardFiles(). For details on how
|
||||
// the AddWildCardFiles() function actually works, please check out
|
||||
// ARCHIVE.CPP, cuz that is where the real code is.
|
||||
//
|
||||
// Like all the other translation routines, this guy just has to
|
||||
// check the arguments to see if they are the correct type (in debug
|
||||
// mode only), then cast and call the C++ member function. The
|
||||
// return value from the function is shot directly back to the C or
|
||||
// VB calling routine.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALArchiveAddFilesToList( hALArchive, hALEntryList list, char *pattern, int traverse )
|
||||
{
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALArchiveAddFilesToList" );
|
||||
return ALArchive::AddWildCardFiles( *( (ALEntryList *) list), pattern, traverse );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListAddFromDialog( hALEntryList this_object,
|
||||
// HWND hDlg,
|
||||
// int id )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// hDlg : Windows handle for a dialog box containing the
|
||||
// target list box.
|
||||
//
|
||||
// id : The id of the list box found in the dialog box.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries added to the list box.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C translation function that provides access to the C++
|
||||
// member function ALArchive::MakeEntriesFromListBox(). Like most of the
|
||||
// translation functions, you don't get to see much here. For detailed
|
||||
// information on what happens in the constructor, check ARCHIVE.CPP.
|
||||
//
|
||||
// You might think that this function looks like a member of ALEntryList,
|
||||
// not ALArchive. Yes, it looks like it, but in fact it is a static
|
||||
// member of ALArchive.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// You might think that this function looks like a member of ALEntryList,
|
||||
// not ALArchive. Yes, it looks like it, but in fact it is a static
|
||||
// member of ALArchive. The fact that it is static explains why there
|
||||
// is no ALArchive object in the argument list.
|
||||
//
|
||||
// You can't use this dude with VB because VB doesn't use Dialog boxes,
|
||||
// at least I don't think so.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
extern "C" int AL_FUNCTION ALEntryListAddFromDialog( hALEntryList this_object,
|
||||
HWND hDlg,
|
||||
int id )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListAddFromDialog" );
|
||||
return ALArchive::MakeEntriesFromListBox( *(ALEntryList *) this_object, hDlg, id );
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// extern "C" int ALEntryListAddFromWindow( hALEntryList this_object,
|
||||
// HWND hwnd )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// hwnd : Windows handle for a the list box control.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries added to the list box.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C translation function that provides access to the C++
|
||||
// member function ALArchive::MakeEntriesFromListBox(). Like most of the
|
||||
// translation functions, you don't get to see much here. For detailed
|
||||
// information on what happens in the constructor, check ARCHIVE.CPP.
|
||||
//
|
||||
// You might think that this function looks like a member of ALEntryList,
|
||||
// not ALArchive. Yes, it looks like it, but in fact it is a static
|
||||
// member of ALArchive. The fact that it is static explains why there
|
||||
// is no ALArchive argument in the picture.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
extern "C" int AL_FUNCTION ALEntryListAddFromWindow( hALEntryList this_object,
|
||||
HWND hwnd )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListAddFromWindow" );
|
||||
return ALArchive::MakeEntriesFromListBox( *(ALEntryList *) this_object, hwnd );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListAddWildCardFiles( hALEntryList this_object,
|
||||
// char *pattern,
|
||||
// int traverse )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntryList. This list
|
||||
// is going to get a bunch of new entries, like it or not.
|
||||
//
|
||||
// pattern : A list of wild-card file specs, separated by spaces,
|
||||
// commas, or semicolons.
|
||||
//
|
||||
// traverse : A flag to indicate whether the search engine should
|
||||
// traverse subdirectories when expanding file specs.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An integer indicating how many entries were added to the list.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is the C/VB translation function to access the C++
|
||||
// member function ALArchive::AddWildCardFiles(). For details on how
|
||||
// the AddWildCardFiles() function actually works, please check out
|
||||
// ARCHIVE.CPP, cuz that is where the real code is. You might notice
|
||||
// that there is no ALArchive object passed to this function. That
|
||||
// is because this function is a static member function of ALArchive,
|
||||
// we just need its ability to create ALFile objects.
|
||||
//
|
||||
// Like all the other translation routines, this guy just has to
|
||||
// check the arguments to see if they are the correct type (in debug
|
||||
// mode only), then cast and call the C++ member function. The
|
||||
// return value from the function is shot directly back to the C or
|
||||
// VB calling routine.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntryListAddWildCardFiles( hALEntryList this_object,
|
||||
char AL_DLL_FAR *pattern,
|
||||
int traverse )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListAddWildCardFiles" );
|
||||
return ALArchive::AddWildCardFiles( *( (ALEntryList *) this_object), pattern, traverse );
|
||||
}
|
||||
|
||||
786
al/cxl_list.cpp
Executable file
786
al/cxl_list.cpp
Executable file
@ -0,0 +1,786 @@
|
||||
//
|
||||
// CXL_LIST.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// newALEntryList()
|
||||
// ALEntryListGetFirstEntry()
|
||||
// ALEntryListUnmarkDuplicates()
|
||||
// ALEntryListSetMarksFromDialog()
|
||||
// ALEntryListSetMarksFromWindow()
|
||||
// ALEntryListFillListBoxWindow()
|
||||
// ALEntryListFillListBoxDialog()
|
||||
// deleteALEntryList()
|
||||
// ALEntryListSetMarks()
|
||||
// ALEntryListClearMarks()
|
||||
// ALEntryListDeleteUnmarked()
|
||||
// ALEntryListToggleMarks()
|
||||
// ALEntryListGetStatusCode()
|
||||
// ALEntryListGetStatusString()
|
||||
// ALEntryListGetStatusDetail()
|
||||
// ALEntryListGetStatusStringVB()
|
||||
// ALEntryListGetStatusDetailVB()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the translation layer for C and VB to the
|
||||
// ALEntryList class. The translation routines are all real short
|
||||
// functions that mostly cast things. If you want to see what is
|
||||
// going on in ALEntryList, take a look at ARCENTRY.CPP for the
|
||||
// details.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" hALEntryList newALEntryList( hALMonitor monitor )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// monitor : A handle for (pointer to) an ALMonitor object.
|
||||
// The monitor will stay attached to the list, and will
|
||||
// be used to provide feedback during all archiving operations.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) an ALEntryList object. It is possible to get
|
||||
// back a 0 if the constructor fails for lack of memory. Not likely
|
||||
// though.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// constructor ALEntryList::ALEntryList(). Like most of the translation
|
||||
// functions, you don't get to see much here. For detailed information
|
||||
// on what happens in the constructor, check ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on all the passed object
|
||||
// handles (in debug mode), then calls the constructor. The returned
|
||||
// object pointer is then cast to a C/VB compatible type and returned
|
||||
// to the calling routine.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALEntryList AL_FUNCTION newALEntryList( hALMonitor monitor )
|
||||
{
|
||||
if ( monitor != 0 )
|
||||
AL_ASSERT( ((ALMonitor *) monitor)->GoodTag(),
|
||||
"monitor argument is not a valid ALMonitor" );
|
||||
ALEntryList *list = new ALEntryList( (ALMonitor *) monitor );
|
||||
return (hALEntryList) list;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" hALEntry ALEntryListGetFirstEntry( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) an ALEntry object. If there are no
|
||||
// entries in the list you will get back a 0.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// member function ALEntryList::GetFirstEntry(). This routine is
|
||||
// the first one called when iterating through an entire list.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. The returned
|
||||
// object pointer is then cast to a C/VB compatible type and returned
|
||||
// to the calling routine.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALEntry AL_FUNCTION
|
||||
ALEntryListGetFirstEntry( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListGetFirstEntry" );
|
||||
return (hALEntry) ( ((ALEntryList *) this_object )->GetFirstEntry() );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void ALEntryListUnmarkDuplicates( hALEntryList this_object,
|
||||
// hALEntryList list,
|
||||
// char *error_message )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// list : Handle for (pointer to) another ALEntryList object.
|
||||
// (can be the same one, no problem).
|
||||
//
|
||||
// error_message : A character string giving an error message that
|
||||
// will be attached to each entry that turns out
|
||||
// to be a duplicate and gets unmarked.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// member function ALEntryList::UnmarkDuplicates(). This routine is
|
||||
// used to remove the marks from any ALEntry objects in the list that
|
||||
// are duplicated in another list.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handles (in debug mode), then calls the member function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION
|
||||
ALEntryListUnmarkDuplicates( hALEntryList this_object,
|
||||
hALEntryList list,
|
||||
char *error_message )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListUnmarkDuplicates" );
|
||||
AL_ASSERT_OBJECT( list, ALEntryList, "ALEntryListUnmarkDuplicates" );
|
||||
( (ALEntryList *) this_object )->UnmarkDuplicates( * (ALEntryList *) list, error_message );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListSetMarksFromDialog( hALEntryList this_object,
|
||||
// HWND hDlg,
|
||||
// int id )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// HDlg : Windows handle for a dialog box containing a list box
|
||||
// control.
|
||||
//
|
||||
// id : The id of the list box in the dialog. The routine
|
||||
// will set marks in the ALEntryList based on the
|
||||
// names are set in the list box.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries marked in the list box.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C translation function that provides access to the C++
|
||||
// member function ALEntryList::SetMarksFromListBox(). This function is
|
||||
// used to set marks in an ALEntryList based on selections made
|
||||
// in a list box.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// Note that since this routine looks to a dialog for its input,
|
||||
// it isn't useful to VB.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntryListSetMarksFromDialog( hALEntryList this_object, HWND hDlg, int id )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListSetMarksFromDialog" );
|
||||
return ( (ALEntryList *) this_object)->SetMarksFromListBox( hDlg, id );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListSetMarksFromWindow( hALEntryList this_object,
|
||||
// HWND hWnd )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// hWnd : Windows handle for a list box that contains names
|
||||
// that are marked.
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries marked in the list box.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// member function ALEntryList::SetMarksFromListBox(). This function is
|
||||
// called to transfer the marks a user makes in a list box into
|
||||
// the ALEntryList.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntryListSetMarksFromWindow( hALEntryList this_object, HWND hWnd )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListSetMarksFromWindow" );
|
||||
return ( (ALEntryList *) this_object )->SetMarksFromListBox( hWnd );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListFillListBoxWindow( hALEntryList this_object,
|
||||
// HWND hWnd )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// hWnd : Windows handle for a list box that is going to get
|
||||
// filled up.
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries placed in the list box.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// member function ALEntryList::SetMarksFromListBox(). This function
|
||||
// is used to transfer the selections a user made in a list box into
|
||||
// marks in the list.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntryListFillListBoxWindow( hALEntryList this_object,
|
||||
HWND hWnd )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListFillListBoxWindow" );
|
||||
return ( (ALEntryList *) this_object )->FillListBox( hWnd );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListFillListBoxDialog( hALEntryList this_object,
|
||||
// HWND hDlg,
|
||||
// int list_box_id )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// HDlg : Windows handle for a dialog box containing a list box
|
||||
// control.
|
||||
//
|
||||
// id : The id of the list box in the dialog. The routine
|
||||
// will fill up this list box with the names of all
|
||||
// the marked files in this_object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries added to the list box.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C translation function that provides access to the C++
|
||||
// member function ALEntryList::FillListBox(). This routine is called
|
||||
// to fill a list box with the names of storage objects in the list.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// Note that since this routine wants to use a list box that is
|
||||
// embedded in a dialog box, it isn't much use to VB.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntryListFillListBoxDialog( hALEntryList this_object,
|
||||
HWND hDlg,
|
||||
int list_box_id )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListFillListBoxDialog" );
|
||||
return ( (ALEntryList *) this_object )->FillListBox( hDlg, list_box_id );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" void deleteALEntryList( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None, a destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB translation routine for the ALEntryList destructor.
|
||||
// You don't see much exciting code in this routine, so if you want to
|
||||
// see exactly what is going on in the destructor, take a look at
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION deleteALEntryList( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "deleteALEntryList" );
|
||||
delete (ALEntryList *) this_object;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListSetMarks( hALEntryList this_object,
|
||||
// char *pattern )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// pattern : A regular expression (wildcard) that will be used as
|
||||
// a pattern to set marks in the list.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries marked in the list.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// member function ALEntryList::SetMarks(). This function is used
|
||||
// to set marks for ALEntry objects in the list that match the wild
|
||||
// card pattern.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALEntryListSetMarks( hALEntryList this_object,
|
||||
char AL_DLL_FAR *pattern )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListSetMarks" );
|
||||
return ( (ALEntryList *) this_object )->SetMarks( pattern );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListClearMarks( hALEntryList this_object,
|
||||
// char *pattern )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// pattern : A regular expression (wildcard) that will be used as
|
||||
// a pattern to clear marks in the list.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries cleared in the list.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// member function ALEntryList::ClearMarks(). It is used to clear
|
||||
// the marks of entries in the list that match the wildcard pattern.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALEntryListClearMarks( hALEntryList this_object,
|
||||
char AL_DLL_FAR *pattern )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListClearMarks" );
|
||||
return ( (ALEntryList *) this_object )->ClearMarks( pattern );
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListDeleteUnmarked( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries deleted from the list.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// member function ALEntryList::DeleteUnmarked(). This function is used
|
||||
// to delete ALEntry objects from the list.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntryListDeleteUnmarked( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListDeleteUnmarked" );
|
||||
return ( (ALEntryList *) this_object )->DeleteUnmarked();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListToggleMarks( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of entries whose marks were toggled.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C/VB translation function that provides access to the C++
|
||||
// member function ALEntryList::ToggleMarks(). This function is used
|
||||
// toggle the marks of *every* entry in the list.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALEntryListToggleMarks( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListToggleMarks" );
|
||||
return ( (ALEntryList *) this_object )->ToggleMarks();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" int ALEntryListGetStatusCode( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The current status integer for the ALEntryList object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is a C/VB translation function that provides access to the C++
|
||||
// member function ALStatus::GetStatusCode(), for the mStatus data
|
||||
// member for the ALEntryList object.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// returns the status integer unchanged to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION
|
||||
ALEntryListGetStatusCode( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListGetStatusCode" );
|
||||
return ( (ALEntryList *) this_object )->mStatus.GetStatusCode();
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char * ALEntryListGetStatusString( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The current status string translation for the ALEntryList object.
|
||||
//
|
||||
// Note that this return type is just not very good for VB people.
|
||||
// They should use the VB specific function to get a real VB string
|
||||
// back.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C translation function that provides access to the C++
|
||||
// member function ALStatus::GetStatusString(), for the mStatus data
|
||||
// member for the ALEntryList object. This is the short string
|
||||
// translation, not the status detail.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// then casts and returns the status string.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
ALEntryListGetStatusString( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListGetStatusString" );
|
||||
const char *status = ( (ALEntryList *) this_object)->mStatus.GetStatusString();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return (char AL_DLL_FAR *) status;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" char * ALEntryListGetStatusDetail( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The current status string detail for the ALEntryList object.
|
||||
//
|
||||
// Note that this return type is just not very good for VB people.
|
||||
// They should use the VB specific function to get a real VB string
|
||||
// back.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is C translation function that provides access to the C++
|
||||
// member function ALStatus::GetStatusDetail(), for the mStatus data
|
||||
// member for the ALEntryList object. This is the detailed message,
|
||||
// not to be confused with the short translation.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// then casts and returns the status string.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
ALEntryListGetStatusDetail( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListGetStatusString" );
|
||||
const char *status = ( (ALEntryList *) this_object )->mStatus.GetStatusDetail();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return (char AL_DLL_FAR *) status;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALEntryListGetStatusStringVB( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The current status string translation for the ALEntryList object.
|
||||
//
|
||||
// Note that this function performs a translation of the string type to
|
||||
// a VB string. It won't do you much good to call this from a C program.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is VB translation function that provides access to the C++
|
||||
// member function ALStatus::GetStatusString(), for the mStatus data
|
||||
// member for the ALEntryList object. This is the short string
|
||||
// translation, not the status detail.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// then converts and returns the status string.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
|
||||
extern "C" long AL_FUNCTION
|
||||
ALEntryListGetStatusStringVB( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryLisGetStatusStringVB" );
|
||||
const char _far *status = ( (ALEntryList *) this_object )->mStatus.GetStatusString();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// extern "C" long ALEntryListGetStatusDetailVB( hALEntryList this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : Handle for (pointer to) an ALEntryList object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The current status detail string for the ALEntryList object.
|
||||
//
|
||||
// Note that this function performs a translation of the string type to
|
||||
// a VB string. It won't do you much good to call this from a C program.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is VB translation function that provides access to the C++
|
||||
// member function ALStatus::GetStatusDetail(), for the mStatus data
|
||||
// member for the ALEntryList object. This is the detailed status
|
||||
// string, not the short status translation.
|
||||
//
|
||||
// Like most of the translation functions, you don't get to see much here.
|
||||
// For detailed information on what happens in the member function, check
|
||||
// ARCENTRY.CPP.
|
||||
//
|
||||
// This routine first performs type checking on the passed object
|
||||
// handle (in debug mode), then calls the member function. It
|
||||
// then converts and returns the status string.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
|
||||
extern "C" long AL_FUNCTION
|
||||
ALEntryListGetStatusDetailVB( hALEntryList this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALEntryList, "ALEntryListGetStatusDetailVB" );
|
||||
const char _far *status = ( (ALEntryList *) this_object )->mStatus.GetStatusDetail();
|
||||
if ( status == 0 )
|
||||
status = "";
|
||||
return ALCreateVBString( status, (unsigned short int) _fstrlen( status ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
348
al/cxl_mem.cpp
Executable file
348
al/cxl_mem.cpp
Executable file
@ -0,0 +1,348 @@
|
||||
//
|
||||
// CXL_MEM.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// newALMemory()
|
||||
// ALMemoryGetBufferOwner()
|
||||
// ALMemorySetBufferOwner()
|
||||
// ALMemoryGetHandle()
|
||||
// ALMemoryGetBufferSize()
|
||||
// ALMemoryGetBuffer()
|
||||
//
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the C and VB translation routines to access
|
||||
// class ALMemory. Most of the ALStorage routines need to be called
|
||||
// via the base class, so most of the functions to use ALMemory
|
||||
// from C or VB will be found in CXL_STOR.CPP.
|
||||
//
|
||||
// As always, these translation routines are extremely uninformative.
|
||||
// To get the real lowdown on what is happening, look first at the C++
|
||||
// member functions in MEMSTORE.CPP, then STORAGE.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
// Windows:
|
||||
//
|
||||
// extern "C" hALStorage newALMemory( char *buffer_name,
|
||||
// char AL_HUGE *user_buffer,
|
||||
// DWORD user_buffer_size )
|
||||
//
|
||||
// MS-DOS:
|
||||
//
|
||||
// extern "C" hALStorage newALMemory( char *buffer_name,
|
||||
// char *user_buffer,
|
||||
// int user_buffer_size )
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// name : A character string containing an arbitrary name
|
||||
// name for the memory buffer.
|
||||
//
|
||||
// user_buffer : If you want to supply a buffer of your own, pass it
|
||||
// here. Otherwise, set it to 0, and the ALMemory
|
||||
// class will allocate storage as needed.
|
||||
//
|
||||
// user_buffer_size : If you are supplying a buffer, you have to say how
|
||||
// long it is.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A handle for (pointer to) a newly created ALMemory object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the ALMemory
|
||||
// constructor. Note that the constructor has the same name under
|
||||
// MS-DOS and Windows, but it does have slightly different capabilities.
|
||||
// Because of this, the Windows version also has different argument types.
|
||||
//
|
||||
// This function passes all of its arguments to the C++ constructor
|
||||
// in unchanged form. It then takes the return from the function, casts
|
||||
// it to a C/VB acceptable type, and returns it otherwise unchanged.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real information about what
|
||||
// is happening in the constructor, take a look at the source for the
|
||||
// C++ functions in MEMSTORE.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
extern "C" hALStorage AL_FUNCTION
|
||||
newALMemory( char AL_DLL_FAR *buffer_name,
|
||||
char AL_HUGE *user_buffer,
|
||||
DWORD user_buffer_size )
|
||||
{
|
||||
if ( user_buffer_size == 0 )
|
||||
return (hALStorage) new ALMemory( buffer_name );
|
||||
else
|
||||
return (hALStorage) new ALMemory( buffer_name, user_buffer, user_buffer_size );
|
||||
}
|
||||
|
||||
#else
|
||||
extern "C" hALStorage AL_FUNCTION newALMemory( char AL_DLL_FAR *buffer_name,
|
||||
char AL_DLL_FAR *user_buffer,
|
||||
int user_buffer_size )
|
||||
{
|
||||
if ( user_buffer_size == 0 )
|
||||
return (hALStorage) new ALMemory( buffer_name );
|
||||
else
|
||||
return (hALStorage) new ALMemory( buffer_name, user_buffer, user_buffer_size );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" int ALMemoryGetBufferOwner( hALStorage this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALMemory object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An integer flag indicating whether the user owns the buffer.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMemory::mfUserOwnsBuffer.
|
||||
//
|
||||
// This function first tests its only argument for correct type (when in
|
||||
// debug mode), then casts and accesses the data member. The value of
|
||||
// the data member is then returned unchanged to the calling C or VB
|
||||
// procedure.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real information about what
|
||||
// is happening in the constructor, take a look at the source for the
|
||||
// C++ functions in MEMSTORE.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" int AL_FUNCTION ALMemoryGetBufferOwner( hALStorage this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMemory, "ALMemoryGetBufferOwner" );
|
||||
return ( (ALMemory *) this_object )->mfUserOwnsBuffer;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void ALMemorySetBufferOwner( hALStorage this_object,
|
||||
// int user_owns_buffer )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALMemory object.
|
||||
//
|
||||
// user_owns_buffer : The new setting of the flag.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMemory::mfUserOwnsBuffer. Why would you want to change this
|
||||
// data member? Well, if the ALMemory object is currently the buffer
|
||||
// owner, the buffer will be deleted when the ALMemory object is destroyed.
|
||||
// You can set the owner of the buffer to be you, the user, and copy
|
||||
// the pointer to it. Then you get to keep it long after the ALMemory
|
||||
// object is done with it.
|
||||
//
|
||||
// This function first tests its only argument for correct type (when in
|
||||
// debug mode), then casts and modifies the data member.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real information about what
|
||||
// is happening in the constructor, take a look at the source for the
|
||||
// C++ functions in MEMSTORE.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION ALMemorySetBufferOwner( hALStorage this_object,
|
||||
int user_owns_buffer )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMemory, "ALMemorySetBufferOwner" );
|
||||
( (ALMemory *) this_object )->mfUserOwnsBuffer = user_owns_buffer;
|
||||
}
|
||||
|
||||
// WINDOWS ONLY PROCEDURE
|
||||
//
|
||||
// extern "C" UINT ALMemoryGetHandle( hALStorage this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALMemory object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A UINT windows memory handle.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMemory::mhUserMemoryHandle. Under C++, this is a public data
|
||||
// member that the programmer is free to access or modify.
|
||||
//
|
||||
// This function first tests its only argument for correct type (when in
|
||||
// debug mode), then casts and accesses the data member. The value of
|
||||
// the data member is then returned unchanged to the calling C or VB
|
||||
// procedure.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real information about what
|
||||
// is happening in the constructor, take a look at the source for the
|
||||
// C++ functions in MEMSTORE.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
extern "C" UINT AL_FUNCTION ALMemoryGetHandle( hALStorage this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMemory, "ALMemorySetBufferOwner" );
|
||||
return (UINT) ( (ALMemory *) this_object )->mhUserMemoryHandle;
|
||||
}
|
||||
#endif
|
||||
|
||||
// WINDOWS Version
|
||||
//
|
||||
// extern "C" long ALMemoryGetBufferSize( hALStorage this_object )
|
||||
//
|
||||
// MS-DOS Real Mode version
|
||||
//
|
||||
// extern "C" size_t ALMemoryGetBufferSize( hALStorage this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALMemory object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The size of the memory buffer being uses as a storage object. The
|
||||
// type of the the size differs between Windows and Real mode DOS, simply
|
||||
// because Windows can access a lot more memory, especially when
|
||||
// using Win32s.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMemory::muUserBufferSize. Under C++, this is a public data
|
||||
// member that the programmer is free to access or modify.
|
||||
//
|
||||
// This function first tests its only argument for correct type (when in
|
||||
// debug mode), then casts and accesses the data member. The value of
|
||||
// the data member is then returned unchanged to the calling C or VB
|
||||
// procedure.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real information about what
|
||||
// is happening in the constructor, take a look at the source for the
|
||||
// C++ functions in MEMSTORE.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
extern "C" long AL_FUNCTION ALMemoryGetBufferSize( hALStorage this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMemory, "ALMemoryGetBufferSize" );
|
||||
return ( (ALMemory *) this_object )->muUserBufferSize;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extern "C" size_t AL_FUNCTION ALMemoryGetBufferSize( hALStorage this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMemory, "ALMemoryGetBufferSize" );
|
||||
return ( (ALMemory *) this_object )->muUserBufferSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
// WINDOWS Version
|
||||
//
|
||||
// extern "C" char AL_HUGE * ALMemoryGetBuffer( hALStorage this_object )
|
||||
//
|
||||
// MS-DOS Real Mode version
|
||||
//
|
||||
// extern "C" char *ALMemoryGetBuffer( hALStorage this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALMemory object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the memory buffer being uses as a storage object. The
|
||||
// type of the the pointer differs between the various modes of our
|
||||
// library. Under Real Dos, it is just a normal pointer. Under Win16
|
||||
// it is a _huge pointer. Under Win32s, it is a flat model pointer.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMemory::mpcUserBuffer. Under C++, this is a public data
|
||||
// member that the programmer is free to access or modify.
|
||||
//
|
||||
// This function first tests its only argument for correct type (when in
|
||||
// debug mode), then casts and accesses the data member. The value of
|
||||
// the data member is then returned unchanged to the calling C or VB
|
||||
// procedure.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real information about what
|
||||
// is happening in the constructor, take a look at the source for the
|
||||
// C++ functions in MEMSTORE.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
extern "C" char AL_HUGE * AL_FUNCTION ALMemoryGetBuffer( hALStorage this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMemory, "ALMemoryGetBuffer" );
|
||||
return ( (ALMemory *) this_object )->mpcUserBuffer;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extern "C" char AL_DLL_FAR *AL_FUNCTION ALMemoryGetBuffer( hALStorage this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMemory, "ALMemoryGetBuffer" );
|
||||
return ( (ALMemory *) this_object )->mpcUserBuffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
246
al/cxl_mon.cpp
Executable file
246
al/cxl_mon.cpp
Executable file
@ -0,0 +1,246 @@
|
||||
//
|
||||
// CXL_MON.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALMonitorSetObjectSize()
|
||||
// ALMonitorSetObjectStart()
|
||||
// ALMonitorSetJobSize()
|
||||
// ALMonitorSetJobSoFar()
|
||||
// deleteALMonitor()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains a few access routines
|
||||
// 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 25, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" long ALMonitorSetObjectSize( hALMonitor this_object,
|
||||
// long size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : The monitor whose object size member needs to be set.
|
||||
//
|
||||
// size : The new value to be assigned to mlObjectSize.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The long size value.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMonitor::mlObjectSize. Why would you want to change this
|
||||
// data member? Normally this data member is set up by the member functions
|
||||
// of ALArchiveBase before performing an operation. If you are trying
|
||||
// to use a monitor to provide feedback on an operation of your own,
|
||||
// such as a file copy, you would have to set the data member up
|
||||
// using this function.
|
||||
//
|
||||
// This function first tests its handle argument for correct type (when in
|
||||
// debug mode), then casts and modifies the data member.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real scoop on monitor objects,
|
||||
// look at MONITOR.CPP and ARCHIVEB.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" long AL_FUNCTION ALMonitorSetObjectSize( hALMonitor this_object,
|
||||
long size )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMonitor, "ALMonitorSetObjectSize" );
|
||||
return ( (ALMonitor *) this_object )->mlObjectSize = size;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALMonitorSetObjectStart( hALMonitor this_object,
|
||||
// long offset )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : The monitor whose object start member needs to be set.
|
||||
//
|
||||
// offset : The new value to be assigned to mlObjectStart.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The long offset value.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMonitor::mlObjectStart. Why would you want to change this
|
||||
// data member? Normally this data member is set up by the member functions
|
||||
// of ALArchiveBase before performing an operation. If you are trying
|
||||
// to use a monitor to provide feedback on an operation of your own,
|
||||
// such as a file copy, you would have to set the data member up
|
||||
// using this function.
|
||||
//
|
||||
// This function first tests its handle argument for correct type (when in
|
||||
// debug mode), then casts and modifies the data member.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real scoop on monitor objects,
|
||||
// look at MONITOR.CPP and ARCHIVEB.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" long AL_FUNCTION ALMonitorSetObjectStart( hALMonitor this_object,
|
||||
long offset )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMonitor, "ALMonitorSetObjectStart" );
|
||||
return ( (ALMonitor *) this_object )->mlObjectStart = offset;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALMonitorSetJobSize( hALMonitor this_object,
|
||||
// long size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : The monitor whose job size member needs to be set.
|
||||
//
|
||||
// size : The new value to be assigned to mlJobSize.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The long size value.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMonitor::mlJobSize. Why would you want to change this
|
||||
// data member? Normally this data member is set up by the member functions
|
||||
// of ALArchiveBase before performing an operation. If you are trying
|
||||
// to use a monitor to provide feedback on an operation of your own,
|
||||
// such as a batch file copy, you would have to set the data member up
|
||||
// using this function.
|
||||
//
|
||||
// This function first tests its handle argument for correct type (when in
|
||||
// debug mode), then casts and modifies the data member.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real scoop on monitor objects,
|
||||
// look at MONITOR.CPP and ARCHIVEB.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" long AL_FUNCTION ALMonitorSetJobSize( hALMonitor this_object,
|
||||
long size )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMonitor, "ALMonitorSetJobSize" );
|
||||
return ( (ALMonitor *) this_object )->mlJobSize = size;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" long ALMonitorSetJobSoFar( hALMonitor this_object,
|
||||
// long job_so_far )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : The monitor whose "job so far" member needs to be set.
|
||||
//
|
||||
// job_so_far : The new value to be assigned to mlJobSoFar.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The new value of mlJobSoFar.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This C/VB translation function provides access to the C++ data member
|
||||
// ALMonitor::mlJobSoFar. Why would you want to change this
|
||||
// data member? Normally this data member is set up by the member functions
|
||||
// of ALArchiveBase before performing an operation. If you are trying
|
||||
// to use a monitor to provide feedback on an operation of your own,
|
||||
// such as a batch file copy, you would have to set the data member up
|
||||
// using this function.
|
||||
//
|
||||
// This function first tests its handle argument for correct type (when in
|
||||
// debug mode), then casts and modifies the data member.
|
||||
//
|
||||
// This function is like all of the other translation routines in that
|
||||
// it is fairly uninformative. To get the real scoop on monitor objects,
|
||||
// look at MONITOR.CPP and ARCHIVEB.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" long AL_FUNCTION ALMonitorSetJobSoFar( hALMonitor this_object,
|
||||
long job_so_far )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMonitor, "ALMonitorSetJobSoFar" );
|
||||
return ( (ALMonitor *) this_object )->mlJobSoFar = job_so_far;
|
||||
}
|
||||
|
||||
//
|
||||
// extern "C" void deleteALMonitor( hALMonitor this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : The monitor object to be destroyed. This will usually
|
||||
// be an object from a derived class, not the base class.
|
||||
// The dtor is virtual, so we always call the base
|
||||
// class destructor using this function.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// No returns, this is a destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the C/VB wrapper function that calls the destructor for an
|
||||
// ALMonitor object. This is a virtual destructor, so you won't find
|
||||
// equivalent functions defined for the base classes used with
|
||||
// ArchiveLib.
|
||||
//
|
||||
// This function just checks its single argument for correct type, then
|
||||
// casts it and calls the destructor.
|
||||
//
|
||||
// Like most of these wrapper functions, this is fairly unenlightening.
|
||||
// For more real dirt, try looking at the base class dtor in MONITOR.CPP,
|
||||
// or derived class dtors in BARGRAPH.CPP and WINMON.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION deleteALMonitor( hALMonitor this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALMonitor, "deleteALMonitor" );
|
||||
delete (ALMonitor *) this_object;
|
||||
}
|
||||
|
||||
2432
al/cxl_sobj.cpp
Executable file
2432
al/cxl_sobj.cpp
Executable file
File diff suppressed because it is too large
Load Diff
153
al/cxl_util.cpp
Executable file
153
al/cxl_util.cpp
Executable file
@ -0,0 +1,153 @@
|
||||
//
|
||||
// CXL_UTIL.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// StripFileName()
|
||||
// StripFileNameVB()
|
||||
// StripPath()
|
||||
// StripPathVB()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains a couple of C/VB functions that are used to
|
||||
// mangle file names. They defied ordinary categorization, so they
|
||||
// ended up here. The deal is that they operate on objects of class
|
||||
// ALName, but there is no C/VB translation for ALName. Because of
|
||||
// this, we provide these versions that return native string types.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
// C TRANSLATION FUNCTION
|
||||
//
|
||||
// extern "C" char * StripFileName( char *filename )
|
||||
//
|
||||
// VB TRANSLATION FUNCTION
|
||||
//
|
||||
// extern "C" long StripFileNameVB( char *filename )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// filename : An ordinary VB or C string that contains a file name.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Either a C or VB string type, containing just the path. Note that
|
||||
// the C version of the function copies over your existing string,
|
||||
// whereas the VB version creates a new VB string.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function takes a file name, and strips off any filename and
|
||||
// extension, leaving the drive and path name. These functions are
|
||||
// very handy when it comes to wild card expansion, which is why
|
||||
// they are in ArchiveLib.
|
||||
//
|
||||
// If you want to see how the C++ member functions perform these
|
||||
// amazing feats, see OBJNAME.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
//
|
||||
// The C translation function.
|
||||
//
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
StripFileName( char AL_DLL_FAR *filename )
|
||||
{
|
||||
ALName temp = filename;
|
||||
temp.StripFileName();
|
||||
strcpy( filename, temp );
|
||||
return filename;
|
||||
}
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
|
||||
//
|
||||
// The VB translation function.
|
||||
//
|
||||
extern "C" long AL_FUNCTION StripFileNameVB( char AL_DLL_FAR *filename )
|
||||
{
|
||||
ALName temp = filename;
|
||||
char _far *p = temp.StripFileName();
|
||||
return ALCreateVBString( p, (unsigned short int) _fstrlen( p ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// C TRANSLATION FUNCTION
|
||||
//
|
||||
// extern "C" char * StripPath( char *filename )
|
||||
//
|
||||
// VB TRANSLATION FUNCTION
|
||||
//
|
||||
// extern "C" long StripPathVB( char *filename )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// filename : An ordinary VB or C string that contains a file name.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Either a C or VB string type, with the drive and path stripped,
|
||||
// leaving just a filename and extension. Note that
|
||||
// the C version of the function copies over your existing string,
|
||||
// whereas the VB version creates a new VB string.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function takes a file name, and strips off any path and drive
|
||||
// information, leaving the file and extension. These functions are
|
||||
// very handy when it comes to wild card expansion, which is why
|
||||
// they are in ArchiveLib.
|
||||
//
|
||||
// If you want to see how the C++ member functions perform these
|
||||
// amazing feats, see OBJNAME.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
//
|
||||
// The C translation function.
|
||||
//
|
||||
extern "C" char AL_DLL_FAR * AL_FUNCTION
|
||||
StripPath( char AL_DLL_FAR *filename )
|
||||
{
|
||||
ALName temp = filename;
|
||||
temp.StripPath();
|
||||
strcpy( filename, temp );
|
||||
return filename;
|
||||
}
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
//
|
||||
// The VB translation function
|
||||
//
|
||||
extern "C" long AL_FUNCTION StripPathVB( char AL_DLL_FAR *filename )
|
||||
{
|
||||
ALName temp = filename;
|
||||
char _far *p = temp.StripPath();
|
||||
return ALCreateVBString( p, (unsigned short int) _fstrlen( p ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
184
al/cxl_wild.cpp
Executable file
184
al/cxl_wild.cpp
Executable file
@ -0,0 +1,184 @@
|
||||
//
|
||||
// CXL_UTIL.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// newALExpander()
|
||||
// ALExpanderGetNextFile()
|
||||
// ALExpanderGetNextFileVB()
|
||||
// deleteALExpander()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the C and VB interface functions for using
|
||||
// the ALWildCardExpander class. This consists of only a
|
||||
// constructor, destructor, and a Get Next File function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "al.h"
|
||||
#include "alcxl.h"
|
||||
|
||||
//
|
||||
// extern "C" hALExpander newALExpander( char *wild_spec,
|
||||
// int traverse_flag,
|
||||
// ALCase name_case )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// wild_spec : A sequence of wild card file specifications separated
|
||||
// by spaces or semicolons.
|
||||
//
|
||||
// traverse_flag : set this guy if you want the wild card expansion
|
||||
// to traverse all subdirectories.
|
||||
//
|
||||
// name_case : How the names will be returned, AL_UPPER, AL_MIXED,
|
||||
// or AL_LOWER.
|
||||
//
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Returns a handle for (pointer to) a newly constructed
|
||||
// ALWildCardExpander object.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This ctor is used to create a new ALWildCardExpander object from
|
||||
// C or VB. It operates identically to the wild card expander
|
||||
// constructors defined in WILDCARD.CPP.
|
||||
//
|
||||
// You don't get to see much of the wild card expander code in this
|
||||
// module, since this is just a translation layer. Look at WILDCARD.CPP
|
||||
// for lots of neat stuff.
|
||||
//
|
||||
// This function passes the arguments it receives to the constructor
|
||||
// with no changes. It then casts the return value to the appropriate
|
||||
// handle type, and returns it to the calling procedure.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" hALExpander AL_FUNCTION newALExpander( char *wild_spec,
|
||||
int recurse_flag,
|
||||
ALCase name_case )
|
||||
{
|
||||
ALWildCardExpander *expander;
|
||||
|
||||
expander = new ALWildCardExpander( wild_spec, recurse_flag, name_case );
|
||||
return (hALExpander) expander;
|
||||
}
|
||||
|
||||
// C TRANSLATION FUNCTION
|
||||
//
|
||||
// extern "C" char * ALExpanderGetNextFile( hALExpander this_object )
|
||||
//
|
||||
// VB TRANSLATION FUNCTION
|
||||
//
|
||||
// extern "C" long ALExpanderGetNextFileVB( hALExpander this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALWildCardExpander
|
||||
// object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A string containing the next expanded wild card generated by
|
||||
// the wild card engine. Note that under C, you will get a pointer
|
||||
// to a string that is residing inside the ALWildCardExpander
|
||||
// object, which you are free to copy or duplicate. The VB translation
|
||||
// function actually creates a new string using the ALCreateVBString
|
||||
// function.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a C or VB translation layer that allows you to
|
||||
// access the ALWildCardExpander::GetNextFile() function. The function
|
||||
// operators by first checking the single handle argument for correct
|
||||
// type (in debug mode). It then casts the handle to an object pointer,
|
||||
// and uses that to invoke the member function. Under C, the return from
|
||||
// the member function is passed directly back to the calling routine.
|
||||
// Under VB, the return is first converted to a Visual Basic string, then
|
||||
// returned.
|
||||
//
|
||||
// To see the details of ALWildCardExpander::GetNextFile(), look at
|
||||
// WILDCARD.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
//
|
||||
// The C translation layer.
|
||||
//
|
||||
extern "C" char * AL_FUNCTION
|
||||
ALExpanderGetNextFile( hALExpander this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALWildCardExpander, "ALExpanderGetNextFile" );
|
||||
return ( (ALWildCardExpander *) this_object )->GetNextFile();
|
||||
}
|
||||
|
||||
#if defined( AL_BUILDING_DLL ) && defined( AL_WINDOWS_GUI ) && !defined( AL_FLAT_MODEL )
|
||||
//
|
||||
// VB translation layer.
|
||||
//
|
||||
extern "C" long AL_FUNCTION
|
||||
ALExpanderGetNextFileVB( hALExpander this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALWildCardExpander, "ALExpanderGetNextFileVB" );
|
||||
char _far *ret_guy = ( (ALWildCardExpander *) this_object )->GetNextFile();
|
||||
if ( ret_guy == 0 )
|
||||
ret_guy = "";
|
||||
return ALCreateVBString( ret_guy, (unsigned short int) _fstrlen( ret_guy ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// extern "C" void deleteALExpander( hALExpander this_object )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// this_object : A handle for (pointer to) an ALWildCardExpander
|
||||
// object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a C or VB translation layer that allows you to
|
||||
// access the ALWildCardExpander destructor. The function works
|
||||
// by first checking the single handle argument for correct
|
||||
// type (in debug mode). It then casts the handle to an object pointer,
|
||||
// and uses that to invoke the destructor.
|
||||
//
|
||||
// To see the details of the ALWildCardExpander destructor, look at
|
||||
// WILDCARD.CPP.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
extern "C" void AL_FUNCTION deleteALExpander( hALExpander this_object )
|
||||
{
|
||||
AL_ASSERT_OBJECT( this_object, ALWildCardExpander, "deleteALExpander" );
|
||||
delete (ALWildCardExpander *) this_object;
|
||||
}
|
||||
|
||||
363
al/fileattr.cpp
Executable file
363
al/fileattr.cpp
Executable file
@ -0,0 +1,363 @@
|
||||
//
|
||||
// FILEATTR.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALFileAttributes::operator new()
|
||||
// ALFileAttributes::ALFileAttributes()
|
||||
// ALFileAttributes::~ALFileAttributes()
|
||||
// ALFileAttributes::SetFromPackedAttributes()
|
||||
// ALFileAttributes::SetFromWin32Attributes()
|
||||
// ALFileAttributes::SetFromDosAttributes()
|
||||
// ALFileAttributes::PackedAttributes()
|
||||
// ALFileAttributes::GetDosAttributes()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all of the source to support the ALFileAttributes
|
||||
// class. Even though this is in theory a standalone, independent class,
|
||||
// it really has not life of its own. It always exists as a data
|
||||
// member embedded in ALStorage. The only reason these functions aren't
|
||||
// member functions of ALStorage was simply to modularize things a bit.
|
||||
// As it is, it makes pretty good sense as a class of its own.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <dos.h>
|
||||
|
||||
#include "fileattr.h"
|
||||
|
||||
//
|
||||
// void * ALFileAttributes::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The amount of storage that needs to be allocated for
|
||||
// this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the storage.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When using the DLL version of ArchiveLib, it is a good idea to
|
||||
// allocate the storage for objects from inside the DLL, since they
|
||||
// will be freed inside the DLL. If we don't have the new operator
|
||||
// for a class, its storage will be allocated from the EXE before
|
||||
// the constructor code is called. Then, when it is time to free
|
||||
// the storage, the delete operator will be called inside the DLL.
|
||||
// Not good, right?
|
||||
//
|
||||
// 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 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALFileAttributes::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALFileAttributes::ALFileAttributes()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Constructor, no return.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the only constructor for class ALFileAttributes. It does
|
||||
// nothing more than set all of the bits to 0. I was thinking that
|
||||
// it might be a good idea to set them to -1 instead, indicating that
|
||||
// they are presently in an unknown state. I would want to set them
|
||||
// to 0 when I called Create(), and read them in when I call Open().
|
||||
// Just thinking out loud.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALFileAttributes::ALFileAttributes()
|
||||
{
|
||||
miReadOnly = 0;
|
||||
miSystem = 0;
|
||||
miHidden = 0;
|
||||
miArchive = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ALFileAttributes::~ALFileAttributes()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Destructor, no returns.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The destructor doesn't have to worry about freeing any dynamic
|
||||
// storage or anything like that, so it gets to do a great big nothing.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALFileAttributes::~ALFileAttributes()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// void ALFileAttributes::SetFromPackedAttributes( short int attributes )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// attributes : A set of attributes that have been packed into a
|
||||
// short int using our internal bit ordering:
|
||||
//
|
||||
// X | X | X | X | A | H | S | R
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, a void function.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The packed format is how we actually store file attributes in an
|
||||
// archive. When we read in the directory from an archive, we can
|
||||
// use this function to apply the packed attribute bits to a storage
|
||||
// object. All it has to do is set the four bits internal to the
|
||||
// class.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALFileAttributes::
|
||||
SetFromPackedAttributes( short int attributes )
|
||||
{
|
||||
miReadOnly = ( attributes & 1 ) != 0;
|
||||
miSystem = ( attributes & 2 ) != 0;
|
||||
miHidden = ( attributes & 4 ) != 0;
|
||||
miArchive = ( attributes & 8 ) != 0;
|
||||
}
|
||||
|
||||
//
|
||||
// void ALFileAttributes::SetFromWin32Attributes( DWORD win32_attributes )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// attributes : The set of file attributes as defined for Win32s.
|
||||
// These are the attributes you get back from the
|
||||
// GetFileAttributes() function call.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, a void function.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When the ALFile class opens a file under Win32s, it reads in
|
||||
// the file attributes with a call to GetFileAttributes. It can then store
|
||||
// those file attributes in the ALFileAttributes member of ALStorage
|
||||
// by calling this function.
|
||||
//
|
||||
// Converting the data to our internal format is simply a matter of picking
|
||||
// bits out of a DWORD.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WIN32S )
|
||||
|
||||
void AL_PROTO ALFileAttributes::
|
||||
SetFromWin32Attributes( DWORD win32_attributes )
|
||||
{
|
||||
miReadOnly = ( win32_attributes & FILE_ATTRIBUTE_READONLY ) != 0;
|
||||
miSystem = ( win32_attributes & FILE_ATTRIBUTE_SYSTEM ) != 0;
|
||||
miHidden = ( win32_attributes & FILE_ATTRIBUTE_HIDDEN ) != 0;
|
||||
miArchive = ( win32_attributes & FILE_ATTRIBUTE_ARCHIVE ) != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// void ALFileAttributes::SetFromDosAttributes( unsigned dos_attributes )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// attributes : The set of file attributes as defined for MS-DOS.
|
||||
// These are the attributes you get back from the
|
||||
// _dos_getfileattr() function call.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, a void function.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When the ALFile class opens a file under MS-DOS or Windows, it reads in
|
||||
// the file attributes with a call to _dos_getfileattr(). It can then store
|
||||
// those file attributes in the ALFileAttributes member of ALStorage
|
||||
// by calling this function.
|
||||
//
|
||||
// Converting the data to our internal format is simply a matter of picking
|
||||
// bits out of an unsigned int
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if !defined( AL_WIN32S )
|
||||
|
||||
void AL_PROTO ALFileAttributes::SetFromDosAttributes( unsigned dos_attributes )
|
||||
{
|
||||
miReadOnly = ( dos_attributes & _A_RDONLY ) != 0;
|
||||
miSystem = ( dos_attributes & _A_SYSTEM ) != 0;
|
||||
miHidden = ( dos_attributes & _A_HIDDEN ) != 0;
|
||||
miArchive = ( dos_attributes & _A_ARCH ) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// unsigned short int ALFileAttributes::PackedAttributes()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An unsigned short int containing the four file attribute bits, packed
|
||||
// into the format we use to store file attributes in an archive:
|
||||
//
|
||||
//
|
||||
// X | X | X | X | A | H | S | R
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When it comes time to write an archive directory out to disk, we need
|
||||
// to store the file attributes in a consistent format. This format
|
||||
// is our internal packed attribute format. You can get the file attributes
|
||||
// in this packed attribute format with a call to this function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 25, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
unsigned short int AL_PROTO ALFileAttributes::PackedAttributes()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
result |= miReadOnly ? 1 : 0;
|
||||
result |= miSystem ? 2 : 0;
|
||||
result |= miHidden ? 4 : 0;
|
||||
result |= miArchive ? 8 : 0;
|
||||
return (unsigned short int ) result;
|
||||
}
|
||||
|
||||
//
|
||||
// unsigned short int ALFileAttributes::GetDosAttributes()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The set of file attributes, packed into the order that MS-DOS
|
||||
// expects them for the _dos_setfileattr() function call.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When we are closing a file that we have to set the time stamp and
|
||||
// attributes for, this function is used to get the attributes.
|
||||
// Under MS-DOS at least. All it needs to do is repack some bits
|
||||
// into the order that MS-DOS expects.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if !defined( AL_WIN32S )
|
||||
|
||||
unsigned short int AL_PROTO ALFileAttributes::GetDosAttributes()
|
||||
{
|
||||
int result = 0;
|
||||
result |= miReadOnly ? _A_RDONLY : 0;
|
||||
result |= miSystem ? _A_SYSTEM : 0;
|
||||
result |= miHidden ? _A_HIDDEN : 0;
|
||||
result |= miArchive ? _A_ARCH : 0;
|
||||
return (unsigned short int) result;
|
||||
}
|
||||
#endif //#if !defined( AL_WIN32S )
|
||||
|
||||
//
|
||||
// DWORD ALFileAttributes::GetWin32Attributes()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The set of file attributes, packed into the order that Win32s
|
||||
// expects them for the SetFileAttributes() function call.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When we are closing a file that we have to set the time stamp and
|
||||
// attributes for, this function is used to get the attributes.
|
||||
// Under Win32s at least. All it needs to do is repack some bits
|
||||
// into the order that Win32s expects.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WIN32S )
|
||||
|
||||
DWORD AL_PROTO ALFileAttributes::GetWin32Attributes()
|
||||
{
|
||||
DWORD result = 0;
|
||||
result |= miReadOnly ? FILE_ATTRIBUTE_READONLY : 0;
|
||||
result |= miSystem ? FILE_ATTRIBUTE_SYSTEM : 0;
|
||||
result |= miHidden ? FILE_ATTRIBUTE_HIDDEN : 0;
|
||||
result |= miArchive ? FILE_ATTRIBUTE_ARCHIVE : 0;
|
||||
return result;
|
||||
}
|
||||
#endif //#if !defined( AL_WIN32S )
|
||||
111
al/fileattr.h
Executable file
111
al/fileattr.h
Executable file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* FIELATTR.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file contains the class definition for ALFileAttributes.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALFileAttributes
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FILEATTR_H
|
||||
#define _FILEATTR_H
|
||||
|
||||
/*
|
||||
* class ALFileAttributes
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This class is used to carry around file attributes. Its only
|
||||
* real job at this time is to sit in the ALStorage class
|
||||
* and then produce packed attributes for inclusion in an archive,
|
||||
* and vice versa. We will need to add some additional members
|
||||
* here for searching archives based on certain attribute criteria.
|
||||
*
|
||||
* Note that most of the classes in Archive library deliberately
|
||||
* withhold the copy constructor and assignment operator. In this case,
|
||||
* however, the compiler is able to generate an adequate version of
|
||||
* these functions, so they aren't disabled.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miReadOnly : The read only file attribute bit, set when the file
|
||||
* is opened or when the directory is read from the archive.
|
||||
*
|
||||
* miSystem : The system file attribute bit.
|
||||
*
|
||||
* miHidden : The hidden file attribute bit.
|
||||
*
|
||||
* miArchive : The archive (backup) file attribute bit.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALFileAttributes() : The constructor, doesn't have to do much.
|
||||
* ~ALFileAttributes() : The destructor, doesn't have to do anything.
|
||||
* operator new( size_t size ) : Memory allocation operator, only used if
|
||||
* the library is inside a DLL.
|
||||
* PackedAttributes() : Returns the bits packed into an integer
|
||||
* in ArchiveLib proprietary format.
|
||||
* SetFromWin32Attributes() : Sets the four member bits using as input
|
||||
* the attributes as returned in a Win32 call.
|
||||
* GetWin32Attributes() : Returns the four member bits packed into
|
||||
* Win 32 format.
|
||||
* SetFromDosAttributes() : Sets the four using as input the settings
|
||||
* returned from a DOS function call.
|
||||
* GetDosAttributes() : Returns the member bits formatted into
|
||||
* the short int used by a Dos function call.
|
||||
* SetFromPackedAttributes() : Sets the member bits using as input a
|
||||
* short int in proprietary ArchiveLib format.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALFileAttributes {
|
||||
/*
|
||||
* Constructors, destructors, declarations, and friends
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALFileAttributes();
|
||||
AL_PROTO ~ALFileAttributes();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
public :
|
||||
short unsigned int AL_PROTO PackedAttributes();
|
||||
#if defined( AL_WIN32S )
|
||||
void AL_PROTO SetFromWin32Attributes( DWORD win32_attributes );
|
||||
DWORD AL_PROTO GetWin32Attributes();
|
||||
#else
|
||||
void AL_PROTO SetFromDosAttributes( unsigned dos_attributes );
|
||||
unsigned short int AL_PROTO GetDosAttributes();
|
||||
#endif
|
||||
void AL_PROTO SetFromPackedAttributes( short int attributes );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
int miReadOnly:1;
|
||||
int miSystem:1;
|
||||
int miHidden:1;
|
||||
int miArchive:1;
|
||||
};
|
||||
|
||||
#endif /* #ifndef _FILEATTR_H */
|
||||
837
al/filestor.cpp
Executable file
837
al/filestor.cpp
Executable file
@ -0,0 +1,837 @@
|
||||
//
|
||||
// FILESTOR.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALFile::operator new()
|
||||
// ALFile::ALFile()
|
||||
// ALFile::~ALFile()
|
||||
// ALFile::LoadBuffer()
|
||||
// ALFile::FlushBuffer()
|
||||
// ALFile::Seek()
|
||||
// ALFile::Open()
|
||||
// ALFile::MakeTempName()
|
||||
// ALFile::Create()
|
||||
// ALFile::Close()
|
||||
// ALFile::RenameToBackup()
|
||||
// ALFile::Rename()
|
||||
// ALFile::UnRename()
|
||||
// ALFile::Delete()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the C++ member functions to support class
|
||||
// ALFile. This class works very closely with the parent class,
|
||||
// ALStorage, found in STORAGE.CPP. You will find in many cases
|
||||
// the virtual functions found here in the derived class call
|
||||
// the same function in the parent class to help out with some
|
||||
// of the work.
|
||||
// We don't really do anything exciting in the WEP, it is just
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
//#include <dos.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "filestor.h"
|
||||
|
||||
//
|
||||
// void * ALFile::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALFile 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 ALFile::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALFile::ALFile( const char *file_name = "",
|
||||
// int buffer_size = 4096,
|
||||
// ALCase name_case = AL_LOWER)
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// file_name : The initial file name of the ALFile object you are
|
||||
// creating. By default, this is a blank string, which
|
||||
// will get converted to a temporary name before opening
|
||||
// the actual disk file.
|
||||
//
|
||||
// buffer_size : The size of the object's I/O buffer. The default of 4096
|
||||
// should give very good performance.
|
||||
//
|
||||
// name_case : This parameter determines whether the file names will
|
||||
// always be converted to upper case, lower case, or left
|
||||
// in mixed case. Under MS-DOS, you shouldn't use mixed
|
||||
// case, because the O/S file naming convention is case
|
||||
// insensitive. ArchiveLib will think "TEMP.BAK" and
|
||||
// "temp.bak" are different, when they really aren't.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, this is a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This constructor is used to create a new ALFile object, which will
|
||||
// usually be treated as an ALStorage object by ArchiveLib functions.
|
||||
// It is important to note that not much happens during construction of
|
||||
// this object, the real activity happens after you call the Open()
|
||||
// function. Just creating this object *does not* create a file on disk!
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALFile::ALFile( const char AL_DLL_FAR *file_name /* = "" */,
|
||||
int buffer_size /* = 4096 */,
|
||||
ALCase name_case /* = AL_LOWER */)
|
||||
// Note: if non-msdos, change case parameter to AL_MIXED
|
||||
: ALStorage( file_name, buffer_size, AL_FILE_OBJECT, name_case ) {
|
||||
miHandle = -1;
|
||||
}
|
||||
|
||||
//
|
||||
// ALFile::~ALFile()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The destructor for an ALFile object doesn't have to do much work.
|
||||
// The base class destructor will take care of freeing the I/O buffer,
|
||||
// and any other loose ends. All we have to do here is make sure
|
||||
// the file gets closed, and that its buffers get flushed to the disk
|
||||
// file.
|
||||
//
|
||||
// Note that in debug mode, the destructor also checks this for the
|
||||
// correct class type. This helps flag erroneous or duplicated
|
||||
// destructor calls.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALFile::~ALFile()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALFile: attempting to delete invalid object" );
|
||||
if ( miHandle != -1 )
|
||||
Close();
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::LoadBuffer( long address )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// address : The long offset into the physical storage object. A
|
||||
// seek/read combination will be executed at this location,
|
||||
// so that subsequent calls to read data will start at
|
||||
// the given address.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, AL_SEEK_ERROR, AL_END_OF_FILE, or possibly another
|
||||
// error code < AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used in the library whenever a byte needs to be read
|
||||
// that isn't present in the current I/O buffer. It has to use
|
||||
// the C RTL function lseek() to go to the correct position in the library.
|
||||
// If that works, it uses the C RTL function read() to read in an I/O
|
||||
// buffer full of data.
|
||||
//
|
||||
// After that operation is performed, muReadIndex is set to 0, indicating
|
||||
// that the next read from the I/O buffer will take place at location 0.
|
||||
// mlFilePointer is set to address plus the number of bytes read, so
|
||||
// we know where the next read from the file will take place. And
|
||||
// muBufferValidData is set to the count of bytes read in from this
|
||||
// location. That lets us know how far we can read in the I/O buffer
|
||||
// before we run out of space.
|
||||
//
|
||||
// Note that if CRC checking has been turned on, we will update the
|
||||
// current working CRC value with the new data that has been read
|
||||
// in from the buffer.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::LoadBuffer( long address )
|
||||
{
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
if ( mlFilePointer != address ) {
|
||||
long result = lseek( miHandle, address, SEEK_SET );
|
||||
if ( result == -1L )
|
||||
return mStatus.SetError( AL_SEEK_ERROR,
|
||||
"Seek failure on %s. errno = %d",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
}
|
||||
int result = read( miHandle, mpcBuffer, muBufferSize );
|
||||
if ( result == 0 )
|
||||
return AL_END_OF_FILE;
|
||||
if ( result < 0 )
|
||||
return mStatus.SetError( AL_READ_ERROR,
|
||||
"Read failure on %s. errno = %d",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
if ( miUpdateCrcFlag )
|
||||
UpdateCrc( result );
|
||||
muReadIndex = 0; //Reading can resume at this location in the I/O buffer
|
||||
mlFilePointer += result;
|
||||
muBufferValidData = result;
|
||||
YieldTime();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::FlushBuffer()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// An integer status value, AL_SUCCESS, AL_WRITE_ERROR, or possibly some
|
||||
// status code < AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is the counterpart to LoadBuffer(). It gets called
|
||||
// when a write operation is poised to overflow the I/O buffer. This
|
||||
// means we need to flush the buffer out to disk, then reset some
|
||||
// data members.
|
||||
//
|
||||
// Unlike LoadBuffer(), this function doesn't have an address argument,
|
||||
// so we don't have to perform a seek(). Instead, the data will be
|
||||
// written out to the current position of the file pointer. If the
|
||||
// write is successful, muWriteIndex is set to 0, indicating that the
|
||||
// next write to the I/O buffer can go to position 0. mlFilePointer is
|
||||
// incremented by the length of the write, so we know where the next read
|
||||
// or write will occur. Finally, muBufferValidData is set to 0, indicating
|
||||
// that there is no data in the I/O buffer that has been written, and
|
||||
// there is no data that can be read.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::FlushBuffer()
|
||||
{
|
||||
if ( mStatus < 0 )
|
||||
return mStatus;
|
||||
if ( muWriteIndex != 0 ) {
|
||||
if ( miUpdateCrcFlag )
|
||||
UpdateCrc( muWriteIndex );
|
||||
int result = write( miHandle, mpcBuffer, muWriteIndex );
|
||||
muWriteIndex = 0;
|
||||
if ( result == -1L )
|
||||
return mStatus.SetError( AL_WRITE_ERROR,
|
||||
"Write failure on %s. errno = %d",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
mlFilePointer += result;
|
||||
}
|
||||
muReadIndex = 0;
|
||||
muBufferValidData = 0;
|
||||
YieldTime();
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::Seek( long address )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// address : The address in the physical disk to seek to.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, AL_SEEK_ERROR, or possibly some other status code < AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is a function the user can call to position the read/write pointer
|
||||
// to a new location in the disk file. If there is any data that has been
|
||||
// written to the I/O buffer, it gets flushed first. After that, we do
|
||||
// a seek, and update mlFilePointer to reflect the new reality. Note that
|
||||
// the other important data members will have been updated by FlushBuffer().
|
||||
//
|
||||
// And no, this guy doesn't do a LoadBuffer(). Which is fine if you are
|
||||
// going to do a bunch of writes afterwards. If you are going to read data
|
||||
// immediately after Seek(), you would have been better of calling
|
||||
// LoadBuffer().
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::Seek( long address )
|
||||
{
|
||||
FlushBuffer();
|
||||
if ( mStatus < 0 )
|
||||
return mStatus;
|
||||
if ( mlFilePointer != address ) {
|
||||
long result = lseek( miHandle, address, SEEK_SET );
|
||||
if ( result == -1L )
|
||||
return mStatus.SetError( AL_SEEK_ERROR,
|
||||
"Seek failure on %s. errno = %d",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
}
|
||||
mlFilePointer = address;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::Open()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_CANT_OPEN_FILE, AL_SUCCESS, or possibly some other error code
|
||||
// < AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is an important function, because it converts the ALFile
|
||||
// object from a dinky little unimportant object, to a big massive
|
||||
// thing that is ready to do serious work.
|
||||
//
|
||||
// The first thing we do here is see if we can open the file. We try
|
||||
// to open it with READ/WRITE privileges, but we give up and drop back
|
||||
// to READ only if that doesn't work out.
|
||||
//
|
||||
// We then call the base class ALStorage::Open() who takes care of
|
||||
// allocating buffers and initializing data members.
|
||||
//
|
||||
// Finally, we have to get the protection attributes and time date
|
||||
// stamps for the file. After those are stored off, the file is ready
|
||||
// for abuse.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::Open()
|
||||
{
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
miHandle = open( mName, O_BINARY | O_RDWR );
|
||||
if ( miHandle == -1 && errno == EACCES )
|
||||
miHandle = open( mName, O_BINARY | O_RDONLY );
|
||||
if ( miHandle == -1 )
|
||||
return mStatus.SetError( AL_CANT_OPEN_FILE,
|
||||
"File open failure. Open of %s returned "
|
||||
"errno = %d",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
|
||||
ALStorage::Open();
|
||||
struct stat buf;
|
||||
struct tm *tblock;
|
||||
if ( stat( mName, &buf ) == -1 )
|
||||
return mStatus.SetError( AL_CANT_OPEN_FILE,
|
||||
"Couldn't get time, date, and size "
|
||||
"information for %s. errno = %d.",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
mlSize = buf.st_size;
|
||||
tblock = localtime( &buf.st_mtime );
|
||||
mTimeDate.SetTimeDate( tblock );
|
||||
#if defined( AL_WIN32S )
|
||||
DWORD attributes = GetFileAttributes( mName );
|
||||
if ( attributes == 0xFFFFFFFF )
|
||||
return mStatus.SetError( AL_CANT_OPEN_FILE,
|
||||
"Couldn't get Win32 file attribute "
|
||||
"information for %s. GetLastError = %d.",
|
||||
mName.GetName(),
|
||||
GetLastError() );
|
||||
mAttributes.SetFromWin32Attributes( attributes );
|
||||
#else
|
||||
unsigned attributes;
|
||||
if ( _dos_getfileattr( mName, &attributes ) != 0 )
|
||||
return mStatus.SetError( AL_CANT_OPEN_FILE,
|
||||
"Couldn't get DOS attribute "
|
||||
"information for %s. errno = %d.",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
mAttributes.SetFromDosAttributes( attributes );
|
||||
#endif
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// void ALFile::MakeTempName( int i )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// i : A numeric argument that can somehow be incorporated into
|
||||
// the temporary file name. Create() will call this function
|
||||
// while incrementing this number in an attempt to find a unique
|
||||
// name.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is called by Create() and other functions when they
|
||||
// decide they need to cook up a temporary file name. The single parameter
|
||||
// i is incremented by the calling program so that repeated calls should
|
||||
// eventually produce a unique name.
|
||||
//
|
||||
// All this function does to create that unique name is perform a sprintf()
|
||||
// into a buffer using a simple template. The result is copied into the
|
||||
// mName member, and is ready to be tried out.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALFile::MakeTempName( int i )
|
||||
{
|
||||
char name[ 21 ];
|
||||
|
||||
sprintf( name, "~al~%03d.tmp", i );
|
||||
mName = name;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::Create()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, AL_CANT_OPEN_FILE, or possibly some other error code
|
||||
// < AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to create a new file storage object. Since
|
||||
// we are creating a new object, we must be able to open it with read
|
||||
// access. We will also rudely obliterate any existing file.
|
||||
//
|
||||
// The first thing we do here is call the base class Create() function.
|
||||
// It takes care of setting up the I/O buffer and initializing the
|
||||
// data members used to support the class.
|
||||
//
|
||||
// Next, function checks to see if we have a valid filename. If
|
||||
// not, a search is made for a valid temporary file name. In either
|
||||
// case, the file is then opened with R/W access, in O_CREAT
|
||||
// mode, obliterating any existing file with the same name.
|
||||
//
|
||||
// Once the file is open, everything is ready to go, and you can write
|
||||
// to the file at will. Don't expect much to happen if you try to
|
||||
// read, however.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::Create()
|
||||
{
|
||||
ALStorage::Create();
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
if ( (char *) mName == 0 || strlen( mName ) == 0 ) {
|
||||
for ( int i = 0 ; i < 999 ; i++ ) {
|
||||
MakeTempName( i );
|
||||
miHandle = open( mName,
|
||||
O_CREAT | O_RDWR | O_BINARY | O_EXCL,
|
||||
S_IREAD | S_IWRITE );
|
||||
if ( miHandle != -1 )
|
||||
break;
|
||||
else if ( errno != EEXIST && errno != EACCES ) {
|
||||
mStatus.SetError( AL_CANT_OPEN_FILE,
|
||||
"Temporary file creation failure. "
|
||||
"Open of %s returned errno = %d",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
mName = "";
|
||||
return AL_CANT_OPEN_FILE;
|
||||
}
|
||||
}
|
||||
if ( i == 1000 ) {
|
||||
mStatus.SetError( AL_CANT_OPEN_FILE,
|
||||
"Temporary file creation failure. "
|
||||
"Tried 1000 times to open %s "
|
||||
"(or a name something like that).",
|
||||
mName.GetName() );
|
||||
mName = "";
|
||||
return AL_CANT_OPEN_FILE;
|
||||
}
|
||||
} else {
|
||||
miHandle = open( mName,
|
||||
O_CREAT | O_RDWR | O_BINARY | O_TRUNC,
|
||||
S_IREAD | S_IWRITE );
|
||||
}
|
||||
if ( miHandle == -1 )
|
||||
return mStatus.SetError( AL_CANT_OPEN_FILE,
|
||||
"File creation failure. "
|
||||
"Open of %s returned errno = %d",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::Close()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Any status code, hopefully AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is called when you are done accessing a file, and want
|
||||
// to free up its resources. The first thing it does is check to see
|
||||
// if the file was ever actually opened. If it was, we flush the output
|
||||
// buffer, then calculate and store the file length. Finally, we close
|
||||
// the disk file, then call the base class Close() function to clean up
|
||||
// the buffers and deal with other miscellaneous dirty work.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::Close()
|
||||
{
|
||||
if ( miHandle == -1 )
|
||||
return mStatus;
|
||||
FlushBuffer();
|
||||
mlSize = filelength( miHandle );
|
||||
if ( miCreated && mTimeDate.Valid() ) {
|
||||
#if defined( AL_WIN32S )
|
||||
// Can you do this under NT? I don't know how.
|
||||
#else
|
||||
_dos_setftime( miHandle, mTimeDate.GetDosDate(), mTimeDate.GetDosTime() );
|
||||
#endif
|
||||
}
|
||||
close( miHandle );
|
||||
miHandle = -1;
|
||||
ALStorage::Close();
|
||||
if ( miCreated && mTimeDate.Valid() ) {
|
||||
#if defined( AL_WIN32S )
|
||||
SetFileAttributes( mName, mAttributes.GetWin32Attributes() );
|
||||
#else
|
||||
_dos_setfileattr( mName, mAttributes.GetDosAttributes() );
|
||||
#endif
|
||||
}
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::RenameToBackup( int delete_on_clash = 1 )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// delete_on_clash : If this flag is set, it means that we will overwrite
|
||||
// an existing file with this file if the names clash.
|
||||
// For example, if I am renaming TEMP.DAT to TEMP.BAK,
|
||||
// and a TEMP.BAK already exists, I will delete it
|
||||
// before renaming if this arg is set.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS or AL_RENAME_ERROR.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is a quick way to rename a storage object. The new
|
||||
// name created is the default name, which usually means changing the
|
||||
// file extension to ".BAK", from whatever it was.
|
||||
//
|
||||
// You don't see it here, but both the mName member and the physical file
|
||||
// name are both updated. That all happens in the Rename() function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::RenameToBackup( int delete_on_clash /* = 1 */ )
|
||||
{
|
||||
mName.ChangeExtension();
|
||||
return Rename( 0, delete_on_clash );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::Rename( const char *new_name /* = 0 */,
|
||||
// int delete_on_clash /* = 1 */ )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// new_name : A character pointer to a new file name. If a name is
|
||||
// defined here, the file is renamed to this new value.
|
||||
// If this value is 0, it means that we expect that
|
||||
// the mName member has already been updated with a
|
||||
// new name. In this case, the old name of the
|
||||
// file is renamed to the new name.
|
||||
//
|
||||
// delete_on_clash : If this flag is set, it means that we will overwrite
|
||||
// an existing file with this file if the names clash.
|
||||
// For example, if I am renaming TEMP.DAT to TEMP.BAK,
|
||||
// and a TEMP.BAK already exists, I will delete it
|
||||
// before renaming if this arg is set.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS or AL_RENAME_ERROR.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This virtual function provides a way to rename a storage object's
|
||||
// physical implementation. It first updates the mName member if a
|
||||
// new_name argument is provided. After that, we unlink the clash file
|
||||
// if one exists, then do a simple rename of mName.mszOldName to
|
||||
// new_name.
|
||||
//
|
||||
// Note that this function does a lot of error checking in debug mode.
|
||||
// It also does a little error checking in release mode.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::Rename( const char AL_DLL_FAR *new_name /* = 0 */,
|
||||
int delete_on_clash /* = 1 */ )
|
||||
{
|
||||
AL_ASSERT( miHandle == -1, "Rename: attempting to rename open file" );
|
||||
AL_ASSERT( mName.GetName() != 0, "Rename: attempting to rename file with null name" );
|
||||
AL_ASSERT( strlen( mName ) > 0, "Rename: attempting to rename file with 0 length name" );
|
||||
|
||||
int status;
|
||||
const char *real_old_name;
|
||||
const char *real_new_name;
|
||||
if ( new_name ) {
|
||||
real_old_name = mName.GetSafeName();
|
||||
real_new_name = new_name;
|
||||
} else {
|
||||
real_old_name = mName.GetSafeOldName();
|
||||
real_new_name = mName.GetSafeName();
|
||||
}
|
||||
#if !defined( AL_WIN32S )
|
||||
const char *p = strchr( real_new_name, '.' );
|
||||
if ( p && strlen( p ) > 4 )
|
||||
return mStatus.SetError( AL_RENAME_ERROR,
|
||||
"Error trying to rename %s. It has a long "
|
||||
"extension, which could lead to inadvertent "
|
||||
"deletion of a file when trying to rename.",
|
||||
real_old_name );
|
||||
#endif
|
||||
if ( delete_on_clash ) {
|
||||
if ( mName.mCase == AL_MIXED )
|
||||
status = strcmp( real_new_name, real_old_name );
|
||||
else
|
||||
status = stricmp( real_new_name, real_old_name );
|
||||
if ( status == 0 )
|
||||
return mStatus.SetError( AL_RENAME_ERROR,
|
||||
"Error attempting to rename %s to %s. "
|
||||
"Can't rename to the same name!",
|
||||
real_new_name,
|
||||
real_old_name );
|
||||
status = unlink( real_new_name );
|
||||
if ( status != 0 && errno != ENOENT )
|
||||
return mStatus.SetError( AL_RENAME_ERROR,
|
||||
"Error deleting %s before renaming %s. "
|
||||
"errno = %d",
|
||||
real_new_name,
|
||||
real_old_name,
|
||||
errno );
|
||||
}
|
||||
status = rename( real_old_name, real_new_name );
|
||||
if ( status != 0 )
|
||||
return mStatus.SetError( AL_RENAME_ERROR,
|
||||
"Error renaming %s to %s. errno = %d",
|
||||
real_old_name,
|
||||
real_new_name,
|
||||
errno );
|
||||
if ( new_name != 0 )
|
||||
mName = new_name;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::UnRename( int delete_on_clash /* = 1 */ )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// delete_on_clash : If this flag is set, it means that we will overwrite
|
||||
// an existing file with this file if the names clash.
|
||||
// For example, if I am renaming TEMP.BAK to TEMP.DAT,
|
||||
// and a TEMP.DAT already exists, I will delete it
|
||||
// before renaming if this arg is set.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS or AL_RENAME_ERROR.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This virtual function provides a way to undo a previous renaming of
|
||||
// a storage object's physical name. We can do this because the mName
|
||||
// member of ALStorage keeps track both of the current name of the file,
|
||||
// and the old name. In this case, we just rename the current name to
|
||||
// the old name. Then we update the mName member so it is accurate.
|
||||
//
|
||||
// Note that this function does a lot of error checking in debug mode.
|
||||
// It also does a little error checking in release mode.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::UnRename( int delete_on_clash /* = 1 */ )
|
||||
{
|
||||
AL_ASSERT( miHandle == -1, "UnRename: attempting to rename open file" );
|
||||
AL_ASSERT( mName.GetName() != 0, "UnRename: attempting to rename file with null name" );
|
||||
AL_ASSERT( mName.GetOldName() != 0, "UnRename: attempting to rename file with null old name" );
|
||||
AL_ASSERT( strlen( mName ) > 0, "UnRename: attempting to rename file with 0 length name" );
|
||||
AL_ASSERT( strlen( mName.GetOldName() ) > 0, "UnRename: attempting to rename file with 0 length old name" );
|
||||
|
||||
int status;
|
||||
|
||||
if ( delete_on_clash ) {
|
||||
status = unlink( mName.GetOldName() );
|
||||
if ( status != 0 && errno != ENOENT )
|
||||
return mStatus.SetError( AL_RENAME_ERROR,
|
||||
"Error deleting %s before renaming %s. "
|
||||
"errno = %d",
|
||||
mName.GetOldName(),
|
||||
mName.GetName(),
|
||||
errno );
|
||||
}
|
||||
status = rename( mName, mName.GetOldName() );
|
||||
if ( status != 0 && errno != ENOENT )
|
||||
return mStatus.SetError( AL_RENAME_ERROR,
|
||||
"Error renaming %s to %s. errno = %d",
|
||||
mName.GetName(),
|
||||
mName.GetOldName(),
|
||||
errno );
|
||||
ALStorage::mName = mName.GetOldName();
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALFile::Delete()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_DELETE_ERROR or AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is called to delete the physical object associated with
|
||||
// a file. This simply means calling the unlink() function for the
|
||||
// given name.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALFile::Delete()
|
||||
{
|
||||
AL_ASSERT( miHandle == -1, "Delete: attempting to delete open file" );
|
||||
AL_ASSERT( mName.GetName() != 0, "Delete: attempting to delete file with null name" );
|
||||
AL_ASSERT( strlen( mName ) > 0, "Delete: attempting to delete file with 0 length name" );
|
||||
|
||||
int status = unlink( mName );
|
||||
if ( status != 0 )
|
||||
return mStatus.SetError( AL_DELETE_ERROR,
|
||||
"Error deleting file %s, errno = %d ",
|
||||
mName.GetName(),
|
||||
errno );
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
133
al/filestor.h
Executable file
133
al/filestor.h
Executable file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* FILESTOR.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file contains the class definition for the frequently used
|
||||
* ALFile class.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALFile
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FILESTOR_H
|
||||
#define _FILESTOR_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
#include "storage.h"
|
||||
|
||||
/*
|
||||
* class ALFile : public ALStorage
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is the class declaration for ALFile. This is the fundamental disk
|
||||
* storage class used in Archive Library. It is derived directly from
|
||||
* ALStorage, so it has to implement versions of the five or six
|
||||
* critical virtual functions, mostly relating to opening files, closing
|
||||
* them, loading and flushing buffers.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miHandle : The handle of the file when opened. This is the value
|
||||
* returned by the function call to open().
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALFile() : The constructor.
|
||||
* ~ALFile() : The virtual destructor.
|
||||
* operator new() : The memory allocation operator, only used when the
|
||||
* library is inside a DLL.
|
||||
* MakeTempName() : Private function used to generate temporary names.
|
||||
* Open() : Virtual function to open the file.
|
||||
* Create() : Virtual function to create the file.
|
||||
* Close() : Virtual fn to close the file.
|
||||
* LoadBuffer() : Virtual fn to load the I/O buffer from a specific address.
|
||||
* FlushBuffer() : Virtual fn to flush the I/O buffer.
|
||||
* Seek() : Virtual fn to seek to seek to a new position in the file.
|
||||
* Rename() : Rename the underlying file.
|
||||
* UnRename() : Undo the rename process.
|
||||
* Delete() : Delete the disk file (not destroy!)
|
||||
* RenameToBackup(): Rename the current file to a backup name.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALFile : public ALStorage {
|
||||
/*
|
||||
* Constructors, destructors, assignment operator, friends, declarations
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALFile( const char AL_DLL_FAR *file_name = "",
|
||||
int buffer_size = 4096,
|
||||
ALCase name_case = AL_LOWER );
|
||||
virtual AL_PROTO ~ALFile();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* As usual, I don't want the compiler to generate a default copy constructor,
|
||||
* or an assignment operator here. I force it to back off by declaring them
|
||||
* here. They do not exist!
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALFile( ALFile AL_DLL_FAR & );
|
||||
ALFile AL_DLL_FAR & AL_PROTO operator=( const ALFile AL_DLL_FAR & );
|
||||
|
||||
/*
|
||||
* Member functions, grouped by category.
|
||||
*
|
||||
*
|
||||
* Protected member manipulation, used inside library, not for public use.
|
||||
*/
|
||||
protected :
|
||||
virtual void AL_PROTO MakeTempName( int i );
|
||||
/*
|
||||
* The file I/O access public interface
|
||||
*/
|
||||
public :
|
||||
virtual int AL_PROTO Open();
|
||||
virtual int AL_PROTO Create();
|
||||
virtual int AL_PROTO Close();
|
||||
virtual int AL_PROTO LoadBuffer( long address );
|
||||
virtual int AL_PROTO FlushBuffer();
|
||||
virtual int AL_PROTO Seek( long address );
|
||||
|
||||
/*
|
||||
* File name and underlying object manipulation public interface
|
||||
*/
|
||||
public :
|
||||
virtual int AL_PROTO Rename( const char AL_DLL_FAR *new_name = 0,
|
||||
int delete_on_clash = 1 );
|
||||
virtual int AL_PROTO UnRename( int delete_on_clash = 1 );
|
||||
virtual int AL_PROTO Delete();
|
||||
virtual int AL_PROTO RenameToBackup( int delete_on_clash = 1 );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
int miHandle;
|
||||
public :
|
||||
AL_CLASS_TAG( _ALFileTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifdef _FILESTOR_H */
|
||||
361
al/grenengn.cpp
Executable file
361
al/grenengn.cpp
Executable file
@ -0,0 +1,361 @@
|
||||
//
|
||||
// GRENENGN.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALGreenleafEngine::operator new()
|
||||
// ALGreenleafEngine::ALGreenleafEngine()
|
||||
// ALGreenleafEngine::~ALGreenleafEngine()
|
||||
// ALGreenleafEngine::Compress()
|
||||
// ALGreenleafEngine::Decompress()
|
||||
// ALGreenleafEngine::WriteEngineData()
|
||||
// ALGreenleafEngine::ReadEngineData()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains the front end to the Greenleaf compression engine.
|
||||
// This contains everything but the actual low level compression
|
||||
// and expansion code, which can be found in _RE.CPP and _RC.CPP. Those
|
||||
// two source files are shrouded though, so you won't get a tremendous
|
||||
// amount of detail!
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "grenengn.h"
|
||||
#include "_openf.h"
|
||||
#include "_r.h"
|
||||
|
||||
|
||||
//
|
||||
// void * ALGreenleafEngine::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new 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 ALGreenleafEngine::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALGreenleafEngine::
|
||||
// ALGreenleafEngine( short int compression_level = AL_GREENLEAF_LEVEL_2,
|
||||
// short int fail_uncompressible = 0 )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// compression_level : This is one of the enumerated types found in ALDEFS.H,
|
||||
// namely AL_GREENLEAF_LEVEL_0 through
|
||||
// AL_GREENLEAF_LEVEL_4. Level 4 gives the most
|
||||
// compression, but takes up the most memory as well.
|
||||
//
|
||||
// fail_uncompressible : This flag is used to indicate the disposition
|
||||
// of an uncompressible file. If this flag is set,
|
||||
// the compression of an incompressible file will
|
||||
// be interrupted, and the file will be recompressed
|
||||
// using a straight copy. Note that this requires
|
||||
// a Seek() operation! Note also that this feature
|
||||
// is NOT YET IMPLEMENTED!!!
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The constructor for the Greenleaf engine has a pretty simple life. All
|
||||
// it has to do is call the base class constructor, then define a couple of
|
||||
// data members. This is a lightweight object until the compression
|
||||
// or expansion routines are invoked, at which time the memory requirements
|
||||
// go through the roof.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALGreenleafEngine::
|
||||
ALGreenleafEngine( short int compression_level /* = AL_GREENLEAF_LEVEL_2 */,
|
||||
short int fail_uncompressible /* = 0 */ )
|
||||
: ALCompressionEngine( AL_COMPRESSION_GREENLEAF, "Greenleaf" )
|
||||
{
|
||||
miCompressionLevel = compression_level;
|
||||
miFailUncompressible = fail_uncompressible;
|
||||
}
|
||||
|
||||
//
|
||||
// ALGreenleafEngine::~ALGreenleafEngine()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The destructor for objects of this class doesn't have to do
|
||||
// anything. In debug mode, we at least check for the validity
|
||||
// of the object.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALGreenleafEngine::~ALGreenleafEngine()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALGreenleafEngine: attempt to delete invalid object" );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALGreenleafEngine::Compress( ALStorage &input,
|
||||
// ALStorage &output )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// input : A reference to the storage object that will be compressed.
|
||||
//
|
||||
// output : A reference to the storage object that will receive the
|
||||
// compressed data.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
//
|
||||
// AL_SUCCESS in the event of a success, an error code < AL_SUCCESS
|
||||
// if a failure occurred.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the virtual function that is called to compress data. The
|
||||
// This section of code is really just a front end to the real engine,
|
||||
// which is found in _RC.CPP. The first thing we do here
|
||||
// is create an RCompress object, which allocates all of the
|
||||
// storage we need to perform the compression. In a tight memory
|
||||
// situation, that may well fail, so we check its status before moving
|
||||
// on. If it succeeded, we can call the low level compression function
|
||||
// to do the real work.
|
||||
//
|
||||
// After the compress function returns, we have to check for errors on
|
||||
// any of the other objects involved in the compression, and return the
|
||||
// cumulative result.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALGreenleafEngine::Compress( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output )
|
||||
{
|
||||
ALOpenFiles files( input, output );
|
||||
|
||||
input.InitCrc32();
|
||||
RCompress rc( input,
|
||||
output,
|
||||
miCompressionLevel + 10,
|
||||
miFailUncompressible );
|
||||
|
||||
if ( rc.mStatus < 0 )
|
||||
return mStatus = rc.mStatus;
|
||||
else
|
||||
rc.Compress();
|
||||
if ( rc.mStatus < 0 )
|
||||
return mStatus = rc.mStatus;
|
||||
else if ( input.mStatus < 0 )
|
||||
return mStatus = input.mStatus;
|
||||
else if ( output.mStatus < 0 )
|
||||
return mStatus = output.mStatus;
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALGreenleafEngine::Decompress( ALStorage &input,
|
||||
// ALStorage &output,
|
||||
// long compressed_length )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// input : A reference to the storage object that will be
|
||||
// expanded.
|
||||
//
|
||||
// output : A reference to the storage object that will receive
|
||||
// the expanded data.
|
||||
//
|
||||
// compressed_length : A long value indicating how long the compressed
|
||||
// object is. This helps to tell the decompressor
|
||||
// when to quit.
|
||||
// RETURNS
|
||||
//
|
||||
//
|
||||
// AL_SUCCESS in the event of a success, an error code < AL_SUCCESS
|
||||
// if a failure occurred.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the virtual function that is called to expand a compressed
|
||||
// object. This section of code is really just a front end to the real
|
||||
// engine, which is found in _RE.CPP. The first thing we do here
|
||||
// is create an RExpand object, which allocates all of the
|
||||
// storage we need to perform the decompression. In a tight memory
|
||||
// situation, that may well fail, so we check its status before moving
|
||||
// on. If it succeeded, we can call the low level expansion function
|
||||
// to do the real work.
|
||||
//
|
||||
// After the expand function returns, we have to check for errors on
|
||||
// any of the other objects involved in the expansion, and return the
|
||||
// cumulative result.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALGreenleafEngine::Decompress( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output,
|
||||
long compressed_length )
|
||||
{
|
||||
ALOpenFiles files( input, output );
|
||||
|
||||
output.InitCrc32();
|
||||
RExpand re( input, output, compressed_length, miCompressionLevel + 10 );
|
||||
|
||||
if ( re.mStatus < 0 )
|
||||
return mStatus = re.mStatus;
|
||||
else
|
||||
re.Expand();
|
||||
if ( re.mStatus < 0 )
|
||||
return mStatus = re.mStatus;
|
||||
else if ( input.mStatus < 0 )
|
||||
return mStatus = input.mStatus;
|
||||
else if ( output.mStatus < 0 )
|
||||
return mStatus = output.mStatus;
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALGreenleafEngine::WriteEngineData( ALStorage * archive )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// A pointer to the storage area where the data is to be written.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if the data was written properly, else an error code
|
||||
// less than AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Every compression engine used in ArchiveLib gets the opportunity
|
||||
// to store data it needs to save in order to characterize its compression
|
||||
// process. The Greenleaf compression engine only needs to save a single
|
||||
// integer, which contains the compression level used. This is the
|
||||
// function that does so.
|
||||
//
|
||||
// Data like this is stored in string format, which consists of a single
|
||||
// short integer describing the number of bytes in the string, followed
|
||||
// by the string. We store in this portable format so that even a program
|
||||
// that doesn't know about compression engines would be able to read in
|
||||
// archive directory data.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALGreenleafEngine::
|
||||
WriteEngineData( ALStorage AL_DLL_FAR * archive )
|
||||
{
|
||||
archive->WritePortableShort( 2 );
|
||||
return archive->WritePortableShort( miCompressionLevel );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALGreenleafEngine::ReadEngineData( ALStorage * archive )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// A pointer to the storage area where the data is to be read.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if the data was read properly, else an error code
|
||||
// less than AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Every compression engine used in ArchiveLib gets the opportunity
|
||||
// to store data it needs to save in order to characterize its compression
|
||||
// process. The Greenleaf compression engine only needs to save a single
|
||||
// integer, which contains the compression level used.
|
||||
//
|
||||
// During the creation of the compression engine, this function gets called
|
||||
// in order to load the engine's private data. All we do is read in
|
||||
// the compression level, along with a little error checking.
|
||||
//
|
||||
// Data like this is stored in string format, which consists of a single
|
||||
// short integer describing the number of bytes in the string, followed
|
||||
// by the string. We store in this portable format so that even a program
|
||||
// that doesn't know about compression engines would be able to read in
|
||||
// archive directory data.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALGreenleafEngine::ReadEngineData( ALStorage AL_DLL_FAR * archive )
|
||||
{
|
||||
short temp;
|
||||
archive->ReadPortableShort( temp );
|
||||
AL_ASSERT( temp == 2, "ReadEngineData: engine data size is not 2, it should be" );
|
||||
return archive->ReadPortableShort( miCompressionLevel );
|
||||
}
|
||||
|
||||
125
al/grenengn.h
Executable file
125
al/grenengn.h
Executable file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* GRENENGH.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file contains the class declaration for ALGreenleafEngine.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALGreenleafEngine
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _GRENENGN_H
|
||||
#define _GRENENGN_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
|
||||
#include "cmpengn.h"
|
||||
|
||||
/*
|
||||
* class ALGreenleafEngine : public ALCompressionEngine
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ALGreenleaf Engine is the Greenleaf proprietary compression
|
||||
* engine. Compression engines are simple, so there aren't
|
||||
* too many functions. This class has two data members that
|
||||
* are initialized in the constructor. One of them, the compression level,
|
||||
* has to be saved with the data in order for decompression to work
|
||||
* properly. It is saved and read with the virtual functions
|
||||
* ReadEngineData() and WriteEngineData(), using a single short
|
||||
* in the archive directory.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miCompressionLevel : This is the compression level that the
|
||||
* compressor will attempt to use, selected
|
||||
* from one of the five settings found in
|
||||
* the enumerated type in ALDEFS.H. If the
|
||||
* file is incompressible and the engine
|
||||
* performs a straight binary copy this value
|
||||
* changes to AL_GREENLEAF_COPY.
|
||||
*
|
||||
* miFailUncompressible : This data member is used to flag the
|
||||
* action the compressor takes if a file
|
||||
* turns out to be incompressible. If this
|
||||
* member is set, the engine will stop compressing,
|
||||
* seek back to the start of the file, and
|
||||
* just copy the data. If this member is clear,
|
||||
* we don't ever check to see if the file is
|
||||
* compressing properly.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALGreenleafEngine() : The constructor.
|
||||
* ~ALGreenleafEngine() : The virtual destructor.
|
||||
* operator new() : The memory allocation operator, which is
|
||||
* only used when the library is in a DLL.
|
||||
* WriteEngineData() : The virtual function that writes private
|
||||
* configuration data. For this class, this
|
||||
* function writes out a single short int
|
||||
* containing the compression level.
|
||||
* ReadEngineData() : The complement for the above function, used
|
||||
* during extraction.
|
||||
* Compress() : The routine that actually performs the
|
||||
* compression.
|
||||
* Decompress() : The routine that actually performs the
|
||||
* decompression.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALGreenleafEngine : public ALCompressionEngine {
|
||||
/*
|
||||
* Declarations, friends, constructors, destructors
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALGreenleafEngine( short int compression_level = AL_GREENLEAF_LEVEL_2,
|
||||
short int fail_uncompressible = 0 );
|
||||
virtual AL_PROTO ~ALGreenleafEngine();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
protected :
|
||||
virtual int AL_PROTO WriteEngineData( ALStorage AL_DLL_FAR * archive );
|
||||
virtual int AL_PROTO ReadEngineData( ALStorage AL_DLL_FAR * archive );
|
||||
|
||||
public :
|
||||
virtual int AL_PROTO Compress( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output );
|
||||
virtual int AL_PROTO Decompress( ALStorage AL_DLL_FAR &input,
|
||||
ALStorage AL_DLL_FAR &output,
|
||||
long compressed_length = -1 );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
short int miCompressionLevel;
|
||||
short int miFailUncompressible;
|
||||
public :
|
||||
AL_CLASS_TAG( _ALGreenleafEngineTag );
|
||||
};
|
||||
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif /* #ifdef _GRENENGN_H */
|
||||
851
al/memstore.cpp
Executable file
851
al/memstore.cpp
Executable file
@ -0,0 +1,851 @@
|
||||
//
|
||||
// MEMSTORE.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALMemory::operator new()
|
||||
// ALMemory::ALMemory()
|
||||
// ALMemory::~ALMemory()
|
||||
// ALMemory::LoadBuffer()
|
||||
// ALMemory::Delete()
|
||||
// ALMemory::Rename()
|
||||
// ALMemory::RenameToBackup()
|
||||
// ALMemory::UnRename()
|
||||
// ALMemory::Seek()
|
||||
// ALMemory::GrowUserBuffer()
|
||||
// ALMemory::FlushBuffer()
|
||||
// ALMemory::Close()
|
||||
// ALMemory::Create()
|
||||
// ALMemory::Open()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the C++ member functions to support the
|
||||
// ALMemory class. ALMemory is conceptually pretty simple, but it suffers
|
||||
// from a little bit of #ifdef'itis. The reason for this is that
|
||||
// things change just a little bit when we are using Windows memory
|
||||
// management. Not enough to create a new class, but enough to have
|
||||
// to make a lot of code conditional.
|
||||
//
|
||||
// The big difference between the Windows and DOS code shows up in two
|
||||
// areas. First, under Windows we have huge buffers that can support
|
||||
// up to either 16Mbytes or 4GBytes, depending. Under MS-DOS real mode,
|
||||
// out biggest buffer is 64Kb. Second, under MS-DOS we get new memory
|
||||
// with malloc/realloc/free. Under Windows we use LocalAlloc etc.
|
||||
//
|
||||
// Other than that, the whole class is pretty straightforward. Try not to
|
||||
// let the issue of naming the buffers throw you, it is basically
|
||||
// irrelevant.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "memstore.h"
|
||||
|
||||
#include <stdlib.h> // might be using malloc()!
|
||||
|
||||
//
|
||||
// void * ALMemory::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The amount of storage that needs to be allocated for
|
||||
// this object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the storage.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When using the DLL version of ArchiveLib, it is a good idea to
|
||||
// allocate the storage for objects from inside the DLL, since they
|
||||
// will be freed inside the DLL. If we don't have the new operator
|
||||
// for a class, its storage will be allocated from the EXE before
|
||||
// the constructor code is called. Then, when it is time to free
|
||||
// the storage, the delete operator will be called inside the DLL.
|
||||
// Not good, right?
|
||||
//
|
||||
//
|
||||
// Very important: this new operator is called to allocate the
|
||||
// storage for the ALMemory object itself. This has nothing to do
|
||||
// with the storage buffer that the memory object will be using
|
||||
// later on. In other words, this new operator is responsible for
|
||||
// no more than a couple of dozen bytes, not potentially hundreds
|
||||
// of Kbytes.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 24, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO ALMemory::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
// WINDOWS version:
|
||||
//
|
||||
// ALMemory::ALMemory( const char *buffer_name = "",
|
||||
// char AL_HUGE *user_buffer = 0,
|
||||
// DWORD user_buffer_size = 0,
|
||||
// ALCase name_case = AL_MIXED )
|
||||
//
|
||||
// MS-DOS real mode version :
|
||||
//
|
||||
// ALMemory::ALMemory( const char *buffer_name = "",
|
||||
// char *user_buffer = 0,
|
||||
// int user_buffer_size = 0,
|
||||
// ALCase name_case = AL_MIXED )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// buffer_name : An arbitrary name assigned to the buffer. Buffer
|
||||
// names don't have to be unique, because buffers aren't
|
||||
// named at the operating system level. But if you are
|
||||
// going to insert the storage object into an archive, the
|
||||
// name needs to be unique so that you will be able to
|
||||
// extract it properly.
|
||||
//
|
||||
// user_buffer : If you want the ALMemory class to automatically allocate
|
||||
// a buffer for you, and grow it as necessary, just leave
|
||||
// this pointer set to 0. If you want to use your own buffer,
|
||||
// which won't have the ability to grow, pass a pointer to
|
||||
// it in this parameter. Note that under Windows 16 this
|
||||
// is a huge pointer, meaning it can span segments, and
|
||||
// access potentially 16 Mbytes of memory.
|
||||
//
|
||||
// user_buffer_size : If you are passing a pointer to your own buffer,
|
||||
// you need to indicate how large it is here. Under
|
||||
// Windows this is a DWORD instead of a size_t.
|
||||
//
|
||||
// name_case : This decides whether you want the file name to be
|
||||
// case sensitive when making comparisons. MS-DOS
|
||||
// file names are case-insensitive. You can make memory
|
||||
// buffers either mixed case, forced upper, or forced
|
||||
// lower. The default of mixed case means that comparisons
|
||||
// will be case sensitive, which is fine.
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, it is a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This constructor calls the base class constructor in an initializer
|
||||
// list, which takes care of most of the dirty work right away. After that
|
||||
// is done, all the constructor has to do is initialize a few data members.
|
||||
// That should be self-explanatory. Remember that if the user doesn't
|
||||
// supply a buffer, we are going to allocate it for her, but not until
|
||||
// there is actually a demand for memory.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
//
|
||||
// The Windows and MS-DOS constructors are nearly identical.
|
||||
//
|
||||
AL_PROTO ALMemory::ALMemory( const char AL_DLL_FAR *buffer_name /* = "" */,
|
||||
char AL_HUGE *user_buffer /* = 0 */,
|
||||
DWORD user_buffer_size /* = 0 */,
|
||||
ALCase name_case /* = AL_MIXED */)
|
||||
: ALStorage( buffer_name, 4096, AL_MEMORY_OBJECT, name_case )
|
||||
{
|
||||
if ( user_buffer != 0 ) {
|
||||
mpcUserBuffer = user_buffer;
|
||||
mfUserOwnsBuffer = 1;
|
||||
muUserBufferSize = user_buffer_size;
|
||||
} else {
|
||||
mfUserOwnsBuffer = 0;
|
||||
mpcUserBuffer = 0;
|
||||
muUserBufferSize = 0;
|
||||
}
|
||||
mhUserMemoryHandle = 0;
|
||||
}
|
||||
|
||||
#else // #if defined( AL_WINDOWS_MEMORY )
|
||||
|
||||
AL_PROTO ALMemory::ALMemory( const char AL_DLL_FAR *buffer_name /* = "" */,
|
||||
char AL_DLL_FAR *user_buffer /* = 0 */ ,
|
||||
int user_buffer_size /* = 0 */,
|
||||
ALCase name_case /* = AL_MIXED */ )
|
||||
: ALStorage( buffer_name, 4096, AL_MEMORY_OBJECT, name_case )
|
||||
{
|
||||
if ( user_buffer != 0 ) {
|
||||
mpcUserBuffer = user_buffer;
|
||||
mfUserOwnsBuffer = 1;
|
||||
muUserBufferSize = user_buffer_size;
|
||||
} else {
|
||||
mfUserOwnsBuffer = 0;
|
||||
mpcUserBuffer = 0;
|
||||
muUserBufferSize = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALMemory::~ALMemory()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None, you don't get any for a destructor.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The destructor has just one thing it has to do before this object
|
||||
// goes away. If the buffer that it has been using all along doesn't
|
||||
// belong to the user, then it is the class's responsibility to get
|
||||
// rid of it. We do so here, using one of two methods, depending on
|
||||
// whether we are under MS-DOS or Windows.
|
||||
//
|
||||
// Note also that we check the GoodTag() function when in Debug mode.
|
||||
// That will help catch really bad mistakes, such as trying to delete
|
||||
// an object that is not even an ALMemory object, maybe a beer can.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALMemory::~ALMemory()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALMemory: attempting to delete invalid object" );
|
||||
if ( !mfUserOwnsBuffer ) {
|
||||
if ( mpcUserBuffer ) {
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
GlobalUnlock( (HGLOBAL) mhUserMemoryHandle );
|
||||
GlobalFree( (HGLOBAL) mhUserMemoryHandle );
|
||||
mhUserMemoryHandle= 0;
|
||||
#else
|
||||
free( mpcUserBuffer );
|
||||
#endif
|
||||
mpcUserBuffer = 0;
|
||||
}
|
||||
}
|
||||
AL_ASSERT( GoodTag(), "~ALMemory: attempting to delete invalid object" );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::LoadBuffer( long address )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// address : An offset that we need to load data from.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SEEK_ERROR if we try to read past the end of file. AL_END_OF_FILE
|
||||
// if we just run out of data. Otherwise an int indicating how many bytes
|
||||
// are now in the buffer.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is a virtual function the ALStorage functions rely on when reading
|
||||
// data. Anytime someone tries to do a ReadChar() or ReadBuffer(), and
|
||||
// it turns out that the I/O buffer has been exhausted, this function
|
||||
// is called.
|
||||
//
|
||||
// The simple job of this function is to read as many bytes as possible out
|
||||
// of the giant memory block allocated for the ALMemory object, and stick
|
||||
// it into the I/O buffer, which caches it for calls to ReadChar()
|
||||
// and friends.
|
||||
//
|
||||
// This works fine unless you try to go past the end of the buffer,
|
||||
// since there is nothing there we flag that as an error.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::LoadBuffer( long address )
|
||||
{
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
if ( mlFilePointer != address ) {
|
||||
if ( mlFilePointer > (long) muUserBufferSize )
|
||||
return mStatus.SetError( AL_SEEK_ERROR,
|
||||
"Attempt to read past end of the "
|
||||
"buffer in ALMemory %s",
|
||||
mName.GetName() );
|
||||
}
|
||||
long load = muUserBufferSize - address;
|
||||
if ( load > (long) muBufferSize )
|
||||
muBufferValidData = muBufferSize;
|
||||
else
|
||||
muBufferValidData = (size_t) load;
|
||||
if ( muBufferValidData <= 0 )
|
||||
return AL_END_OF_FILE;
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
//
|
||||
// Some problems passing huge arrays to memcpy, got to do it inline instead
|
||||
// I think Microsoft says memcpy() will work with huge pointers as long
|
||||
// as you don't try to use the inline optimizations, but I say why take
|
||||
// chances...
|
||||
//
|
||||
// Another note: AL_HUGE is _huge for win16, but blank for win32.
|
||||
//
|
||||
char AL_HUGE *temp = mpcUserBuffer + address;
|
||||
for ( unsigned i = 0 ; i < muBufferValidData ; i++ )
|
||||
mpcBuffer[ i ] = *temp++;
|
||||
// memcpy( mpcBuffer, mpcUserBuffer + address, muBufferValidData );
|
||||
#else
|
||||
memcpy( mpcBuffer, mpcUserBuffer + (size_t) address, muBufferValidData );
|
||||
#endif
|
||||
if ( miUpdateCrcFlag )
|
||||
UpdateCrc( muBufferValidData );
|
||||
muReadIndex = 0; //Reading can resume at this location
|
||||
mlFilePointer += muBufferValidData;
|
||||
YieldTime();
|
||||
return muBufferValidData;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::Delete()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is supposed to delete the underlying physical object.
|
||||
// This makes a lot of sense with files, because you are essentially
|
||||
// emulating the MS-DOS command line DEL function. With memory
|
||||
// objects things aren't quite as clear. So we destroy the buffer,
|
||||
// and that's that.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::Delete()
|
||||
{
|
||||
if ( !mfUserOwnsBuffer ) {
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
GlobalUnlock( (HGLOBAL) mhUserMemoryHandle );
|
||||
GlobalFree( (HGLOBAL) mhUserMemoryHandle );
|
||||
mhUserMemoryHandle= 0;
|
||||
#else
|
||||
free( mpcUserBuffer );
|
||||
#endif
|
||||
mpcUserBuffer = 0;
|
||||
}
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::Rename( const char *new_name /* = 0 */,
|
||||
// int /* delete_on_clash = 1 */ )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// new_name : The new name of the buffer.
|
||||
//
|
||||
// delete_on_clash : This argument makes sense with files. What it says
|
||||
// is that if you try to rename BOB.DAT to BOB.BAK,
|
||||
// and it turns out that there is another BOB.BAK, should
|
||||
// you delete the other one? With memory buffers,
|
||||
// there is no clash, cause the OS doesn't care about
|
||||
// unique names. So we ignore this parm.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is supposed to rename the underlying physical object.
|
||||
// But in the case of memory buffers, the underlying physical object
|
||||
// doesn't actually have a name, so this is really just a local rename.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::Rename( const char AL_DLL_FAR *new_name /* = 0 */,
|
||||
int /* delete_on_clash = 1 */ )
|
||||
{
|
||||
if ( new_name )
|
||||
mName = new_name;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::RenameToBackup( int delete_on_clash /* = 1 */ )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// delete_on_clash : This argument makes sense with files. What it says
|
||||
// is that if you try to rename BOB.DAT to BOB.BAK,
|
||||
// and it turns out that there is another BOB.BAK, should
|
||||
// you delete the other one? With memory buffers,
|
||||
// there is no clash, cause the OS doesn't care about
|
||||
// unique names. So it doesn't matter what value you
|
||||
// pass to the Rename() function, it is going to be
|
||||
// ignored.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function renames an object. But instead of making you sweat in
|
||||
// order to come up with a new name, it just uses the default name
|
||||
// that we use to assign a backup name.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::RenameToBackup( int delete_on_clash /* = 1 */ )
|
||||
{
|
||||
mName.ChangeExtension();
|
||||
return Rename( 0, delete_on_clash );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::UnRename( int /* delete_on_clash = 1 */)
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// delete_on_clash : This argument makes sense with files. What it says
|
||||
// is that if you try to rename BOB.DAT to BOB.BAK,
|
||||
// and it turns out that there is another BOB.BAK, should
|
||||
// you delete the other one? With memory buffers,
|
||||
// there is no clash, cause the OS doesn't care about
|
||||
// unique names. So we just ignore it here.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Always returns AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// If you decide you didn't really want to rename an object after all, you
|
||||
// can call this function to get the old name back!
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::UnRename( int /* delete_on_clash = 1 */)
|
||||
{
|
||||
AL_ASSERT( mName.GetName() != 0, "UnRename: trying to rename with a null name" );
|
||||
AL_ASSERT( mName.GetOldName() != 0, "UnRename: trying to rename with a null old name" );
|
||||
AL_ASSERT( strlen( mName ) > 0, "UnRename: trying to rename with a zero length name" );
|
||||
AL_ASSERT( strlen( mName.GetOldName() ) > 0, "UnRename: trying to rename with a zero length old name" );
|
||||
|
||||
ALStorage::mName = mName.GetOldName();
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::Seek( long address )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// address : The address in the memory object to go to. The read and
|
||||
// write pointers will now be repositioned to this point.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SEEK_ERROR if we can't get to that point in the buffer. Otherwise
|
||||
// AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function acts just like the seek() function in the C runtime
|
||||
// library. It flushes the current I/O buffers, and then moves the file
|
||||
// read and write pointers to a new spot, specified by the address. if
|
||||
// there is no memory there, you will get an error. Note that this
|
||||
// makes it not quite like the C run time library, since it can create
|
||||
// new space with a seek(). But I don't think we need that ability yet.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::Seek( long address )
|
||||
{
|
||||
FlushBuffer();
|
||||
if ( mStatus < 0 )
|
||||
return mStatus;
|
||||
|
||||
if ( mlFilePointer != address ) {
|
||||
if ( mlFilePointer > (long) muUserBufferSize )
|
||||
return mStatus.SetError( AL_SEEK_ERROR,
|
||||
"Attempt to read past end of the "
|
||||
"buffer in ALMemory %s",
|
||||
mName.GetName() );
|
||||
}
|
||||
mlFilePointer = address;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::GrowUserBuffer( long minimum_new_size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// minimum_new_size : The absolute minimum new size you need the buffer
|
||||
// to grow to. This amount is usually determined by
|
||||
// a pending I/O request. For example, if the current
|
||||
// size of the buffer is 1000, and you have a 1 byte
|
||||
// data block to write at 1000, the minimum new size
|
||||
// will be 1001.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_CANT_ALLOCATE_MEMORY, if we just can't get it. AL_SUCCESS if we can.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When you are trying to write to the memory object, and you have hit
|
||||
// the end of the currently allocated area, it would seem like a good
|
||||
// time to allocate more. When that situation occurs, this function is
|
||||
// called. If the user owns the buffer, we don't have the option of asking
|
||||
// the O/S or RTL for more memory, because we don't even know if the user
|
||||
// memory is on the heap or what. But if we own the memory we know how
|
||||
// to ask for more.
|
||||
//
|
||||
// The strategy for asking for more memory is pretty simple. Normally,
|
||||
// we ask for another 16K. If that fails, we fall back to asking for
|
||||
// just enough memory to cover our current I/O request. Asking for
|
||||
// this memory is sufficiently different under real mode dos and protected
|
||||
// mode windows that we have two completely different routines, separated
|
||||
// only by #ifdefs.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
int AL_PROTO ALMemory::GrowUserBuffer( long minimum_new_size )
|
||||
{
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
if ( mfUserOwnsBuffer )
|
||||
return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Attempt to write past the end of a "
|
||||
"user owned buffer for ALMemory "
|
||||
"%s",
|
||||
mName.GetSafeName() );
|
||||
long trial_size = muUserBufferSize + 16384;
|
||||
GlobalUnlock( (HGLOBAL) mhUserMemoryHandle );
|
||||
HGLOBAL new_handle = GlobalReAlloc( (HGLOBAL) mhUserMemoryHandle, trial_size, GMEM_MOVEABLE );
|
||||
if ( new_handle == 0 ) {
|
||||
trial_size = minimum_new_size;
|
||||
new_handle = GlobalReAlloc( (HGLOBAL) mhUserMemoryHandle, trial_size, GMEM_MOVEABLE );
|
||||
}
|
||||
if ( new_handle == 0 ) {
|
||||
mpcUserBuffer = (char AL_HUGE *) GlobalLock( (HGLOBAL) mhUserMemoryHandle );
|
||||
return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Allocation failure when attempting to "
|
||||
"allocate a buffer "
|
||||
"of %ld bytes for ALMemory "
|
||||
"%s",
|
||||
minimum_new_size,
|
||||
mName.GetSafeName() );
|
||||
}
|
||||
mpcUserBuffer = (char AL_HUGE *) GlobalLock( new_handle );
|
||||
mhUserMemoryHandle = new_handle;
|
||||
muUserBufferSize = trial_size;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
#else // #ifdef AL_WINDOWS_MEMORY
|
||||
|
||||
int AL_PROTO ALMemory::GrowUserBuffer( long minimum_new_size )
|
||||
{
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
if ( mfUserOwnsBuffer )
|
||||
return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Attempt to write past the end of a "
|
||||
"user owned buffer for ALMemory "
|
||||
"%s",
|
||||
mName.GetSafeName() );
|
||||
if ( minimum_new_size >= 65535L )
|
||||
return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Attempt to allocate a huge buffer "
|
||||
"of %ld bytes for ALMemory "
|
||||
"%s",
|
||||
minimum_new_size,
|
||||
mName.GetSafeName() );
|
||||
long trial_size = muUserBufferSize + 16384;
|
||||
if ( trial_size >= 65000U )
|
||||
trial_size = 65000U;
|
||||
if ( trial_size >= minimum_new_size ) {
|
||||
char *new_buf = (char *) realloc( mpcUserBuffer, (size_t) trial_size );
|
||||
if ( new_buf ) {
|
||||
mpcUserBuffer = new_buf;
|
||||
muUserBufferSize = (size_t) trial_size;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
}
|
||||
char *new_buf = (char *) realloc( mpcUserBuffer, (size_t) minimum_new_size );
|
||||
if ( new_buf ) {
|
||||
mpcUserBuffer = new_buf;
|
||||
muUserBufferSize = (size_t) trial_size;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Allocation failure when attempting to "
|
||||
"allocate a buffer "
|
||||
"of %ld bytes for ALMemory "
|
||||
"%s",
|
||||
minimum_new_size,
|
||||
mName.GetSafeName() );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// int ALMemory::FlushBuffer()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_CANT_ALLOCATE_MEMORY, if we run out. Otherwise, AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This routine is called when the I/O buffer is filled up. It means
|
||||
// you have filled up the cache with what is usually 4K bytes of data.
|
||||
// This routine is also called if you have hot data in the I/O buffer
|
||||
// and you decide to do a seek(), or a read().
|
||||
//
|
||||
// All we have to do here is take the hot data in the I/O buffer and
|
||||
// write it out to our massive memory object. The big complication is
|
||||
// that sometimes the memory object isn't big enough, so while we are
|
||||
// all busy trying to do this, we have to ask for more data at the
|
||||
// same time.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::FlushBuffer()
|
||||
{
|
||||
if ( mStatus < 0 )
|
||||
return mStatus;
|
||||
//
|
||||
// If the write index is 0, we can skip all this stuff, because there
|
||||
// is nothing in the buffer to flush out.
|
||||
//
|
||||
if ( muWriteIndex != 0 ) {
|
||||
if ( miUpdateCrcFlag )
|
||||
UpdateCrc( muWriteIndex );
|
||||
if ( ( muWriteIndex + mlFilePointer ) > (long)muUserBufferSize )
|
||||
if ( GrowUserBuffer( muWriteIndex + mlFilePointer ) < 0 )
|
||||
return mStatus;
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
//
|
||||
// Can't use memcpy with huge pointers, at least not with the optimized
|
||||
// versions.
|
||||
//
|
||||
char AL_HUGE *temp = mpcUserBuffer + mlFilePointer;
|
||||
for ( unsigned int i = 0 ; i < muWriteIndex ; i++ )
|
||||
*temp++ = mpcBuffer[ i ];
|
||||
// memcpy( mpcUserBuffer + mlFilePointer, mpcBuffer, muWriteIndex );
|
||||
#else
|
||||
memcpy( mpcUserBuffer + (size_t) mlFilePointer, mpcBuffer, muWriteIndex );
|
||||
#endif
|
||||
mlFilePointer += muWriteIndex;
|
||||
muWriteIndex = 0;
|
||||
if ( mlSize < mlFilePointer )
|
||||
mlSize = mlFilePointer;
|
||||
}
|
||||
muReadIndex = 0;
|
||||
muBufferValidData = 0;
|
||||
YieldTime();
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::Close()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, or various error codes that filter on down from other
|
||||
// routines.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Close() is supposed to do the same thing as fclose() in the run
|
||||
// time library. The most important thing we are concerned about is
|
||||
// that the I/O buffer gets freed up by the base class, so this suddenly
|
||||
// might not be a giant heavyweight object any more.
|
||||
//
|
||||
// After freeing things up in the base class, we check to see if
|
||||
// we have allocated more space than we really need. If so, we do
|
||||
// a realloc() of some sort to give space back to the O/S.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::Close()
|
||||
{
|
||||
if ( mpcBuffer == 0 )
|
||||
return mStatus;
|
||||
FlushBuffer();
|
||||
ALStorage::Close();
|
||||
//
|
||||
// If we aren't using all our space, give back the extra.
|
||||
//
|
||||
if ( mlSize < (long) muUserBufferSize ) {
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
GlobalUnlock( (HGLOBAL) mhUserMemoryHandle );
|
||||
HGLOBAL new_handle = GlobalReAlloc( (HGLOBAL) mhUserMemoryHandle, mlSize, GMEM_MOVEABLE );
|
||||
if ( new_handle != 0 )
|
||||
mhUserMemoryHandle = new_handle;
|
||||
mpcUserBuffer = (char AL_HUGE *) GlobalLock( (HGLOBAL) mhUserMemoryHandle );
|
||||
muUserBufferSize = mlSize;
|
||||
#else
|
||||
char *new_buf = (char *) realloc( mpcUserBuffer, (size_t) mlSize );
|
||||
if ( new_buf )
|
||||
mpcUserBuffer = new_buf;
|
||||
muUserBufferSize = (size_t) mlSize;
|
||||
#endif
|
||||
}
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::Create()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, AL_CANT_ALLOCATE_MEMORY, or various error codes that
|
||||
// filter on down from other routines.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is like creating a new file. If there isn't a memory buffer
|
||||
// already assigned to this object, we create one, with an initial
|
||||
// allocation of 16Kbytes.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::Create()
|
||||
{
|
||||
ALStorage::Create();
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
if ( (char *) mName == 0 || strlen( mName ) == 0 )
|
||||
mName = "AL.TMP";
|
||||
if ( mfUserOwnsBuffer )
|
||||
return AL_SUCCESS; //If the user supplied the buffer, we take what's available
|
||||
#if defined( AL_WINDOWS_MEMORY )
|
||||
mhUserMemoryHandle = GlobalAlloc( GMEM_MOVEABLE, 16384 );
|
||||
if ( mhUserMemoryHandle ) {
|
||||
mpcUserBuffer = (char AL_HUGE *) GlobalLock( (HGLOBAL) mhUserMemoryHandle );
|
||||
muUserBufferSize = 16384;
|
||||
} else {
|
||||
mpcUserBuffer = 0;
|
||||
return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Allocation failure when attempting to "
|
||||
"create a buffer "
|
||||
"of %ld bytes for ALMemory "
|
||||
"%s in Create()",
|
||||
16384,
|
||||
mName.GetSafeName() );
|
||||
}
|
||||
#else
|
||||
mpcUserBuffer = (char *) malloc( 16384 );
|
||||
muUserBufferSize = 16384;
|
||||
if ( mpcUserBuffer == 0 )
|
||||
return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Allocation failure when attempting to "
|
||||
"create a buffer "
|
||||
"of %ld bytes for ALMemory "
|
||||
"%s in Create()",
|
||||
16384,
|
||||
mName.GetSafeName() );
|
||||
#endif
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALMemory::Open()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, AL_CANT_OPEN_FILE, or various error codes that
|
||||
// filter on down from other routines.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is like opening an existing file. Since there is supposed to be
|
||||
// an existing memory buffer already, we gripe if we can't find one.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 22, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALMemory::Open()
|
||||
{
|
||||
ALStorage::Open();
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
if ( mpcUserBuffer == 0 )
|
||||
return mStatus.SetError( AL_CANT_OPEN_FILE,
|
||||
"Attempt to open ALMemory %s "
|
||||
"with no buffer allocated",
|
||||
mName.GetSafeName() );
|
||||
else
|
||||
mlSize = (long) muUserBufferSize;
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
182
al/memstore.h
Executable file
182
al/memstore.h
Executable file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* MEMSTORE.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class declaration for ALMemory.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALMemory
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MEMSTORE_H
|
||||
#define _MEMSTORE_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/*
|
||||
* class ALMemory : public ALStorage
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Class ALMemory is an ALStorage class that stores its data in memory
|
||||
* buffers. Under real mode MS-DOS, buffers are limited to 64Kbytes.
|
||||
* Under Windows, they can get a lot bigger. There are slight
|
||||
* differences in operations between the the Windows and MS-DOS
|
||||
* versions, so you will see some #ifdefs here and there.
|
||||
*
|
||||
* You can use ALMemory to work with a buffer of your own, or you
|
||||
* can ask the class to allocate the memory for you. You can
|
||||
* also change the ownership of the buffer in midstream, allowing
|
||||
* you to take control of a buffer that the class has generated.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mfUserOwnsBuffer : If this flag is set, it indicates that the user
|
||||
* owns the buffer, not the class. This means
|
||||
* the class can't grow the buffer if it runs out
|
||||
* of space, and it can't delete it in the
|
||||
* ALMemory destructor.
|
||||
*
|
||||
* mhUserMemoryHandle : Under Windows, this member contains the handle
|
||||
* of the Windows memory block that has been
|
||||
* allocated
|
||||
*
|
||||
* muUserBufferSize : The actual size of the buffer, whether it is
|
||||
* owned by the user or not. This is a size_t
|
||||
* member under real mode DOS, and a long under
|
||||
* Windows.
|
||||
*
|
||||
* mpcUserBuffer : A pointer to the buffer the class is presently
|
||||
* using. The name User Buffer was probably a bad
|
||||
* choice, because this is the pointer we use
|
||||
* regardless of whether or not the user owns the
|
||||
* buffer.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALMemory() : The constructor, slightly different between DOS
|
||||
* and Windows.
|
||||
* ~ALMemory() : The virtual destructor.
|
||||
* operator new() : Memory allocation operator, only used when the
|
||||
* library is in a DLL. Note that this isn't the
|
||||
* operator used to allocate the buffer, just the
|
||||
* one to allocate a class object.
|
||||
* Open() : Open the storage object for reading and writing.
|
||||
* Create() : Create a new buffer to write to.
|
||||
* Close() : Close the existing memory object.
|
||||
* LoadBuffer() : Load a new block from the memory object into
|
||||
* the I/O buffer.
|
||||
* FlushBuffer() : Flush the contents of the I/O buffer, sending
|
||||
* the contents into the memory object.
|
||||
* Seek() : Seek to a new location in the memory object.
|
||||
* Rename() : Give the object a new name. Names are pretty
|
||||
* irrelevant for memory objects, feel free to use
|
||||
* whatever you want here.
|
||||
* UnRename() : Restore the old name.
|
||||
* Delete() : Delete the memory object. It is gone forever.
|
||||
* RenameToBackup() : Give the memory object an arbitrary new name.
|
||||
* GrowUserBuffer() : A private function used to give us more space
|
||||
* when the memory object is owner of the buffer.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALMemory : public ALStorage {
|
||||
/*
|
||||
* Constructors, destructors, assignment operator, friends, declarations
|
||||
*/
|
||||
|
||||
public :
|
||||
#ifdef AL_WINDOWS_MEMORY
|
||||
AL_PROTO ALMemory( const char AL_DLL_FAR *buffer_name = "",
|
||||
char AL_HUGE *user_buffer = 0,
|
||||
DWORD user_buffer_size = 0,
|
||||
ALCase name_case = AL_MIXED );
|
||||
#else
|
||||
AL_PROTO ALMemory( const char AL_DLL_FAR *buffer_name = "",
|
||||
char AL_DLL_FAR *user_buffer = 0,
|
||||
int user_buffer_size = 0,
|
||||
ALCase name_case = AL_MIXED );
|
||||
#endif
|
||||
virtual AL_PROTO ~ALMemory();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* As usual, I don't want the compiler to generate a default copy constructor,
|
||||
* or an assignment operator here. I force it to back off by declaring them
|
||||
* here. They do not exist!
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALMemory( ALMemory AL_DLL_FAR & );
|
||||
ALMemory AL_DLL_FAR & AL_PROTO operator=( const ALMemory AL_DLL_FAR & );
|
||||
|
||||
/*
|
||||
* Member functions, grouped by category.
|
||||
*
|
||||
*
|
||||
* Protected member manipulation, used inside library, not for public use.
|
||||
*/
|
||||
protected :
|
||||
/*
|
||||
* The file I/O access public interface
|
||||
*/
|
||||
public :
|
||||
virtual int AL_PROTO Open();
|
||||
virtual int AL_PROTO Create();
|
||||
virtual int AL_PROTO Close();
|
||||
virtual int AL_PROTO LoadBuffer( long address );
|
||||
virtual int AL_PROTO FlushBuffer();
|
||||
virtual int AL_PROTO Seek( long address );
|
||||
|
||||
/*
|
||||
* File name and underlying object manipulation public interface
|
||||
*/
|
||||
public :
|
||||
virtual int AL_PROTO Rename( const char AL_DLL_FAR *new_name = 0,
|
||||
int delete_on_clash = 1 );
|
||||
virtual int AL_PROTO UnRename( int delete_on_clash = 1 );
|
||||
virtual int AL_PROTO Delete();
|
||||
virtual int AL_PROTO RenameToBackup( int delete_on_clash = 1 );
|
||||
/*
|
||||
* Unique to this class
|
||||
*/
|
||||
protected :
|
||||
int AL_PROTO GrowUserBuffer( long minimum_new_size );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
public : /* Should some of these might be better off private */
|
||||
int mfUserOwnsBuffer;
|
||||
#ifdef AL_WINDOWS_MEMORY
|
||||
HGLOBAL mhUserMemoryHandle;
|
||||
long muUserBufferSize;
|
||||
char AL_HUGE *mpcUserBuffer;
|
||||
#else
|
||||
size_t muUserBufferSize;
|
||||
char AL_DLL_FAR *mpcUserBuffer;
|
||||
#endif
|
||||
AL_CLASS_TAG( _ALMemoryTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifndef _MEMSTORE_H */
|
||||
244
al/monitor.cpp
Executable file
244
al/monitor.cpp
Executable file
@ -0,0 +1,244 @@
|
||||
//
|
||||
// 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 * )
|
||||
{
|
||||
}
|
||||
194
al/monitor.h
Executable file
194
al/monitor.h
Executable file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* MONITOR.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file contains the class declaration for the base class ALMonitor.
|
||||
* You can instantiate objects of this class, but they don't do
|
||||
* anything. The derived classes are much more interesting.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALMonitor
|
||||
*
|
||||
* ENUMERATED TYPES:
|
||||
*
|
||||
* ALArchiveOperation
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MONITOR_H
|
||||
#define _MONITOR_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/*
|
||||
* Most of our enumerated types are defined in ALDEFS.H so C programs
|
||||
* have easy access to them. But C and VB have no use for these
|
||||
* values, because they are only used by members of ALMonitor,
|
||||
* they can't be passed to C or VB procedures.
|
||||
*
|
||||
* This type defines the various messages that are passed to
|
||||
* ALMonitor::ArchiveOperation() during progress of an
|
||||
* archiving operation.
|
||||
*/
|
||||
|
||||
enum ALArchiveOperation {
|
||||
AL_ARCHIVE_OPEN,
|
||||
AL_ARCHIVE_CLOSE,
|
||||
AL_EXTRACTION_OPEN,
|
||||
AL_EXTRACTION_CLOSE,
|
||||
AL_INSERTION_OPEN,
|
||||
AL_INSERTION_CLOSE,
|
||||
AL_COPY_OPEN,
|
||||
AL_COPY_CLOSE,
|
||||
AL_START_DIRECTORY_WRITE,
|
||||
AL_END_DIRECTORY_WRITE,
|
||||
AL_START_DIRECTORY_READ,
|
||||
AL_END_DIRECTORY_READ
|
||||
};
|
||||
|
||||
/*
|
||||
* A forward declaration.
|
||||
*
|
||||
*/
|
||||
class AL_CLASS_TYPE ALEntry;
|
||||
|
||||
/*
|
||||
* class ALMonitor
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* The ALMonitor class is used primarily for providing user interface
|
||||
* information during archiving or other operations. Each ALEntryList
|
||||
* object has an ALMonitor attached to it. When the archive operations
|
||||
* are performed, the ALMonitor object is called using its two functions,
|
||||
* Progress() and ArchiveOperation(). Progress() is used to update
|
||||
* progress information, such as byte count or percent complete. The
|
||||
* archive operation is functioned at various times, such as when files
|
||||
* are opened, archives are opened, files are closed, etc.
|
||||
*
|
||||
* Good examples of how derived classes do all this stuff can be found in
|
||||
* BARGRAPH.CPP and WINMON.CPP.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mlJobSize : The total size of the job being monitored. If the
|
||||
* monitor is in AL_MONITOR_JOBS mode, we care about
|
||||
* this. The archive base class has to set up this
|
||||
* member before the archiving procedure starts.
|
||||
*
|
||||
* mlJobSoFar : The total number of bytes that have already been
|
||||
* processed so far in this job. This number is
|
||||
* updated after each file is completely processed. It
|
||||
* does not reflect work done on the current file.
|
||||
*
|
||||
* mlObjectSize : The size of the current object being processed. This
|
||||
* is usually set up by the archive function at the start
|
||||
* of processing for the current file. If this number is
|
||||
* set to -1, it means we have to check on it, since
|
||||
* the archiving program was to lazy to open the file and
|
||||
* check on.
|
||||
*
|
||||
* mlObjectStart : The starting offset of the current object in the
|
||||
* file being processed. Sometimes the object we are
|
||||
* working on might be in an archive, in which case
|
||||
* we need to know where it starts.
|
||||
*
|
||||
* mlByteCount : This private member contains the byte count for all
|
||||
* the data processed so far. Derived classes can
|
||||
* call Progress() for the base class, and it will
|
||||
* calculate this number. The number will be for
|
||||
* the entire job when we are in AL_MONITOR_JOB mode,
|
||||
* but just for the current object when we are in
|
||||
* AL_MONITOR_OBJECTS mode.
|
||||
*
|
||||
* miRatio : The percentage of processing we have completed, an
|
||||
* integer that hopefully ranges from 0 to 100. This
|
||||
* number can also be calculated by calling Progress()
|
||||
* in the base class. It will differ depending on whether
|
||||
* we are in AL_MONITOR_JOB mode or AL_MONITOR_OBJECTS.
|
||||
*
|
||||
* miMonitorType : Either AL_MONITOR_OBJECT or AL_MONITOR_JOBS, depending
|
||||
* on what was specified in the constructor.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALMonitor() : The constructor.
|
||||
* ~ALMonitor() : The virtual destructor.
|
||||
* operator new() : The memory allocation operator used when the
|
||||
* library resides in a DLL.
|
||||
* Progress() : The routine called periodically to update progress
|
||||
* indicators. The base class version just makes
|
||||
* calculations.
|
||||
* ArchiveOperation() : The routine called at various points during an
|
||||
* archive operation. Does nothing worthwhile in the
|
||||
* base class.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALMonitor
|
||||
{
|
||||
/*
|
||||
* Constructors, destructors, friends, declarations
|
||||
*/
|
||||
friend class AL_CLASS_TYPE ALArchiveBase;
|
||||
friend class AL_CLASS_TYPE ALStorage;
|
||||
|
||||
public :
|
||||
AL_PROTO ALMonitor( ALMonitorType monitor_type );
|
||||
virtual AL_PROTO ~ALMonitor();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* The copy constructor and assignment operator do not exist.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALMonitor( ALMonitor AL_DLL_FAR &);
|
||||
ALMonitor AL_DLL_FAR & AL_PROTO operator=( ALMonitor AL_DLL_FAR & );
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
protected :
|
||||
virtual void AL_PROTO Progress( long mlObjectTell,
|
||||
ALStorage AL_DLL_FAR & object );
|
||||
virtual void AL_PROTO
|
||||
ArchiveOperation( enum ALArchiveOperation operation,
|
||||
ALArchiveBase AL_DLL_FAR *archive,
|
||||
ALEntry AL_DLL_FAR *job );
|
||||
/*
|
||||
* Data members, not sure if we should keep these public or not
|
||||
*/
|
||||
public :
|
||||
long mlJobSize;
|
||||
long mlJobSoFar;
|
||||
long mlObjectSize;
|
||||
long mlObjectStart;
|
||||
/*
|
||||
* Calculated by ALMonitor::Progress()
|
||||
*/
|
||||
long mlByteCount;
|
||||
int miRatio;
|
||||
|
||||
public :
|
||||
const ALMonitorType miMonitorType;
|
||||
AL_CLASS_TAG( _ALMonitorTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifndef _MONITOR_H */
|
||||
754
al/objname.cpp
Executable file
754
al/objname.cpp
Executable file
@ -0,0 +1,754 @@
|
||||
//
|
||||
// OBJNAME.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALName::operator new()
|
||||
// ALName::operator+()
|
||||
// ALName::ALName( const char *, ALCase )
|
||||
// ALName::ALName( const ALName & )
|
||||
// ALName::operator=( const char * )
|
||||
// ALName::operator = ( const ALName & )
|
||||
// ALName::~ALName()
|
||||
// ALName::ChangeExtension()
|
||||
// ALName::ChangeTrailingChar()
|
||||
// ALName::GetSafeName()
|
||||
// ALName::GetSafeOldName()
|
||||
// ALName::operator char *()
|
||||
// ALName::StripFileName()
|
||||
// ALName::StripPath()
|
||||
// ALName::WildCardMatch()
|
||||
// ALName::Strcpy()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the source code to support class ALName.
|
||||
// Class ALName doesn't really do much outside of ALStorage, where
|
||||
// it shows up as the mName data member. It does make cameo appearances
|
||||
// elsewhere, such as in the wild card expansion code, but those
|
||||
// are pretty limited.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "_match.h"
|
||||
|
||||
//
|
||||
// void * ALName::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALName 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 ALName::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALName ALName::operator+( const char *rhs )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// rhs : The character pointer that is going to be added to the
|
||||
// ALName object. This will often be the string component
|
||||
// of another ALName object, cast to type const char *.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A newly created ALName object. This disappears quickly, but can
|
||||
// be copied into a result object using either the assignment operator
|
||||
// or the copy constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is one of those C++ functions that makes converts out of C
|
||||
// programmers. It allows me to add two strings together to create
|
||||
// a third. I really like that.
|
||||
//
|
||||
// The implementation is pretty easy. I allocate a new character buffer of
|
||||
// the correct length, the copy the two strings into it. I use this
|
||||
// result as the initializer for a new ALName object, and return that.
|
||||
//
|
||||
// Note that the new string will have the same case sensitivity as this.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALName ALName::operator+( const char AL_DLL_FAR *rhs )
|
||||
{
|
||||
int l1 = ( rhs ) ? strlen( rhs ) : 0;
|
||||
int l2 = ( mszName ) ? strlen( mszName ) : 0;
|
||||
char *p = new char[ l1 + l2 + 1 ];
|
||||
if ( p ) {
|
||||
strcpy( p, mszName );
|
||||
if ( rhs )
|
||||
strcat( p, rhs );
|
||||
}
|
||||
ALName result( p, mCase );
|
||||
if ( p )
|
||||
delete p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ALName::ALName( const char *s = "", ALCase name_case = AL_MIXED )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// s : The initial string value of the new object. Note that
|
||||
// you can pass a null pointer here and all will still be okay.
|
||||
//
|
||||
// name_case: The case sensitivity of the new ALName object. Will its
|
||||
// contents be mixed, or will it always be forced to upper
|
||||
// or lower.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This constructor first initializes the mCase member in an initializer.
|
||||
// mCase is a const member, which is nice, because you can make it public.
|
||||
// But, it means you can't initialize it *in* the constructor, you have
|
||||
// to do it before the body.
|
||||
//
|
||||
// Things are pretty easy after that. We allocate enough space to hold
|
||||
// the initializer string and copy it in. The old name gets set to 0, since
|
||||
// this name hasn't been around long enough to have been renamed.
|
||||
// And that's it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALName::ALName( const char AL_DLL_FAR *s /* = "" */,
|
||||
ALCase name_case /* = AL_MIXED */ )
|
||||
: mCase( name_case )
|
||||
{
|
||||
mszName = new AL_DLL_FAR char[ strlen( s ) + 1 ];
|
||||
if ( mszName )
|
||||
Strcpy( s );
|
||||
mszOldName = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ALName::ALName( const ALName &rhs )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// rhs : A reference to another ALName object. This is the ALName
|
||||
// we are going to copy.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the copy constructor. It is very nearly the same as the
|
||||
// other constructor.
|
||||
//
|
||||
// This constructor first initializes the mCase member in an initializer.
|
||||
// mCase is a const member, which is nice, because you can make it public.
|
||||
// But, it means you can't initialize it *in* the constructor, you have
|
||||
// to do it before the body.
|
||||
//
|
||||
// Things are pretty easy after that. We allocate enough space to hold
|
||||
// a copy of the string in the rhs, and then copy it. The old name gets
|
||||
// set to 0, since this name hasn't been around long enough to have been
|
||||
// renamed. We could have copied the old name from the rhs, but I think
|
||||
// this way makes more sense.
|
||||
// And that's it.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALName::ALName( const ALName AL_DLL_FAR &rhs )
|
||||
: mCase( rhs.mCase )
|
||||
{
|
||||
const char *s = rhs.GetSafeName();
|
||||
mszName = new AL_DLL_FAR char[ strlen( s ) + 1 ];
|
||||
if ( mszName )
|
||||
Strcpy( s );
|
||||
mszOldName = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ALName & ALName::operator = ( const char * rhs )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// rhs : This is the character string that we are going to assign to this.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A reference to this. We need to do it that way so we can do:
|
||||
//
|
||||
// a = b = c = "test";
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function performs roughly the same function as the first
|
||||
// constructor, but there is a twist. When we assign a new name to
|
||||
// an ALName object, we also make a copy of fit and place it in
|
||||
// the old name data member.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALName AL_DLL_FAR & AL_PROTO ALName::
|
||||
operator = ( const char AL_DLL_FAR * rhs )
|
||||
{
|
||||
if ( rhs == 0 )
|
||||
rhs = "";
|
||||
if ( rhs == mszName ) // Pathological?
|
||||
return *this;
|
||||
|
||||
char AL_DLL_FAR *new_name = new AL_DLL_FAR char[ strlen( rhs ) + 1 ];
|
||||
if ( new_name ) {
|
||||
if ( mszOldName )
|
||||
delete[] mszOldName;
|
||||
mszOldName = mszName;
|
||||
mszName = new_name;
|
||||
Strcpy( rhs );
|
||||
} else {
|
||||
if ( mszOldName )
|
||||
delete[] mszOldName;
|
||||
mszOldName = mszName;
|
||||
mszName = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// ALName & ALName::operator = ( const ALName & rhs )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// rhs : The right hand side of the assignment operator.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A reference to this. Like in the above function, we do this so
|
||||
// that you can stack assignments:
|
||||
//
|
||||
// a = b = c = "Dummy";
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
//
|
||||
// This function is very similar to the copy constructor, but it has
|
||||
// one additional twist. When we copy the rhs string value into our
|
||||
// string, we move our old name into the backup copy member,
|
||||
// mszOldName. That way, if we change our mind, we can easily
|
||||
// switch back to the old name.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
ALName AL_DLL_FAR & AL_PROTO ALName::
|
||||
operator = ( const ALName AL_DLL_FAR & rhs )
|
||||
{
|
||||
return *this = rhs.GetName();
|
||||
}
|
||||
|
||||
//
|
||||
// ALName::~ALName()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None, this is a destructor.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None, destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// All this function has to do is free up the two pieces of
|
||||
// dynamic memory. I just can't get out of that old C habit of
|
||||
// checking a pointer for NULL before deleting it.
|
||||
//
|
||||
// In debug mode, I check the state of this before and after freeing
|
||||
// the dynamically allocated memory, in hopes of catching any
|
||||
// heap errors near their source.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALName::~ALName()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALName: attempt to delete invalid object" );
|
||||
if ( mszName )
|
||||
delete[] mszName;
|
||||
if ( mszOldName )
|
||||
delete[] mszOldName;
|
||||
AL_ASSERT( GoodTag(), "~ALName: attempt to delete invalid object" );
|
||||
}
|
||||
|
||||
//
|
||||
// ALName & ALName::ChangeExtension( const char *new_extension = ".bak" )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// new_extension : The new extension you want to apply to the name.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A reference to this. This is nice, because it lets you do things
|
||||
// like this:
|
||||
//
|
||||
// fopen( name.ChangeExtension( ".OBJ" ), "rb" );
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to change the extension of a filename stored
|
||||
// in an ALName object. A lot of times you will want to do this
|
||||
// in order to create a backup. For example, you could change
|
||||
// TEMP.DAT to TEMP.BAK.
|
||||
//
|
||||
// This function makes a copy of the current name in mszOldName, so we
|
||||
// can keep track of it later. It then searches for the '.' character
|
||||
// in the new file name, and sticks the new extension there.
|
||||
//
|
||||
// If you apply this function to a filename, you can then rename the file
|
||||
// by calling ALStorage::Rename() with no argument. When you do this,
|
||||
// the rename function uses the saved OldName and current name as its
|
||||
// arguments for the rename() function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
//
|
||||
// I need to fix this code up to handle extensions with and without a
|
||||
// leading '.' character. Maybe you can use a leading character
|
||||
// other than '.' to indicate a different type of extension?
|
||||
//
|
||||
|
||||
ALName AL_DLL_FAR & AL_PROTO ALName::
|
||||
ChangeExtension( const char AL_DLL_FAR *new_extension /* = ".bak" */ )
|
||||
{
|
||||
AL_ASSERT( new_extension != 0, "ChangeExtension: new extension is null" );
|
||||
AL_ASSERT( mszName, "ChangeExtension: current name is null" );
|
||||
|
||||
char *file_name = new char[ strlen( mszName ) + strlen( new_extension ) + 1 ];
|
||||
if ( mszOldName )
|
||||
delete[] mszOldName;
|
||||
mszOldName = mszName;
|
||||
mszName = file_name;
|
||||
|
||||
if ( !file_name )
|
||||
return *this;
|
||||
strcpy( mszName, mszOldName );
|
||||
char *p = strrchr( file_name, '.' );
|
||||
if ( p )
|
||||
strcpy( p, new_extension );
|
||||
else
|
||||
strcat( mszName, new_extension );
|
||||
switch ( mCase ) {
|
||||
case AL_UPPER : strupr( mszName ); break;
|
||||
case AL_LOWER : strlwr( mszName ); break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// ALName & ALName::ChangeTrailingChar( char new_char = '@' )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// new_char : The new character to use as the last name of the file
|
||||
// name.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A reference to this. This is nice, because it lets you do things
|
||||
// like this:
|
||||
//
|
||||
// fopen( name.ChangeTrailingChar(), "rb" );
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to change the the last character of the extension
|
||||
// in filename stored in an ALName object. A lot of times you will want to
|
||||
// do this in order to create a backup. For example, you could change
|
||||
// TEMP.DAT to TEMP.DA@.
|
||||
//
|
||||
// This function makes a copy of the current name in mszOldName, so we
|
||||
// can keep track of it later. It then searches for the end of the
|
||||
// current file name, and changes it.
|
||||
//
|
||||
// Note that if the filename doesn't have an extension, we do something
|
||||
// funny. Instead of just changing the last character, we create a
|
||||
// new extension, and append that instead. So if the filename is
|
||||
// "TEST", the new name will be "TEST.@".
|
||||
//
|
||||
// If you apply this function to a filename, you can then rename the file
|
||||
// by calling ALStorage::Rename() with no argument. When you do this,
|
||||
// the rename function uses the saved OldName and current name as its
|
||||
// arguments for the rename() function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALName AL_DLL_FAR & AL_PROTO ALName::
|
||||
ChangeTrailingChar( char new_char /* = '@' */ )
|
||||
{
|
||||
AL_ASSERT( mszName != 0, "ChangeTrailingChar: current name is null" );
|
||||
|
||||
char *file_name = new char[ strlen( mszName ) + 2 ];
|
||||
if ( mszOldName )
|
||||
delete[] mszOldName;
|
||||
mszOldName = mszName;
|
||||
mszName = file_name;
|
||||
switch ( mCase ) {
|
||||
case AL_UPPER : new_char = (char) toupper( new_char ); break;
|
||||
case AL_LOWER : new_char = (char) tolower( new_char ); break;
|
||||
}
|
||||
if ( !file_name )
|
||||
return *this;
|
||||
strcpy( mszName, mszOldName );
|
||||
char *p;
|
||||
if ( ( p = strrchr( mszName, '.' ) ) != 0 ) {
|
||||
if ( p[ 1 ] == '0' ) {
|
||||
p[ 1 ] = new_char;
|
||||
p[ 2 ] = '\0';
|
||||
} else
|
||||
mszName[ strlen( mszName ) - 1 ] = new_char;
|
||||
} else {
|
||||
char new_extension[ 3 ];
|
||||
new_extension[ 0 ] ='.';
|
||||
new_extension[ 1 ] = new_char;
|
||||
new_extension[ 2 ] = 0;
|
||||
strcat( mszName, new_extension );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// const char * ALName::GetSafeName() const
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// This function normally returns the value of mszName. However, if
|
||||
// mszName is currently a null pointer, we return a pointer to an
|
||||
// empty string instead. This means you can use the return value from
|
||||
// this function anywhere you want without checking for its NULLity.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// See above.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
const char AL_DLL_FAR * AL_PROTO ALName::GetSafeName() const
|
||||
{
|
||||
if ( mszName )
|
||||
return mszName;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
//
|
||||
// const char * ALName::GetSafeOldName() const
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// This function normally returns the value of mszOldName. However, if
|
||||
// mszOldName is currently a null pointer, we return a pointer to an
|
||||
// empty string instead. This means you can use the return value from
|
||||
// this function anywhere you want without checking for its NULLity.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// See above.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
const char AL_DLL_FAR * AL_PROTO ALName::GetSafeOldName() const
|
||||
{
|
||||
if ( mszOldName )
|
||||
return mszOldName;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
//
|
||||
// ALName::operator const char *() const
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to the string inside the object. If the string is
|
||||
// presently a null pointer, we return a pointer to an empty string
|
||||
// instead. See ALName::GetSafeName() for an explanation of why
|
||||
// this is.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is the casting operator that pretty much lets me use
|
||||
// an ALName object anywhere I use a char *. There are some strange
|
||||
// Microsoft compiler problems that make me use this goofy STRINGF
|
||||
// typedef instead of char *, but it all adds up the same in
|
||||
// the wash.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_MICROSOFT ) && ( AL_MICROSOFT < 800 ) && defined( AL_BUILDING_DLL ) //??????
|
||||
AL_PROTO ALName::operator char *() const
|
||||
#else
|
||||
AL_PROTO ALName::operator const STRINGF() const
|
||||
#endif
|
||||
{
|
||||
if ( mszName )
|
||||
return mszName;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
//
|
||||
// ALName & ALName::StripFileName()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A reference to this. This is nice, because you can strip the
|
||||
// file name from an object and use it in the same operation.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// In the wildcard parsing code, sometimes I need to get the path
|
||||
// of a file, which means stripping off the filename and extension.
|
||||
// This is pretty easy to do, I just find the right spot and stick
|
||||
// a string termination character in that position.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALName AL_DLL_FAR & AL_PROTO ALName::StripFileName()
|
||||
{
|
||||
if ( mszName ) {
|
||||
char *p = strrchr( mszName, '\\' );
|
||||
if ( p == 0 )
|
||||
p = strrchr( mszName, ':' );
|
||||
if ( p )
|
||||
p[ 1 ] = '\0';
|
||||
else
|
||||
mszName[ 0 ] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// ALName & ALName::StripPath()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A reference to this. This is nice, because you can strip the
|
||||
// file name from an object and use it in the same operation.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// In the wildcard parsing code, sometimes I need to get just the
|
||||
// filename and extension of a file, which means stripping off the
|
||||
// drive and path information. This is pretty easy to do, I just find
|
||||
// the start of the filename, and move it up to the start of the string.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
ALName AL_DLL_FAR & AL_PROTO ALName::StripPath()
|
||||
{
|
||||
if ( mszName ) {
|
||||
char *p = strrchr( mszName, '\\' );
|
||||
if ( p == 0 )
|
||||
p = strrchr( mszName, ':' );
|
||||
if ( p ) {
|
||||
p++;
|
||||
char *s = mszName;
|
||||
while( ( *s++ = *p++ ) != 0 )
|
||||
;
|
||||
*s = '\0';
|
||||
} //If not p, path is already stripped
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALName::WildCardMatch( const char *pattern )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// pattern : A pointer to a regular expression, including wildcards
|
||||
// and sets. It can get pretty complicated.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// 0 if the pattern doesn't match the object name, 1 if it does.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This is a super-duper powerful function. It is used to compare
|
||||
// a regular expression to the contents of an ALName. The real meat
|
||||
// here is in the public domain string matching code found in _MATCH.CPP.
|
||||
//
|
||||
// The tricky bit here is that we have to make a comparison based
|
||||
// on the case sensitivity of this. Rather than trying to modify
|
||||
// the code in _MATCH.CPP, I just make a new copy of the pattern, and
|
||||
// mangle the case according to what this expects.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALName::WildCardMatch( const char AL_DLL_FAR *pattern )
|
||||
{
|
||||
int error;
|
||||
int result;
|
||||
char *p = new char[ strlen( pattern ) + 1 ];
|
||||
|
||||
if ( !p )
|
||||
return 0;
|
||||
strcpy( p, pattern );
|
||||
switch ( mCase ) {
|
||||
case AL_UPPER : strupr( p ); break;
|
||||
case AL_LOWER : strlwr( p ); break;
|
||||
}
|
||||
if ( !is_valid_pattern( p, &error ) )
|
||||
result = 0;
|
||||
else if ( matche( p, mszName ) == MATCH_VALID )
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
delete p;
|
||||
return result;
|
||||
}
|
||||
|
||||
// PROTECTED MEMBER FUNCTION.
|
||||
//
|
||||
// void ALName::Strcpy( const char *s )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// s : A character string to be copied into mszName.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Whenever I am going to copy a string into mszName, I need to convert
|
||||
// it to the case that this object expects. If it is AL_UPPER or
|
||||
// AL_LOWER, that means copying and then converting to either all upper
|
||||
// case or all lower case. I do that here.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALName::Strcpy( const char *s )
|
||||
{
|
||||
strcpy( mszName, s );
|
||||
switch ( mCase ) {
|
||||
case AL_UPPER : strupr( mszName ); break;
|
||||
case AL_LOWER : strlwr( mszName ); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
215
al/objname.h
Executable file
215
al/objname.h
Executable file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* OBJNAME.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file contains the class definition for ALName. Most of the time
|
||||
* this class is used to contain file names.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALName
|
||||
*
|
||||
* FUNCTIONS:
|
||||
*
|
||||
* ostream& operator << ( ostream& stream, const ALName &object )
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OBJNAME_H
|
||||
#define _OBJNAME_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
#include <string.h>
|
||||
#include <iostream.h>
|
||||
|
||||
/*
|
||||
* class ALName
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Object names are mostly used for names of storage objects.
|
||||
* There are enough things that I do with these guys to justify
|
||||
* a class of their own. Having all the object name functions in their
|
||||
* own class also cuts back on the number of functions in ALStorage,
|
||||
* which is already cluttered.
|
||||
*
|
||||
* Besides serving as the mName member in ALStorage, this class is
|
||||
* also pressed into service in ALWildCardExpander, where it is very
|
||||
* handy.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mszName : A pointer to the name associated with this object.
|
||||
* This pointer can be a null pointer. The object is
|
||||
* responsible for deleting this guy in the ALName
|
||||
* destructor, along with the next member, mszOldName.
|
||||
*
|
||||
* mszOldName : A pointer to the last name associated with this
|
||||
* object. When you assign a new name to one of these
|
||||
* objects, the old name gets stored here. This makes
|
||||
* it easy to revert to the old name in case of trouble.
|
||||
*
|
||||
* mCase : One of AL_UPPER, AL_LOWER, or AL_MIXED. If the value
|
||||
* is AL_UPPER or AL_LOWER, the name is forced to all
|
||||
* upper or lower case whenever it is assigned to the
|
||||
* object.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALName(const ALName &) : The copy constructor.
|
||||
* ALName(const char *) : Constructor that initializes with a char *.
|
||||
* operator=(const ALName&) : Assignment operator.
|
||||
* operator=(const char *) : Assignment operator for char *.
|
||||
* ~ALName() : Destructor, has to clean up dynamic storage.
|
||||
* operator new() : Memory allocation operatory, only used
|
||||
* when the library is inside the DLL. Be
|
||||
* aware that this operator allocates space for
|
||||
* the object itself, not the strings that it
|
||||
* will contain.
|
||||
* Strcpy() : A protected member function, copies and
|
||||
* converts to the appropriate case if necessary.
|
||||
* GetName() : Returns a pointer to the name string, might
|
||||
* be 0.
|
||||
* GetOldName() : Returns a pointer to the previous name
|
||||
* string, might be 0.
|
||||
* GetSafeName() : Returns a pointer to the name string, but
|
||||
* is guaranteed not to return 0.
|
||||
* GetSafeOldName() : Returns a pointer to the old name string, but
|
||||
* is guaranteed not to return 0.
|
||||
* ChangeExtension() : Change a filename extension to a new one.
|
||||
* ChangeTrailingChar() : Change the trailing character in the filename.
|
||||
* StripFileName() : Remove the filename, leaving the path and drive.
|
||||
* StripPath() : Remove path and drive, leaving the filename.
|
||||
* WildCardMatch() : Test for a match against a regular expression.
|
||||
* operator const char *() : Return a char *.
|
||||
* operator+() : Append a string to this string.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Microsoft won't let me create a cast operator for char _far *.
|
||||
* But they will let me cast to this typedef. Ugly, but it works.
|
||||
*/
|
||||
|
||||
typedef char AL_DLL_FAR * STRINGF;
|
||||
|
||||
class AL_CLASS_TYPE ALName {
|
||||
/*
|
||||
* Constructors, destructors, assignment operator, and friends
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALName( const ALName AL_DLL_FAR & );
|
||||
AL_PROTO ALName( const char AL_DLL_FAR *s = "",
|
||||
ALCase name_case = AL_MIXED );
|
||||
ALName AL_DLL_FAR & AL_PROTO operator = ( const ALName AL_DLL_FAR & rhs );
|
||||
ALName AL_DLL_FAR & AL_PROTO operator = ( const char AL_DLL_FAR * rhs );
|
||||
AL_PROTO ~ALName();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Note that I don't have the normal prohibition against a copy constructor
|
||||
* or an assignment operator in this class, because I support them here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Member Functions
|
||||
*/
|
||||
protected :
|
||||
void AL_PROTO Strcpy( const char AL_DLL_FAR *s );
|
||||
|
||||
public :
|
||||
const char AL_DLL_FAR * AL_PROTO GetName() const { return mszName; }
|
||||
const char AL_DLL_FAR * AL_PROTO GetOldName() const { return mszOldName; }
|
||||
const char AL_DLL_FAR * AL_PROTO GetSafeName() const;
|
||||
const char AL_DLL_FAR * AL_PROTO GetSafeOldName() const;
|
||||
ALName AL_DLL_FAR & AL_PROTO
|
||||
ChangeExtension( const char AL_DLL_FAR *new_extension = ".bak" );
|
||||
ALName AL_DLL_FAR & AL_PROTO ChangeTrailingChar( char new_char = '@' );
|
||||
ALName AL_DLL_FAR & AL_PROTO StripFileName();
|
||||
ALName AL_DLL_FAR & AL_PROTO StripPath();
|
||||
int AL_PROTO WildCardMatch( const char AL_DLL_FAR *pattern );
|
||||
/*
|
||||
* Operators
|
||||
*/
|
||||
public :
|
||||
#if defined( AL_MICROSOFT ) && ( AL_MICROSOFT < 800 ) && ( defined( AL_BUILDING_DLL ) || defined( AL_USING_DLL ) ) /*??? DON'T ASK ME WHY */
|
||||
AL_PROTO operator STRINGF() const;
|
||||
#else
|
||||
AL_PROTO operator const STRINGF() const;
|
||||
#endif
|
||||
ALName AL_PROTO operator + ( const char AL_DLL_FAR *rhs );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
char AL_DLL_FAR * mszName;
|
||||
char AL_DLL_FAR * mszOldName;
|
||||
public :
|
||||
const ALCase mCase;
|
||||
AL_CLASS_TAG( _ALNameTag );
|
||||
};
|
||||
|
||||
/*
|
||||
* ostream& operator << ( ostream& stream, const ALName &object )
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* stream : An I/O stream.
|
||||
*
|
||||
* object : A reference to an ALName object.
|
||||
*
|
||||
* RETURNS
|
||||
*
|
||||
* A reference to the stream provided as an operator.
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This stream operator makes it easy to send ALName objects
|
||||
* to an output stream. I need to define this function as inline,
|
||||
* because it is tough to use far references to ostreams from a DLL.
|
||||
* There are other problems associated with using this function
|
||||
* in a DLL, and I don't understand them all.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
inline ostream& operator << ( ostream& stream, const ALName AL_DLL_FAR &object )
|
||||
{
|
||||
#if defined( AL_USING_DLL ) && !defined( AL_LARGE_MODEL ) && !defined( AL_FLAT_MODEL )
|
||||
const char _far *p = (STRINGF) object;
|
||||
char *near_string = new char[ _fstrlen( p ) + 1 ];
|
||||
if ( near_string ) {
|
||||
_fstrcpy( near_string, p );
|
||||
stream << near_string;
|
||||
delete near_string;
|
||||
} else
|
||||
stream << "Memory allocation failure!";
|
||||
#else
|
||||
stream << (STRINGF) object;
|
||||
#endif
|
||||
return stream;
|
||||
}
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifndef _OBJNAME_H */
|
||||
|
||||
100
al/spinner.h
Executable file
100
al/spinner.h
Executable file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* SPINNER.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class definition for the ALMonitor
|
||||
* derived object ALSpinner.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALSpinner
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SPINNER_H
|
||||
#define _SPINNER_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/*
|
||||
* class ALSpinner : public ALMonitor
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ALSpinner is a very simple monitor class, and is only useful under
|
||||
* DOS, not Windows. All ALSpinner does is spin a little propellor
|
||||
* around while the file is being processed. This lets you know
|
||||
* that something is happening in an otherwise boring process.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miSpinIndex : A Static variable that keeps track of which
|
||||
* position the propellor should be in. The
|
||||
* propellor travels through one of four different
|
||||
* positions.
|
||||
*
|
||||
* mrStream : A reference to the stream that the propellor is
|
||||
* going to be written on.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALSpinner() : The one and only constructor.
|
||||
* ~ALSpinner() : The virtual destructor.
|
||||
* Progress() : The routine that gets called to make the
|
||||
* propellor twitch.
|
||||
* ArchiveOperation() : The routine that gets called when archiving
|
||||
* starts, stops, etc.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALSpinner : public ALMonitor {
|
||||
/*
|
||||
* Constructors, destructors, and friend classes
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALSpinner( ALMonitorType monitor_type,
|
||||
ostream& stream = cout );
|
||||
virtual AL_PROTO ~ALSpinner();
|
||||
/*
|
||||
* The copy constructor and assignment operator do not exist.
|
||||
*/
|
||||
protected :
|
||||
ALSpinner( const ALSpinner& );
|
||||
ALSpinner& operator=( const ALSpinner& );
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
protected :
|
||||
virtual void AL_PROTO Progress( long mlObjectSoFar, ALStorage& object );
|
||||
virtual void AL_PROTO ArchiveOperation( ALArchiveOperation operation,
|
||||
ALArchiveBase *archive,
|
||||
ALEntry *job );
|
||||
/*
|
||||
* Data Members
|
||||
*/
|
||||
protected :
|
||||
static int miSpinIndex;
|
||||
ostream& mrStream;
|
||||
public :
|
||||
AL_CLASS_TAG( _ALSpinnerTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifdef SPINNER_H */
|
||||
335
al/status.cpp
Executable file
335
al/status.cpp
Executable file
@ -0,0 +1,335 @@
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
158
al/status.h
Executable file
158
al/status.h
Executable file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* STATUS.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class declaration for ALStatus.
|
||||
* This is a utility class that is used as a data member in many
|
||||
* different types of objects. It holds the current error status
|
||||
* of an object.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALStatus
|
||||
*
|
||||
* MACROS
|
||||
*
|
||||
* ostream& operator << ( ostream& stream, const ALStatus &status )
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _STATUS_H
|
||||
#define _STATUS_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/*
|
||||
* class ALStatus
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ALStatus is a utility class that is used as a data member of several
|
||||
* other classes. It provides an integer member that keeps track
|
||||
* of the current status of the object, with AL_SUCCESS meaning
|
||||
* everything is okay, and a code < 0 meaning the object has
|
||||
* experienced an error.
|
||||
*
|
||||
* The object also contains a character pointer to a detailed error
|
||||
* message. Usually when an error occurs in ArchiveLib, the
|
||||
* routine that detects the error generates a detailed message that
|
||||
* can be stored to provide additional information.
|
||||
*
|
||||
* Error states in ArchiveLib are "sticky". Once an object is flagged
|
||||
* as being in error, it will stay that way until the programmer
|
||||
* resets it, which means it will fail most ordinary operations.
|
||||
* When you want to clear the error statue of an object, call
|
||||
* SetError() with AL_SUCCESS as the error code.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miStatus : The current status of the object, with AL_SUCCESS
|
||||
* being a good value. You can get at this easily
|
||||
* by casting ALStatus to type int.
|
||||
*
|
||||
* miStatusDetailLength : This member keeps track of the length of the
|
||||
* status detail. The status detail buffer
|
||||
* is dynamically allocated when it is needed.
|
||||
* Keeping this member is really kind of dumb, I
|
||||
* need to just allocate as much space as necessary
|
||||
* when the error detail is created. Look for this
|
||||
* data member to go away in an upcoming release.
|
||||
*
|
||||
* mszStatusDetail : The detailed error message. It will be set to
|
||||
* 0 until a message is generated, when it
|
||||
* is dynamically allocated. Cleaned up if necessary
|
||||
* in the destructor.
|
||||
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALStatus() : The default and only constructor.
|
||||
* ~ALStatus() : The destructor, has to clean up detail string.
|
||||
* operator new() : Memory allocation operator, allocates space
|
||||
* for the class object when the library is in
|
||||
* the DLL.
|
||||
* SetError() : Sets the error code to a value, and writes
|
||||
* new data into the detail string.
|
||||
* GetStatusCode() : Returns the current integer status code,
|
||||
* just like operator int().
|
||||
* GetStatusString() : Returns the short string translation.
|
||||
* GetStatusDetail() : Returns the detailed status message, created
|
||||
* at the point the error took place.
|
||||
* operator int() : The casting operator, used all over ArchiveLib
|
||||
* when testing a status for a value < AL_SUCCESS.
|
||||
* operator=() : Assignment operator, easy here.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class AL_CLASS_TYPE ALStatus {
|
||||
/*
|
||||
* Constructors, destructors, assignment operators, and declarations
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALStatus();
|
||||
AL_PROTO ~ALStatus();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* I don't want to allow the copy constructor, although I probably could
|
||||
* support it without too much trouble.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALStatus( ALStatus AL_DLL_FAR & );
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
public :
|
||||
int AL_PROTO SetError( int error, const char AL_DLL_FAR *fmt, ... );
|
||||
AL_PROTO GetStatusCode(){ return miStatus; }
|
||||
const char AL_DLL_FAR * AL_PROTO GetStatusString();
|
||||
const char AL_DLL_FAR * AL_PROTO GetStatusDetail() const;
|
||||
AL_PROTO operator int(){ return miStatus; }
|
||||
ALStatus AL_DLL_FAR & AL_PROTO operator = ( ALStatus AL_DLL_FAR & );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
int miStatus;
|
||||
const int miStatusDetailLength;
|
||||
char AL_DLL_FAR *mszStatusDetail;
|
||||
|
||||
};
|
||||
|
||||
inline ostream& operator << ( ostream& stream, const ALStatus AL_DLL_FAR &status )
|
||||
{
|
||||
#if defined( AL_USING_DLL ) && !defined( AL_LARGE_MODEL ) && !defined( AL_FLAT_MODEL )
|
||||
const char _far *p = status.GetStatusDetail();
|
||||
char *near_string = new char[ _fstrlen( p ) + 1 ];
|
||||
if ( near_string ) {
|
||||
_fstrcpy( near_string, p );
|
||||
stream << near_string;
|
||||
delete near_string;
|
||||
} else
|
||||
stream << "Memory allocation failure!";
|
||||
return stream;
|
||||
#else
|
||||
return stream << status.GetStatusDetail();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifdef _STATUS_H */
|
||||
|
||||
979
al/storage.cpp
Executable file
979
al/storage.cpp
Executable file
@ -0,0 +1,979 @@
|
||||
//
|
||||
// STORAGE.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALStorage::operator new()
|
||||
// ALStorage::ALStorage()
|
||||
// ALStorage::~ALStorage()
|
||||
// ALStorage::UpdateCrc()
|
||||
// ALStorage::Open()
|
||||
// ALStorage::Create()
|
||||
// ALStorage::Close()
|
||||
// ALStorage::GetCrc32()
|
||||
// ALStorage::InitCrc32()
|
||||
// ALStorage::ReadBuffer()
|
||||
// ALStorage::WriteBuffer()
|
||||
// ALStorage::WritePortableShort()
|
||||
// ALStorage::WritePortableLong()
|
||||
// ALStorage::ReadPortableShort()
|
||||
// ALStorage::ReadPortableLong()
|
||||
// ALStorage::WriteString()
|
||||
// ALStorage::ReadString()
|
||||
// ALStorage::Tell()
|
||||
// ALStorage::YieldTime()
|
||||
// ALStorage::WriteStorageObjectData()
|
||||
// ALStorage::ReadStorageObjectData()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all of the source code for the member functions
|
||||
// of ALStorage. AlStorage has pure virtual functions, so you can't
|
||||
// ever instantiate one of these guys.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//
|
||||
// void * ALStorage::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALStorage 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 ALStorage::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALStorage::ALStorage( const char *file_name,
|
||||
// size_t size,
|
||||
// const enum ALStorageType object_type,
|
||||
// ALCase name_case )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// file_name : The name to assign to the mName data member of the
|
||||
// newly created storage object.
|
||||
//
|
||||
// size : The size of the I/O buffer that is going to be used
|
||||
// for the storage object. ALFile uses 4096 as a default.
|
||||
//
|
||||
// object_type : The type of object, as defined in ALDEFS.H. Good
|
||||
// values include AL_FILE_OBJECT and AL_MEMORY_OBJECT.
|
||||
//
|
||||
// name_case : The case sensitivity of the object name. For objects
|
||||
// such as ALFile, AL_MIXED is a no-no. Those objects
|
||||
// need to be forced to convert names to all upper
|
||||
// or all lower, because the operating system considers
|
||||
// file names to be case insensitive.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing, it is a constructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The constructor for ALStorage gets called from the constructor of
|
||||
// derived classes. It has to initialize all sorts of data members.
|
||||
// First, in the initializer list, it sets up the mName data member,
|
||||
// as well as muBufferSize and miStorageObjectType. The latter two
|
||||
// data members are set to be const so I can make them public, which
|
||||
// means we have to initialize them in the initializer list.
|
||||
//
|
||||
// In the body of the constructor, we initialize a bunch of data members,
|
||||
// none of which mean anything at this point.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALStorage::ALStorage( const char AL_DLL_FAR *file_name,
|
||||
size_t size,
|
||||
const enum ALStorageType object_type,
|
||||
ALCase name_case )
|
||||
: mName( file_name, name_case ),
|
||||
miStorageObjectType( object_type ),
|
||||
muBufferSize( size )
|
||||
{
|
||||
mpcBuffer = 0;
|
||||
muBufferValidData = 0;
|
||||
muWriteIndex = 0;
|
||||
muReadIndex = 0;
|
||||
mlFilePointer = 0;
|
||||
miUpdateCrcFlag = 0;
|
||||
mlCrc32 = 0xffffffffL;
|
||||
mlSize = -1L;
|
||||
mpMonitor = 0;
|
||||
miCreated = 0;
|
||||
if ( mName.GetName() == 0 )
|
||||
mStatus.SetError( AL_CANT_OPEN_BUFFER,
|
||||
"Allocation of buffer failed in "
|
||||
"ALStorage constructor" );
|
||||
}
|
||||
|
||||
//
|
||||
// ALStorage::~ALStorage()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// No arguments for destructors.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// No returns from destructors.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// In debug mode, we first check to make sure we are destroying the
|
||||
// right type of object.
|
||||
//
|
||||
// The only thing left to do is free up the I/O buffer if it is still
|
||||
// allocated. This piece of work probably isn't necessary. Since this
|
||||
// is a virtual destructor, we will be called after the destructors
|
||||
// for the derived class. Any derived class that is doing its job
|
||||
// will make sure that it calls Close() before destroying itself. If
|
||||
// it doesn't, it will probably be leaving unfinished business behind
|
||||
// that we aren't going to be able to deal with here. Even so, we will
|
||||
// be diligent in our attention to detail.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALStorage::~ALStorage()
|
||||
{
|
||||
AL_ASSERT( GoodTag(), "~ALStorage: attempting to delete invalid object" );
|
||||
if ( mpcBuffer )
|
||||
Close();
|
||||
}
|
||||
|
||||
//
|
||||
// This giant table is used by the CRC routines. These are the coefficients
|
||||
// for calculating the CCITT 32 bit CRC. I typed these in from memory, so
|
||||
// I hope they are correct.
|
||||
//
|
||||
static unsigned long ccitt_32[ 256 ] =
|
||||
{
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
|
||||
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
|
||||
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
|
||||
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
|
||||
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
|
||||
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
|
||||
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
|
||||
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
|
||||
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
|
||||
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
|
||||
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
|
||||
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
|
||||
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
|
||||
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
|
||||
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
|
||||
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
|
||||
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
|
||||
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
|
||||
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
|
||||
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
|
||||
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
|
||||
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
|
||||
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
|
||||
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
|
||||
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
|
||||
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
|
||||
};
|
||||
|
||||
//
|
||||
// void ALStorage::UpdateCrc( size_t count )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// count : The number of characters to process in the I/O buffer.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// If CRC checking has been turned on for the storage object, this
|
||||
// routine will be called every time LoadBuffer() or FlushBuffer()
|
||||
// are called. It does CRC checking on a buffer full of data at
|
||||
// a time. Hopefully this means the compiler can optimize the
|
||||
// heck out of this code.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALStorage::UpdateCrc( size_t count )
|
||||
{
|
||||
unsigned char *p = (unsigned char *) mpcBuffer;
|
||||
while ( count-- != 0 )
|
||||
mlCrc32 = ( ( mlCrc32 >> 8 ) & 0x00FFFFFFL ) ^
|
||||
( ccitt_32[ ( (int) mlCrc32 ^ *p++ ) & 0xff ] );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::Open()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, or AL_CANT_OPEN_BUFFER on memory allocation failure.
|
||||
// If the object was already in an error state, it is very possible to
|
||||
// get some other error code < 0.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Any derived class needs to have its own Open() function. However,
|
||||
// the derived class can also call this Open() function in the base
|
||||
// class to do some odds and ends for it. The most important thing it
|
||||
// does is allocate the I/O buffer, which is what makes ALStorage a
|
||||
// relatively fast way to read and write data. Although the buffer
|
||||
// is in place, there is no data in it, so this guy also sets up the
|
||||
// indices and pointers to reflect that.
|
||||
//
|
||||
// Upon exit, all you need to to is start reading or writing, and the
|
||||
// whole thing should be ready to go.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::Open()
|
||||
{
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
if ( muBufferSize != 0 )
|
||||
mpcBuffer = new unsigned char[ muBufferSize ];
|
||||
muBufferValidData = 0;
|
||||
muWriteIndex = 0;
|
||||
muReadIndex = 0;
|
||||
mlFilePointer = 0;
|
||||
miUpdateCrcFlag = 0;
|
||||
mlCrc32 = 0xffffffffL;
|
||||
if ( mpcBuffer == 0 )
|
||||
return mStatus.SetError( AL_CANT_OPEN_BUFFER,
|
||||
"Allocation of buffer failed in Open()" );
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::Create()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS, or AL_CANT_OPEN_BUFFER on memory allocation failure.
|
||||
// If the object was already in an error state, it is very possible to
|
||||
// get some other error code < 0.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is nearly identical to ALStorage::Open().
|
||||
//
|
||||
// Any derived class needs to have its own Create() function. However,
|
||||
// the derived class can also call this Create() function in the base
|
||||
// class to do some odds and ends for it. The most important thing it
|
||||
// does is allocate the I/O buffer, which is what makes ALStorage a
|
||||
// relatively fast way to read and write data. Although the buffer
|
||||
// is in place, there is no data in it, so this guy also sets up the
|
||||
// indices and pointers to reflect that.
|
||||
//
|
||||
// Upon exit, all you need to to is start writing, and the
|
||||
// whole thing should be ready to go.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::Create()
|
||||
{
|
||||
if ( mStatus < AL_SUCCESS )
|
||||
return mStatus;
|
||||
mpcBuffer = new unsigned char[ muBufferSize ];
|
||||
muBufferValidData = 0;
|
||||
muWriteIndex = 0;
|
||||
muReadIndex = 0;
|
||||
mlFilePointer = 0;
|
||||
miUpdateCrcFlag = 0;
|
||||
mlCrc32 = 0xffffffffL;
|
||||
miCreated = 1;
|
||||
if ( mpcBuffer == 0 )
|
||||
return mStatus.SetError( AL_CANT_OPEN_BUFFER,
|
||||
"Allocation of buffer failed in Open()" );
|
||||
return AL_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::Close()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The current integer status of the object. Hopefully this will be
|
||||
// AL_SUCCESS, but it could well be a value < AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Just like with Open(), must derived classes will have their own
|
||||
// versions of Close(). They can call this version to delete the I/O
|
||||
// buffer if they feel like it is too hard to do themselves.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::Close()
|
||||
{
|
||||
if ( mpcBuffer ) {
|
||||
delete[] mpcBuffer;
|
||||
mpcBuffer = 0;
|
||||
}
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// long ALStorage::GetCrc32()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The current value of the CRC-32.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to get the CRC-32 of a storage object. But it
|
||||
// does a little bit more than just give you the CRC. First, it makes
|
||||
// sure the buffers have been flushed, so that the CRC is accurate. If
|
||||
// we didn't do this we might try to get the CRC on an incompletely
|
||||
// written file.
|
||||
//
|
||||
// Once we get the CRC,the miUpdateCrcFlag is set to 0, which means
|
||||
// that from here on out the value will not be updated. So retrieving
|
||||
// the CRC means you are no longer interested in further calculation.
|
||||
// It also means you can trust the value you just read, because it
|
||||
// will never be modified again.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
long AL_PROTO ALStorage::GetCrc32()
|
||||
{
|
||||
if ( IsOpen() && miUpdateCrcFlag )
|
||||
FlushBuffer();
|
||||
miUpdateCrcFlag = 0;
|
||||
return mlCrc32;
|
||||
}
|
||||
|
||||
//
|
||||
// void ALStorage::InitCrc32( unsigned long seed = 0xffffffffL )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// seed : The long value to start the CRC off at. There is probably
|
||||
// no reason to change this from the default value, although
|
||||
// I won't be surprised if someone comes up with one.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Calling this function kicks off the CRC calculation for a given
|
||||
// storage object should be done immediately after the object is
|
||||
// opened. Once the miUpdateCrcFlag is set, the CRC will be updated
|
||||
// every time a LoadBuffer() or FlushBuffer() is called.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALStorage::InitCrc32( unsigned long seed /* = 0xffffffffL */ )
|
||||
{
|
||||
miUpdateCrcFlag = 1;
|
||||
mlCrc32 = seed;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// size_t ALStorage::ReadBuffer( unsigned char *buf, size_t length )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// buf : The buffer that is going to receive input characters.
|
||||
//
|
||||
// length : The number of bytes you want to read.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of bytes read in, always. If this function generates an
|
||||
// error, it will be found in the mStatus member.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// We could write a simple version of this function by just calling
|
||||
// ReadChar() over and over, but it would be nice to do things
|
||||
// a little more efficiently. Since we have this nice big buffer
|
||||
// full of data ready to read, it makes sense to copy big chunks of
|
||||
// it in one fell swoop. That is what this guy does. It sits in a loop
|
||||
// doing a memcpy() followed by LoadBuffer() until all of the data
|
||||
// that has been asked for got moved. As data is read in, we have to
|
||||
// update the data member muReadIndex. Other data members will get
|
||||
// updated by LoadBuffer().
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
size_t AL_PROTO ALStorage::ReadBuffer( unsigned char *buf,
|
||||
size_t length )
|
||||
{
|
||||
size_t bytes_left_to_read = length;
|
||||
size_t buffer_bytes_available;
|
||||
|
||||
while ( bytes_left_to_read ) {
|
||||
buffer_bytes_available = muBufferValidData - muReadIndex;
|
||||
if ( buffer_bytes_available == 0 ) {
|
||||
if ( LoadBuffer( mlFilePointer ) < 0 )
|
||||
return length - bytes_left_to_read;
|
||||
buffer_bytes_available = muBufferValidData;
|
||||
}
|
||||
if ( bytes_left_to_read <= buffer_bytes_available ) {
|
||||
memcpy( buf, mpcBuffer + muReadIndex, bytes_left_to_read );
|
||||
muReadIndex += bytes_left_to_read;
|
||||
return length;
|
||||
} else {
|
||||
memcpy( buf, mpcBuffer + muReadIndex, buffer_bytes_available );
|
||||
buf += buffer_bytes_available;
|
||||
bytes_left_to_read -= buffer_bytes_available;
|
||||
muReadIndex += buffer_bytes_available;
|
||||
if ( LoadBuffer( mlFilePointer ) < 0 )
|
||||
return length - bytes_left_to_read;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
//
|
||||
// size_t ALStorage::WriteBuffer( const unsigned char *buf,
|
||||
// size_t length )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// buf : The buffer that is contains the output data.
|
||||
//
|
||||
// length : The number of bytes you want to write.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// The number of bytes written, always. If this function generates an
|
||||
// error, it will be found in the mStatus member.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// We could write a simple version of this function by just calling
|
||||
// WriteChar() over and over, but it would be nice to do things
|
||||
// a little more efficiently. Since we have this nice big buffer
|
||||
// just waiting for data, it makes sense to copy big chunks to
|
||||
// it in one fell swoop. That is what this guy does. It sits in a loop
|
||||
// doing a memcpy() followed by FlushBuffer() until all of the data
|
||||
// that was ready to go has been sent. As data is written, we have to
|
||||
// update the data member muWriteIndex. Other data members will get
|
||||
// updated by FlushBuffer().
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
size_t AL_PROTO ALStorage::WriteBuffer( const unsigned char *buf,
|
||||
size_t length )
|
||||
{
|
||||
size_t buffer_bytes_free;
|
||||
size_t write_bytes_left = length;
|
||||
|
||||
if ( mStatus < 0 )
|
||||
return 0;
|
||||
while ( write_bytes_left > 0 ) {
|
||||
buffer_bytes_free = muBufferSize - muWriteIndex;
|
||||
if ( buffer_bytes_free == 0 ) {
|
||||
if ( FlushBuffer() < 0 )
|
||||
return length - write_bytes_left;
|
||||
buffer_bytes_free = muBufferSize;
|
||||
}
|
||||
if ( write_bytes_left <= buffer_bytes_free ) {
|
||||
memcpy( mpcBuffer + muWriteIndex, buf, write_bytes_left );
|
||||
muWriteIndex += write_bytes_left;
|
||||
return length;
|
||||
} else {
|
||||
memcpy( mpcBuffer + muWriteIndex, buf, buffer_bytes_free );
|
||||
muWriteIndex += buffer_bytes_free;
|
||||
buf += buffer_bytes_free;
|
||||
write_bytes_left -= buffer_bytes_free;
|
||||
if ( FlushBuffer() < 0 )
|
||||
return length - write_bytes_left;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::WritePortableShort( short int short_data )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// short_data : A 16 bit int that is going to be written out in
|
||||
// little endian format.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if all goes well. Otherwise, some error code < AL_STATUS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// In order to make sure our archives can be read and written on all sorts
|
||||
// of systems, we have a few functions that are used to write numerical
|
||||
// data in a portable fashion. This function writes short integers in
|
||||
// little endian format (which is not native Intel format). The complementary
|
||||
// function, ReadPortableShort(), reads short integers back using the
|
||||
// same format.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::WritePortableShort( short int short_data )
|
||||
{
|
||||
WriteChar( short_data >> 8 );
|
||||
WriteChar( short_data );
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::WritePortableLong( long int long_data )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// long_data : A 32 bit long int that is going to be written out in
|
||||
// little endian format.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if all goes well. Otherwise, some error code < AL_STATUS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// In order to make sure our archives can be read and written on all sorts
|
||||
// of systems, we have a few functions that are used to write numerical
|
||||
// data in a portable fashion. This function writes long integers in
|
||||
// little endian format (which is not native Intel format). The
|
||||
// complementary function, ReadPortableLong(), reads long integers back
|
||||
// using the same format.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::WritePortableLong( long long_data )
|
||||
{
|
||||
WriteChar( (int) ( long_data >> 24 ) );
|
||||
WriteChar( (int) ( long_data >> 16 ) );
|
||||
WriteChar( (int) ( long_data >> 8 ) );
|
||||
WriteChar( (int) long_data );
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::ReadPortableShort( short int &short_data )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// short_data : A reference to a 16 bit integer that is going to
|
||||
// have data read in from this storage object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if all goes well. Otherwise, some error code < AL_STATUS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// In order to make sure our archives can be read and written on all sorts
|
||||
// of systems, we have a few functions that are used to read numerical
|
||||
// data in a portable fashion. This function reads short integers in
|
||||
// little endian format (which is not native Intel format). The
|
||||
// complementary function, WritePortableShort(), writes short integers out
|
||||
// using the same format.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::ReadPortableShort( short int & short_data )
|
||||
{
|
||||
short_data = (short int) ( ReadChar() << 8 );
|
||||
short_data |= (short int) ReadChar();
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::ReadPortableLong( long int &short_data )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// long_data : A reference to a 32 bit integer that is going to
|
||||
// have data read in from this storage object.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if all goes well. Otherwise, some error code < AL_STATUS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// In order to make sure our archives can be read and written on all sorts
|
||||
// of systems, we have a few functions that are used to read numerical
|
||||
// data in a portable fashion. This function reads long integers in
|
||||
// little endian format (which is not native Intel format). The
|
||||
// complementary function, WritePortableLong(), writes long integers out
|
||||
// using the same format.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::ReadPortableLong( long & long_data )
|
||||
{
|
||||
long_data = (long) ReadChar() << 24;
|
||||
long_data |= (long) ReadChar() << 16;
|
||||
long_data |= (long) ReadChar() << 8;
|
||||
long_data |= ReadChar();
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::WriteString( const char *string_data )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// string_data : A string to be written out in our portable format.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if things work, or an error code < AL_SUCCESS if an error
|
||||
// occurs writing the data out.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// We write random length data to archive directories using this special
|
||||
// format, which is a 16 bit int describing the length of the data,
|
||||
// followed by the data itself. All of the storage objects and compression
|
||||
// engines write their own private data out using this format. This
|
||||
// means that even if another class doesn't understand the content of data
|
||||
// stored in this format, at least it knows how to read it in so as to
|
||||
// move past it.
|
||||
//
|
||||
// This function won't write just any random data, it is specifically
|
||||
// oriented towards C strings. This means it is mostly used to write
|
||||
// file names and comments. Their are a few places where classes
|
||||
// write private data that isn't kept in C strings, they just manually
|
||||
// write the length with WritePortableShort(), followed by the data.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::WriteString( const char *string_data )
|
||||
{
|
||||
short unsigned int len;
|
||||
if ( string_data != 0 )
|
||||
len = (short unsigned int) strlen( string_data );
|
||||
else
|
||||
len = 0;
|
||||
WritePortableShort( len );
|
||||
if ( len )
|
||||
WriteBuffer( (unsigned char *) string_data, len );
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
// PROTECTED MEMBER FUNCTION
|
||||
//
|
||||
// char * ALStorage::ReadString()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A pointer to a string. This string has been allocated by the library,
|
||||
// which can cause a problem if you are using a DLL. If an EXE tried
|
||||
// to free a string pointer allocated by the DLL, havoc would result.
|
||||
// Because of this hassle, this is a protected function.
|
||||
//
|
||||
// The solution to this is to write a new version of this that returns
|
||||
// an ALName object. I thought of that, but too late.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used internally by ArchiveLib. It is used to read
|
||||
// random length blocks of data out of archives (or other storage objects).
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
char AL_DLL_FAR * AL_PROTO ALStorage::ReadString()
|
||||
{
|
||||
short int len;
|
||||
|
||||
if ( ReadPortableShort( len ) < 0 )
|
||||
return 0;
|
||||
char *new_string = new char[ len + 1 ];
|
||||
if ( new_string ) {
|
||||
ReadBuffer( (unsigned char *) new_string, len );
|
||||
new_string[ len ] = '\0';
|
||||
return new_string;
|
||||
} else {
|
||||
mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
|
||||
"Error allocating buffer space in call "
|
||||
"to ReadString() for object %s",
|
||||
mName.GetSafeName() );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// long ALStorage::Tell()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A long integer indicating the current position of the read/write
|
||||
// pointer for the file.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// Because we are using buffered I/O here, figuring out the current
|
||||
// position of the read write pointer is just a tiny bit more complicated
|
||||
// than just checking a pointer. We have to find the physical location of
|
||||
// the file pointer, then add in any offset created by the presence of
|
||||
// data in the I/O buffer.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
long AL_PROTO ALStorage::Tell()
|
||||
{
|
||||
if ( muWriteIndex )
|
||||
return mlFilePointer + muWriteIndex;
|
||||
else
|
||||
return mlFilePointer - muBufferValidData + muReadIndex;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// void ALStorage::YieldTime()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function has two important things to do. It gets called
|
||||
// at a few different points in the process of reading or writing data
|
||||
// from storage objects. During normal reading and writing, it
|
||||
// will get called every time the buffer is loaded or flushed.
|
||||
//
|
||||
// If we are in Windows mode, we execute a PeekMessage() loop. This
|
||||
// makes sure that we aren't hogging the CPU. By doing it this way,
|
||||
// the programmer can be ensure that he/she is being a good citizen
|
||||
// without any significant effort.
|
||||
//
|
||||
// The second important function is that of calling the monitor function.
|
||||
// The user interface elements need to be updated regularly, and this
|
||||
// is done via this call.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALStorage::YieldTime()
|
||||
{
|
||||
if ( mpMonitor )
|
||||
mpMonitor->Progress( Tell(), *this );
|
||||
/*
|
||||
* For right now I am going to put the PeekMessage loop in the load
|
||||
* buffer routine by default. Most Windows applications are going
|
||||
* to want to use this, right?
|
||||
*/
|
||||
#if defined( AL_WINDOWS_GUI )
|
||||
MSG msg;
|
||||
|
||||
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::WriteStorageObjectData( ALStorage * archive )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// archive : A pointer to the storage object where we are going to
|
||||
// write the private data.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if things went okay, otherwise an error code < AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// All storage objects have the ability to create a private data block
|
||||
// that will be stored along with the directory when creating an archive.
|
||||
// None of the classes predefined in ArchiveLib use this data block, which
|
||||
// means they use this function instead of providing their own virtual
|
||||
// substitute. This function writes a private data block of exactly 0
|
||||
// bytes in length. Our internal storage format means that a block
|
||||
// of 0 bytes length takes 2 bytes to store.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::WriteStorageObjectData( ALStorage * archive )
|
||||
{
|
||||
return archive->WritePortableShort( 0 );
|
||||
}
|
||||
|
||||
//
|
||||
// int ALStorage::ReadStorageObjectData( ALStorage * archive )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// archive : A pointer to the storage object where we are going to
|
||||
// read in the private data..
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if things went okay, otherwise an error code < AL_SUCCESS.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// All storage objects have the ability to create a private data block
|
||||
// that will be stored along with the directory when creating an archive.
|
||||
// None of the classes predefined in ArchiveLib use this data block, which
|
||||
// means they use this function instead of providing their own virtual
|
||||
// substitute. This function reads a private data block of exactly 0
|
||||
// bytes in length. Our internal storage format means that a block
|
||||
// of 0 bytes length takes 2 bytes to store.
|
||||
//
|
||||
// In debug mode, we get really bent out of shape if this data block
|
||||
// doesn't look exactly like we expect it to.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::ReadStorageObjectData( ALStorage * archive )
|
||||
{
|
||||
short int temp;
|
||||
int status = archive->ReadPortableShort( temp );
|
||||
AL_ASSERT( temp == 0, "ReadStorageObjectData: stored data is not null" );
|
||||
return status;
|
||||
}
|
||||
424
al/storage.h
Executable file
424
al/storage.h
Executable file
@ -0,0 +1,424 @@
|
||||
/*
|
||||
* STORAGE.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file contains the class declaration for the very important
|
||||
* base class ALStorage.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALStorage
|
||||
*
|
||||
* FUNCTIONS:
|
||||
*
|
||||
* ALStorage::ReadChar()
|
||||
* ALStorage::WriteChar()
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _STORAGE_H
|
||||
#define _STORAGE_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
#include <stddef.h> /* need for size_t */
|
||||
|
||||
#include "timedate.h"
|
||||
#include "fileattr.h"
|
||||
|
||||
/*
|
||||
* class ALStorage
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ALStorage is a base class that defines the different types
|
||||
* of storage objects used by Archive Library. The two most
|
||||
* commonly used storage object types are file objects and memory
|
||||
* objects, defined by the derived classes ALFile and
|
||||
* ALMemory.
|
||||
*
|
||||
* ALStorage objects are used to store and retrieve objects from archives.
|
||||
* They are also used to store and retrieve the archives themselves,
|
||||
* allowing archives to be stored in files or directly in memory.
|
||||
*
|
||||
* The ALStorage adds buffering to the storage object, allowing for
|
||||
* fast access to data presently cached in memory. This is very similar to
|
||||
* the buffering provided for FILE types in stdio.h. Note that this
|
||||
* buffering is generally only efficient/useful if lots of sequential
|
||||
* reads or writes are being done, as opposed to random accessess.
|
||||
*
|
||||
* ALStorage objects give up a lot of flexibility in order to provide
|
||||
* quick and efficient access to data. The primary way this affects
|
||||
* use of the class is that the I/O buffer can only be used for reading
|
||||
* or writing, but not both simultaneously. The class doesn't check
|
||||
* for this at run time, so programmers need to enforce it themselves.
|
||||
*
|
||||
* When a read is initiated for the first time, the buffer is loaded up,
|
||||
* and subsequent reads are performed out of the I/O buffer. To switch
|
||||
* to writing mode, a call to FlushBuffer needs to be performed, which
|
||||
* will reset the input and output indices. Likewise, when, done writing,
|
||||
* a call to FlushBuffer() can be performed to clear the indices. A
|
||||
* read can be done subsequently.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mpcBuffer : This is the I/O buffer. I read big blocks of
|
||||
* data into this buffer, then I can perform
|
||||
* character reads from an inline functin that
|
||||
* doesn't have to access any virtual fns. Speeds
|
||||
* things up tremendously. Likewise, I write
|
||||
* to this buffer using inline functions until it
|
||||
* it is full. Only then do I call a virtual
|
||||
* to flush it to disk, memory, or whatever.
|
||||
*
|
||||
* muBufferValidData : This keeps track of the end of valid data,
|
||||
* both when reading and writing. When re
|
||||
* read in a block of data, this index is set
|
||||
* to the end of the data. When writing, this
|
||||
* index is continually updated to reflect the
|
||||
* end of the user written data.
|
||||
*
|
||||
* muWriteIndex : The index in the I/O buffer where the next byte
|
||||
* is going to be written.
|
||||
*
|
||||
* muReadIndex : The index in the I/O buffer where the next read
|
||||
* will come from.
|
||||
*
|
||||
* mlFilePointer : The current location of the read/write pointer
|
||||
* in the underlying object, e.g. a file. This
|
||||
* is the location where the data will be written
|
||||
* out of the I/O buffer when a FlushBuffer() call
|
||||
* is made. Or, if reading, it is where the next
|
||||
* LoadBuffer() will read data from.
|
||||
*
|
||||
* mlSize : The size of the file/object. This will ordinarily
|
||||
* be set to -1 when we create an object, because
|
||||
* we don't know the size yet. When you call Open()
|
||||
* for an existing object, the value will usually
|
||||
* be loaded using some sort of system call. We
|
||||
* also can figure out what the size is when we do
|
||||
* a ReadDirectory call on an archive.
|
||||
*
|
||||
* mlCrc32 : The CRC-32 for the object. This value normally
|
||||
* won't be known until an object has been placed
|
||||
* in an archive, or when the information has
|
||||
* been read out using in ReadDirectory().
|
||||
*
|
||||
* miUpdateCrcFlag : This flag is set to indicate that we are in the
|
||||
* process of calculating the CRC while the file
|
||||
* is being compressed.
|
||||
*
|
||||
* miCreated : This flag will be set if the file was opened
|
||||
* using Create(), clear if it was opened using
|
||||
* Open(). When miCreated is set, we will try
|
||||
* to set the file time, date and attributes when
|
||||
* we close the file. This is so we can set these
|
||||
* attributes when we are recreating a file that
|
||||
* was stored in an archive.
|
||||
*
|
||||
* miStorageObjectType : An integer that is assigned when the object was
|
||||
* constructed. Usually one of the enumerated
|
||||
* constants found in ALDEFS.H. This is the number
|
||||
* that gets stored in the Archive directory with
|
||||
* the object, so we can figure out what type of
|
||||
* object to create when extracting.
|
||||
*
|
||||
* muBufferSize : The size of the I/O buffer.
|
||||
*
|
||||
* mpMonitor : A pointer to the monitor attached to this object.
|
||||
* During the archiving process, this pointer gets
|
||||
* set by the archive routine for each storage object
|
||||
* as it is being processes. A value of 0 just
|
||||
* means no monitor is watching this object at the
|
||||
* moment.
|
||||
*
|
||||
* mTimeDate : The time and date stamp for the file, this usually
|
||||
* gets set when the object is opened using Open(),
|
||||
* it is also set when we read in a storage object's
|
||||
* information using ReadDirectory().
|
||||
*
|
||||
* mAttributes : The attributes associated with the file. R/H/S/A.
|
||||
*
|
||||
* mName : The name of the storage object.
|
||||
*
|
||||
* mStatus : The current status of the object.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALStorage() : The constructor, creates the object, but doesn't
|
||||
* necessarily create the file/whatever.
|
||||
* operator=() : Assignment operator.
|
||||
* operator new() : The memory allocation operator. This is only
|
||||
* used if the library is in a DLL.
|
||||
* ~ALStorage() : Virtual destructor.
|
||||
* UpdateCrc() : Protected function used internally when the
|
||||
* crc is being calculated
|
||||
* ReadString() : Read a string in ArchiveLib's proprietary format.
|
||||
* WriteStorageObjectData() : Protected function to write custom data needed
|
||||
* for a particular derived classe.
|
||||
* ReadStorageObjectData() : Protected function read that data back in.
|
||||
* ReadChar() : Superfast inline function to read a bytee
|
||||
* WriteChar() : Fast inline function to write a byte.
|
||||
* ReadBuffer() : Function to read blocks of data.
|
||||
* WriteBuffer() : Function to write blocks of data.
|
||||
* Open() : Open() used to prepare an existing object for I/O.
|
||||
* Create() : Create a new underlying object for I/O.
|
||||
* Close() : Called when I/O is complete.
|
||||
* LoadBuffer() : Called to reload the I/O buffer, used internally
|
||||
* when ReadChar() runs out of stuff to read.
|
||||
* FlushBuffer() : Called to flush the I/O buffer to the underlying
|
||||
* object. Called when WriteChar() has gone too far.
|
||||
* Seek() : Called to reposition the I/O pointer of the
|
||||
* underlying object.
|
||||
* YieldTime() : Called whenever a FlushBuffer() or LoadBuffer()
|
||||
* takes place. Used to update the Monitor attached
|
||||
* to the file, and to yield time to the O/S.
|
||||
* Compare() : Compare two storage objects.
|
||||
* InitCrc32() : Called to start calculating the CRC for an object.
|
||||
* WritePortableShort() : Write 16 bit integer in little endian format.
|
||||
* WritePortableLong() : Write 32 bit integer in little endian format.
|
||||
* ReadPortableShort() : Read 16 bit integer in little endian format.
|
||||
* ReadPortableLong() : Read 32 bit integer in little endian format.
|
||||
* WriteString() : Write string in ArchiveLib format.
|
||||
* Rename() : Rename the underlying object.
|
||||
* UnRename() : Undo a rename operation.
|
||||
* RenameToBackup() : Rename to a special backup name.
|
||||
* Delete() : Delete an underlying storage object.
|
||||
* GetCrc32() : Return value of the CRC member.
|
||||
* GetSize() : Reeturn value of the size member.
|
||||
* IsOpen() : Indicate if the file is open.
|
||||
* Tell() : Indicate where the next read or write will
|
||||
* take place.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Forward declaration
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALMonitor;
|
||||
|
||||
class AL_CLASS_TYPE ALStorage {
|
||||
public :
|
||||
/*
|
||||
* Classes I trust
|
||||
*/
|
||||
friend class AL_CLASS_TYPE ALArchiveBase;
|
||||
friend class AL_CLASS_TYPE ALCompressedObject;
|
||||
/*
|
||||
* Constructors, destructors, assignment operator
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALStorage( const char AL_DLL_FAR *file_name,
|
||||
size_t buffer_size,
|
||||
const ALStorageType storage_type,
|
||||
ALCase name_case = AL_MIXED );
|
||||
ALStorage AL_DLL_FAR & AL_PROTO operator=( const ALStorage AL_DLL_FAR & );
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
public :
|
||||
virtual AL_PROTO ~ALStorage();
|
||||
/*
|
||||
* I don't want to allow the copy constructor to exist.
|
||||
*/
|
||||
protected :
|
||||
AL_PROTO ALStorage( const ALStorage AL_DLL_FAR & );
|
||||
|
||||
/*
|
||||
* Member functions, grouped somewhat
|
||||
*
|
||||
*
|
||||
* Private member manipulation
|
||||
*/
|
||||
protected :
|
||||
void AL_PROTO UpdateCrc( size_t count );
|
||||
/*
|
||||
* This is private, because it allocates memory in the DLL, so it
|
||||
* must be deleted in the DLL as well.
|
||||
*/
|
||||
private :
|
||||
char AL_DLL_FAR * AL_PROTO ReadString();
|
||||
virtual int AL_PROTO
|
||||
WriteStorageObjectData( ALStorage AL_DLL_FAR * archive );
|
||||
virtual int AL_PROTO
|
||||
ReadStorageObjectData( ALStorage AL_DLL_FAR * archive );
|
||||
/*
|
||||
* The file I/O access public interface
|
||||
*/
|
||||
public :
|
||||
int AL_PROTO ReadChar();
|
||||
int AL_PROTO WriteChar( int c );
|
||||
size_t AL_PROTO ReadBuffer( unsigned char AL_DLL_FAR *buffer,
|
||||
size_t length );
|
||||
/* Please keep this arg const, breaks WriteString o/w */
|
||||
size_t AL_PROTO WriteBuffer( const unsigned char AL_DLL_FAR *buffer,
|
||||
size_t length );
|
||||
virtual int AL_PROTO Open();
|
||||
virtual int AL_PROTO Create();
|
||||
virtual int AL_PROTO Close();
|
||||
virtual int AL_PROTO LoadBuffer( long address ) = 0;
|
||||
virtual int AL_PROTO FlushBuffer() = 0;
|
||||
virtual int AL_PROTO Seek( long address ) = 0;
|
||||
virtual void AL_PROTO YieldTime();
|
||||
int AL_PROTO Compare( ALStorage AL_DLL_FAR &test_object );
|
||||
void AL_PROTO InitCrc32( unsigned long seed = 0xffffffffl );
|
||||
int AL_PROTO WritePortableShort( short int short_data );
|
||||
int AL_PROTO WritePortableLong( long long_data );
|
||||
int AL_PROTO ReadPortableShort( short int AL_DLL_FAR &short_data );
|
||||
int AL_PROTO ReadPortableLong( long AL_DLL_FAR &long_data );
|
||||
int AL_PROTO WriteString( const char AL_DLL_FAR *string_data );
|
||||
/*
|
||||
* File manipulation public interface
|
||||
*/
|
||||
public :
|
||||
virtual int AL_PROTO Rename( const char AL_DLL_FAR *new_name = 0,
|
||||
int delete_on_clash = 1 ) = 0;
|
||||
virtual int AL_PROTO UnRename( int delete_on_clash = 1 ) = 0;
|
||||
virtual int AL_PROTO RenameToBackup( int delete_on_clash = 1 ) = 0;
|
||||
virtual int AL_PROTO Delete() = 0;
|
||||
/*
|
||||
* Access functions
|
||||
*/
|
||||
public :
|
||||
long AL_PROTO GetCrc32();
|
||||
long AL_PROTO GetSize() const { return mlSize; }
|
||||
int AL_PROTO IsOpen(){ return mpcBuffer != 0; }
|
||||
long AL_PROTO Tell();
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
unsigned char AL_DLL_FAR *mpcBuffer;
|
||||
size_t muBufferValidData;
|
||||
size_t muWriteIndex;
|
||||
size_t muReadIndex;
|
||||
long mlFilePointer;
|
||||
long mlSize;
|
||||
long mlCrc32;
|
||||
short int miUpdateCrcFlag;
|
||||
short int miCreated;
|
||||
/*
|
||||
* Public members
|
||||
*/
|
||||
public :
|
||||
const ALStorageType miStorageObjectType;
|
||||
const size_t muBufferSize;
|
||||
ALMonitor AL_DLL_FAR *mpMonitor;
|
||||
ALTimeDate mTimeDate;
|
||||
ALFileAttributes mAttributes;
|
||||
ALName mName;
|
||||
ALStatus mStatus;
|
||||
AL_CLASS_TAG( _ALStorageTag );
|
||||
};
|
||||
|
||||
/*
|
||||
* It is really important to keep these guys inline.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* inline int ALStorage::ReadChar()
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* RETURNS
|
||||
*
|
||||
* Either the next character available from the I/O buffer, or
|
||||
* AL_END_OF_FILE.
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is an inline function that is able to quickly do buffered I/O.
|
||||
* By utilizing an I/O buffer we can make this routine very fast, since
|
||||
* it doesn't have to call a virtual function. The virtual function
|
||||
* only has to be called when LoadBuffer() gets called.
|
||||
*
|
||||
* Different compilers have different abilities to make this code inline,
|
||||
* so sometimes it needs to be tinkered with. If you see anything in here
|
||||
* that looks funny, that probably explains why.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
inline int AL_PROTO ALStorage::ReadChar()
|
||||
{
|
||||
int result;
|
||||
|
||||
AL_ASSERT( muWriteIndex == 0, "ReadChar(): Attempt to read while in write mode" ); /*Can't read if I've done a write!*/
|
||||
result = muBufferValidData - muReadIndex;
|
||||
if ( result <= 0 )
|
||||
result = LoadBuffer( mlFilePointer );
|
||||
AL_ASSERT( mpcBuffer != 0, "ReadChar(): Attempt to read from closed file" ); /*Potential disaster*/
|
||||
if ( result < 0 )
|
||||
return result;
|
||||
else
|
||||
return mpcBuffer[ muReadIndex++ ] & 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* inline int ALStorage::WriteChar( int c )
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* c : The character that is going to be written.
|
||||
*
|
||||
* RETURNS
|
||||
*
|
||||
* Either the character that we just wrote out, or an error < AL_SUCCESS.
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This is an inline function that is able to quickly do buffered I/O.
|
||||
* By utilizing an I/O buffer we can make this routine very fast, since
|
||||
* it doesn't have to call a virtual function. The virtual function
|
||||
* only has to be called when FlushBuffer() gets called.
|
||||
*
|
||||
* Different compilers have different abilities to make this code inline,
|
||||
* so sometimes it needs to be tinkered with. If you see anything in here
|
||||
* that looks funny, that probably explains why.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
inline int AL_PROTO ALStorage::WriteChar( int c )
|
||||
{
|
||||
int result;
|
||||
|
||||
/* assert( muReadIndex == 0 ); */ /* Can't write if I've done a read */
|
||||
AL_ASSERT( mpcBuffer != 0, "WriteChar(): Attempt to write to closed file" ); /* Disaster! */
|
||||
result = muBufferSize - muWriteIndex;
|
||||
if ( result <= 0 )
|
||||
result = FlushBuffer();
|
||||
if ( result < 0 )
|
||||
return mStatus;
|
||||
else
|
||||
return mpcBuffer[ muWriteIndex++ ] = (char) c;
|
||||
}
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifndef _STORAGE_H */
|
||||
85
al/storcmp.cpp
Executable file
85
al/storcmp.cpp
Executable file
@ -0,0 +1,85 @@
|
||||
//
|
||||
// STORCMP.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALStorage::Compare()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains a single function from ALStorage. I'm not
|
||||
// sure why it is in a separate file.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "storage.h"
|
||||
#include "_openf.h"
|
||||
|
||||
//
|
||||
// int ALStorage::Compare( ALStorage & test )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// test : The storage object that will be compared to this.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// AL_SUCCESS if the two files match. AL_COMPARE_ERROR if the files
|
||||
// don't match. An error code < AL_SUCCESS is possible if some other
|
||||
// error takes place during the process.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides a convenient way to test this object
|
||||
// against another. Note that if the comparison fails, the status
|
||||
// code of this object will be set to an error state. You will need
|
||||
// to clear that error if you intend to use this object again.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALStorage::Compare( ALStorage AL_DLL_FAR & test )
|
||||
{
|
||||
ALOpenInputFile in1( test );
|
||||
ALOpenInputFile in2( *this );
|
||||
|
||||
if ( test.mStatus < 0 )
|
||||
return mStatus = test.mStatus;
|
||||
if ( GetSize() != test.GetSize() )
|
||||
return mStatus.SetError( AL_COMPARE_ERROR,
|
||||
"Comparison failed. "
|
||||
"File %s and %s are two different sizes.",
|
||||
mName.GetSafeName(),
|
||||
test.mName.GetSafeName() );
|
||||
long position = 0;
|
||||
for ( ; ; ) {
|
||||
int c = ReadChar();
|
||||
if ( c < 0 )
|
||||
break;
|
||||
if ( c != test.ReadChar() )
|
||||
return mStatus.SetError( AL_COMPARE_ERROR,
|
||||
"File %s and %s differed at position %ld",
|
||||
mName.GetSafeName(),
|
||||
test.mName.GetSafeName(),
|
||||
position );
|
||||
position++;
|
||||
}
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
457
al/timedate.cpp
Executable file
457
al/timedate.cpp
Executable file
@ -0,0 +1,457 @@
|
||||
//
|
||||
// TIMEDATE.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALTimeDate::operator new()
|
||||
// ALTimeDate::ALTimeDate()
|
||||
// ALTimeDate::~ALTimeDate()
|
||||
// ALTimeDate::ToJulian()
|
||||
// ALTimeDate::FromJulian()
|
||||
// ALTimeDate::GetUnixTime()
|
||||
// ALTimeDate::SetTimeDate(long)
|
||||
// ALTimeDate::SetTimeDate(struct tm *)
|
||||
// ALTimeDate::GetTimeDate()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all of the member functions of class ALTimeDate.
|
||||
// This class is used only by ALStorage, but it seemed like a good
|
||||
// idea to break it out in a separate class. A lot of the code in here
|
||||
// came straight out of CommLib.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <time.h>
|
||||
#include "timedate.h"
|
||||
|
||||
//
|
||||
// void * ALTimeDate::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALTimeDate 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 ALTimeDate::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALTimeDate::ALTimeDate()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// All the constructor does is initialize the data members. By
|
||||
// setting the year to an invalid value of 0, we can always see
|
||||
// that the time date stamp for a file hasn't been initialized.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALTimeDate::ALTimeDate()
|
||||
{
|
||||
miYear = 0; //This is an illegal year, means it is uninitialized
|
||||
miMonth = 0;
|
||||
miDate = 0;
|
||||
miHour = 0;
|
||||
miMinute = 0;
|
||||
miSecond = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ALTimeDate::~ALTimeDate()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The destructor has nothing to do.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALTimeDate::~ALTimeDate()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// long ALTimeDate::ToJulian()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A Julian day.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to make a Julian day number from a normal
|
||||
// month/day/year thing. We need a Julian day in order to make a
|
||||
// UNIX style time stamp. The UNIX time stamp is used to store
|
||||
// time stamps in Archive directories.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
long AL_PROTO ALTimeDate::ToJulian()
|
||||
{
|
||||
return (long)( miDate - 32076)
|
||||
+ 1461L * ( miYear + 4800L + ( miMonth - 14) / 12) / 4
|
||||
+ 367 * ( miMonth - 2 - ( miMonth - 14) / 12 * 12) / 12
|
||||
- 3 * (( miYear + 4900L + ( miMonth - 14) / 12) / 100) / 4
|
||||
+ 1;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// void ALTimeDate::FromJulian( long jdn )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// jdn : A julian date number, ideally one produced by ToJulian().
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to convert a julian date to a normal
|
||||
// year/month/day. Time/date stamps are stored in Archives in
|
||||
// UNIX format. This function is needed to convert a UNIX
|
||||
// time stamp to a normal mm/dd/yy.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALTimeDate::FromJulian( long jdn )
|
||||
{
|
||||
long x;
|
||||
long z;
|
||||
long m;
|
||||
long d;
|
||||
long y;
|
||||
const long daysPer400Years = 146097L;
|
||||
const long fudgedDaysPer4000Years = 1460970L + 31;
|
||||
|
||||
x = jdn + 68569L;
|
||||
z = 4 * x / daysPer400Years;
|
||||
x = x - (daysPer400Years * z + 3) / 4;
|
||||
y = 4000 * (x + 1) / fudgedDaysPer4000Years;
|
||||
x = x - 1461 * y / 4 + 31;
|
||||
m = 80 * x / 2447;
|
||||
d = x - 2447 * m / 80;
|
||||
x = m / 11;
|
||||
m = m + 2 - 12 * x;
|
||||
y = 100 * (z - 49) + y + x;
|
||||
//
|
||||
// I don't know whether or not we could eliminate these temporary longs
|
||||
//
|
||||
miYear = (short int) y;
|
||||
miMonth = (short int) m;
|
||||
miDate = (short int) d;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// long ALTimeDate::GetUnixTime()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// A UNIX time, converted from the internal m/d/y h:m:s data.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is used to convert the m/d/y h:m:s time stamp for a file
|
||||
// into a UNIX time stamp. The UNIX time stamp is a 32 bit long that
|
||||
// is used to store time stamps in an Archive.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
long AL_PROTO ALTimeDate::GetUnixTime()
|
||||
{
|
||||
const long UnixFirstDay = 2440588L;
|
||||
long result;
|
||||
|
||||
result = ToJulian();
|
||||
result -= UnixFirstDay;
|
||||
if ( result >= 0L ) {
|
||||
result *= 3600L * 24;
|
||||
result += 3600L * miHour;
|
||||
result += 60L * miMinute;
|
||||
result += miSecond;
|
||||
} else
|
||||
result = 0L;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// void ALTimeDate::SetTimeDate( long unix_time )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// unix_time : A long integer in UNIX timestamp format.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is called when we are reading a directory in from
|
||||
// an archive. It is used to set the internal data members of an
|
||||
// ALTimeDate object, after converting from unix time.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALTimeDate::SetTimeDate( long unix_time )
|
||||
{
|
||||
const long UnixFirstDay = 2440588L;
|
||||
|
||||
long jd = unix_time / ( 3600L * 24 );
|
||||
long hms = unix_time % ( 3600L * 24 );
|
||||
FromJulian( jd + UnixFirstDay );
|
||||
miHour = (short int) ( hms / 3600 );
|
||||
hms -= 3600L * miHour;
|
||||
miMinute = (short int) ( hms / 60 );
|
||||
miSecond = (short int) ( hms - ( miMinute * 60 ) );
|
||||
}
|
||||
|
||||
//
|
||||
// void ALTimeDate::SetTimeDate( struct tm *tblock )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// tblock : A time date stamp as used by the C run time library.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When working with DOS files, time stamps are read in to a structure
|
||||
// in the struct tm format. This function provides an easy way to convert
|
||||
// the structure into our internal format. When a DOS file is opened
|
||||
// using Open(), this function is called.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALTimeDate::SetTimeDate( struct tm AL_DLL_FAR *tblock )
|
||||
{
|
||||
AL_ASSERT( tblock != 0, "SetTimeDate: passing illegal null parameter" );
|
||||
miYear = (short int) ( tblock->tm_year + 1900 );
|
||||
miMonth = (short int) ( tblock->tm_mon + 1 );
|
||||
miDate = (short int) tblock->tm_mday;
|
||||
miHour = (short int) tblock->tm_hour;
|
||||
miMinute = (short int) tblock->tm_min;
|
||||
miSecond = (short int) tblock->tm_sec;
|
||||
}
|
||||
|
||||
//
|
||||
// void ALTimeDate::GetTimeDate( struct tm *tblock )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// tblock : A structure in the format used by the C runtime library for
|
||||
// storing time and date stamps.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// Nothing.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function provides the reverse of SetTimeDate(). You would think
|
||||
// that we could just set the appropriate members of struct tm, but
|
||||
// there is a problem with that. struct tm has one element that is
|
||||
// supposed to be the day of the week, and another that is supposed
|
||||
// to be the number of the day within the year. We could try to
|
||||
// figure those out using the julian day function, but since gmtime()
|
||||
// will figure them out for us, we'll use that instead.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
void AL_PROTO ALTimeDate::GetTimeDate( struct tm AL_DLL_FAR *tblock )
|
||||
{
|
||||
AL_ASSERT( tblock != 0, "GetTimeDate: passing illegal null parameter" );
|
||||
long unix_time = GetUnixTime();
|
||||
struct tm *result = gmtime( (const time_t *) &unix_time );
|
||||
if ( result ) {
|
||||
*tblock = *result;
|
||||
tblock->tm_isdst = 0;
|
||||
} else { //This should never happen!
|
||||
tblock->tm_year = miYear - 1900;
|
||||
tblock->tm_mon = miMonth - 1;
|
||||
tblock->tm_mday = miDate;
|
||||
tblock->tm_hour = miHour;
|
||||
tblock->tm_min = miMinute;
|
||||
tblock->tm_sec = miSecond;
|
||||
tblock->tm_wday = 0;
|
||||
tblock->tm_yday = 0;
|
||||
tblock->tm_isdst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// unsigned short int ALTimeDate::GetDosTime()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// This function returns the time stored in this. The bits of the
|
||||
// time are packed into the form that is needed by the _dos_setftime()
|
||||
// format.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When we close a file that needs to have its time and date stamp
|
||||
// set, we normally use the _dos_setftime() function to do the
|
||||
// work. It expects to see the time packed into a particular
|
||||
// sequence of bits in an unsigned short. That is what this
|
||||
// function does. It packs the bits just the way you want them.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if !defined( AL_WIN32S )
|
||||
|
||||
unsigned short int AL_PROTO ALTimeDate::GetDosTime()
|
||||
{
|
||||
int result;
|
||||
result = miSecond / 2;
|
||||
result |= miMinute << 5;
|
||||
result |= miHour << 11;
|
||||
return (unsigned short int) result;
|
||||
}
|
||||
|
||||
#endif //#if !defined( AL_WIN32S )
|
||||
|
||||
|
||||
//
|
||||
// unsigned short int ALTimeDate::GetDosDate()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// This function returns the date stored in this object. The bits of the
|
||||
// date are packed into the form that is needed by the _dos_setftime()
|
||||
// format.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// When we close a file that needs to have its time and date stamp
|
||||
// set, we normally use the _dos_setftime() function to do the
|
||||
// work. It expects to see the date packed into a particular
|
||||
// sequence of bits in an unsigned short. That is what this
|
||||
// function does. It packs the bits just the way you want them.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if !defined( AL_WIN32S )
|
||||
|
||||
unsigned short int AL_PROTO ALTimeDate::GetDosDate()
|
||||
{
|
||||
int result;
|
||||
result = miDate;
|
||||
result |= miMonth << 5;
|
||||
result |= (miYear-1980) << 9;
|
||||
return (unsigned short int ) result;
|
||||
}
|
||||
#endif //#if !defined( AL_WIN32S )
|
||||
|
||||
125
al/timedate.h
Executable file
125
al/timedate.h
Executable file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* TIMEDATE.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the class declaration for ALTimeDate.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALTimeDate
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TIMEDATE_H
|
||||
#define _TIMEDATE_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/*
|
||||
* class ALOpenInputFile
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* class ALTimeDate is used strictly to keep track of the time/date
|
||||
* stamp of an ALStorage object. The only place this class appears is
|
||||
* as the mTimeDate member of ALStorage. It has a number of conversion
|
||||
* utilities for loading and exporting its values in various formats.
|
||||
* Since most of the ways we have to set time stamps for objects
|
||||
* are not ANSI standard, we end up with quite a few conversion utilities.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* miYear : The year just like you would expect, e.g 1994. A value of
|
||||
* 0 in this field indicates an invalid time.
|
||||
*
|
||||
* miMonth : The month, 1-12.
|
||||
*
|
||||
* miDate : The date, 1-31.
|
||||
*
|
||||
* miHour : In 2400 format, 0 - 23.
|
||||
*
|
||||
* miMinute : 0 - 59
|
||||
*
|
||||
* miSecond : 0 -59,
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALTimeDate() : The constructor, sets all members to 0.
|
||||
* ~ALTimeDate() : The destructor, has no work to do.
|
||||
* operator new() : The memory allocation operator, only used
|
||||
* when the library is inside a DLL.
|
||||
* ToJulian() : Convert the internal m/d/y members to
|
||||
* a julian day number.
|
||||
* FromJulian() : Convert a julian day number to internal
|
||||
* data members m/d/y.
|
||||
* GetUnixTime() : Convert all members to a long in unix format,
|
||||
* total seconds since 1/1/1970.
|
||||
* GetDosTime() : Convert h:m:s data members to the unsigned int
|
||||
* used in certain DOS commands.
|
||||
* GetDosDate() : Convert m/d/y data members to the unsigned int
|
||||
* used in certain DOS commands.
|
||||
* SetTimeDate(long) : Set internal data members from a UNIX long.
|
||||
* SetTimeDate(struct tm*) : Set internal data members from a DOS
|
||||
* struct tm *.
|
||||
* GetTimeDate() : Convert internal data members to a DOS struct tm *.
|
||||
* Valid() : Indicate if a valid time has been set.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class AL_CLASS_TYPE ALTimeDate {
|
||||
/*
|
||||
* Constructors, destructors, declarations, assignment operator
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALTimeDate();
|
||||
AL_PROTO ~ALTimeDate();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* I usually hide the copy constructor and assignment operators,
|
||||
* but in this case they are OK
|
||||
*
|
||||
*
|
||||
* Member functions
|
||||
*/
|
||||
public :
|
||||
long AL_PROTO ToJulian();
|
||||
void AL_PROTO FromJulian( long jdn );
|
||||
long AL_PROTO GetUnixTime();
|
||||
#if !defined( AL_WIN32S )
|
||||
unsigned short int AL_PROTO GetDosTime();
|
||||
unsigned short int AL_PROTO GetDosDate();
|
||||
#endif /* #if !defined( AL_WIN32S ) */
|
||||
void AL_PROTO SetTimeDate( long unix_time );
|
||||
void AL_PROTO SetTimeDate( struct tm AL_DLL_FAR *tblock );
|
||||
void AL_PROTO GetTimeDate( struct tm AL_DLL_FAR *tblock );
|
||||
int AL_PROTO Valid(){ return miYear != 0; }
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
short int miYear; /* What you expect, e.g. 1995 */
|
||||
short int miMonth; /* 1-12 */
|
||||
short int miDate; /* 1-31 */
|
||||
short int miHour; /* 0-23 */
|
||||
short int miMinute; /* 0-59 */
|
||||
short int miSecond; /* 0-59 */
|
||||
};
|
||||
|
||||
#endif
|
||||
594
al/wildcard.cpp
Executable file
594
al/wildcard.cpp
Executable file
@ -0,0 +1,594 @@
|
||||
//
|
||||
// WILDCARD.CPP
|
||||
//
|
||||
// Source file for ArchiveLib 1.0
|
||||
//
|
||||
// Copyright (c) Greenleaf Software, Inc. 1994
|
||||
// All Rights Reserved
|
||||
//
|
||||
// CONTENTS
|
||||
//
|
||||
// ALWildCardExpander::operator new()
|
||||
// ALWildCardExpander::ALWildCardExpander()
|
||||
// ALWildCardExpander::~ALWildCardExpander()
|
||||
// ALWildCardExpander::GetNextWildName()
|
||||
// ALWildCardExpander::GetNextFile()
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file contains all the source code for the nifty class
|
||||
// ALWildCardExpander. The wild card expansion code is a state
|
||||
// drive routine, which keeps track of its entire state between
|
||||
// calls. So you can call it once to get a new file name, then
|
||||
// do some processing. When you call it again later, you will
|
||||
// get the next file name in the sequence.
|
||||
//
|
||||
// There is a little difference between the NT version and the DOS
|
||||
// version, because the function calls for get first/get next
|
||||
// are different. A minor difference is created by the fact
|
||||
// that under NT you can't specify attributes in a search, so when
|
||||
// you want to look for subdirectories, you have to search all files
|
||||
// and see if any of your matches turn out to be directories.
|
||||
//
|
||||
// The way the wild card class handles searching through subdirectories
|
||||
// is by keeping a link pointer to a subdirectory search. When it
|
||||
// is time to open up a subdirectory search, we create a new file
|
||||
// expander, and assign its pointer to our link pointer. As long as
|
||||
// the link is active, we keep searching there. When the link runs
|
||||
// out of files to return, we continue searching in our own directory.
|
||||
//
|
||||
// A lot of this code is easier to deal with because we use the
|
||||
// ALName class. That makes it easy to strip file names and
|
||||
// paths apart, and even easier to put them back together again.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
//
|
||||
|
||||
#include "arclib.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef __BORLANDC__
|
||||
#include <dir.h>
|
||||
#endif
|
||||
|
||||
#include "wildcard.h"
|
||||
|
||||
//
|
||||
// void * ALWildCardExpander::operator new( size_t size )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// size : The number of bytes needed to create a new ALWildCardExpander
|
||||
// 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 ALWildCardExpander::operator new( size_t size )
|
||||
{
|
||||
return ::new char[ size ];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ALWildCardExpander::ALWildCardExpander( const char *file_list,
|
||||
// int traverse_flag = 0,
|
||||
// ALCase name_case = AL_LOWER )
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// file_list : A list of wild card file specifications, separated
|
||||
// by commas, semicolons, or spaces, maybe looking
|
||||
// something like this: "*.CPP, BOB.DAT, *.*"
|
||||
//
|
||||
// traverse_flag : A flag that indicates whether you want to traverse
|
||||
// all subdirectories under the current path.
|
||||
//
|
||||
// name_case : An indicator of whether you want all the returned
|
||||
// file names forced to a certain case.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// No returns.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// The constructor for the expander has to set up a bunch of data members
|
||||
// that will all be used during the expansion process. The mCase
|
||||
// member is easy to understand. All of the objname objects that
|
||||
// we create are going to be force to a certain case by this
|
||||
// using this data member. miTraverseFlag is just our copy of the
|
||||
// input parameter. And the mState variable keeps track of what we
|
||||
// are doing in between function calls. We set it to GET_NEXT_WILD_NAME,
|
||||
// which means we will be doing that the first time we get called.
|
||||
//
|
||||
// mInputLine is where we keep a copy of the list of wild card file
|
||||
// specifications passed by the calling program. Each time we take
|
||||
// a new file name out of mInputLine, we remove it from the ALName
|
||||
// object, making mInputLine just a little shorter.
|
||||
//
|
||||
// The mResultFileName member is the storage area where we keep a copy
|
||||
// of the file name created by the expander. This is our local copy,
|
||||
// when it gets returned to the calling program they need to make
|
||||
// their own copy of it and leave ours alone.
|
||||
//
|
||||
// Every time we get asked to get a new file, the very first thing
|
||||
// we do is check to see if the mpNextExpander member is pointing
|
||||
// to a new expander object. If it is, we ask him to provide
|
||||
// the next file name, instead of giving it ourselves. When he
|
||||
// doesn't have any file names left to give, we destroy him and
|
||||
// set that pointer back to 0. Here in the constructor, the smart
|
||||
// thing to do is set him to 0 for starters.
|
||||
//
|
||||
// The final data member differs between NT and DOS. The structure
|
||||
// NT uses to expand directories is store in mFindFileHandle. The
|
||||
// DOS version is stored in mpFfblk. Both of these are presently
|
||||
// in an invalid state, but will get initialized when the user
|
||||
// calls the member function.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALWildCardExpander::ALWildCardExpander(
|
||||
const char AL_DLL_FAR *file_list,
|
||||
int traverse_flag /* = 0 */,
|
||||
ALCase name_case /* = AL_LOWER */ )
|
||||
: mCase( name_case ),
|
||||
mResultFileName( "", name_case )
|
||||
{
|
||||
mInputLine = file_list;
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
mpNextExpander = 0;
|
||||
miTraverseFlag = traverse_flag;
|
||||
#if defined( AL_WIN32S )
|
||||
mFindFileHandle = INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
mpFfblk = new find_t;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// ALWildCardExpander::~ALWildCardExpander()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None, destructors don't get any.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// None, destructor.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// There are a couple of big deals we need to worry about in the
|
||||
// destructor an ALWildCardExpander. First, we have to worry about
|
||||
// any additional handlers we created to search subdirectories. If
|
||||
// this destructor is being called before our search is done, we
|
||||
// may have some of those expander objects just hanging around out
|
||||
// there. We take care of the by checking the mpNextExpander member.
|
||||
// If it isn't set to 0, we delete the dynamically created expander.
|
||||
//
|
||||
// Under NT we also have to worry about our mpFindFileHandle. Under
|
||||
// NT, the file expansion algorithm isn't just a get first/get next
|
||||
// deal. Instead, it is get first/get next/terminate. The termination
|
||||
// is done using the FindClose() call. If we still had a search in progress
|
||||
// we call that function.
|
||||
//
|
||||
// Under DOS, we just have to delete the dynamically created
|
||||
// mpFfblk structure. I wanted to make that a data member of this
|
||||
// class, instead of a pointer, but one of our compilers wasn't happy
|
||||
// about putting this C struct in a class, it complained about something.
|
||||
// So, to expedite, we made it a pointer.
|
||||
//
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
AL_PROTO ALWildCardExpander::~ALWildCardExpander()
|
||||
{
|
||||
if ( mpNextExpander )
|
||||
delete mpNextExpander;
|
||||
#if defined( AL_WIN32S )
|
||||
if ( mFindFileHandle != INVALID_HANDLE_VALUE )
|
||||
FindClose( mFindFileHandle );
|
||||
#else
|
||||
if ( mpFfblk )
|
||||
delete mpFfblk;
|
||||
#endif
|
||||
}
|
||||
|
||||
// PROTECTED MEMBER FUNCTION
|
||||
//
|
||||
// int ALWildCardExpander::GetNextWildName()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// 1 if it got a new file spec, 0 if it didn't.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This function is called internally to get the next file spec out of
|
||||
// the input line. This is simply a matter of parsing past all the
|
||||
// delimiter characters. The resulting file spec is stored in
|
||||
// data member mFullWildName. That member will be the one used to
|
||||
// kick off the next wild card search.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
int AL_PROTO ALWildCardExpander::GetNextWildName()
|
||||
{
|
||||
char wild_spec[ _MAX_PATH ];
|
||||
int i = 0;
|
||||
char *p = mInputLine;
|
||||
|
||||
for ( ; ; p++ ) {
|
||||
int c = *p;
|
||||
if ( c != ' ' && c != ',' && c != '\t' )
|
||||
break;
|
||||
}
|
||||
for ( ; ; p++ ) {
|
||||
int c = *p;
|
||||
if ( c == ' ' || c == ',' || c == '\t' || c == '\0' )
|
||||
break;
|
||||
wild_spec[ i++ ] = (char) c;
|
||||
if ( i >= ( _MAX_PATH - 2 ) )
|
||||
return 0;
|
||||
}
|
||||
wild_spec[ i++ ] = '\0';
|
||||
if ( i <= 1 )
|
||||
return 0;
|
||||
mFullWildName = wild_spec;
|
||||
mInputLine = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// char * ALWildCardExpander::GetNextFile()
|
||||
//
|
||||
// ARGUMENTS:
|
||||
//
|
||||
// None.
|
||||
//
|
||||
// RETURNS
|
||||
//
|
||||
// In the event that this routine is able to come up with a new
|
||||
// file name, it returns a character pointer to the name, which
|
||||
// is kept in member variable mResultFileName. If no new file
|
||||
// name could be cooked up, we return a 0, which means you are
|
||||
// done.
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// There are two wild card expander routines. One for NT, and one
|
||||
// for DOS. They are both very similar in structure, but they weren't
|
||||
// quite close enough to combine into a single routine. However, the
|
||||
// both share a common structure, which is being described here.
|
||||
//
|
||||
// The ALWildCardExpander has what amounts to six different internal
|
||||
// states. They are:
|
||||
//
|
||||
// Searching subdirectories, using another object
|
||||
//
|
||||
// Extracting the next wild spec from the input line
|
||||
//
|
||||
// Expanding the wild card to get the first matching file
|
||||
//
|
||||
// Expanding the wild card to get the next matching file
|
||||
//
|
||||
// Looking for the first subdirectory
|
||||
//
|
||||
// Looking for the next subdirectory
|
||||
//
|
||||
// For the most part, we keep track of the state using the mState
|
||||
// variable. However, we keep track of whether we are searching
|
||||
// subdirectories by examining the pointer to the next expander. If
|
||||
// it is non-null, it means we are in that state.
|
||||
//
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// May 26, 1994 1.0A : First release
|
||||
//
|
||||
|
||||
#if defined( AL_WIN32S )
|
||||
//
|
||||
// This is the NT version. It has to use FindFirstFile() and
|
||||
// FindNextFile() to get file names. Note that this is implemented
|
||||
// as a giant loop. This means we may go through several states
|
||||
// inside this routine until we finally come up with a filename.
|
||||
//
|
||||
char AL_DLL_FAR * AL_PROTO ALWildCardExpander::GetNextFile()
|
||||
{
|
||||
for ( ; ; ) {
|
||||
//
|
||||
// If the pointer to the next expander is set, it means we are working
|
||||
// on a subdirectory, so I have to let him do the work. If the subdirectory
|
||||
// search fails, I continue right back where I was when interrupted.
|
||||
//
|
||||
if ( mpNextExpander ) {
|
||||
char *p = mpNextExpander->GetNextFile();
|
||||
if ( p )
|
||||
return p; // Return the name if he found one
|
||||
delete mpNextExpander; // If not, he is toast
|
||||
mpNextExpander = 0;
|
||||
}
|
||||
switch ( mState ) {
|
||||
//
|
||||
// This is where I get the next wild spec from the input line. If
|
||||
// there aren't any more, I return 0, because we are done. If there
|
||||
// is one, I set up the member variable that will be used in the
|
||||
// rest of the search, and set up the state so that next I will get
|
||||
// get the first file name.
|
||||
//
|
||||
case GET_NEXT_WILD_NAME :
|
||||
if ( GetNextWildName() == 0 )
|
||||
return 0;
|
||||
mWildPathOnly = mFullWildName;
|
||||
mWildPathOnly.StripFileName();
|
||||
mWildNameOnly = mFullWildName;
|
||||
mWildNameOnly.StripPath();
|
||||
mState = GET_FIRST_FILE_NAME;
|
||||
break;
|
||||
//
|
||||
// Once I have a wild spec, time to start getting file names.
|
||||
// FindFirstFile() does it for me. if there aren't any files, I
|
||||
// either go on to search directories, or go the the next wild
|
||||
// name in the input line. If there is a name, I return it to
|
||||
// the calling procedure.
|
||||
//
|
||||
case GET_FIRST_FILE_NAME :
|
||||
mFindFileHandle = FindFirstFile( mFullWildName, &mFindFileData );
|
||||
if ( mFindFileHandle == INVALID_HANDLE_VALUE ) {
|
||||
if ( miTraverseFlag )
|
||||
mState = GET_FIRST_DIRECTORY;
|
||||
else
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
break;
|
||||
}
|
||||
mState = GET_NEXT_FILE_NAME;
|
||||
if ( mFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
||||
break;
|
||||
mResultFileName = ALName( mWildPathOnly + mFindFileData.cFileName );
|
||||
return mResultFileName;
|
||||
//
|
||||
// Time to get another file name with FindNextFile(). If there aren't
|
||||
// any more, I clean up, and either get the next name for the input
|
||||
// line or start searching subdirectories. If there was a name, I return
|
||||
// it to the calling procedure.
|
||||
//
|
||||
case GET_NEXT_FILE_NAME :
|
||||
if ( !FindNextFile( mFindFileHandle, &mFindFileData ) ) {
|
||||
FindClose( mFindFileHandle );
|
||||
mFindFileHandle = INVALID_HANDLE_VALUE;
|
||||
if ( miTraverseFlag )
|
||||
mState = GET_FIRST_DIRECTORY;
|
||||
else
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
break;
|
||||
}
|
||||
if ( mFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
||||
break;
|
||||
mResultFileName = ALName( mWildPathOnly + mFindFileData.cFileName );
|
||||
return mResultFileName;
|
||||
//
|
||||
// The procedure to get the first subdirectory is an awful lot like that
|
||||
// we use to get the first file. If we find a valid subdirectory, we create
|
||||
// a new expander to deal with its wildcards. If we find a file, but
|
||||
// it isn't a subdirectory, we keep on searching. If we don't find
|
||||
// anything, we are going to go back and check out the next file spec
|
||||
// from the input line.
|
||||
//
|
||||
case GET_FIRST_DIRECTORY :
|
||||
mFindFileHandle = FindFirstFile( mWildPathOnly + "*.*", &mFindFileData );
|
||||
if ( mFindFileHandle == INVALID_HANDLE_VALUE ) {
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
break;
|
||||
}
|
||||
mState = GET_NEXT_DIRECTORY;
|
||||
if ( mFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
|
||||
if ( strcmp( mFindFileData.cFileName, ".." ) == 0 )
|
||||
break;
|
||||
if ( strcmp( mFindFileData.cFileName, "." ) == 0 )
|
||||
break;
|
||||
mpNextExpander = new ALWildCardExpander( mWildPathOnly + mFindFileData.cFileName + "\\" + (char *) mWildNameOnly, 1, mCase );
|
||||
}
|
||||
break;
|
||||
//
|
||||
// This works the same as the state where I get the first directory.
|
||||
// The only difference here is that if I run out of file names in the
|
||||
// directory, I have to call FindClose() to clean up after myself.
|
||||
//
|
||||
case GET_NEXT_DIRECTORY :
|
||||
if ( !FindNextFile( mFindFileHandle, &mFindFileData ) ) {
|
||||
FindClose( mFindFileHandle );
|
||||
mFindFileHandle = INVALID_HANDLE_VALUE;
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
break;
|
||||
}
|
||||
if ( mFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
|
||||
if ( strcmp( mFindFileData.cFileName, ".." ) == 0 )
|
||||
break;
|
||||
if ( strcmp( mFindFileData.cFileName, "." ) == 0 )
|
||||
break;
|
||||
mpNextExpander = new ALWildCardExpander( mWildPathOnly + mFindFileData.cFileName + "\\" + (char *) mWildNameOnly, 1 );
|
||||
}
|
||||
break;
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
//
|
||||
// This is the MS-DOS version of the file expander. In structure,
|
||||
// it is almost identical to the NT version.
|
||||
//
|
||||
char AL_DLL_FAR * AL_PROTO ALWildCardExpander::GetNextFile()
|
||||
{
|
||||
//
|
||||
// mpFfblk is the pointer to my structure used by _dos_findfirst()
|
||||
// and _dos_findnext(). If for some reason this is a null pointer,
|
||||
// I need to quit. The only reason this should be null is a memory
|
||||
// allocation failure.
|
||||
//
|
||||
if ( mpFfblk == 0 )
|
||||
return 0;
|
||||
for ( ; ; ) {
|
||||
//
|
||||
// If the pointer to the next expander is non-zero, it means I am in
|
||||
// the middle of a subdirectory search. If that is the case, I call
|
||||
// the next expander to see if it can come up with a file name. if
|
||||
// it does, we return it. If it doesn't, it means it is done, and
|
||||
// I can delete it and try my luck with the next subdirectory.
|
||||
//
|
||||
if ( mpNextExpander ) {
|
||||
char *p = mpNextExpander->GetNextFile();
|
||||
if ( p )
|
||||
return p;
|
||||
delete mpNextExpander;
|
||||
mpNextExpander = 0;
|
||||
}
|
||||
switch ( mState ) {
|
||||
//
|
||||
// This is where I start, and this is where I end up after completely
|
||||
// processing one of the input wild specs. I get the next name from
|
||||
// the input line here. If there aren't any more names, I can return
|
||||
// 0, meaning the whole thing is done.
|
||||
//
|
||||
case GET_NEXT_WILD_NAME :
|
||||
if ( GetNextWildName() == 0 )
|
||||
return 0;
|
||||
mWildPathOnly = mFullWildName;
|
||||
mWildPathOnly.StripFileName();
|
||||
mWildNameOnly = mFullWildName;
|
||||
mWildNameOnly.StripPath();
|
||||
mState = GET_FIRST_FILE_NAME;
|
||||
break;
|
||||
//
|
||||
// Once I have a file name, I start parsing using _dos_findfirst().
|
||||
// If that doesn't return a name, I have struck out on my first swing.
|
||||
// if that is the case, I either move on to start searching subdirectories,
|
||||
// or go back and look for another name from the input line. On the
|
||||
// other hand, if I get a name, I return it to the caller.
|
||||
//
|
||||
case GET_FIRST_FILE_NAME :
|
||||
if ( _dos_findfirst( mFullWildName, 0, mpFfblk ) ) {
|
||||
if ( miTraverseFlag )
|
||||
mState = GET_FIRST_DIRECTORY;
|
||||
else
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
break;
|
||||
}
|
||||
mState = GET_NEXT_FILE_NAME;
|
||||
mResultFileName = ALName( mWildPathOnly + mpFfblk->name );
|
||||
return mResultFileName;
|
||||
//
|
||||
// This state is identical to GET_FIRST_FILE_NAME, except it has to
|
||||
// use _dos_findnext() instead of _dos_findfirst()
|
||||
//
|
||||
case GET_NEXT_FILE_NAME :
|
||||
if ( _dos_findnext( mpFfblk ) ) {
|
||||
if ( miTraverseFlag )
|
||||
mState = GET_FIRST_DIRECTORY;
|
||||
else
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
break;
|
||||
}
|
||||
mResultFileName = mWildPathOnly + mpFfblk->name;
|
||||
return mResultFileName;
|
||||
//
|
||||
// After getting all of the file names that a wildspec expands into,
|
||||
// we can start searching subdirectories, if needed. Unlike with NT,
|
||||
// we can set our search up to look for directories only. that means
|
||||
// we don't have to check the status of the file returned from _dos_findxxxx().
|
||||
// However, we always do have to check to make sure it isn't one of the
|
||||
// two bogus directory entries, "." or "..".
|
||||
//
|
||||
// If we score here, we create a new ALWildCardExpander, and put him to
|
||||
// work. If we strike out, time to go back and get our next input
|
||||
// file name.
|
||||
//
|
||||
case GET_FIRST_DIRECTORY :
|
||||
if ( _dos_findfirst( mWildPathOnly + "*.*", _A_SUBDIR, mpFfblk ) ) {
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
break;
|
||||
}
|
||||
mState = GET_NEXT_DIRECTORY;
|
||||
if ( mpFfblk->attrib & _A_SUBDIR ) {
|
||||
if ( strcmp( mpFfblk->name, ".." ) == 0 )
|
||||
break;
|
||||
if ( strcmp( mpFfblk->name, "." ) == 0 )
|
||||
break;
|
||||
mpNextExpander = new ALWildCardExpander( mWildPathOnly + mpFfblk->name + "\\" + (char *) mWildNameOnly, 1, mCase );
|
||||
}
|
||||
break;
|
||||
//
|
||||
// This is just like GET_FIRST_DIRECTORY, except it gets to call
|
||||
// _dos_findnext() instead of _dos_findfirst().
|
||||
//
|
||||
case GET_NEXT_DIRECTORY :
|
||||
if ( _dos_findnext( mpFfblk ) ) {
|
||||
mState = GET_NEXT_WILD_NAME;
|
||||
break;
|
||||
}
|
||||
if ( mpFfblk->attrib & _A_SUBDIR ) {
|
||||
if ( strcmp( mpFfblk->name, ".." ) == 0 )
|
||||
break;
|
||||
if ( strcmp( mpFfblk->name, "." ) == 0 )
|
||||
break;
|
||||
mpNextExpander = new ALWildCardExpander( mWildPathOnly + mpFfblk->name + "\\" + (char *) mWildNameOnly, 1 );
|
||||
}
|
||||
break;
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#if defined( AL_MICROSOFT ) && ( AL_MICROSOFT < 800 )
|
||||
return 0; //MSC 7.0 thinks I need this return path. No way to get here!
|
||||
#endif
|
||||
}
|
||||
#endif // #if defined( AL_WIN32S )... #else
|
||||
169
al/wildcard.h
Executable file
169
al/wildcard.h
Executable file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* WILDCARD.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file contains the class declaration for ALWildCardExpander,
|
||||
* the class used to expand wildcard file specifications under
|
||||
* DOS and Win32s.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALWildCardExpander
|
||||
*
|
||||
* ENUMERATED TYPES:
|
||||
*
|
||||
* ALExpanderState (embedded in ALWildCardExpander)
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _WILDCARD_H
|
||||
#define _WILDCARD_H
|
||||
|
||||
// #include <dos.h>
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
|
||||
/*
|
||||
* class ALOpenInputFile
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This class is used to expand wild card specifications on a DOS
|
||||
* or NT file system. Note that you can do exciting things with this, like
|
||||
* traversing through subdirectories, and separate various specs using
|
||||
* commas or white space.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mState : The current state of the expander. This is a value
|
||||
* from ALExpander state that lets use keep track
|
||||
* of where we are between calls to the expander.
|
||||
*
|
||||
* mpNextExpander : If we are traversing subdirectories, we will
|
||||
* open a new expander for each subdirectory. This
|
||||
* is a pointer to any subdirectory we might already
|
||||
* have open for a search in progress.
|
||||
*
|
||||
* mInputLine : The list of wildcard filespecs passed in as an
|
||||
* argument. This gets whittled away, and will be
|
||||
* smaller and smaller as all the names are parsed out.
|
||||
*
|
||||
* mFullWildName : The current wild card file spec that is being
|
||||
* expanded.
|
||||
*
|
||||
* mWildNameOnly : The current wild name that is being expanded,
|
||||
* stripped of its drive and path information.
|
||||
*
|
||||
* mWildPathOnly : The current drive and path being expanded, stripped
|
||||
* of its filename and extension.
|
||||
*
|
||||
* mResultFileName : The file name that is returned to the calling
|
||||
* program.
|
||||
*
|
||||
* mFindFileData : Under Win32s, this holds data about the file we
|
||||
* found.
|
||||
*
|
||||
* mFindFileHandle : Under Win32s, this is a handle used during the
|
||||
* wildcard expansion.
|
||||
*
|
||||
* mpFfblk : Under MS-DOS, this structure holds the state of
|
||||
* the wildcard expansion in progress.
|
||||
*
|
||||
* miTraverseFlag : This flag indicates whether the search should traverse
|
||||
* traverse through subdirectories or just search
|
||||
* in the current directory.
|
||||
*
|
||||
* mCase : Indicates whether file names should always be forced
|
||||
* to upper case, forced to lower case, or left mixed.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALWildCardExpander() : Constructor, everything we need to know to
|
||||
* perform the search is defined here.
|
||||
* ~ALWildCardExpander() : Destructor.
|
||||
* operator new() : Memory allocation function, used when the
|
||||
* library is in a DLL.
|
||||
* GetNextWildName() : Protected routine to get the next wild name
|
||||
* from the input line.
|
||||
* GetNextFile() : The function to get the next expanded file
|
||||
* name. It keeps chunking out names until
|
||||
* the search is complete.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
class AL_CLASS_TYPE ALWildCardExpander {
|
||||
/*
|
||||
* Constructors, destructors, assignment operators, declarations
|
||||
*/
|
||||
protected :
|
||||
enum ALExpanderState {
|
||||
GET_NEXT_WILD_NAME,
|
||||
GET_FIRST_FILE_NAME,
|
||||
GET_NEXT_FILE_NAME,
|
||||
GET_FIRST_DIRECTORY,
|
||||
GET_NEXT_DIRECTORY,
|
||||
};
|
||||
public :
|
||||
AL_PROTO ALWildCardExpander( const char AL_DLL_FAR *file_list,
|
||||
int traverse_flag = 0,
|
||||
ALCase name_case = AL_LOWER );
|
||||
AL_PROTO ~ALWildCardExpander();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
/*
|
||||
* Disable copy constructor and assignment operator
|
||||
*/
|
||||
protected :
|
||||
ALWildCardExpander AL_DLL_FAR & AL_PROTO operator=( ALWildCardExpander AL_DLL_FAR & );
|
||||
AL_PROTO ALWildCardExpander( ALWildCardExpander AL_DLL_FAR & );
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
protected :
|
||||
int AL_PROTO GetNextWildName();
|
||||
|
||||
public :
|
||||
char AL_DLL_FAR * AL_PROTO GetNextFile();
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
ALExpanderState mState;
|
||||
ALWildCardExpander AL_DLL_FAR *mpNextExpander;
|
||||
ALName mInputLine;
|
||||
ALName mFullWildName;
|
||||
ALName mWildNameOnly;
|
||||
ALName mWildPathOnly;
|
||||
ALName mResultFileName;
|
||||
#if defined( AL_WIN32S )
|
||||
WIN32_FIND_DATA mFindFileData;
|
||||
HANDLE mFindFileHandle;
|
||||
#else
|
||||
struct find_t AL_DLL_FAR *mpFfblk;
|
||||
#endif
|
||||
int miTraverseFlag;
|
||||
public :
|
||||
const ALCase mCase;
|
||||
AL_CLASS_TAG( _ALWildCardExpanderTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifdef _WINMON_H */
|
||||
113
al/winmon.h
Executable file
113
al/winmon.h
Executable file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* WINMON.H
|
||||
*
|
||||
* Header file for ArchiveLib 1.0
|
||||
*
|
||||
* Copyright (c) 1994 Greenleaf Software, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This header file contains the declaration for ALWindowsMessage,
|
||||
* a monitor class used under Windows.
|
||||
*
|
||||
* CLASS DEFINITIONS:
|
||||
*
|
||||
* ALWindowsMessage
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _WINMON_H
|
||||
#define _WINMON_H
|
||||
|
||||
#include "arclib.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
|
||||
/*
|
||||
* class ALWindowsMessage
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This class is used to provide user feedback when operating under
|
||||
* windows. It can be constructed to send messages to windows from
|
||||
* YieldTime(), allowing you to easily update progress bars, text
|
||||
* boxes, or whatever.
|
||||
*
|
||||
* DATA MEMBERS
|
||||
*
|
||||
* mhMessageWindowHandle : The handle of the window that is going to
|
||||
* get the text messages generated by the
|
||||
* ArchiveOperation() procedure. If this
|
||||
* member is set to 0, no messages are sent.
|
||||
*
|
||||
* mhNumberWindowHandle : The handle of the window that is going to
|
||||
* get either the byte count or the percent
|
||||
* complete figure. If miMessage is 0, it
|
||||
* is formatted as ASCII and sent using a
|
||||
* SetWindowText() call. O/W, it is sent
|
||||
* using SendMessage(), in Lparam and Wparam.
|
||||
*
|
||||
* mMessageType : AL_SEND_BYTE_COUNT or AL_SEND_RATIO.
|
||||
*
|
||||
* miMessage : The message that gets sent with with the
|
||||
* byte count or ratio.
|
||||
*
|
||||
* MEMBER FUNCTIONS
|
||||
*
|
||||
* ALWindowsMessage() : The one and only constructor.
|
||||
* ~ALWindowsMessage() : The destructor.
|
||||
* operator new() : The memory allocation operator, only used
|
||||
* when the library is in a DLL.
|
||||
* Progress() : The virtual function that gets called to
|
||||
* update progress through the file/job.
|
||||
* ArchiveOperation() : The virtual function that gets called
|
||||
* at key points in the archiving process.
|
||||
*
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* May 26, 1994 1.0A : First release
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class AL_CLASS_TYPE ALWindowsMessage : public ALMonitor {
|
||||
/*
|
||||
* Constructors, destructors, and friends
|
||||
*/
|
||||
public :
|
||||
AL_PROTO ALWindowsMessage( ALMonitorType monitor_type,
|
||||
HWND progress_text_window,
|
||||
ALWindowsMessageType message_type,
|
||||
HWND progress_number_window,
|
||||
UINT windows_message = 0 );
|
||||
virtual AL_PROTO ~ALWindowsMessage();
|
||||
#if defined( AL_USING_DLL ) || defined( AL_BUILDING_DLL )
|
||||
void AL_DLL_FAR * AL_PROTO operator new( size_t size );
|
||||
#endif
|
||||
protected :
|
||||
virtual void AL_PROTO Progress( long mlObjectSoFar,
|
||||
ALStorage AL_DLL_FAR & object );
|
||||
virtual void AL_PROTO
|
||||
ArchiveOperation( ALArchiveOperation operation,
|
||||
ALArchiveBase AL_DLL_FAR *archive,
|
||||
ALEntry AL_DLL_FAR *job );
|
||||
/*
|
||||
* Data members
|
||||
*/
|
||||
protected :
|
||||
HWND mhMessageWindowHandle;
|
||||
HWND mhNumberWindowHandle;
|
||||
ALWindowsMessageType mMessageType;
|
||||
int miMessage;
|
||||
public :
|
||||
AL_CLASS_TAG( _ALWindowsMessageTag );
|
||||
};
|
||||
|
||||
#endif /* #if defined( __cplusplus ) */
|
||||
|
||||
#endif /* #ifdef _WINMON_H */
|
||||
Loading…
x
Reference in New Issue
Block a user