📄 ddffielddefn.cpp
字号:
case dtc_mixed_data_type: pszValue = "mixed_data_type"; break; default: CPLAssert( FALSE ); pszValue = "(unknown)"; break; } fprintf( fp, " _data_type_code = %s\n", pszValue ); for( int i = 0; i < nSubfieldCount; i++ ) papoSubfields[i]->Dump( fp );}/************************************************************************//* BuildSubfields() *//* *//* Based on the _arrayDescr build a set of subfields. *//************************************************************************/int DDFFieldDefn::BuildSubfields(){ char **papszSubfieldNames; const char *pszSublist = _arrayDescr; if( pszSublist[0] == '*' ) { bRepeatingSubfields = TRUE; pszSublist++; } papszSubfieldNames = CSLTokenizeStringComplex( pszSublist, "!", FALSE, FALSE ); int nSFCount = CSLCount( papszSubfieldNames ); for( int iSF = 0; iSF < nSFCount; iSF++ ) { DDFSubfieldDefn *poSFDefn = new DDFSubfieldDefn; poSFDefn->SetName( papszSubfieldNames[iSF] ); AddSubfield( poSFDefn, TRUE ); } CSLDestroy( papszSubfieldNames ); return TRUE;}/************************************************************************//* ExtractSubstring() *//* *//* Extract a substring terminated by a comma (or end of *//* string). Commas in brackets are ignored as terminated with *//* bracket nesting understood gracefully. If the returned *//* string would being and end with a bracket then strip off the *//* brackets. *//* *//* Given a string like "(A,3(B,C),D),X,Y)" return "A,3(B,C),D". *//* Give a string like "3A,2C" return "3A". *//************************************************************************/char *DDFFieldDefn::ExtractSubstring( const char * pszSrc ){ int nBracket=0, i; char *pszReturn; for( i = 0; pszSrc[i] != '\0' && (nBracket > 0 || pszSrc[i] != ','); i++ ) { if( pszSrc[i] == '(' ) nBracket++; else if( pszSrc[i] == ')' ) nBracket--; } if( pszSrc[0] == '(' ) { pszReturn = CPLStrdup( pszSrc + 1 ); pszReturn[i-2] = '\0'; } else { pszReturn = CPLStrdup( pszSrc ); pszReturn[i] = '\0'; } return pszReturn;}/************************************************************************//* ExpandFormat() *//************************************************************************/char *DDFFieldDefn::ExpandFormat( const char * pszSrc ){ int nDestMax = 32; char *pszDest = (char *) CPLMalloc(nDestMax+1); int iSrc, iDst; int nRepeat = 0; iSrc = 0; iDst = 0; pszDest[0] = '\0'; while( pszSrc[iSrc] != '\0' ) { /* This is presumably an extra level of brackets around some binary stuff related to rescaning which we don't care to do (see 6.4.3.3 of the standard. We just strip off the extra layer of brackets */ if( (iSrc == 0 || pszSrc[iSrc-1] == ',') && pszSrc[iSrc] == '(' ) { char *pszContents = ExtractSubstring( pszSrc+iSrc ); char *pszExpandedContents = ExpandFormat( pszContents ); if( (int) (strlen(pszExpandedContents) + strlen(pszDest) + 1) > nDestMax ) { nDestMax = 2 * (strlen(pszExpandedContents) + strlen(pszDest)); pszDest = (char *) CPLRealloc(pszDest,nDestMax+1); } strcat( pszDest, pszExpandedContents ); iDst = strlen(pszDest); iSrc = iSrc + strlen(pszContents) + 2; CPLFree( pszContents ); CPLFree( pszExpandedContents ); } /* this is a repeated subclause */ else if( (iSrc == 0 || pszSrc[iSrc-1] == ',') && isdigit(pszSrc[iSrc]) ) { const char *pszNext; nRepeat = atoi(pszSrc+iSrc); // skip over repeat count. for( pszNext = pszSrc+iSrc; isdigit(*pszNext); pszNext++ ) iSrc++; char *pszContents = ExtractSubstring( pszNext ); char *pszExpandedContents = ExpandFormat( pszContents ); for( int i = 0; i < nRepeat; i++ ) { if( (int) (strlen(pszExpandedContents) + strlen(pszDest) + 1) > nDestMax ) { nDestMax = 2 * (strlen(pszExpandedContents) + strlen(pszDest)); pszDest = (char *) CPLRealloc(pszDest,nDestMax+1); } strcat( pszDest, pszExpandedContents ); if( i < nRepeat-1 ) strcat( pszDest, "," ); } iDst = strlen(pszDest); if( pszNext[0] == '(' ) iSrc = iSrc + strlen(pszContents) + 2; else iSrc = iSrc + strlen(pszContents); CPLFree( pszContents ); CPLFree( pszExpandedContents ); } else { if( iDst+1 >= nDestMax ) { nDestMax = 2 * iDst; pszDest = (char *) CPLRealloc(pszDest,nDestMax); } pszDest[iDst++] = pszSrc[iSrc++]; pszDest[iDst] = '\0'; } } return pszDest;} /************************************************************************//* ApplyFormats() *//* *//* This method parses the format string partially, and then *//* applies a subfield format string to each subfield object. *//* It in turn does final parsing of the subfield formats. *//************************************************************************/int DDFFieldDefn::ApplyFormats(){ char *pszFormatList; char **papszFormatItems; /* -------------------------------------------------------------------- *//* Verify that the format string is contained within brackets. *//* -------------------------------------------------------------------- */ if( strlen(_formatControls) < 2 || _formatControls[0] != '(' || _formatControls[strlen(_formatControls)-1] != ')' ) { CPLError( CE_Failure, CPLE_AppDefined, "Format controls for `%s' field missing brackets:%s\n", pszTag, _formatControls ); return FALSE; }/* -------------------------------------------------------------------- *//* Duplicate the string, and strip off the brackets. *//* -------------------------------------------------------------------- */ pszFormatList = ExpandFormat( _formatControls );/* -------------------------------------------------------------------- *//* Tokenize based on commas. *//* -------------------------------------------------------------------- */ papszFormatItems = CSLTokenizeStringComplex(pszFormatList, ",", FALSE, FALSE ); CPLFree( pszFormatList );/* -------------------------------------------------------------------- *//* Apply the format items to subfields. *//* -------------------------------------------------------------------- */ int iFormatItem; for( iFormatItem = 0; papszFormatItems[iFormatItem] != NULL; iFormatItem++ ) { const char *pszPastPrefix; pszPastPrefix = papszFormatItems[iFormatItem]; while( *pszPastPrefix >= '0' && *pszPastPrefix <= '9' ) pszPastPrefix++; /////////////////////////////////////////////////////////////// // Did we get too many formats for the subfields created // by names? This may be legal by the 8211 specification, but // isn't encountered in any formats we care about so we just // blow. if( iFormatItem >= nSubfieldCount ) { CPLError( CE_Warning, CPLE_AppDefined, "Got more formats than subfields for field `%s'.\n", pszTag ); break; } if( !papoSubfields[iFormatItem]->SetFormat(pszPastPrefix) ) return FALSE; }/* -------------------------------------------------------------------- *//* Verify that we got enough formats, cleanup and return. *//* -------------------------------------------------------------------- */ CSLDestroy( papszFormatItems ); if( iFormatItem < nSubfieldCount ) { CPLError( CE_Failure, CPLE_AppDefined, "Got less formats than subfields for field `%s',\n", pszTag ); return FALSE; }/* -------------------------------------------------------------------- *//* If all the fields are fixed width, then we are fixed width *//* too. This is important for repeating fields. *//* -------------------------------------------------------------------- */ nFixedWidth = 0; for( int i = 0; i < nSubfieldCount; i++ ) { if( papoSubfields[i]->GetWidth() == 0 ) { nFixedWidth = 0; break; } else nFixedWidth += papoSubfields[i]->GetWidth(); } return TRUE;}/************************************************************************//* FindSubfieldDefn() *//************************************************************************//** * Find a subfield definition by it's mnemonic tag. * * @param pszMnemonic The name of the field. * * @return The subfield pointer, or NULL if there isn't any such subfield. */ DDFSubfieldDefn *DDFFieldDefn::FindSubfieldDefn( const char * pszMnemonic ){ for( int i = 0; i < nSubfieldCount; i++ ) { if( EQUAL(papoSubfields[i]->GetName(),pszMnemonic) ) return papoSubfields[i]; } return NULL;}/************************************************************************//* GetSubfield() *//* *//* Fetch a subfield by it's index. *//************************************************************************//** * Fetch a subfield by index. * * @param i The index subfield index. (Between 0 and GetSubfieldCount()-1) * * @return The subfield pointer, or NULL if the index is out of range. */DDFSubfieldDefn *DDFFieldDefn::GetSubfield( int i ){ if( i < 0 || i >= nSubfieldCount ) { CPLAssert( FALSE ); return NULL; } return papoSubfields[i];}/************************************************************************//* GetDefaultValue() *//************************************************************************//** * Return default data for field instance. */char *DDFFieldDefn::GetDefaultValue( int *pnSize ){ /* -------------------------------------------------------------------- *//* Loop once collecting the sum of the subfield lengths. *//* -------------------------------------------------------------------- */ int iSubfield; int nTotalSize = 0; for( iSubfield = 0; iSubfield < nSubfieldCount; iSubfield++ ) { int nSubfieldSize; if( !papoSubfields[iSubfield]->GetDefaultValue( NULL, 0, &nSubfieldSize ) ) return NULL; nTotalSize += nSubfieldSize; }/* -------------------------------------------------------------------- *//* Allocate buffer. *//* -------------------------------------------------------------------- */ char *pachData = (char *) CPLMalloc( nTotalSize ); if( pnSize != NULL ) *pnSize = nTotalSize;/* -------------------------------------------------------------------- *//* Loop again, collecting actual default values. *//* -------------------------------------------------------------------- */ int nOffset = 0; for( iSubfield = 0; iSubfield < nSubfieldCount; iSubfield++ ) { int nSubfieldSize; if( !papoSubfields[iSubfield]->GetDefaultValue( pachData + nOffset, nTotalSize - nOffset, &nSubfieldSize ) ) { CPLAssert( FALSE ); return NULL; } nOffset += nSubfieldSize; } CPLAssert( nOffset == nTotalSize ); return pachData;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -