/* ** CPQDIF_E_Collection class. Implements the PQDIF collection element. ** -------------------------------------------------------------------------- ** ** File name: $Workfile: el_coll.cpp $ ** Last modified: $Modtime: 11/21/00 10:59a $ ** Last modified by: $Author: Bill $ ** ** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/el_coll.cpp $ ** VCS revision: $Revision: 17 $ */ #include "PQDIF_classes.h" // Local constants const char cTerminator = '\0'; // Relational operators for for ordering a collection. bool operator<( const CPQDIF_Element * pel, const GUID &tag ) { return ( memcmp( &(pel->GetTag()), &tag, sizeof( tag ) ) < 0 ); } bool operator<( const GUID &tag, const CPQDIF_Element * pel ) { return ( memcmp( &tag, &(pel->GetTag()), sizeof( tag ) ) < 0 ); } // Construction // ============ CPQDIF_E_Collection::CPQDIF_E_Collection() { m_array.reserve( 32 ); } CPQDIF_E_Collection::~CPQDIF_E_Collection() { // Destroy all elements in the array CArrayElements::iterator iter; for( iter = m_array.begin(); iter != m_array.end(); iter++ ) { delete *iter; *iter = NULL; } } long CPQDIF_E_Collection::GetCount( void ) const { return m_array.size(); } CPQDIF_Element * CPQDIF_E_Collection::GetElement( long index ) const { CPQDIF_Element * pel = NULL; if( index >= 0 && index < GetCount() ) { pel = m_array[ index ]; } return pel; } CPQDIF_Element * CPQDIF_E_Collection::GetElement( const GUID& tag, long elementType ) const { CPQDIF_Element * pelReturn = NULL; // See if specified element is in the collection. CArrayElements::const_iterator iter; iter = lower_bound( m_array.begin(), m_array.end(), tag ); while( pelReturn == NULL && iter != m_array.end() && *iter != NULL && PQDIF_IsEqualGUID( (*iter)->GetTag(), tag ) ) { // Matching type. if( elementType == -1 || elementType == (*iter)->GetElementType() ) { pelReturn = *iter; } iter++; } return pelReturn; } void CPQDIF_E_Collection::SetRecord( CPQDIFRecord * pRecord ) { CPQDIF_Element * pel; // Call the base class method. CPQDIF_Element::SetRecord( pRecord ); // Do the same thing to the objects we own CArrayElements::iterator iter; for( iter = m_array.begin(); iter != m_array.end(); iter++ ) { pel = *iter; //ASSERT_VALID( pel ); if( pel ) { pel->SetRecord( pRecord ); } } return; } void CPQDIF_E_Collection::Add( CPQDIF_Element * pel ) { // Add the element to the collection. CArrayElements::iterator iter = upper_bound( m_array.begin(), m_array.end(), pel->GetTag() ); m_array.insert( iter, pel ); // Set the element to reference the collections record. if( pel ) pel->SetRecord( GetRecord() ); // Signal that the record has changed. if( m_pRecord ) m_pRecord->SetChanged( true ); } // Should this delete the element or not? void CPQDIF_E_Collection::RemoveAt( long index ) { // If a valid element was specified then .... //ASSERT( index >= 0 && index < GetCount() ); if( index >= 0 && index < GetCount() ) { // Dereference the element. CArrayElements::iterator where = m_array.begin(); where += index; CPQDIF_Element * pel = *where; // Clear the element's reference to the record. if( pel ) pel->SetRecord( NULL ); // Remove it from the list. m_array.erase( where ); // Mark the collection as dirty. if( m_pRecord ) m_pRecord->SetChanged( true ); } } void CPQDIF_E_Collection::AddOrReplace( CPQDIF_Element * pel ) { bool bFound = false; CPQDIF_Element * pelToCompare = NULL; const GUID & tagToAdd = pel->GetTag(); // See if this tag already exists CArrayElements::iterator iter; iter = lower_bound( m_array.begin(), m_array.end(), tagToAdd ); if( iter != m_array.end() ) { pelToCompare = *iter; if( pelToCompare ) { // Matching tags? if( PQDIF_IsEqualGUID( pelToCompare->GetTag(), tagToAdd ) ) { // Delete the old element. delete pelToCompare; // Add the new element to the collection. *iter = pel; // Signal that the element is found. bFound = true; } } } // If an existing element was not found then add the element. if( !bFound ) { m_array.insert( iter, pel ); } // Set the element to reference the collections record. if( pel ) pel->SetRecord( GetRecord() ); // Signal that the record has changed. if( m_pRecord ) m_pRecord->SetChanged( true ); } void CPQDIF_E_Collection::SetVectorString ( const GUID& tagElement, const char * text, bool allowReplace ) { CPQDIF_E_Vector * pvectString; if( text ) { // Create the new vector to hold the string pvectString = (CPQDIF_E_Vector *) theFactory.NewElement( ID_ELEMENT_TYPE_VECTOR ); if( pvectString ) { // Set it up ... pvectString->SetTag( tagElement ); pvectString->SetPhysicalType( ID_PHYS_TYPE_CHAR1 ); pvectString->SetValues( text ); // Add it if( allowReplace ) AddOrReplace( pvectString ); else Add( pvectString ); } } } // Parameterized SetVector...() functions // ====================================== #define SETVECTOR( nametype, type, idtype ) \ void CPQDIF_E_Collection::SetVector##nametype \ ( const GUID& tagElement, \ const type * values, \ long count, \ bool allowReplace ) \ { \ CPQDIF_E_Vector * pvect; \ if( values ) \ { \ /* Create the new vector to hold the string */ \ pvect = (CPQDIF_E_Vector *) theFactory.NewElement( ID_ELEMENT_TYPE_VECTOR ); \ if( pvect ) \ { \ /* Set it up ... */ \ pvect->SetTag( tagElement ); \ pvect->SetPhysicalType( idtype ); \ pvect->SetValues##nametype( values, count ); \ /* Add it */ \ if( allowReplace ) \ AddOrReplace( pvect ); \ else \ Add( pvect ); \ } \ } \ } SETVECTOR( INT1, INT1, ID_PHYS_TYPE_INTEGER1 ); SETVECTOR( INT2, INT2, ID_PHYS_TYPE_INTEGER2 ); SETVECTOR( INT4, INT4, ID_PHYS_TYPE_INTEGER4 ); SETVECTOR( UINT4, UINT4, ID_PHYS_TYPE_UNS_INTEGER4 ); SETVECTOR( REAL4, REAL4, ID_PHYS_TYPE_REAL4 ); SETVECTOR( REAL8, REAL8, ID_PHYS_TYPE_REAL8 ); SETVECTOR( TimeStamp, TIMESTAMPPQDIF, ID_PHYS_TYPE_TIMESTAMPPQDIF ); bool CPQDIF_E_Collection::GetVectorString ( const GUID& tagElement, char * text, long max ) const { bool status = false; const CPQDIF_Element * pel; string values; pel = GetElement( tagElement ); if( pel && pel->GetElementType() == ID_ELEMENT_TYPE_VECTOR ) { const CPQDIF_E_Vector * pvect = (const CPQDIF_E_Vector *) pel; status = pvect->GetValues( values ); if( status ) { #ifdef WIN32 strncpy_s(text, strlen(text),values.c_str(), max); #else strncpy(text, values.c_str(), max); #endif // WIN32 text[ max - 1 ] = cTerminator; } } return status; } // Parameterized GetVector...() functions // ====================================== #define GETVECTOR( nametype, type ) \ long CPQDIF_E_Collection::GetVector##nametype \ ( \ const GUID& tagElement, \ type * values, \ long max \ ) const \ { \ long sizeActual = 0; \ const CPQDIF_Element * pel; \ pel = GetElement( tagElement ); \ if( pel && pel->GetElementType() == ID_ELEMENT_TYPE_VECTOR ) \ { \ const CPQDIF_E_Vector * pvect = (const CPQDIF_E_Vector *) pel; \ sizeActual = pvect->GetValues##nametype( values, max ); \ } \ return sizeActual; \ } GETVECTOR( INT1, INT1 ); GETVECTOR( INT2, INT2 ); GETVECTOR( INT4, INT4 ); GETVECTOR( UINT4, UINT4 ); GETVECTOR( REAL4, REAL4 ); GETVECTOR( REAL8, REAL8 ); GETVECTOR( TimeStamp, TIMESTAMPPQDIF ); // Parameterized SetScalar...() functions // ====================================== #define SETSCALAR( nametype, type ) \ void CPQDIF_E_Collection::SetScalar##nametype \ ( \ const GUID& tagElement, \ type value, \ bool allowReplace \ ) \ { \ CPQDIF_E_Scalar * psc; \ psc = (CPQDIF_E_Scalar *) theFactory.NewElement( ID_ELEMENT_TYPE_SCALAR ); \ if( psc ) \ { \ psc->SetTag( tagElement ); \ psc->SetValue##nametype( value ); \ if( allowReplace ) \ AddOrReplace( psc ); \ else \ Add( psc ); \ } \ } SETSCALAR( BOOL4, bool ) SETSCALAR( INT2, INT2 ) SETSCALAR( UINT2, UINT2 ) SETSCALAR( INT4, INT4 ) SETSCALAR( UINT4, UINT4 ) SETSCALAR( REAL4, REAL4 ) SETSCALAR( REAL8, REAL8 ) SETSCALAR( COMPLEX8, COMPLEX8 ) SETSCALAR( COMPLEX16, COMPLEX16 ) SETSCALAR( GUID, GUID ) SETSCALAR( TimeStamp, TIMESTAMPPQDIF ) // Parameterized GetScalar...() functions // ====================================== #define GETSCALAR( nametype, type ) \ bool CPQDIF_E_Collection::GetScalar##nametype \ ( \ const GUID& tagElement, \ type& value \ ) const \ { \ bool status = false; \ const CPQDIF_Element * pel; \ pel = GetElement( tagElement ); \ if( pel && pel->GetElementType() == ID_ELEMENT_TYPE_SCALAR ) \ { \ const CPQDIF_E_Scalar * psc = (const CPQDIF_E_Scalar *) pel; \ status = psc->GetValue##nametype( value ); \ } \ return status; \ } GETSCALAR( BOOL4, bool ) GETSCALAR( INT2, INT2 ) GETSCALAR( UINT2, UINT2 ) GETSCALAR( INT4, INT4 ) GETSCALAR( UINT4, UINT4 ) GETSCALAR( REAL4, REAL4 ) GETSCALAR( REAL8, REAL8 ) GETSCALAR( COMPLEX8, COMPLEX8 ) GETSCALAR( COMPLEX16, COMPLEX16 ) GETSCALAR( GUID, GUID ) GETSCALAR( TimeStamp, TIMESTAMPPQDIF )