590 lines
14 KiB
C++
590 lines
14 KiB
C++
/*
|
|
** PQAlloc class. A simple allocator class that understands all of the
|
|
** fundamental PQDIF physical types.
|
|
** --------------------------------------------------------------------------
|
|
**
|
|
** File name: $Workfile: ser_alloc.cpp $
|
|
** Last modified: $Modtime: 9/03/98 9:52a $
|
|
** Last modified by: $Author: Rob $
|
|
**
|
|
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/ser_alloc.cpp $
|
|
** VCS revision: $Revision: 5 $
|
|
*/
|
|
#include "PQDIF_classes.h"
|
|
|
|
|
|
|
|
/*
|
|
**
|
|
** Private node structure
|
|
*/
|
|
struct MemNode
|
|
{
|
|
void * obj;
|
|
size_t siz;
|
|
|
|
MemNode * pPrev;
|
|
MemNode * pNext;
|
|
};
|
|
|
|
|
|
// Memory debug
|
|
const int sizeGuardBand = 8;
|
|
const DWORD dataGuardBand = 121458711L;
|
|
|
|
|
|
|
|
void PQAlloc::Reinitialize(long offset)
|
|
{
|
|
DestroyList();
|
|
Initialize();
|
|
idxOffset = offset;
|
|
}
|
|
|
|
void PQAlloc::Initialize()
|
|
{
|
|
// DebugPrint("Initialize PQAlloc\n");
|
|
bShowMessage = 0;
|
|
lMemTotal = 0;
|
|
idxOffset = 0;
|
|
pmemFirst = 0;
|
|
pmemLast = 0;
|
|
}
|
|
|
|
PQAlloc::PQAlloc()
|
|
{
|
|
// DebugPrint("Create PQAlloc\n");
|
|
Initialize();
|
|
}
|
|
|
|
PQAlloc::~PQAlloc()
|
|
{
|
|
DestroyList();
|
|
// DebugPrint("Destroy PQAlloc\n");
|
|
}
|
|
|
|
//static char szBuffer[80];
|
|
|
|
void *PQAlloc::allocate(size_t siz)
|
|
{
|
|
size_t siz_obj;
|
|
void *obj;
|
|
|
|
siz_obj = siz;
|
|
obj = calloc( 1, siz + sizeGuardBand );
|
|
|
|
// Fill guard band with special p
|
|
//
|
|
if( sizeGuardBand > 0 )
|
|
{
|
|
DWORD *pdw = (DWORD *)((char *)obj+siz);
|
|
*pdw = dataGuardBand;
|
|
}
|
|
|
|
// Link memory object into list
|
|
//
|
|
LinkIn( obj, siz_obj );
|
|
|
|
return obj;
|
|
}
|
|
|
|
void *PQAlloc::allocate(size_t siz, long &idx)
|
|
{
|
|
/*
|
|
**
|
|
** Return offset into file for this object
|
|
*/
|
|
idx = lMemTotal + idxOffset;
|
|
|
|
return allocate(siz);
|
|
}
|
|
|
|
|
|
c_collection_element * PQAlloc::addCollection
|
|
(
|
|
UINT4 count,
|
|
long & idx,
|
|
SIZE4& size
|
|
)
|
|
{
|
|
struct c_collection * pcoll = NULL;
|
|
struct c_collection_element * parrayElement = NULL;
|
|
|
|
size = sizeof( c_collection ) + ( count * sizeof( c_collection_element ) );
|
|
size = theInfo.padSizeTo4Bytes( size );
|
|
|
|
pcoll = (c_collection *) allocate( size, idx );
|
|
if( pcoll )
|
|
{
|
|
// Init the collection header
|
|
pcoll->count = count;
|
|
|
|
// Find the beginning of the array
|
|
parrayElement = ( c_collection_element * ) ( ( (char *) pcoll ) + sizeof ( *pcoll ) );
|
|
}
|
|
|
|
return parrayElement;
|
|
}
|
|
|
|
|
|
c_collection_element * PQAlloc::addCollection
|
|
(
|
|
UINT4 count,
|
|
long & idx,
|
|
SIZE4& size,
|
|
const GUID& tag,
|
|
c_collection_element& ce
|
|
)
|
|
{
|
|
struct c_collection_element * parrayElement = NULL;
|
|
|
|
parrayElement = addCollection( count, idx, size );
|
|
if( parrayElement )
|
|
{
|
|
// Set up the collection element properly
|
|
ce.tagElement = tag;
|
|
ce.typeElement = ID_ELEMENT_TYPE_COLLECTION;
|
|
ce.typePhysical = 0; // ???
|
|
ce.isEmbedded = FALSE;
|
|
ce.reserved = 0;
|
|
ce.link.linkElement = idx;
|
|
ce.link.sizeElement = size;
|
|
}
|
|
|
|
return parrayElement;
|
|
}
|
|
|
|
|
|
bool PQAlloc::addScalarValue
|
|
(
|
|
long typePhysical,
|
|
PQDIFValue value,
|
|
long & idx,
|
|
SIZE4& size,
|
|
const GUID& tag,
|
|
c_collection_element& ce
|
|
)
|
|
{
|
|
bool status = FALSE;
|
|
SIZE4 sizeValue;
|
|
BYTE * pdata;
|
|
|
|
// Init the element header
|
|
ce.tagElement = tag;
|
|
ce.typeElement = ID_ELEMENT_TYPE_SCALAR;
|
|
ce.typePhysical = (INT1) typePhysical;
|
|
ce.isEmbedded = FALSE;
|
|
ce.reserved = 0;
|
|
|
|
// Init
|
|
pdata = NULL;
|
|
|
|
sizeValue = theInfo.GetNumBytesOfType( typePhysical );
|
|
if( sizeValue <= sizeof( ce.valueEmbedded ) )
|
|
{
|
|
// This is less than 8 bytes -- no allocation necessary
|
|
// Thereforem, it IS embedded
|
|
ce.isEmbedded = TRUE;
|
|
size = 0; // No add'l space allocated
|
|
|
|
// Set up the collection element properly
|
|
pdata = (BYTE *)( ce.valueEmbedded );
|
|
}
|
|
else
|
|
{
|
|
// Not embedded; gotta allocate memory (be sure to pad it
|
|
// to 4 bytes).
|
|
size = theInfo.padSizeTo4Bytes( sizeValue );
|
|
pdata = (BYTE *) allocate( size, idx );
|
|
if( pdata )
|
|
{
|
|
// Set up the collection element properly
|
|
ce.link.linkElement = idx;
|
|
ce.link.sizeElement = size;
|
|
}
|
|
}
|
|
|
|
// If we have the pointer, convert the value itself
|
|
if( pdata )
|
|
{
|
|
convertValue( typePhysical, value, pdata );
|
|
status = TRUE;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
bool PQAlloc::addVectorValue
|
|
(
|
|
long typePhysical,
|
|
long count,
|
|
//PQDIFValue ** values,
|
|
BYTE * values,
|
|
long & idx,
|
|
SIZE4& size,
|
|
const GUID & tag,
|
|
c_collection_element& ce
|
|
)
|
|
{
|
|
bool status = FALSE;
|
|
SIZE4 sizeValue;
|
|
//long idxValue;
|
|
|
|
struct c_vector * pvector = NULL;
|
|
BYTE * pdata = NULL;
|
|
|
|
// Init the element header
|
|
ce.tagElement = tag;
|
|
ce.typeElement = ID_ELEMENT_TYPE_VECTOR;
|
|
ce.typePhysical = (INT1) typePhysical;
|
|
ce.isEmbedded = FALSE;
|
|
ce.reserved = 0;
|
|
|
|
// Determine the size of the vector
|
|
sizeValue = theInfo.GetNumBytesOfType( typePhysical );
|
|
size = sizeof( c_vector ) + ( count * sizeValue );
|
|
size = theInfo.padSizeTo4Bytes( size );
|
|
|
|
// Allocate the vector
|
|
pvector = (c_vector *) allocate( size, idx );
|
|
if( pvector )
|
|
{
|
|
// Init the vector header
|
|
pvector->count = count;
|
|
|
|
// Copy over the string portion
|
|
pdata = (BYTE *) ( ( (BYTE *) pvector ) + sizeof( c_vector ) );
|
|
if( pdata )
|
|
{
|
|
// Convert all the values in the array...
|
|
memcpy( pdata, values, count * sizeValue );
|
|
//for( idxValue = 0; idxValue < count; idxValue++ )
|
|
//{
|
|
//convertValue( typePhysical, *( values[ idxValue ] ), pdata );
|
|
//pdata += sizeValue;
|
|
//}
|
|
|
|
// All values in array have been transferred...
|
|
ce.link.linkElement = idx;
|
|
ce.link.sizeElement = size;
|
|
status = TRUE;
|
|
}
|
|
|
|
} // if( pvector )
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
bool PQAlloc::convertValue
|
|
(
|
|
long typePhysical,
|
|
PQDIFValue value,
|
|
BYTE * pdata
|
|
)
|
|
{
|
|
bool status = TRUE;
|
|
|
|
switch( typePhysical )
|
|
{
|
|
case ID_PHYS_TYPE_BOOLEAN1:
|
|
*( (BOOL1 *) pdata ) = value.bool1;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_CHAR1:
|
|
*( (CHAR1 *) pdata ) = value.char1;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_INTEGER1:
|
|
*( (INT1 *) pdata ) = value.int1;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_UNS_INTEGER1:
|
|
*( (UINT1 *) pdata ) = value.uint1;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_BOOLEAN2:
|
|
*( (BOOL2 *) pdata ) = value.bool2;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_CHAR2:
|
|
*( (CHAR2 *) pdata ) = value.char2;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_INTEGER2:
|
|
*( (INT2 *) pdata ) = value.int2;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_UNS_INTEGER2:
|
|
*( (UINT2 *) pdata ) = value.uint2;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_BOOLEAN4:
|
|
*( (BOOL4 *) pdata ) = value.bool4;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_INTEGER4:
|
|
*( (INT4 *) pdata ) = value.int4;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_UNS_INTEGER4:
|
|
*( (UINT4 *) pdata ) = value.uint4;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_REAL4:
|
|
*( (REAL4 *) pdata ) = value.real4;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_REAL8:
|
|
*( (REAL8 *) pdata ) = value.real8;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_COMPLEX8:
|
|
*( (COMPLEX8 *) pdata ) = value.complex8;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_COMPLEX16:
|
|
*( (COMPLEX16 *) pdata ) = value.complex16;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_TIMESTAMPPQDIF:
|
|
*( (ts *) pdata ) = value.ts;
|
|
break;
|
|
|
|
case ID_PHYS_TYPE_GUID:
|
|
*( (GUID *) pdata ) = value.guid ;
|
|
break;
|
|
|
|
default:
|
|
status = FALSE;
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
void PQAlloc::deallocate( void *obj )
|
|
{
|
|
LinkOut( obj );
|
|
free( obj );
|
|
}
|
|
|
|
|
|
void PQAlloc::LinkIn(void *obj, size_t siz)
|
|
{
|
|
MemNode *pNode;
|
|
/*
|
|
**
|
|
** Allocate a new node
|
|
*/
|
|
pNode = (MemNode *) calloc( 1, sizeof( MemNode ) );
|
|
pNode->obj = obj;
|
|
pNode->siz = siz;
|
|
pNode->pNext = 0;
|
|
/*
|
|
**
|
|
** Save position suitable for use as the file offset
|
|
*/
|
|
lMemTotal += siz;
|
|
idxFilePosition = lMemTotal + idxOffset;
|
|
/*
|
|
**
|
|
** Put in chain
|
|
*/
|
|
if ( pmemLast )
|
|
pmemLast->pNext = pNode;
|
|
else
|
|
pmemFirst = pNode;
|
|
pNode->pPrev = pmemLast;
|
|
pmemLast = pNode;
|
|
}
|
|
|
|
int PQAlloc::LinkOut( void *obj )
|
|
{
|
|
MemNode *pNode;
|
|
int rc = 0;
|
|
|
|
pNode = pmemFirst;
|
|
while (pNode)
|
|
{
|
|
if (obj == pNode->obj)
|
|
{
|
|
if (pNode->pPrev)
|
|
pNode->pPrev->pNext = pNode->pNext;
|
|
else
|
|
pmemFirst = pNode->pNext;
|
|
|
|
if (pNode->pNext)
|
|
pNode->pNext->pPrev = pNode->pPrev;
|
|
else
|
|
pmemLast = pNode->pPrev;
|
|
|
|
lMemTotal -= pNode->siz;
|
|
|
|
if( sizeGuardBand )
|
|
{
|
|
DWORD *pdw = (DWORD *)( (char *) obj+pNode->siz );
|
|
if( *pdw != dataGuardBand )
|
|
{
|
|
if (bShowMessage)
|
|
{
|
|
//DebugPrint("Corrupted memory guard - %lu\n", *pdw);
|
|
// if (pNode->pszText)
|
|
// DebugPrint("obj= %p, size= %u, sz= %s\n",
|
|
// pNode->obj, pNode->siz, pNode->pszText);
|
|
// else
|
|
// DebugPrint("obj= %p, size= %u, Unknown location\n",
|
|
// pNode->obj, pNode->siz);
|
|
}
|
|
}
|
|
}
|
|
|
|
// if (pNode->pszText)
|
|
// free(pNode->pszText);
|
|
free( pNode );
|
|
rc = TRUE;
|
|
break;
|
|
}
|
|
pNode = pNode->pNext;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
void PQAlloc::WalkList()
|
|
{
|
|
MemNode *pNode;
|
|
|
|
if (!bShowMessage)
|
|
return;
|
|
|
|
pNode = pmemFirst;
|
|
//if (pNode == NULL)
|
|
// DebugPrint("The memory list is empty.\n");
|
|
while (pNode)
|
|
{
|
|
// if (pNode->pszText)
|
|
// DebugPrint("obj= %p, size= %u, sz= %s\n",
|
|
// pNode->obj, pNode->siz, pNode->pszText);
|
|
// else
|
|
// DebugPrint("obj= %p, size= %u, Unknown location\n",
|
|
// pNode->obj, pNode->siz);
|
|
|
|
pNode = pNode->pNext;
|
|
}
|
|
}
|
|
|
|
long PQAlloc::WriteListToFile(FILE *pf)
|
|
{
|
|
MemNode *pNode;
|
|
|
|
pNode = pmemFirst;
|
|
//if (pNode == NULL)
|
|
// DebugPrint("The memory list is empty.\n");
|
|
while (pNode)
|
|
{
|
|
fwrite(pNode->obj, 1, pNode->siz, pf);
|
|
|
|
// if (pNode->pszText)
|
|
// DebugPrint("obj= %p, size= %u, sz= %s\n",
|
|
// pNode->obj, pNode->siz, pNode->pszText);
|
|
// else
|
|
// DebugPrint("obj= %p, size= %u, Unknown location\n",
|
|
// pNode->obj, pNode->siz);
|
|
|
|
pNode = pNode->pNext;
|
|
}
|
|
return idxFilePosition;
|
|
}
|
|
|
|
|
|
long PQAlloc::WriteListToStream( CPQDIF_StreamIO *pstrm )
|
|
{
|
|
MemNode * pNode;
|
|
int sizeActualTotal;
|
|
|
|
sizeActualTotal = 0;
|
|
|
|
pstrm->BeginBlock();
|
|
|
|
pNode = pmemFirst;
|
|
//if (pNode == NULL)
|
|
// DebugPrint("The memory list is empty.\n");
|
|
while (pNode)
|
|
{
|
|
pstrm->AppendBlock( (BYTE *) pNode->obj, pNode->siz );
|
|
|
|
// if (pNode->pszText)
|
|
// DebugPrint("obj= %p, size= %u, sz= %s\n",
|
|
// pNode->obj, pNode->siz, pNode->pszText);
|
|
// else
|
|
// DebugPrint("obj= %p, size= %u, Unknown location\n",
|
|
// pNode->obj, pNode->siz);
|
|
|
|
pNode = pNode->pNext;
|
|
}
|
|
|
|
pstrm->WriteBlock( sizeActualTotal );
|
|
|
|
return sizeActualTotal;
|
|
}
|
|
|
|
|
|
void PQAlloc::DestroyList()
|
|
{
|
|
MemNode *pNode;
|
|
MemNode *pNext;
|
|
|
|
pNode = pmemFirst;
|
|
while (pNode)
|
|
{
|
|
pNext = pNode->pNext;
|
|
|
|
if (pNode->obj)
|
|
free(pNode->obj);
|
|
free(pNode);
|
|
|
|
pNode = pNext;
|
|
}
|
|
}
|
|
|
|
//int cdecl DebugPrint (char *szFormat,...)
|
|
// {
|
|
// char szBuffer [255];
|
|
// va_list arg_ptr;
|
|
//
|
|
// va_start (arg_ptr, szFormat);
|
|
//
|
|
// vsprintf (szBuffer, szFormat, arg_ptr);
|
|
//
|
|
// //printf(szBuffer);
|
|
//
|
|
//#ifdef _DEBUG
|
|
// //DebugOutput( DBF_TRACE, szBuffer );
|
|
//#endif
|
|
//
|
|
// return (0);
|
|
// }
|
|
|
|
#ifndef NOAUXPRINT
|
|
|
|
//int cdecl AuxPrint (char *szFormat,...)
|
|
// {
|
|
// char szBuffer [255];
|
|
// va_list arg_ptr;
|
|
//
|
|
// va_start (arg_ptr, szFormat);
|
|
//
|
|
// vsprintf (szBuffer, szFormat, arg_ptr);
|
|
//
|
|
//// OutputDebugString(szBuffer);
|
|
//
|
|
// return (0);
|
|
// }
|
|
|
|
#endif
|
|
|
|
|