/* ** 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