714dd74636
git-svn-id: svn://10.65.10.50/trunk@5350 c028cbd2-c16b-5b4b-a496-9718f37d4682
1007 lines
25 KiB
C++
Executable File
1007 lines
25 KiB
C++
Executable File
//
|
|
// MEMSTORE.CPP
|
|
//
|
|
// Source file for ArchiveLib 2.0
|
|
//
|
|
// Copyright (c) Greenleaf Software, Inc. 1996
|
|
// All Rights Reserved
|
|
//
|
|
// CONTENTS
|
|
//
|
|
// ALMemoryBase::operator new()
|
|
// ALMemoryBase::ALMemoryBase()
|
|
// ALMemoryBase::~ALMemoryBase()
|
|
// ALMemoryBase::LoadBuffer()
|
|
// ALMemoryBase::Rename()
|
|
// ALMemoryBase::RenameToBackup()
|
|
// ALMemoryBase::UnRename()
|
|
// ALMemoryBase::Seek()
|
|
// ALMemoryBase::FlushBuffer()
|
|
// ALMemoryBase::Close()
|
|
// ALMemoryBase::Create()
|
|
// ALMemoryBase::Open()
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// This file contains all the C++ member functions to support the
|
|
// ALMemoryBase class. ALMemoryBase doesn't do anything on its
|
|
// own. It instead provides a framework for the three derived
|
|
// memory classes: ALWinMemory, ALMemory, and ALHugeMemory.
|
|
//
|
|
// The only thing those classes do that ALMemory can't do is to
|
|
// allocate, free, and copy memory. Since each of three classes
|
|
// has their own pointer type, that has to be viewed here as an
|
|
// abstraction.
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
#include "arclib.h"
|
|
#if !defined( AL_IBM )
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#include "memstore.h"
|
|
|
|
//
|
|
// Need this for malloc()
|
|
//
|
|
#include <stdlib.h>
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::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"
|
|
// #include "memstore.h"
|
|
//
|
|
// void * ALMemoryBase::operator new( size_t size )
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, this is an internal C++ function.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// size : The number of bytes that the compiler has decided will be
|
|
// necessary to construct a new ALMemoryBase 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.
|
|
//
|
|
// Incidentally, I suspect that this function never gets called. If an
|
|
// object of a derived archive class is being created, it should use
|
|
// its own new operator, rendering this one useless.
|
|
//
|
|
// Very important: this new operator is called to allocate the
|
|
// storage for the ALMemoryBase 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.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// A pointer to some memory that should have been pulled out of the
|
|
// heap for the DLL.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
#if defined( AL_BUILDING_DLL )
|
|
|
|
void AL_DLL_FAR * AL_PROTO
|
|
ALMemoryBase::operator new( size_t size ) /* Tag internal function */
|
|
{
|
|
return ::new char[ size ];
|
|
}
|
|
|
|
#endif
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::ALMemoryBase()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// The base class constructor for ALMemory objects.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// ALMemoryBase::ALMemoryBase( const char *buffer_name = "",
|
|
// ALCase name_case = AL_MIXED );
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, this is an internal class.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, this is an internal class.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, this is an internal class.
|
|
//
|
|
// 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.
|
|
//
|
|
// 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.
|
|
//
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// There are three different memory base storage objects in ArchiveLib
|
|
// 2.0: ALMemory, ALWinMemory, and ALHugeMemory. The only substantial
|
|
// difference between these three is in the pointer type they use to
|
|
// point to their memory buffer. So they can share a lotta code. That
|
|
// code is all combined into a single base class, ALMemoryBase. The
|
|
// base class code has to rely on a few virtual functions to take over
|
|
// when pointer manipulation is needed.
|
|
//
|
|
// This constructor doesn't do anything except pass the appropriate
|
|
// initialization information on to the base class constructor.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Nothing.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
AL_PROTO
|
|
ALMemoryBase::ALMemoryBase( /* Tag public function */
|
|
const char AL_DLL_FAR *buffer_name /* = "" */,
|
|
ALCase name_case /* = AL_MIXED */ )
|
|
: ALStorage( buffer_name, 4096, AL_MEMORY_OBJECT, name_case )
|
|
{
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::~ALMemoryBase()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// The destructor for the base memory storage class.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// ALMemoryBase::~ALMemoryBase();
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, destroy using base class function deleteALStorage().
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, destroy using base class function deleteALStorage().
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, destroy using base class function deleteALStorage().
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// None.
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// The most important thing memory objects have to do in their destructor
|
|
// is free up the big buffer that underlies the object. This has to be
|
|
// handled by the derived classes, since only they know how to handle
|
|
// specific pointer types. That leaves this destructor with not much
|
|
// to do!
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Nothing.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
AL_PROTO
|
|
ALMemoryBase::~ALMemoryBase() /* Tag public function */
|
|
{
|
|
AL_ASSERT( GoodTag(), "~ALMemoryBase: attempting to delete invalid object" );
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::LoadBuffer();
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Load a new batch of data from the big buffer into the I/O buffer.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::LoadBuffer( long address );
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, this is a protected C++ internal function.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, this is a protected C++ internal function.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, this is a protected C++ internal function.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// address : The desired offset in the storage object to load from.
|
|
// This is used to calculate a simple offset into the
|
|
// big 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 derived class 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.
|
|
//
|
|
// This function takes care of lots of member data maintenance, but the
|
|
// one thing it won't do is actually load the data from the big buffer.
|
|
// It has to use the virtual function _LoadBuffer() in the derived class
|
|
// to to actually move data out of the big buffer and into the I/O buffer.
|
|
//
|
|
// 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.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::LoadBuffer( long address ) /* Tag protected function */
|
|
{
|
|
if ( mStatus < AL_SUCCESS )
|
|
return mStatus;
|
|
if ( mlFilePointer != address ) {
|
|
if ( mlFilePointer > mlUserBufferSize )
|
|
return mStatus.SetError( AL_SEEK_ERROR,
|
|
"Attempt to read past end of the "
|
|
"buffer in ALMemoryBase %s",
|
|
mName.GetName() );
|
|
}
|
|
long load = mlUserBufferSize - address;
|
|
if ( load > (long) muBufferSize )
|
|
muBufferValidData = muBufferSize;
|
|
else
|
|
muBufferValidData = (size_t) load;
|
|
if ( muBufferValidData <= 0 ) {
|
|
muReadIndex = 0;
|
|
return AL_END_OF_FILE;
|
|
}
|
|
_LoadBuffer( address );
|
|
if ( miUpdateCrcFlag )
|
|
UpdateCrc( muBufferValidData );
|
|
muReadIndex = 0; //Reading can resume at this location
|
|
mlFilePointer += muBufferValidData;
|
|
YieldTime();
|
|
return muBufferValidData;
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::Rename()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Rename a memory storage object.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::Rename( const char *new_name = 0,
|
|
// int delete_on_clash = 1 );
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// Use the base class function ALStorageRename().
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// Use the base class function ALStorageRename().
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// Use the base class function ALStorageRename().
|
|
//
|
|
// 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.
|
|
//
|
|
// 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.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Always returns AL_SUCCESS.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::Rename( const char AL_DLL_FAR *new_name /* = 0 */, /* Tag public function */
|
|
int /* delete_on_clash = 1 */ )
|
|
{
|
|
if ( new_name )
|
|
mName = new_name;
|
|
return AL_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::RenameToBackup()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Renames the storage object to a backup name.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::RenameToBackup( int delete_on_clash /* = 1 */ )
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// C programs should use the base class function ALStorageRenameToBackup().
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// VB programs should use the base class function ALStorageRenameToBackup().
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// Delphi programs should use the base class function
|
|
// ALStorageRenameToBackup().
|
|
//
|
|
// 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.
|
|
//
|
|
// 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.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Always returns AL_SUCCESS.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::RenameToBackup( int delete_on_clash /* = 1 */ ) /* Tag public function */
|
|
{
|
|
mName.ChangeExtension();
|
|
return Rename( 0, delete_on_clash );
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::UnRename()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Restore the old name of the object.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::UnRename( int delete_on_clash = 1 );
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// C programs use the base class function ALStorageUnRename().
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// VB programs use the base class function ALStorageUnRename().
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// Delphi programs use the base class function ALStorageUnRename().
|
|
//
|
|
// 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.
|
|
//
|
|
//
|
|
// 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! It takes advantage of
|
|
// the fact that ALName objects always remember their old name after getting
|
|
// a new one.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// Always returns AL_SUCCESS.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::UnRename( int /* delete_on_clash = 1 */) /* Tag public function */
|
|
{
|
|
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;
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::Seek()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Seek to a specified offset in the big memory buffer.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::Seek( long address );
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// C programs should use the base class functin ALStorageSeek().
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// VB programs should use the base class functin ALStorageSeek().
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// Delphi programs should use the base class functin ALStorageSeek().
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// address : The address in the memory object to go to. The read and
|
|
// write pointers will now be repositioned to this point.
|
|
//
|
|
// 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 the C RTL can
|
|
// create new storage space with a seek(). But I don't think we need that
|
|
// capability yet.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// AL_SEEK_ERROR if we can't get to that point in the buffer. Otherwise
|
|
// AL_SUCCESS.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::Seek( long address ) /* Tag public function */
|
|
{
|
|
FlushBuffer();
|
|
if ( mStatus < 0 )
|
|
return mStatus;
|
|
|
|
if ( mlFilePointer != address ) {
|
|
if ( mlFilePointer > mlUserBufferSize )
|
|
return mStatus.SetError( AL_SEEK_ERROR,
|
|
"Attempt to read past end of the "
|
|
"buffer in ALMemoryBase %s",
|
|
mName.GetName() );
|
|
}
|
|
mlFilePointer = address;
|
|
return AL_SUCCESS;
|
|
}
|
|
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::FlushBuffer()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Flush the I/O buffer of any newly written data.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::FlushBuffer()
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, this is an internal C++ function.
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, this is an internal C++ function.
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, this is an internal C++ function.
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// None.
|
|
//
|
|
// 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 big memory object. Since the base class doesn't
|
|
// know anything about the pointer types used in derive classes, that
|
|
// piece of work is done in a virtual function callled _FlushBuffer().
|
|
//
|
|
//
|
|
// RETURNS
|
|
//
|
|
// AL_CANT_ALLOCATE_MEMORY, if we run out. Otherwise, AL_SUCCESS.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::FlushBuffer() /* Tag protected function */
|
|
{
|
|
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 ( (long) ( muWriteIndex + mlFilePointer ) > mlUserBufferSize )
|
|
if ( GrowUserBuffer( muWriteIndex + mlFilePointer ) < 0 )
|
|
return mStatus;
|
|
_FlushBuffer( mlFilePointer );
|
|
mlFilePointer += muWriteIndex;
|
|
muWriteIndex = 0;
|
|
if ( mlSize < mlFilePointer )
|
|
mlSize = mlFilePointer;
|
|
}
|
|
muReadIndex = 0;
|
|
muBufferValidData = 0;
|
|
YieldTime();
|
|
return AL_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::Close()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Close the memory object.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::Close();
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// C programs must use the base class function, ALStorageClose().
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// VB programs must use the base class function, ALStorageClose().
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// Delphi programs must use the base class function, ALStorageClose().
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// None.
|
|
//
|
|
// 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.
|
|
//
|
|
// Note that the virtual Close() function is called in the base class,
|
|
// which does significant work in addition to what you see here.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// AL_SUCCESS, or various error codes that filter up or down from other
|
|
// routines.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::Close() /* Tag public function */
|
|
{
|
|
if ( mpcBuffer == 0 )
|
|
return mStatus;
|
|
FlushBuffer();
|
|
ALStorage::Close();
|
|
return mStatus;
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::Create()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Create a new memory storage object.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::Create( long size )
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, C programs should use ALStorageCreate().
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, VB programs should use ALStorageCreate().
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, Delphi programs should use ALStorageCreate().
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// size : This is the desired size of the memory object. This parameter
|
|
// is important to the derived class, which will use this argument
|
|
// to initialize a buffer. At this level, we don't care, and
|
|
// therefore we don't use it.
|
|
//
|
|
// 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. Note that this class will never be constructed
|
|
// on its own, it is safe to assume that some additional work is being
|
|
// passed off to the derived class.
|
|
//
|
|
// Note that the virtual Create() function is called in the base class,
|
|
// which does significant work in addition to what you see here.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// AL_SUCCESS, AL_CANT_ALLOCATE_MEMORY, or various error codes that
|
|
// filter on down from other routines.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::Create( long ) /* Tag public function */
|
|
{
|
|
ALStorage::Create();
|
|
if ( mStatus < AL_SUCCESS )
|
|
return mStatus;
|
|
if ( (char AL_DLL_FAR *) mName == 0 || strlen( mName ) == 0 )
|
|
mName = "AL.TMP";
|
|
if ( mfUserOwnsBuffer )
|
|
return AL_SUCCESS; //If the user supplied the buffer, we take what's available
|
|
return AL_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// NAME
|
|
//
|
|
// ALMemoryBase::Open()
|
|
//
|
|
// PLATFORMS/ENVIRONMENTS
|
|
//
|
|
// Console Windows PM
|
|
// C++
|
|
//
|
|
// SHORT DESCRIPTION
|
|
//
|
|
// Open a memory storage object.
|
|
//
|
|
// C++ SYNOPSIS
|
|
//
|
|
// #include "arclib.h"
|
|
// #include "memstore.h"
|
|
//
|
|
// int ALMemoryBase::Open();
|
|
//
|
|
// C SYNOPSIS
|
|
//
|
|
// None, C programs should use the base class function ALStorageOpen().
|
|
//
|
|
// VB SYNOPSIS
|
|
//
|
|
// None, VB programs should use the base class function ALStorageOpen().
|
|
//
|
|
// DELPHI SYNOPSIS
|
|
//
|
|
// None, Delphi programs should use the base class function ALStorageOpen().
|
|
//
|
|
// ARGUMENTS
|
|
//
|
|
// None.
|
|
//
|
|
// 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.
|
|
//
|
|
// Note that the virtual Open() function is called in the base class,
|
|
// which does significant work in addition to what you see here.
|
|
//
|
|
// RETURNS
|
|
//
|
|
// AL_SUCCESS, AL_CANT_OPEN_FILE, or various error codes that
|
|
// filter on down from other routines.
|
|
//
|
|
// EXAMPLE
|
|
//
|
|
// SEE ALSO
|
|
//
|
|
// REVISION HISTORY
|
|
//
|
|
// February 14, 1996 2.0A : New Release
|
|
//
|
|
|
|
int AL_PROTO
|
|
ALMemoryBase::Open() /* Tag public function */
|
|
{
|
|
ALStorage::Open();
|
|
if ( mStatus < AL_SUCCESS )
|
|
return mStatus;
|
|
else
|
|
return AL_SUCCESS;
|
|
}
|
|
|
|
|