📄 ddfmodule.cpp
字号:
/* -------------------------------------------------------------------- *//* Create the file on disk. *//* -------------------------------------------------------------------- */ fpDDF = VSIFOpen( pszFilename, "wb+" ); if( fpDDF == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create file %s, check path and permissions.", pszFilename ); return FALSE; } bReadOnly = FALSE;/* -------------------------------------------------------------------- *//* Prepare all the field definition information. *//* -------------------------------------------------------------------- */ int iField; _fieldControlLength = 9; _recLength = 24 + nFieldDefnCount * (_sizeFieldLength+_sizeFieldPos+_sizeFieldTag) + 1; _fieldAreaStart = _recLength; for( iField=0; iField < nFieldDefnCount; iField++ ) { int nLength; papoFieldDefns[iField]->GenerateDDREntry( NULL, &nLength ); _recLength += nLength; }/* -------------------------------------------------------------------- *//* Setup 24 byte leader. *//* -------------------------------------------------------------------- */ char achLeader[25]; sprintf( achLeader+0, "%05d", (int) _recLength ); achLeader[5] = _interchangeLevel; achLeader[6] = _leaderIden; achLeader[7] = _inlineCodeExtensionIndicator; achLeader[8] = _versionNumber; achLeader[9] = _appIndicator; sprintf( achLeader+10, "%02d", (int) _fieldControlLength ); sprintf( achLeader+12, "%05d", (int) _fieldAreaStart ); strncpy( achLeader+17, _extendedCharSet, 3 ); sprintf( achLeader+20, "%1d", (int) _sizeFieldLength ); sprintf( achLeader+21, "%1d", (int) _sizeFieldPos ); achLeader[22] = '0'; sprintf( achLeader+23, "%1d", (int) _sizeFieldTag ); VSIFWrite( achLeader, 24, 1, fpDDF );/* -------------------------------------------------------------------- *//* Write out directory entries. *//* -------------------------------------------------------------------- */ int nOffset = 0; for( iField=0; iField < nFieldDefnCount; iField++ ) { char achDirEntry[12]; int nLength; papoFieldDefns[iField]->GenerateDDREntry( NULL, &nLength ); strcpy( achDirEntry, papoFieldDefns[iField]->GetName() ); sprintf( achDirEntry + _sizeFieldTag, "%03d", nLength ); sprintf( achDirEntry + _sizeFieldTag + _sizeFieldLength, "%04d", nOffset ); nOffset += nLength; VSIFWrite( achDirEntry, 11, 1, fpDDF ); } char chUT = DDF_FIELD_TERMINATOR; VSIFWrite( &chUT, 1, 1, fpDDF );/* -------------------------------------------------------------------- *//* Write out the field descriptions themselves. *//* -------------------------------------------------------------------- */ for( iField=0; iField < nFieldDefnCount; iField++ ) { char *pachData; int nLength; papoFieldDefns[iField]->GenerateDDREntry( &pachData, &nLength ); VSIFWrite( pachData, nLength, 1, fpDDF ); CPLFree( pachData ); } return TRUE;}/************************************************************************//* Dump() *//************************************************************************//** * Write out module info to debugging file. * * A variety of information about the module is written to the debugging * file. This includes all the field and subfield definitions read from * the header. * * @param fp The standard io file handle to write to. ie. stderr. */void DDFModule::Dump( FILE * fp ){ fprintf( fp, "DDFModule:\n" ); fprintf( fp, " _recLength = %ld\n", _recLength ); fprintf( fp, " _interchangeLevel = %c\n", _interchangeLevel ); fprintf( fp, " _leaderIden = %c\n", _leaderIden ); fprintf( fp, " _inlineCodeExtensionIndicator = %c\n", _inlineCodeExtensionIndicator ); fprintf( fp, " _versionNumber = %c\n", _versionNumber ); fprintf( fp, " _appIndicator = %c\n", _appIndicator ); fprintf( fp, " _extendedCharSet = `%s'\n", _extendedCharSet ); fprintf( fp, " _fieldControlLength = %d\n", _fieldControlLength ); fprintf( fp, " _fieldAreaStart = %ld\n", _fieldAreaStart ); fprintf( fp, " _sizeFieldLength = %ld\n", _sizeFieldLength ); fprintf( fp, " _sizeFieldPos = %ld\n", _sizeFieldPos ); fprintf( fp, " _sizeFieldTag = %ld\n", _sizeFieldTag ); for( int i = 0; i < nFieldDefnCount; i++ ) { papoFieldDefns[i]->Dump( fp ); }}/************************************************************************//* FindFieldDefn() *//************************************************************************//** * Fetch the definition of the named field. * * This function will scan the DDFFieldDefn's on this module, to find * one with the indicated field name. * * @param pszFieldName The name of the field to search for. The comparison is * case insensitive. * * @return A pointer to the request DDFFieldDefn object is returned, or NULL * if none matching the name are found. The return object remains owned by * the DDFModule, and should not be deleted by application code. */DDFFieldDefn *DDFModule::FindFieldDefn( const char *pszFieldName ){ int i; /* -------------------------------------------------------------------- *//* This pass tries to reduce the cost of comparing strings by *//* first checking the first character, and by using strcmp() *//* -------------------------------------------------------------------- */ for( i = 0; i < nFieldDefnCount; i++ ) { const char *pszThisName = papoFieldDefns[i]->GetName(); if( *pszThisName == *pszFieldName && strcmp( pszFieldName+1, pszThisName+1) == 0 ) return papoFieldDefns[i]; }/* -------------------------------------------------------------------- *//* Now do a more general check. Application code may not *//* always use the correct name case. *//* -------------------------------------------------------------------- */ for( i = 0; i < nFieldDefnCount; i++ ) { if( EQUAL(pszFieldName, papoFieldDefns[i]->GetName()) ) return papoFieldDefns[i]; } return NULL;}/************************************************************************//* ReadRecord() *//* *//* Read one record from the file, and return to the *//* application. The returned record is owned by the module, *//* and is reused from call to call in order to preserve headers *//* when they aren't being re-read from record to record. *//************************************************************************//** * Read one record from the file. * * @return A pointer to a DDFRecord object is returned, or NULL if a read * error, or end of file occurs. The returned record is owned by the * module, and should not be deleted by the application. The record is * only valid untill the next ReadRecord() at which point it is overwritten. */DDFRecord *DDFModule::ReadRecord(){ if( poRecord == NULL ) poRecord = new DDFRecord( this ); if( poRecord->Read() ) return poRecord; else return NULL;}/************************************************************************//* AddField() *//************************************************************************//** * Add new field definition. * * Field definitions may only be added to DDFModules being used for * writing, not those being used for reading. Ownership of the * DDFFieldDefn object is taken by the DDFModule. * * @param poNewFDefn definition to be added to the module. */void DDFModule::AddField( DDFFieldDefn *poNewFDefn ){ nFieldDefnCount++; papoFieldDefns = (DDFFieldDefn **) CPLRealloc(papoFieldDefns, sizeof(void*)*nFieldDefnCount); papoFieldDefns[nFieldDefnCount-1] = poNewFDefn;}/************************************************************************//* GetField() *//************************************************************************//** * Fetch a field definition by index. * * @param i (from 0 to GetFieldCount() - 1. * @return the returned field pointer or NULL if the index is out of range. */DDFFieldDefn *DDFModule::GetField(int i){ if( i < 0 || i >= nFieldDefnCount ) return NULL; else return papoFieldDefns[i];} /************************************************************************//* AddCloneRecord() *//* *//* We want to keep track of cloned records, so we can clean *//* them up when the module is destroyed. *//************************************************************************/void DDFModule::AddCloneRecord( DDFRecord * poRecord ){/* -------------------------------------------------------------------- *//* Do we need to grow the container array? *//* -------------------------------------------------------------------- */ if( nCloneCount == nMaxCloneCount ) { nMaxCloneCount = nCloneCount*2 + 20; papoClones = (DDFRecord **) CPLRealloc(papoClones, nMaxCloneCount * sizeof(void*)); }/* -------------------------------------------------------------------- *//* Add to the list. *//* -------------------------------------------------------------------- */ papoClones[nCloneCount++] = poRecord;}/************************************************************************//* RemoveCloneRecord() *//************************************************************************/void DDFModule::RemoveCloneRecord( DDFRecord * poRecord ){ int i; for( i = 0; i < nCloneCount; i++ ) { if( papoClones[i] == poRecord ) { papoClones[i] = papoClones[nCloneCount-1]; nCloneCount--; return; } } CPLAssert( FALSE );}/************************************************************************//* Rewind() *//************************************************************************//** * Return to first record. * * The next call to ReadRecord() will read the first data record in the file. * * @param nOffset the offset in the file to return to. By default this is * -1, a special value indicating that reading should return to the first * data record. Otherwise it is an absolute byte offset in the file. */void DDFModule::Rewind( long nOffset ){ if( nOffset == -1 ) nOffset = nFirstRecordOffset; if( fpDDF == NULL ) return; VSIFSeek( fpDDF, nOffset, SEEK_SET ); if( nOffset == nFirstRecordOffset && poRecord != NULL ) poRecord->Clear(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -