int main( int nArgc, char ** papszArgv ) { DDFModule oModule; const char *pszFilename = NULL; int bFSPTHack = FALSE; int bXML = FALSE; bool bAllDetails = 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 if( EQUAL(papszArgv[iArg],"-xml_all_details") ) { bXML = TRUE; bAllDetails = true; } else pszFilename = papszArgv[iArg]; } if( pszFilename == NULL ) { printf( "Usage: 8211dump [-xml|-xml_all_details] [-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. */ /* -------------------------------------------------------------------- */ if( bXML ) { printf("<DDFModule"); if( bAllDetails ) { printf(" _interchangeLevel=\"%c\"", oModule.GetInterchangeLevel()); printf(" _leaderIden=\"%c\"", oModule.GetLeaderIden()); printf(" _inlineCodeExtensionIndicator=\"%c\"", oModule.GetCodeExtensionIndicator()); printf(" _versionNumber=\"%c\"", oModule.GetVersionNumber()); printf(" _appIndicator=\"%c\"", oModule.GetAppIndicator()); printf(" _extendedCharSet=\"%s\"", oModule.GetExtendedCharSet()); printf(" _fieldControlLength=\"%d\"", oModule.GetFieldControlLength()); printf(" _sizeFieldLength=\"%d\"", oModule.GetSizeFieldLength()); printf(" _sizeFieldPos=\"%d\"", oModule.GetSizeFieldPos()); printf(" _sizeFieldTag=\"%d\"", oModule.GetSizeFieldTag()); } printf(">\n"); int nFieldDefnCount = oModule.GetFieldCount(); for( int i = 0; i < nFieldDefnCount; i++ ) { DDFFieldDefn* poFieldDefn = oModule.GetField(i); const char* pszDataStructCode = NULL; 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 = NULL; 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\"" " dataStructCode=\"%s\" dataTypeCode=\"%s\"", poFieldDefn->GetName(), poFieldDefn->GetDescription(), pszDataStructCode, pszDataTypeCode); int nSubfieldCount = poFieldDefn->GetSubfieldCount(); if( bAllDetails || nSubfieldCount == 0 ) { printf(" arrayDescr=\"%s\"", poFieldDefn->GetArrayDescr()); printf(" formatControls=\"%s\"", poFieldDefn->GetFormatControls()); } printf(">\n"); 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"); } // DDFRecord *poRecord; for( DDFRecord *poRecord = oModule.ReadRecord(); poRecord != NULL; poRecord = oModule.ReadRecord() ) { printf("<DDFRecord"); if( bAllDetails ) { if( poRecord->GetReuseHeader() ) printf(" reuseHeader=\"1\""); printf(" dataSize=\"%d\"", poRecord->GetDataSize()); printf(" _sizeFieldTag=\"%d\"", poRecord->GetSizeFieldTag()); printf(" _sizeFieldPos=\"%d\"", poRecord->GetSizeFieldPos()); printf(" _sizeFieldLength=\"%d\"", poRecord->GetSizeFieldLength()); } printf(">\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( DDFRecord *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 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; }