int main( int nArgc, char ** papszArgv ) { DDFModule oModule; const char *pszFilename; int i; if( nArgc > 1 ) pszFilename = papszArgv[1]; else { printf( "Usage: 8211view filename\n" ); exit( 1 ); } for( i = 0; i < 40; i++ ) { /* -------------------------------------------------------------------- */ /* Open the file. Note that by default errors are reported to */ /* stderr, so we don't bother doing it ourselves. */ /* -------------------------------------------------------------------- */ if( !oModule.Open( pszFilename ) ) { exit( 1 ); } /* -------------------------------------------------------------------- */ /* Loop reading records till there are none left. */ /* -------------------------------------------------------------------- */ DDFRecord *poRecord; int nRecordCount = 0; int nFieldCount = 0; while( (poRecord = oModule.ReadRecord()) != NULL ) { /* ------------------------------------------------------------ */ /* Loop over each field in this particular record. */ /* ------------------------------------------------------------ */ for( int iField = 0; iField < poRecord->GetFieldCount(); iField++ ) { DDFField *poField = poRecord->GetField( iField ); ViewRecordField( poField ); nFieldCount++; } nRecordCount++; } oModule.Close(); printf( "Read %d records, %d fields.\n", nRecordCount, nFieldCount ); } }
int main( int nArgc, char ** papszArgv ) { DDFModule oModule; const char *pszFilename = NULL; int bFSPTHack = FALSE; int bXML = FALSE; /* -------------------------------------------------------------------- */ /* Check arguments. */ /* -------------------------------------------------------------------- */ for( int iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg],"-fspt_repeating") ) bFSPTHack = TRUE; else if( EQUAL(papszArgv[iArg],"-xml") ) bXML = TRUE; else pszFilename = papszArgv[iArg]; } if( pszFilename == NULL ) { printf( "Usage: 8211dump [-xml] [-fspt_repeating] filename\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open file. */ /* -------------------------------------------------------------------- */ if( !oModule.Open( pszFilename ) ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Apply FSPT hack if required. */ /* -------------------------------------------------------------------- */ if( bFSPTHack ) { DDFFieldDefn *poFSPT = oModule.FindFieldDefn( "FSPT" ); if( poFSPT == NULL ) fprintf( stderr, "unable to find FSPT field to set repeating flag.\n" ); else poFSPT->SetRepeatingFlag( TRUE ); } /* -------------------------------------------------------------------- */ /* Dump header, and all records. */ /* -------------------------------------------------------------------- */ DDFRecord *poRecord; if( bXML ) { printf("<DDFModule>\n"); int nFieldDefnCount = oModule.GetFieldCount(); for( int i = 0; i < nFieldDefnCount; i++ ) { DDFFieldDefn* poFieldDefn = oModule.GetField(i); const char* pszDataStructCode; switch( poFieldDefn->GetDataStructCode() ) { case dsc_elementary: pszDataStructCode = "elementary"; break; case dsc_vector: pszDataStructCode = "vector"; break; case dsc_array: pszDataStructCode = "array"; break; case dsc_concatenated: pszDataStructCode = "concatenated"; break; default: pszDataStructCode = "(unknown)"; break; } const char* pszDataTypeCode; switch( poFieldDefn->GetDataTypeCode() ) { case dtc_char_string: pszDataTypeCode = "char_string"; break; case dtc_implicit_point: pszDataTypeCode = "implicit_point"; break; case dtc_explicit_point: pszDataTypeCode = "explicit_point"; break; case dtc_explicit_point_scaled: pszDataTypeCode = "explicit_point_scaled"; break; case dtc_char_bit_string: pszDataTypeCode = "char_bit_string"; break; case dtc_bit_string: pszDataTypeCode = "bit_string"; break; case dtc_mixed_data_type: pszDataTypeCode = "mixed_data_type"; break; default: pszDataTypeCode = "(unknown)"; break; } printf("<DDFFieldDefn tag=\"%s\" fieldName=\"%s\" arrayDescr=\"%s\" " "formatControls=\"%s\" dataStructCode=\"%s\" dataTypeCode=\"%s\">\n", poFieldDefn->GetName(), poFieldDefn->GetDescription(), poFieldDefn->GetArrayDescr(), poFieldDefn->GetFormatControls(), pszDataStructCode, pszDataTypeCode); int nSubfieldCount = poFieldDefn->GetSubfieldCount(); for( int iSubField = 0; iSubField < nSubfieldCount; iSubField++ ) { DDFSubfieldDefn* poSubFieldDefn = poFieldDefn->GetSubfield(iSubField); printf(" <DDFSubfieldDefn name=\"%s\" format=\"%s\"/>\n", poSubFieldDefn->GetName(), poSubFieldDefn->GetFormat()); } printf("</DDFFieldDefn>\n"); } for( poRecord = oModule.ReadRecord(); poRecord != NULL; poRecord = oModule.ReadRecord() ) { printf("<DDFRecord>\n"); int nFieldCount = poRecord->GetFieldCount(); for( int iField = 0; iField < nFieldCount; iField++ ) { DDFField* poField = poRecord->GetField(iField); DDFFieldDefn* poDefn = poField->GetFieldDefn(); const char* pszFieldName = poDefn->GetName(); printf(" <DDFField name=\"%s\"", pszFieldName); if( poField->GetRepeatCount() > 1 ) printf(" repeatCount=\"%d\"", poField->GetRepeatCount()); int iOffset = 0, nLoopCount; int nRepeatCount = poField->GetRepeatCount(); const char* pachData = poField->GetData(); int nDataSize = poField->GetDataSize(); if( nRepeatCount == 1 && poDefn->GetSubfieldCount() == 0 ) { printf(" value=\"0x"); for( int i = 0; i < nDataSize - 1; i++ ) printf( "%02X", pachData[i] ); printf("\">\n"); } else printf(">\n"); for( nLoopCount = 0; nLoopCount < nRepeatCount; nLoopCount++ ) { for( int iSubField = 0; iSubField < poDefn->GetSubfieldCount(); iSubField++ ) { int nBytesConsumed; DDFSubfieldDefn* poSubFieldDefn = poDefn->GetSubfield(iSubField); const char* pszSubFieldName = poSubFieldDefn->GetName(); printf(" <DDFSubfield name=\"%s\" ", pszSubFieldName); DDFDataType eType = poSubFieldDefn->GetType(); const char* pachSubdata = pachData + iOffset; int nMaxBytes = nDataSize - iOffset; if( eType == DDFFloat ) printf("type=\"float\">%f", poSubFieldDefn->ExtractFloatData( pachSubdata, nMaxBytes, NULL ) ); else if( eType == DDFInt ) printf("type=\"integer\">%d", poSubFieldDefn->ExtractIntData( pachSubdata, nMaxBytes, NULL ) ); else if( eType == DDFBinaryString ) { int nBytes, i; GByte *pabyBString = (GByte *) poSubFieldDefn->ExtractStringData( pachSubdata, nMaxBytes, &nBytes ); printf( "type=\"binary\">0x" ); for( i = 0; i < nBytes; i++ ) printf( "%02X", pabyBString[i] ); } else { GByte* pabyString = (GByte *)poSubFieldDefn->ExtractStringData( pachSubdata, nMaxBytes, NULL ); int bBinary = FALSE; int i; for( i = 0; pabyString[i] != '\0'; i ++ ) { if( pabyString[i] < 32 || pabyString[i] > 127 ) { bBinary = TRUE; break; } } if( bBinary ) { printf( "type=\"binary\">0x" ); for( i = 0; pabyString[i] != '\0'; i ++ ) printf( "%02X", pabyString[i] ); } else { char* pszEscaped = CPLEscapeString((const char*)pabyString, -1, CPLES_XML); printf("type=\"string\">%s", pszEscaped); CPLFree(pszEscaped); } } printf("</DDFSubfield>\n"); poSubFieldDefn->GetDataLength( pachSubdata, nMaxBytes, &nBytesConsumed ); iOffset += nBytesConsumed; } } printf(" </DDFField>\n"); } printf("</DDFRecord>\n"); } printf("</DDFModule>\n"); } else { oModule.Dump( stdout ); long nStartLoc; nStartLoc = VSIFTellL( oModule.GetFP() ); for( poRecord = oModule.ReadRecord(); poRecord != NULL; poRecord = oModule.ReadRecord() ) { printf( "File Offset: %ld\n", nStartLoc ); poRecord->Dump( stdout ); nStartLoc = VSIFTellL( oModule.GetFP() ); } } oModule.Close(); #ifdef DBMALLOC malloc_dump(1); #endif }
int SDTSRasterReader::Open( SDTS_CATD * poCATD, SDTS_IREF * poIREF, const char * pszModule ) { strncpy( szModule, pszModule, sizeof(szModule) ); szModule[sizeof(szModule) - 1] = '\0'; /* ==================================================================== */ /* Search the LDEF module for the requested cell module. */ /* ==================================================================== */ DDFModule oLDEF; DDFRecord *poRecord; /* -------------------------------------------------------------------- */ /* Open the LDEF module, and report failure if it is missing. */ /* -------------------------------------------------------------------- */ if( poCATD->GetModuleFilePath("LDEF") == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find LDEF entry in CATD module ... " "can't treat as raster.\n" ); return FALSE; } if( !oLDEF.Open( poCATD->GetModuleFilePath("LDEF") ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read each record, till we find what we want. */ /* -------------------------------------------------------------------- */ while( (poRecord = oLDEF.ReadRecord() ) != NULL ) { const char* pszCandidateModule = poRecord->GetStringSubfield("LDEF",0,"CMNM",0); if( pszCandidateModule == NULL ) { poRecord = NULL; break; } if( EQUAL(pszCandidateModule, pszModule) ) break; } if( poRecord == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find module `%s' in LDEF file.\n", pszModule ); return FALSE; } /* -------------------------------------------------------------------- */ /* Extract raster dimensions, and origin offset (0/1). */ /* -------------------------------------------------------------------- */ nXSize = poRecord->GetIntSubfield( "LDEF", 0, "NCOL", 0 ); nYSize = poRecord->GetIntSubfield( "LDEF", 0, "NROW", 0 ); nXStart = poRecord->GetIntSubfield( "LDEF", 0, "SOCI", 0 ); nYStart = poRecord->GetIntSubfield( "LDEF", 0, "SORI", 0 ); /* -------------------------------------------------------------------- */ /* Get the point in the pixel that the origin defines. We only */ /* support top left and center. */ /* -------------------------------------------------------------------- */ const char* pszINTR = poRecord->GetStringSubfield( "LDEF", 0, "INTR", 0 ); if( pszINTR == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find INTR subfield of LDEF field" ); return FALSE; } strcpy( szINTR, pszINTR ); if( EQUAL(szINTR,"") ) strcpy( szINTR, "CE" ); if( !EQUAL(szINTR,"CE") && !EQUAL(szINTR,"TL") ) { CPLError( CE_Warning, CPLE_AppDefined, "Unsupported INTR value of `%s', assume CE.\n" "Positions may be off by one pixel.\n", szINTR ); strcpy( szINTR, "CE" ); } /* -------------------------------------------------------------------- */ /* Record the LDEF record number we used so we can find the */ /* corresponding RSDF record. */ /* -------------------------------------------------------------------- */ int nLDEF_RCID; nLDEF_RCID = poRecord->GetIntSubfield( "LDEF", 0, "RCID", 0 ); oLDEF.Close(); /* ==================================================================== */ /* Search the RSDF module for the requested cell module. */ /* ==================================================================== */ DDFModule oRSDF; /* -------------------------------------------------------------------- */ /* Open the RSDF module, and report failure if it is missing. */ /* -------------------------------------------------------------------- */ if( poCATD->GetModuleFilePath("RSDF") == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find RSDF entry in CATD module ... " "can't treat as raster.\n" ); return FALSE; } if( !oRSDF.Open( poCATD->GetModuleFilePath("RSDF") ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read each record, till we find what we want. */ /* -------------------------------------------------------------------- */ while( (poRecord = oRSDF.ReadRecord() ) != NULL ) { if( poRecord->GetIntSubfield("LYID",0,"RCID",0) == nLDEF_RCID ) break; } if( poRecord == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find LDEF:%d record in RSDF file.\n", nLDEF_RCID ); return FALSE; } /* -------------------------------------------------------------------- */ /* Establish the raster pixel/line to georef transformation. */ /* -------------------------------------------------------------------- */ double dfZ; if( poRecord->FindField( "SADR" ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find SADR field in RSDF record.\n" ); return FALSE; } poIREF->GetSADR( poRecord->FindField( "SADR" ), 1, adfTransform + 0, adfTransform + 3, &dfZ ); adfTransform[1] = poIREF->dfXRes; adfTransform[2] = 0.0; adfTransform[4] = 0.0; adfTransform[5] = -1 * poIREF->dfYRes; /* -------------------------------------------------------------------- */ /* If the origin is the center of the pixel, then shift it back */ /* half a pixel to the top left of the top left. */ /* -------------------------------------------------------------------- */ if( EQUAL(szINTR,"CE") ) { adfTransform[0] -= adfTransform[1] * 0.5; adfTransform[3] -= adfTransform[5] * 0.5; } /* -------------------------------------------------------------------- */ /* Verify some other assumptions. */ /* -------------------------------------------------------------------- */ const char *pszString; pszString = poRecord->GetStringSubfield( "RSDF", 0, "OBRP", 0); if( pszString == NULL ) pszString = ""; if( !EQUAL(pszString,"G2") ) { CPLError( CE_Failure, CPLE_AppDefined, "OBRP value of `%s' not expected 2D raster code (G2).\n", pszString ); return FALSE; } pszString = poRecord->GetStringSubfield( "RSDF", 0, "SCOR", 0); if( pszString == NULL ) pszString = ""; if( !EQUAL(pszString,"TL") ) { CPLError( CE_Warning, CPLE_AppDefined, "SCOR (origin) is `%s' instead of expected top left.\n" "Georef coordinates will likely be incorrect.\n", pszString ); } oRSDF.Close(); /* -------------------------------------------------------------------- */ /* For now we will assume that the block size is one scanline. */ /* We will blow a gasket later while reading the cell file if */ /* this isn't the case. */ /* */ /* This isn't a very flexible raster implementation! */ /* -------------------------------------------------------------------- */ nXBlockSize = nXSize; nYBlockSize = 1; /* ==================================================================== */ /* Fetch the data type used for the raster, and the units from */ /* the data dictionary/schema record (DDSH). */ /* ==================================================================== */ DDFModule oDDSH; /* -------------------------------------------------------------------- */ /* Open the DDSH module, and report failure if it is missing. */ /* -------------------------------------------------------------------- */ if( poCATD->GetModuleFilePath("DDSH") == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find DDSH entry in CATD module ... " "can't treat as raster.\n" ); return FALSE; } if( !oDDSH.Open( poCATD->GetModuleFilePath("DDSH") ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read each record, till we find what we want. */ /* -------------------------------------------------------------------- */ while( (poRecord = oDDSH.ReadRecord() ) != NULL ) { const char* pszName = poRecord->GetStringSubfield("DDSH",0,"NAME",0); if( pszName == NULL ) { poRecord = NULL; break; } if( EQUAL(pszName,pszModule) ) break; } if( poRecord == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find DDSH record for %s.\n", pszModule ); return FALSE; } /* -------------------------------------------------------------------- */ /* Get some values we are interested in. */ /* -------------------------------------------------------------------- */ if( poRecord->GetStringSubfield("DDSH",0,"FMT",0) != NULL ) strcpy( szFMT, poRecord->GetStringSubfield("DDSH",0,"FMT",0) ); else strcpy( szFMT, "BUI16" ); if( poRecord->GetStringSubfield("DDSH",0,"UNIT",0) != NULL ) strcpy( szUNITS, poRecord->GetStringSubfield("DDSH",0,"UNIT",0) ); else strcpy( szUNITS, "METERS" ); if( poRecord->GetStringSubfield("DDSH",0,"ATLB",0) != NULL ) strcpy( szLabel, poRecord->GetStringSubfield("DDSH",0,"ATLB",0) ); else strcpy( szLabel, "" ); /* -------------------------------------------------------------------- */ /* Open the cell file. */ /* -------------------------------------------------------------------- */ return( oDDFModule.Open( poCATD->GetModuleFilePath(pszModule) ) ); }
int main(int nArgc, char* papszArgv[]) { const char *pszFilename = NULL, *pszOutFilename = NULL; DDFModule oModule; /* -------------------------------------------------------------------- */ /* Check arguments. */ /* -------------------------------------------------------------------- */ for( int iArg = 1; iArg < nArgc; iArg++ ) { if( pszFilename == NULL ) pszFilename = papszArgv[iArg]; else if( pszOutFilename == NULL ) pszOutFilename = papszArgv[iArg]; else { pszFilename = NULL; break; } } if( pszFilename == NULL ) { printf( "Usage: 8211createfromxml filename.xml outfilename\n" ); exit( 1 ); } CPLXMLNode* poRoot = CPLParseXMLFile( pszFilename ); if( poRoot == NULL ) { fprintf(stderr, "Cannot parse XML file '%s'\n", pszFilename); exit( 1 ); } CPLXMLNode* poXMLDDFModule = CPLSearchXMLNode(poRoot, "=DDFModule"); if( poXMLDDFModule == NULL ) { fprintf(stderr, "Cannot find DDFModule node in XML file '%s'\n", pszFilename); exit( 1 ); } /* Compute the size of the DDFField tag */ CPLXMLNode* psIter = poXMLDDFModule->psChild; int nSizeFieldTag = 0; while( psIter != NULL ) { if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFFieldDefn") == 0 ) { const char* pszTag = CPLGetXMLValue(psIter, "tag", ""); if( nSizeFieldTag == 0 ) nSizeFieldTag = (int)strlen(pszTag); else if( nSizeFieldTag != (int)strlen(pszTag) ) { fprintf(stderr, "All fields have not the same tag size\n"); exit( 1 ); } } psIter = psIter->psNext; } char chInterchangeLevel = '3'; char chLeaderIden = 'L'; char chCodeExtensionIndicator = 'E'; char chVersionNumber = '1'; char chAppIndicator = ' '; const char *pszExtendedCharSet = " ! "; int nSizeFieldLength = 3; int nSizeFieldPos = 4; chInterchangeLevel = CPLGetXMLValue(poXMLDDFModule, "_interchangeLevel", CPLSPrintf("%c", chInterchangeLevel))[0]; chLeaderIden = CPLGetXMLValue(poXMLDDFModule, "_leaderIden", CPLSPrintf("%c", chLeaderIden))[0]; chCodeExtensionIndicator = CPLGetXMLValue(poXMLDDFModule, "_inlineCodeExtensionIndicator", CPLSPrintf("%c", chCodeExtensionIndicator))[0]; chVersionNumber = CPLGetXMLValue(poXMLDDFModule, "_versionNumber", CPLSPrintf("%c", chVersionNumber))[0]; chAppIndicator = CPLGetXMLValue(poXMLDDFModule, "_appIndicator", CPLSPrintf("%c", chAppIndicator))[0]; char szExtendedCharSet[4]; snprintf(szExtendedCharSet, sizeof(szExtendedCharSet), "%s", CPLGetXMLValue(poXMLDDFModule, "_extendedCharSet", pszExtendedCharSet)); pszExtendedCharSet = szExtendedCharSet; nSizeFieldLength = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldLength", CPLSPrintf("%d", nSizeFieldLength))); nSizeFieldPos = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldPos", CPLSPrintf("%d", nSizeFieldPos))); nSizeFieldTag = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldTag", CPLSPrintf("%d", nSizeFieldTag))); oModule.Initialize(chInterchangeLevel, chLeaderIden, chCodeExtensionIndicator, chVersionNumber, chAppIndicator, pszExtendedCharSet, nSizeFieldLength, nSizeFieldPos, nSizeFieldTag); oModule.SetFieldControlLength(atoi(CPLGetXMLValue(poXMLDDFModule, "_fieldControlLength", CPLSPrintf("%d", oModule.GetFieldControlLength())))); int bCreated = FALSE; /* Create DDFFieldDefn and DDFRecord elements */ psIter = poXMLDDFModule->psChild; while( psIter != NULL ) { if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFFieldDefn") == 0 ) { DDFFieldDefn* poFDefn = new DDFFieldDefn(); DDF_data_struct_code eStructCode = dsc_elementary; const char* pszStructCode = CPLGetXMLValue(psIter, "dataStructCode", ""); if( strcmp(pszStructCode, "elementary") == 0 ) eStructCode = dsc_elementary; else if( strcmp(pszStructCode, "vector") == 0 ) eStructCode = dsc_vector; else if( strcmp(pszStructCode, "array") == 0 ) eStructCode = dsc_array; else if( strcmp(pszStructCode, "concatenated") == 0 ) eStructCode = dsc_concatenated; DDF_data_type_code eTypeCode = dtc_char_string; const char* pszTypeCode = CPLGetXMLValue(psIter, "dataTypeCode", ""); if( strcmp(pszTypeCode, "char_string") == 0 ) eTypeCode = dtc_char_string; else if( strcmp(pszTypeCode, "implicit_point") == 0 ) eTypeCode = dtc_implicit_point; else if( strcmp(pszTypeCode, "explicit_point") == 0 ) eTypeCode = dtc_explicit_point; else if( strcmp(pszTypeCode, "explicit_point_scaled") == 0 ) eTypeCode = dtc_explicit_point_scaled; else if( strcmp(pszTypeCode, "char_bit_string") == 0 ) eTypeCode = dtc_char_bit_string; else if( strcmp(pszTypeCode, "bit_string") == 0 ) eTypeCode = dtc_bit_string; else if( strcmp(pszTypeCode, "mixed_data_type") == 0 ) eTypeCode = dtc_mixed_data_type; const char* pszFormatControls = CPLGetXMLValue(psIter, "formatControls", NULL); if( eStructCode != dsc_elementary ) pszFormatControls = NULL; const char* pszArrayDescr = CPLGetXMLValue(psIter, "arrayDescr", ""); if( eStructCode == dsc_vector ) pszArrayDescr = ""; else if( eStructCode == dsc_array ) pszArrayDescr = "*"; poFDefn->Create( CPLGetXMLValue(psIter, "tag", ""), CPLGetXMLValue(psIter, "fieldName", ""), pszArrayDescr, eStructCode, eTypeCode, pszFormatControls ); CPLXMLNode* psSubIter = psIter->psChild; while( psSubIter != NULL ) { if( psSubIter->eType == CXT_Element && strcmp(psSubIter->pszValue, "DDFSubfieldDefn") == 0 ) { poFDefn->AddSubfield( CPLGetXMLValue(psSubIter, "name", ""), CPLGetXMLValue(psSubIter, "format", "") ); } psSubIter = psSubIter->psNext; } pszFormatControls = CPLGetXMLValue(psIter, "formatControls", NULL); if( pszFormatControls ) poFDefn->SetFormatControls(pszFormatControls); oModule.AddField( poFDefn ); } else if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFRecord") == 0 ) { //const bool bFirstRecord = !bCreated; if( !bCreated ) { oModule.Create( pszOutFilename ); bCreated = TRUE; } DDFRecord *poRec = new DDFRecord( &oModule ); std::map<std::string, int> oMapField; //if( !bFirstRecord ) // poRec->SetReuseHeader(atoi(CPLGetXMLValue(psIter, "reuseHeader", CPLSPrintf("%d", poRec->GetReuseHeader())))); poRec->SetSizeFieldLength(atoi(CPLGetXMLValue(psIter, "_sizeFieldLength", CPLSPrintf("%d", poRec->GetSizeFieldLength())))); poRec->SetSizeFieldPos(atoi(CPLGetXMLValue(psIter, "_sizeFieldPos", CPLSPrintf("%d", poRec->GetSizeFieldPos())))); poRec->SetSizeFieldTag(atoi(CPLGetXMLValue(psIter, "_sizeFieldTag", CPLSPrintf("%d", poRec->GetSizeFieldTag())))); CPLXMLNode* psSubIter = psIter->psChild; while( psSubIter != NULL ) { if( psSubIter->eType == CXT_Element && strcmp(psSubIter->pszValue, "DDFField") == 0 ) { const char* pszFieldName = CPLGetXMLValue(psSubIter, "name", ""); DDFFieldDefn* poFieldDefn = oModule.FindFieldDefn( pszFieldName ); if( poFieldDefn == NULL ) { fprintf(stderr, "Can't find field '%s'\n", pszFieldName ); exit(1); } int nFieldOcc = oMapField[pszFieldName]; oMapField[pszFieldName] ++ ; DDFField *poField = poRec->AddField( poFieldDefn ); const char* pszValue = CPLGetXMLValue(psSubIter, "value", NULL); if( pszValue != NULL && STARTS_WITH(pszValue, "0x") ) { pszValue += 2; int nDataLen = (int)strlen(pszValue) / 2; char* pabyData = (char*) malloc(nDataLen); for(int i=0;i<nDataLen;i++) { char c; int nHigh, nLow; c = pszValue[2*i]; if( c >= 'A' && c <= 'F' ) nHigh = 10 + c - 'A'; else nHigh = c - '0'; c = pszValue[2*i + 1]; if( c >= 'A' && c <= 'F' ) nLow = 10 + c - 'A'; else nLow = c - '0'; pabyData[i] = (nHigh << 4) + nLow; } poRec->SetFieldRaw( poField, nFieldOcc, (const char *) pabyData, nDataLen ); free(pabyData); } else { CPLXMLNode* psSubfieldIter = psSubIter->psChild; std::map<std::string, int> oMapSubfield; while( psSubfieldIter != NULL ) { if( psSubfieldIter->eType == CXT_Element && strcmp(psSubfieldIter->pszValue, "DDFSubfield") == 0 ) { const char* pszSubfieldName = CPLGetXMLValue(psSubfieldIter, "name", ""); const char* pszSubfieldType = CPLGetXMLValue(psSubfieldIter, "type", ""); const char* pszSubfieldValue = CPLGetXMLValue(psSubfieldIter, NULL, ""); int nOcc = oMapSubfield[pszSubfieldName]; oMapSubfield[pszSubfieldName] ++ ; if( strcmp(pszSubfieldType, "float") == 0 ) { poRec->SetFloatSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, CPLAtof(pszSubfieldValue) ); } else if( strcmp(pszSubfieldType, "integer") == 0 ) { poRec->SetIntSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, atoi(pszSubfieldValue) ); } else if( strcmp(pszSubfieldType, "string") == 0 ) { poRec->SetStringSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, pszSubfieldValue ); } else if( strcmp(pszSubfieldType, "binary") == 0 && STARTS_WITH(pszSubfieldValue, "0x") ) { pszSubfieldValue += 2; int nDataLen = (int)strlen(pszSubfieldValue) / 2; char* pabyData = (char*) malloc(nDataLen); for(int i=0;i<nDataLen;i++) { char c; int nHigh, nLow; c = pszSubfieldValue[2*i]; if( c >= 'A' && c <= 'F' ) nHigh = 10 + c - 'A'; else nHigh = c - '0'; c = pszSubfieldValue[2*i + 1]; if( c >= 'A' && c <= 'F' ) nLow = 10 + c - 'A'; else nLow = c - '0'; pabyData[i] = (nHigh << 4) + nLow; } poRec->SetStringSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, pabyData, nDataLen ); free(pabyData); } } psSubfieldIter = psSubfieldIter->psNext; } } } psSubIter = psSubIter->psNext; } poRec->Write(); delete poRec; } psIter = psIter->psNext; } CPLDestroyXMLNode(poRoot); oModule.Close(); return 0; }