1476 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1476 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
//
 | 
						|
// STORAGE.CPP
 | 
						|
//
 | 
						|
//  Source file for ArchiveLib 2.0
 | 
						|
//
 | 
						|
//  Copyright (c) Greenleaf Software, Inc. 1994-1996
 | 
						|
//  All Rights Reserved
 | 
						|
//
 | 
						|
// CONTENTS
 | 
						|
//
 | 
						|
//  ALStorage::operator new()
 | 
						|
//  ALStorage::ALStorage()
 | 
						|
//  ALStorage::~ALStorage()
 | 
						|
//  deleteALStorage()
 | 
						|
//  ALStorage::Open()
 | 
						|
//  ALStorageOpen()
 | 
						|
//  ALStorage::Create()
 | 
						|
//  ALStorageCreate()
 | 
						|
//  ALStorage::Close()
 | 
						|
//  ALStorageClose()
 | 
						|
//  ALStorage::ReadBuffer()
 | 
						|
//  ALStorageReadBuffer()
 | 
						|
//  ALStorageReadBufferVB32()
 | 
						|
//  ALStorage::WriteBuffer()
 | 
						|
//  ALStorageWriteBuffer()
 | 
						|
//  ALStorageWriteBufferVB32()
 | 
						|
//  ALStorage::WriteString()
 | 
						|
//  ALStorageWriteString()
 | 
						|
//  ALStorage::ReadString()
 | 
						|
//  ALStorage::Tell()
 | 
						|
//  ALStorageTell()
 | 
						|
//  ALStorage::WriteStorageObjectData()
 | 
						|
//  ALStorage::ReadStorageObjectData()
 | 
						|
//  ALStorage::ReadCopyright()
 | 
						|
//  ALStorageReadCopyright()
 | 
						|
//  ALStorageReadCopyrightVB()
 | 
						|
//
 | 
						|
// 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
 | 
						|
//
 | 
						|
//  July 7, 1994  1.0B  : Minor bug fixes
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
#include "arclib.h"
 | 
						|
#if !defined( AL_IBM )
 | 
						|
#pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#include "_vbutil.h"
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::operator new()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Memory allocator used when ArchiveLib resides in a 16 bit DLL.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  void * ALStorage::operator new( size_t size )
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None, internal C++ member function.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None, internal C++ member function.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None, internal C++ member function.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  size  :  The number of bytes that the compiler has decided will be
 | 
						|
//           necessary to construct a new ALStorage object.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  When using a DLL, it is easy to get into a dangerous situation when
 | 
						|
//  creating objects whose ctor and dtor are both in the DLL.  The problem
 | 
						|
//  arises because when you create an object using new, the memory for
 | 
						|
//  the object will be allocated from the EXE.  However, when you destroy
 | 
						|
//  the object using delete, the memory is freed inside the DLL.  Since
 | 
						|
//  the DLL doesn't really own that memory, bad things can happen.
 | 
						|
//
 | 
						|
//  But, you say, won't the space just go back to the Windows heap regardless
 | 
						|
//  of who tries to free it?  Maybe, but maybe not.  If the DLL is using
 | 
						|
//  a subsegment allocation scheme, it might do some sort of local free
 | 
						|
//  before returning the space to the windows heap.  That is the point where
 | 
						|
//  you could conceivably cook your heap.
 | 
						|
//
 | 
						|
//  By providing our own version of operator new inside this class, we
 | 
						|
//  ensure that all memory allocation for the class will be done from
 | 
						|
//  inside the DLL, not the EXE calling the DLL.
 | 
						|
//
 | 
						|
//  Note that this function will probably never be called.  You can't
 | 
						|
//  instantiate an ALStorage object, because it has some pure virtual
 | 
						|
//  functions.  So only derived classes get instantiated, and they
 | 
						|
//  really ought to have their own new operators.
 | 
						|
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  A pointer to some memory that should have been pulled out of the
 | 
						|
//  heap for the DLL.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   May 24, 1994  1.0A  : First release
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
#if defined( AL_BUILDING_DLL )
 | 
						|
 | 
						|
void AL_DLL_FAR * AL_PROTO
 | 
						|
ALStorage::operator new( size_t size )  /* Tag protected function */
 | 
						|
{
 | 
						|
    return ::new char[ size ];
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::ALStorage()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  The ALStorage constructor.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  ALStorage::ALStorage( const char *file_name,
 | 
						|
//                        size_t size,
 | 
						|
//                        const enum ALStorageType object_type,
 | 
						|
//                        ALCase name_case = AL_MIXED );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this function is not available to C programmers.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this function is not available to VB programmers.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this function is not available to Delphi programmers.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  Nothing, it is a constructor.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
//  N/A, not part of the public API.
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALFile::ALFile(), ALMemory::ALMemory()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
AL_PROTO
 | 
						|
ALStorage::ALStorage( const char AL_DLL_FAR *file_name,  /* Tag public function */
 | 
						|
                      size_t size,
 | 
						|
                      const enum ALStorageType object_type,
 | 
						|
                      ALCase name_case /* = AL_MIXED */ )
 | 
						|
    : 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" );
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::~ALStorage()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  The ALStorage destructor.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  ALStorage::~ALStorage();
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  void deleteALStorage( hALStorage this_object );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Sub deleteALStorage Lib "AL20LW" (ByVal this_object&)
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  procedure deleteALStorage( this_object : hALStorage );
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  : A handle for (pointer to) the storage object that
 | 
						|
//                 is going to be destroyed.  Note that the C++ version
 | 
						|
//                 of this function doesn't have this argument, since it
 | 
						|
//                 has implicit access to 'this'.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  Nothing.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
AL_PROTO
 | 
						|
ALStorage::~ALStorage()  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT( GoodTag(), "~ALStorage: attempting to delete invalid object" );
 | 
						|
    if ( mpcBuffer )
 | 
						|
        Close();
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE void AL_FUNCTION
 | 
						|
deleteALStorage( hALStorage this_object )  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "deleteALStorage" );
 | 
						|
    delete (ALStorage *) this_object;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::Open()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Open a storage object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorage::Open()
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorageOpen( hALStorage this_object )
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALStorageOpen Lib "AL20LW"
 | 
						|
//    (ByVal this_object&) As Integer
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALStorageOpen( this_object : hALStorage ) : Integer;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALStorage object that
 | 
						|
//                  is going to be opened.  Note that the C++
 | 
						|
//                  version of this call doesn't have an explicit argument
 | 
						|
//                  here, since it has access to 'this' implicitly.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALStorage::Create(), ALStorage::Close()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
int AL_PROTO
 | 
						|
ALStorage::Open()  /* Tag public function */
 | 
						|
{
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE int AL_FUNCTION
 | 
						|
ALStorageOpen( hALStorage this_object )  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageOpen" );
 | 
						|
    return ( (ALStorage *) this_object )->Open();
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::Create();
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Create a new storage object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorage::Create( long desired_size = - 1 );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorageCreate( hALStorage this_object, long desired_size );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALStorageCreate Lib "AL20LW"
 | 
						|
//    (ByVal this_object&, ByVal desired_size&) As Integer
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALStorageCreate( this_object : hALStorage;
 | 
						|
//                            desired_size : Long ) : Integer;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALStorage object that
 | 
						|
//                  is going to be created.  Note that the C++
 | 
						|
//                  version of this call doesn't have an explicit argument
 | 
						|
//                  here, since it has access to 'this' implicitly.
 | 
						|
//
 | 
						|
//  desired_size :  If you know in advance how much space a storage object
 | 
						|
//                  is going to occupy, you can pass that number as the
 | 
						|
//                  desired_size argument.  Some storage types, such as
 | 
						|
//                  ALMemory, can make good use of this information.  Others
 | 
						|
//                  such as ALFile, could care less.  In any case, the base
 | 
						|
//                  class, ALStorage, ignores the info.  If you don't know
 | 
						|
//                  how many bytes the storage object is going to need,
 | 
						|
//                  pass a -1L as the argument.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALStorage::Delete(), ALStorage::Open()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
int AL_PROTO
 | 
						|
ALStorage::Create( long /* desired_size = - 1 */ )  /* Tag public function */
 | 
						|
{
 | 
						|
    if ( mStatus < AL_SUCCESS )
 | 
						|
        return mStatus;
 | 
						|
    mpcBuffer = new unsigned char[ muBufferSize ];
 | 
						|
    muBufferValidData = 0;
 | 
						|
    muWriteIndex = 0;
 | 
						|
    muReadIndex = 0;
 | 
						|
    mlFilePointer = 0;
 | 
						|
    miUpdateCrcFlag = 0;
 | 
						|
    mlSize = 0; //If the file has been opened previously, mlSize might be non-zero
 | 
						|
    mlCrc32 = 0xffffffffL;
 | 
						|
    miCreated = 1;
 | 
						|
    if ( mpcBuffer == 0 )
 | 
						|
        return mStatus.SetError( AL_CANT_OPEN_BUFFER,
 | 
						|
                                 "Allocation of buffer failed in Open()" );
 | 
						|
    return AL_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE int AL_FUNCTION
 | 
						|
ALStorageCreate( hALStorage this_object, /* Tag public function */
 | 
						|
                 long desired_size )
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageCreate" );
 | 
						|
    if ( desired_size == AL_DEFAULT )
 | 
						|
        desired_size = -1;
 | 
						|
    return ( (ALStorage *) this_object )->Create( desired_size );
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::Close()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Close an ALStorage object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorage::Close();
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorageClose( hALStorage this_object );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALStorageClose Lib "AL20LW"
 | 
						|
//    (ByVal this_object&) As Integer
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALStorageClose( this_object : hALStorage ) : Integer;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALStorage object that
 | 
						|
//                  is going to be closed.  Note that the C++
 | 
						|
//                  version of this call doesn't have an explicit argument
 | 
						|
//                  here, since it has access to 'this' implicitly.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  Just like with Open(), most 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.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  The current integer status of the object.  Hopefully this will be
 | 
						|
//  AL_SUCCESS, but it could well be a value < AL_SUCCESS.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALFile::Create(), ALFile::Open()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
int AL_PROTO
 | 
						|
ALStorage::Close()  /* Tag public function */
 | 
						|
{
 | 
						|
    if ( mpcBuffer ) {
 | 
						|
        delete[] mpcBuffer;
 | 
						|
        mpcBuffer = 0;
 | 
						|
    }
 | 
						|
    return mStatus;
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE int AL_FUNCTION
 | 
						|
ALStorageClose( hALStorage this_object )  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageClose" );
 | 
						|
    return ( (ALStorage *) this_object )->Close();
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::ReadBuffer()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Read in a buffer full of data.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  size_t ALStorage::ReadBuffer( unsigned char *buf, size_t length );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  size_t ALStorageReadBuffer( hALStorage this_object,
 | 
						|
//                              unsigned char *buffer,
 | 
						|
//                              size_t length );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALStorageReadBuffer Lib "AL20LW"
 | 
						|
//    (ByVal this_object&, ByVal buffer$, ByVal length%) As Integer
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALStorageReadBuffer( this_object : hALStorage;
 | 
						|
//                                buffer : PChar;
 | 
						|
//                                length : Integer ) : Integer;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALStorage object that
 | 
						|
//                  is going to be read.  Note that the C++
 | 
						|
//                  version of this call doesn't have an explicit argument
 | 
						|
//                  here, since it has access to 'this' implicitly.
 | 
						|
//
 | 
						|
//  buf    :  The buffer that is going to receive input characters.
 | 
						|
//
 | 
						|
//  length :  The number of bytes you want to read.
 | 
						|
//
 | 
						|
// 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().
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  The number of bytes read in, always.  If this function generates an
 | 
						|
//  error, it will be found in the mStatus member.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALStorage::ReadChar(), ALStorage::WriteBuffer()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
size_t AL_PROTO
 | 
						|
ALStorage::ReadBuffer( unsigned char AL_DLL_FAR *buf,  /* Tag public function */
 | 
						|
                       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;
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE size_t AL_FUNCTION
 | 
						|
ALStorageReadBuffer( hALStorage this_object,  /* Tag public function */
 | 
						|
                     unsigned char AL_DLL_FAR *buffer,
 | 
						|
                     size_t length )
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageReadBuffer" );
 | 
						|
    AL_ASSERT( buffer != 0, "Passed a null buffer to ALStorageReadBuffer" );
 | 
						|
    return ( (ALStorage * ) this_object )->ReadBuffer( buffer, length );
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined( AL_VB32 )
 | 
						|
extern "C" AL_LINKAGE size_t AL_FUNCTION
 | 
						|
ALStorageReadBufferVB32( hALStorage this_object,  /* Tag public function */
 | 
						|
                         LPSAFEARRAY *ppsa,
 | 
						|
                         size_t length )
 | 
						|
{
 | 
						|
    unsigned char *p;
 | 
						|
    size_t result;
 | 
						|
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageReadBufferVB32" );
 | 
						|
    AL_ASSERT( SafeArrayGetDim( *ppsa ) > 0, "Array with < 1 dimensions in ALStorageWriteBufferVB32" );
 | 
						|
//
 | 
						|
// This doesn't work, don't know why
 | 
						|
//
 | 
						|
//    int j = SafeArrayGetElemsize( *ppsa );
 | 
						|
//    wsprintf( buffer, "Array dim = %d  j = %d  length = %d", i, j, length );
 | 
						|
//    char buffer[ 81 ];
 | 
						|
//    MessageBox( 0, buffer, buffer, MB_OK );
 | 
						|
//    AL_ASSERT( j >= (int) length, "Buffer too small in ALStorageReadBufferVB32" );
 | 
						|
//    int j =
 | 
						|
    SafeArrayAccessData( *ppsa, (void **) &p );
 | 
						|
    result = ( (ALStorage * ) this_object )->ReadBuffer( p, length );
 | 
						|
    SafeArrayUnaccessData( *ppsa );
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::WriteBuffer()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Write a buffer to a storage object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  size_t ALStorage::WriteBuffer( const unsigned char *buf,
 | 
						|
//                                 size_t length );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  size_t ALStorageWriteBuffer( hALStorage this_object,
 | 
						|
//                               unsigned char *buffer,
 | 
						|
//                               size_t length );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALStorageWriteBuffer Lib "AL20LW"
 | 
						|
//    (ByVal this_object&, ByVal buffer$, ByVal length%) As Integer
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALStorageWriteBuffer( this_object : hALStorage;
 | 
						|
//                                 buffer : PChar;
 | 
						|
//                                 length : Integer ) : Integer;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALStorage object that
 | 
						|
//                  is going to be written to.  Note that the C++
 | 
						|
//                  version of this call doesn't have an explicit argument
 | 
						|
//                  here, since it has access to 'this' implicitly.
 | 
						|
//
 | 
						|
//  buf    :  The buffer that is contains the output data.
 | 
						|
//
 | 
						|
//  length :  The number of bytes you want to write.
 | 
						|
//
 | 
						|
// 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().
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  The number of bytes written, always.  If this function generates an
 | 
						|
//  error, it will be found in the mStatus member.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALStorage::WriteChar(), ALStorage::ReadBuffer()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
size_t AL_PROTO
 | 
						|
ALStorage::WriteBuffer( const unsigned char AL_DLL_FAR *buf,  /* Tag public function */
 | 
						|
                        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;
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE size_t AL_FUNCTION
 | 
						|
ALStorageWriteBuffer( hALStorage this_object,  /* Tag public function */
 | 
						|
                      unsigned char AL_DLL_FAR *buffer,
 | 
						|
                      size_t length )
 | 
						|
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageWriteBuffer" );
 | 
						|
    AL_ASSERT( buffer != 0, "Passed a null buffer to ALStorageWriteBuffer" );
 | 
						|
    return ( (ALStorage * ) this_object )->WriteBuffer( buffer, length );
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined( AL_VB32 )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE size_t AL_FUNCTION
 | 
						|
ALStorageWriteBufferVB32( hALStorage this_object,  /* Tag public function */
 | 
						|
                          LPSAFEARRAY *ppsa,
 | 
						|
                          size_t length )
 | 
						|
 | 
						|
{
 | 
						|
    unsigned char *p;
 | 
						|
    size_t result;
 | 
						|
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageWriteBufferVB32" );
 | 
						|
    AL_ASSERT( SafeArrayGetDim( *ppsa ) > 0, "Array with < 1 dimensions in ALStorageWriteBufferVB32" );
 | 
						|
//    i = SafeArrayGetElemsize( *ppsa );
 | 
						|
//    AL_ASSERT( i >= (int)length, "Buffer too small in ALStorageWriteBufferVB32" );
 | 
						|
//    int j =
 | 
						|
    SafeArrayAccessData( *ppsa, (void **) &p );
 | 
						|
    result = ( (ALStorage * ) this_object )->WriteBuffer( p, length );
 | 
						|
    SafeArrayUnaccessData( *ppsa );
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::WriteString()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Write a null terminated string to a storage object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorage::WriteString( const char AL_DLL_FAR *string_data );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorageWriteString( hALStorage this_object,
 | 
						|
//                            char *string );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALStorageWriteString Lib "AL20LW"
 | 
						|
//    (ByVal this_object&, ByVal string_data$) As Integer
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALStorageWriteString( this_object : hALStorage;
 | 
						|
//                                 string_data : PChar ) : Integer;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALStorage object that
 | 
						|
//                  is going to have a string written to it.  Note that the C++
 | 
						|
//                  version of this call doesn't have an explicit argument
 | 
						|
//                  here, since it has access to 'this' implicitly.
 | 
						|
//
 | 
						|
//  string_data  :  A C-style null terminated string to be written out in
 | 
						|
//                  our portable format.
 | 
						|
//
 | 
						|
// 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 WriteGlShort(), followed by the data.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  AL_SUCCESS if things work, or an error code < AL_SUCCESS if an error
 | 
						|
//  occurs writing the data out.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALStorage::ReadString()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
int AL_PROTO
 | 
						|
ALStorage::WriteString( const char AL_DLL_FAR *string_data )  /* Tag public function */
 | 
						|
{
 | 
						|
    short unsigned int len;
 | 
						|
    if ( string_data != 0 )
 | 
						|
        len = (short unsigned int) strlen( string_data );
 | 
						|
    else
 | 
						|
        len = 0;
 | 
						|
    WriteGlShort( len );
 | 
						|
    if ( len )
 | 
						|
        WriteBuffer( (unsigned char *) string_data, len );
 | 
						|
    return mStatus;
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE int AL_FUNCTION
 | 
						|
ALStorageWriteString( hALStorage this_object,  /* Tag public function */
 | 
						|
                      char AL_DLL_FAR *string )
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageWriteString" );
 | 
						|
    AL_ASSERT( string != 0, "Passing null string in ALStorageWriteString()" );
 | 
						|
    return ( (ALStorage *) this_object )->WriteString( string );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::ReadString()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Read a string from a storage object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorage::ReadString( ALName &name,
 | 
						|
//                             short int length = -1 );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None, we have problems with this in C/VB/Delphi.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None, we have problems with this in C/VB/Delphi.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None, we have problems with this in C/VB/Delphi.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  name  :  A reference to the storage object that is going to be loaded
 | 
						|
//           up with a string.  Note that using an ALName object is a good
 | 
						|
//           thing here, because we are going to have to dynamically allocate
 | 
						|
//           data based on how long the input string is.  If we returned a
 | 
						|
//           char *, we would have problems, because the pointer would be
 | 
						|
//           allocated inside the DLL, but the user would have to free it
 | 
						|
//           outside the DLL.  With an ALName, the data will be freed inside
 | 
						|
//           the DLL when the ALName object is destroyed.
 | 
						|
//
 | 
						|
//           We can't pass around this ALName object to C/VB/Delphi, so they
 | 
						|
//           don't get access to this function.  Sorry.
 | 
						|
//
 | 
						|
//  length : Normally, you read the length in from the storage object,
 | 
						|
//           and then read in the data.  But sometimes, you know the
 | 
						|
//           length in advance, and don't want to read it from the
 | 
						|
//           storage object.  In that case, pass the length in this arg.
 | 
						|
//           O/w, pass -1.
 | 
						|
//
 | 
						|
// 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).
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  AL_SUCCESS, or not.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALStorage::WriteString()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
int AL_PROTO
 | 
						|
ALStorage::ReadString( ALName AL_DLL_FAR &name,  /* Tag public function */
 | 
						|
                       short int length /* = -1 */ )
 | 
						|
{
 | 
						|
    if ( length == -1 ) {
 | 
						|
        if ( ReadGlShort( length ) < 0 )
 | 
						|
        return mStatus.SetError( AL_READ_ERROR,
 | 
						|
                                 "Error reading string length"
 | 
						|
                                 "in ReadString() for object %s",
 | 
						|
                                  mName.GetSafeName() );
 | 
						|
    }
 | 
						|
    char *new_string = new char[ length + 1 ];
 | 
						|
    if ( new_string ) {
 | 
						|
        ReadBuffer( (unsigned char *) new_string, length );
 | 
						|
        new_string[ length ] = '\0';
 | 
						|
        name = new_string;
 | 
						|
        delete[] new_string;
 | 
						|
        return AL_SUCCESS;
 | 
						|
    }
 | 
						|
    return mStatus.SetError( AL_CANT_ALLOCATE_MEMORY,
 | 
						|
                             "Error allocating buffer space in call "
 | 
						|
                             "to ReadString() for object %s",
 | 
						|
                              mName.GetSafeName() );
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::Tell()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Return the current offset in the storage object.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  long ALStorage::Tell();
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  long ALStorageTell( hALStorage this_object );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALStorageTell Lib "AL20LW"
 | 
						|
//    (ByVal this_object&) As Long
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALStorageTell( this_object : hALStorage ) : LongInt;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :  A reference or pointer to the ALStorage object that
 | 
						|
//                  is going to have its offset returned.  Note that the C++
 | 
						|
//                  version of this call doesn't have an explicit argument
 | 
						|
//                  here, since it has access to 'this' implicitly.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  A long integer indicating the current position of the read/write
 | 
						|
//  pointer for the file.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALStorage::Seek(), ALStorage::WriteBuffer()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
long AL_PROTO
 | 
						|
ALStorage::Tell()  /* Tag public function */
 | 
						|
{
 | 
						|
    if ( muWriteIndex )
 | 
						|
        return mlFilePointer + muWriteIndex;
 | 
						|
    else
 | 
						|
        return mlFilePointer - muBufferValidData + muReadIndex;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE long AL_FUNCTION
 | 
						|
ALStorageTell( hALStorage this_object )  /* Tag public function */
 | 
						|
{
 | 
						|
    AL_ASSERT_OBJECT( this_object, ALStorage, "ALStorageTell" );
 | 
						|
    return ( (ALStorage *) this_object )->Tell();
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::WriteStorageObjectData()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Write out class-specific storage object data.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorage::WriteStorageObjectData( ALStorage * archive );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is an internal callback virtual function.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is an internal callback virtual function.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is an internal callback virtual function.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  archive : A pointer to the storage object where we are going to
 | 
						|
//            write the private data.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  AL_SUCCESS if things went okay, otherwise an error code < AL_SUCCESS.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
int AL_PROTO
 | 
						|
ALStorage::WriteStorageObjectData( ALStorage AL_DLL_FAR * archive )  /* Tag public function */
 | 
						|
{
 | 
						|
    return archive->WriteGlShort( 0 );
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::ReadStorageObjectData()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Read in class specific data from an archive.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALStorage::ReadStorageObjectData( ALStorage * archive );
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is an internal callback virtual function.
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is an internal callback virtual function.
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  None, this is an internal callback virtual function.
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  archive : A pointer to the storage object where we are going to
 | 
						|
//            read in the private data..
 | 
						|
//
 | 
						|
// 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.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  AL_SUCCESS if things went okay, otherwise an error code < AL_SUCCESS.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
//  ALStorage::WriteStorageObjectData()
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
int AL_PROTO
 | 
						|
ALStorage::ReadStorageObjectData( ALStorage AL_DLL_FAR * archive )  /* Tag public function */
 | 
						|
{
 | 
						|
    short int temp;
 | 
						|
    int status = archive->ReadGlShort( temp );
 | 
						|
    AL_ASSERT( temp == 0, "ReadStorageObjectData: stored data is not null" );
 | 
						|
    return status;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALStorage::ReadCopyright()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Read a copyright string for human display.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  char * ALStorage::ReadCopyright();
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  char * ALReadCopyright( void );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALReadCopyright Lib "AL20FW"
 | 
						|
//    Alias "ALReadCopyrightVB"
 | 
						|
//    As String
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALReadCopyright : PChar;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  None.  Note that we don't have the usual this_object argument, because
 | 
						|
//  this is a static function.  It's only in the ALStorage class to avoid
 | 
						|
//  name space clutter.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  It is a good idea for us to have a copyright notice embedded in the
 | 
						|
//  library.  Hopefully, this notice will show up in any executables linked
 | 
						|
//  using this library, or in the DLL they link to.
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  A pointer to a copyright notice.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release.
 | 
						|
//
 | 
						|
 | 
						|
char *_al_copyright =  "Copyright (c) 1994-1996 Greenleaf Software, Inc.\n"
 | 
						|
                       "All Rights Reserved.\n";
 | 
						|
 | 
						|
char AL_DLL_FAR * AL_PROTO
 | 
						|
ALStorage::ReadCopyright()  /* Tag public function */
 | 
						|
{
 | 
						|
    return _al_copyright;
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE char AL_DLL_FAR * AL_FUNCTION
 | 
						|
ALReadCopyright( void ) /* Tag public function */
 | 
						|
{
 | 
						|
    return _al_copyright;
 | 
						|
}
 | 
						|
 | 
						|
#if defined( AL_VB )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE long AL_FUNCTION
 | 
						|
ALReadCopyrightVB( void )  /* Tag public function */
 | 
						|
{
 | 
						|
    return ALCreateVBString( _al_copyright,
 | 
						|
                            (unsigned short int) _fstrlen( _al_copyright ) );
 | 
						|
}
 | 
						|
 | 
						|
#elif defined( AL_VB32 )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE BSTR AL_FUNCTION
 | 
						|
ALReadCopyrightVB( void )  /* Tag public function */
 | 
						|
{
 | 
						|
    return SysAllocStringByteLen( _al_copyright, strlen( _al_copyright ) );
 | 
						|
}
 | 
						|
 | 
						|
#endif /* #if defined( AL_VB ) */
 | 
						|
 | 
						|
#endif /* #if !defined( AL_NO_C ) */
 | 
						|
 |