#include "Stdafx.h" #include "DNTableFile.h" #include "Stream.h" #include "SundriesFunc.h" #include "./boost/algorithm/string.hpp" CDNTableFile::CDNTableFile() : m_nFieldCount(0), m_iDataCount(0), m_pmStringItemID(NULL), m_pmIntItemID(NULL), m_pmFloatItemID(NULL), m_bDontUseItemIDData( false ) { _Reset(); } CDNTableFile::CDNTableFile( const char *szFileName ) : m_nFieldCount(0), m_iDataCount(0), m_pmStringItemID(NULL), m_pmIntItemID(NULL), m_pmFloatItemID(NULL), m_bDontUseItemIDData( false ) { _Reset(); } CDNTableFile::~CDNTableFile() { _Reset(); } void CDNTableFile::_Reset() { SAFE_DELETE_VEC( m_vCellRepository ); m_mItemIDStartCellIndex.clear(); m_vLabel.clear(); m_mFieldNameFieldIndex.clear(); m_StringPool.Clear(); m_vItemID.clear(); for( int i=0; i vSplit; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(";") ); if( vSplit.empty() ) return false; for( size_t i=0 ; i& VecStream, bool bDontUseItemIDData ) { m_bDontUseItemIDData = bDontUseItemIDData; _Reset(); short nFieldCount = 0; int iDataCount = 0; for( DWORD i=0 ; iIsValid() == false ) return false; VecStream[i]->Seek( HeaderSize::Version, SEEK_SET ); VecStream[i]->Read( &nTemp, HeaderSize::ReserveLen ); if( nTemp > 0 ) VecStream[i]->Seek( nTemp, SEEK_CUR ); VecStream[i]->Read( &nFieldCount, HeaderSize::FieldCount ); VecStream[i]->Read( &iTemp, HeaderSize::DataCount ); iDataCount += iTemp; } m_vCellRepository.resize( iDataCount * nFieldCount + iDataCount ); for( DWORD i=0 ; iIsValid() == false ) return false; if( bResetData ) _Reset(); pStream->Seek( 0, SEEK_SET ); pStream->Seek( HeaderSize::Version, SEEK_CUR ); short nTemp = 0; pStream->Read( &nTemp, HeaderSize::ReserveLen ); if( nTemp > 0 ) pStream->Seek( nTemp, SEEK_CUR ); short nFieldCount; pStream->Read( &nFieldCount, HeaderSize::FieldCount ); if( m_nFieldCount != 0 && m_nFieldCount != nFieldCount ) { OutputDebug( "Invalid Field Count : %s - ( %d - %d )\n", ( pStream->GetName() ) ? pStream->GetName() : "Unknown", m_nFieldCount, nFieldCount ); return false; } m_nFieldCount = nFieldCount; int iDataCount = 0; pStream->Read( &iDataCount, HeaderSize::DataCount ); int iPrevDataCount = m_iDataCount; m_iDataCount += iDataCount; m_vLabel.resize( nFieldCount ); if( !m_bDontUseItemIDData ) { if( m_pmStringItemID == NULL ) m_pmStringItemID = new TDStringItemID[nFieldCount]; if( m_pmIntItemID == NULL ) m_pmIntItemID = new TDIntItemID[nFieldCount]; // if( m_pmFloatItemID == NULL ) // m_pmFloatItemID = new TDFloatItemID[nFieldCount]; } std::vector vFieldType; for( int i=0; iRead( &nFieldNameLen, HeaderSize::FieldNameLen ); if( nFieldNameLen >= MAX_PATH ) return false; pStream->Read( szFieldName, nFieldNameLen ); szFieldName[nFieldNameLen] = 0; m_vLabel[i] = szFieldName; m_mFieldNameFieldIndex.insert( std::make_pair(m_vLabel[i],i) ); pStream->Read( &cFieldType, HeaderSize::FieldType ); switch( cFieldType ) { case FieldType::NA: case FieldType::STRING: case FieldType::BOOL: case FieldType::INT: case FieldType::PER: case FieldType::FLOAT: break; default: return false; } vFieldType.push_back( static_cast(cFieldType) ); } // GenerationLavel Check for( UINT i=0 ; i m_vCellRepository.size() ) m_vCellRepository.resize( tResizeCount ); int iOffset = (iPrevDataCount*m_nFieldCount+iPrevDataCount); for( int i=0; iRead( &iItemID, sizeof(int) ); tempCell.SetInteger( iItemID ); if( m_mItemIDStartCellIndex.find( iItemID ) == m_mItemIDStartCellIndex.end() ) m_vItemID.push_back( iItemID ); m_vCellRepository[iOffset++] = tempCell; m_mItemIDStartCellIndex.insert( TDItemIDCellIndex::value_type( iItemID, (iPrevDataCount+i )*(m_nFieldCount+1) ) ); for( int j=0; jRead( &nTemp, sizeof(short) ); if( nTemp < 0 || nTemp >= _countof(szTemp) ) return false; pStream->Read( szTemp, nTemp ); szTemp[nTemp] = 0; tempCell.SetString( m_StringPool.Alloc( szTemp, strlen(szTemp) ) ); break; } case FieldType::BOOL: case FieldType::NA: case FieldType::INT: { pStream->Read( &iTemp, sizeof(int) ); tempCell.SetInteger( iTemp ); break; } case FieldType::PER: case FieldType::FLOAT: { pStream->Read( &fTemp, sizeof(float) ); tempCell.SetFloat( fTemp ); break; } } m_vCellRepository[iOffset++] = tempCell; if( !m_vGenerationInverseLabel.empty() && std::find( m_vGenerationInverseLabel.begin(), m_vGenerationInverseLabel.end(), m_vLabel[j] ) == m_vGenerationInverseLabel.end() ) continue; if( m_bDontUseItemIDData ) continue; switch( vFieldType[j] ) { case FieldType::NA: case FieldType::BOOL: case FieldType::INT: { TDIntItemID::iterator itor = m_pmIntItemID[j].find( iTemp ); if( itor == m_pmIntItemID[j].end() ) { std::vector vTemp; vTemp.push_back( iItemID ); m_pmIntItemID[j].insert( std::make_pair( iTemp, vTemp ) ); } else { (*itor).second.push_back( iItemID ); } break; } case FieldType::STRING: { TDStringItemID::iterator itor = m_pmStringItemID[j].find( szTemp ); if( itor == m_pmStringItemID[j].end() ) { std::vector vTemp; vTemp.push_back( iItemID ); m_pmStringItemID[j].insert( std::make_pair( szTemp, vTemp ) ); } else { (*itor).second.push_back( iItemID ); } break; } /* case FieldType::PER: case FieldType::FLOAT: { TDFloatItemID::iterator itor = m_pmFloatItemID[j].find( fTemp ); if( itor == m_pmFloatItemID[j].end() ) { std::vector vTemp; vTemp.push_back( iItemID ); m_pmFloatItemID[j].insert( std::make_pair( fTemp, vTemp ) ); } else { (*itor).second.push_back( iItemID ); } break; }*/ } } } return true; } int CDNTableFile::_GetStartCellIndexFromItemID( int iItemID ) { TDItemIDCellIndex::iterator itor = m_mItemIDStartCellIndex.find( iItemID ); return (itor==m_mItemIDStartCellIndex.end()) ? -1 : (*itor).second; } int CDNTableFile::_GetFieldIndexFromFieldName( const char* pszFieldName ) { TDFieldNameFieldIndex::iterator itor = m_mFieldNameFieldIndex.find( pszFieldName ); return (itor==m_mFieldNameFieldIndex.end()) ? -1 : (*itor).second; } bool CDNTableFile::GetFieldFromLable( int iItemID, const char* pszFieldName, DNTableCell& retCell ) { retCell = Cell(); int iStartCellIndex = _GetStartCellIndexFromItemID( iItemID ); if( iStartCellIndex == -1 ) return false; int iFieldIndex = _GetFieldIndexFromFieldName( pszFieldName ); if( iFieldIndex < 0 ) { ASSERT(0); return false; } retCell = m_vCellRepository[ iStartCellIndex + iFieldIndex + 1 ]; return true; } CDNTableFile::Cell* CDNTableFile::GetFieldPtr( int iItemID, int iFieldNum ) { int iStartCellIndex = _GetStartCellIndexFromItemID(iItemID); if( iStartCellIndex == -1 || iFieldNum < 0 || iFieldNum >= GetFieldCount() ) return NULL; return &m_vCellRepository[iStartCellIndex+iFieldNum+1]; } CDNTableFile::Cell* CDNTableFile::GetFieldFromLablePtr( int iItemID, const char* pszFieldName ) { int iStartCellIndex = _GetStartCellIndexFromItemID( iItemID ); if( iStartCellIndex == -1 ) return NULL; int iFieldIndex = _GetFieldIndexFromFieldName( pszFieldName ); if( iFieldIndex == -1 ) return NULL; return &m_vCellRepository[iStartCellIndex+iFieldIndex+1]; } CDNTableFile::Cell* CDNTableFile::GetFieldFromLablePtr( int iStartCellIndex, int iFieldNum ) { if( iStartCellIndex == -1 || iFieldNum < 0 ) return NULL; return &m_vCellRepository[iStartCellIndex+iFieldNum+1]; } int CDNTableFile::GetItemID( UINT uiIndex ) { return (uiIndex >= m_vItemID.size()) ? -1 : m_vItemID[uiIndex]; } bool CDNTableFile::IsExistItem( int iItemID ) { return ( _GetStartCellIndexFromItemID( iItemID ) == -1 ) ? false : true; } int CDNTableFile::GetArrayIndex( int iItemID ) { int iCellStartIndex = _GetStartCellIndexFromItemID(iItemID); return iCellStartIndex / ( GetFieldCount() + 1 ); } int CDNTableFile::GetItemIDListFromField( const char *szFieldLabel, int iValue, std::vector& vVec, bool bClearList/*=true*/ ) { if( m_pmIntItemID == NULL ) return -1; int iFieldNum = _GetFieldIndexFromFieldName( szFieldLabel ); if( iFieldNum == -1 ) return -1; TDIntItemID::iterator itor = m_pmIntItemID[iFieldNum].find(iValue); if( itor == m_pmIntItemID[iFieldNum].end() ) return -1; if( (*itor).second.empty() ) return -1; if( bClearList == true ) vVec = (*itor).second; else vVec.insert( vVec.end(), (*itor).second.begin(), (*itor).second.end() ); return static_cast((*itor).second.size()); } int CDNTableFile::GetItemIDFromField( const char* pszFieldName, const char* pszValue ) { if( m_pmStringItemID == NULL ) return -1; int iFieldIndex = _GetFieldIndexFromFieldName( pszFieldName ); if( iFieldIndex == -1 ) return -1; TDStringItemID::iterator itor = m_pmStringItemID[iFieldIndex].find( pszValue ); if( itor == m_pmStringItemID[iFieldIndex].end() ) return -1; return (*itor).second.empty() ? -1 : (*itor).second[0]; } int CDNTableFile::GetItemIDFromField( const char* pszFieldName, int iValue ) { if( m_pmIntItemID == NULL ) return -1; int iFieldIndex = _GetFieldIndexFromFieldName( pszFieldName ); if( iFieldIndex == -1 ) return -1; TDIntItemID::iterator itor = m_pmIntItemID[iFieldIndex].find( iValue ); if( itor == m_pmIntItemID[iFieldIndex].end() ) return -1; return (*itor).second.empty() ? -1 : (*itor).second[0]; } int CDNTableFile::GetItemIDFromFieldCaseFree( const char* pszFieldName, const char* pszValue ) { int iFieldIndex = _GetFieldIndexFromFieldName( pszFieldName ); if( iFieldIndex == -1 ) return -1; for( UINT i=0 ; i < m_vItemID.size() ; ++i ) { if( stricmp( GetFieldPtr( m_vItemID[i], iFieldIndex )->GetString(), pszValue ) == 0 ) return m_vItemID[i]; } return -1; }