MOAB: Mesh Oriented datABase  (version 5.3.0)
WriteNC.cpp
Go to the documentation of this file.
00001 #include "WriteNC.hpp"
00002 #include "moab/CN.hpp"
00003 #include "MBTagConventions.hpp"
00004 #include "MBParallelConventions.h"
00005 #include "moab/Interface.hpp"
00006 #include "moab/Range.hpp"
00007 #include "moab/WriteUtilIface.hpp"
00008 #include "moab/FileOptions.hpp"
00009 #include "NCWriteHelper.hpp"
00010 
00011 #include <fstream>
00012 #include <map>
00013 #include <set>
00014 
00015 #include <iostream>
00016 #include <sstream>
00017 
00018 #ifdef WIN32
00019 #ifdef size_t
00020 #undef size_t
00021 #endif
00022 #endif
00023 
00024 namespace moab
00025 {
00026 
00027 WriterIface* WriteNC::factory( Interface* iface )
00028 {
00029     return new WriteNC( iface );
00030 }
00031 
00032 WriteNC::WriteNC( Interface* impl )
00033     : mbImpl( impl ), dbgOut( stderr ),
00034 #ifdef MOAB_HAVE_MPI
00035       myPcomm( NULL ),
00036 #endif
00037       noMesh( false ), noVars( false ), append( false ), mGlobalIdTag( 0 ), isParallel( false ), myHelper( NULL )
00038 {
00039     assert( impl != NULL );
00040     impl->query_interface( mWriteIface );
00041 }
00042 
00043 WriteNC::~WriteNC()
00044 {
00045     mbImpl->release_interface( mWriteIface );
00046     if( myHelper != NULL ) delete myHelper;
00047 }
00048 
00049 //! Writes out a file
00050 ErrorCode WriteNC::write_file( const char* file_name, const bool overwrite, const FileOptions& options,
00051                                const EntityHandle* file_set, const int num_set, const std::vector< std::string >&,
00052                                const Tag*, int, int )
00053 {
00054     ErrorCode rval;
00055     // See if opts has variable(s) specified
00056     std::vector< std::string > var_names;
00057     std::vector< std::string > desired_names;
00058     std::vector< int > tstep_nums;
00059     std::vector< double > tstep_vals;
00060 
00061     // Get and cache predefined tag handles
00062     mGlobalIdTag = mbImpl->globalId_tag();
00063 
00064     // num set has to be 1, we will write only one set, the original file set used to load
00065     if( num_set != 1 ) MB_SET_ERR( MB_FAILURE, "We should write only one set (the file set used to read data into)" );
00066 
00067     rval = parse_options( options, var_names, desired_names, tstep_nums, tstep_vals );MB_CHK_SET_ERR( rval, "Trouble parsing option string" );
00068 
00069     // Important to create some data that will be used to write the file; dimensions, variables, etc
00070     // new variables still need to have some way of defining their dimensions
00071     // maybe it will be passed as write options
00072     rval = process_conventional_tags( *file_set );MB_CHK_SET_ERR( rval, "Trouble processing conventional tags" );
00073 
00074     // Create or append the file
00075     if( append )
00076         dbgOut.tprintf( 1, "opening file %s for appending \n", file_name );
00077     else
00078         dbgOut.tprintf( 1, "creating file %s\n", file_name );
00079     fileName = file_name;
00080     int success;
00081 
00082     if( append )
00083     {
00084         int omode = NC_WRITE;
00085 #ifdef MOAB_HAVE_PNETCDF
00086         if( isParallel )
00087             success = NCFUNC( open )( myPcomm->proc_config().proc_comm(), file_name, omode, MPI_INFO_NULL, &fileId );
00088         else
00089             success = NCFUNC( open )( MPI_COMM_SELF, file_name, omode, MPI_INFO_NULL, &fileId );
00090 #else
00091         // This is a regular netcdf file, open in write mode
00092         success = NCFUNC( open )( file_name, omode, &fileId );
00093 #endif
00094         if( success ) MB_SET_ERR( MB_FAILURE, "Trouble opening file " << file_name << " for appending" );
00095     }
00096     else
00097     {  // Case when the file is new, will be overwritten, most likely
00098         int cmode = overwrite ? NC_CLOBBER : NC_NOCLOBBER;
00099 #ifdef MOAB_HAVE_PNETCDF
00100         if( isParallel )
00101             success = NCFUNC( create )( myPcomm->proc_config().proc_comm(), file_name, cmode, MPI_INFO_NULL, &fileId );
00102         else
00103             success = NCFUNC( create )( MPI_COMM_SELF, file_name, cmode, MPI_INFO_NULL, &fileId );
00104 #else
00105         // This is a regular netcdf file
00106         success = NCFUNC( create )( file_name, cmode, &fileId );
00107 #endif
00108         if( success ) MB_SET_ERR( MB_FAILURE, "Trouble creating file " << file_name << " for writing" );
00109     }
00110 
00111     if( NULL != myHelper ) delete myHelper;
00112 
00113     // Get appropriate helper instance for WriteNC class based on some info in the file set
00114     myHelper = NCWriteHelper::get_nc_helper( this, fileId, options, *file_set );
00115     if( NULL == myHelper ) { MB_SET_ERR( MB_FAILURE, "Failed to get NCWriteHelper class instance" ); }
00116 
00117     rval = myHelper->collect_mesh_info();MB_CHK_SET_ERR( rval, "Trouble collecting mesh information" );
00118 
00119     rval = myHelper->collect_variable_data( var_names, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble collecting variable data" );
00120 
00121     rval = myHelper->init_file( var_names, desired_names, append );MB_CHK_SET_ERR( rval, "Trouble initializing file" );
00122 
00123     rval = myHelper->write_values( var_names, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble writing values to file" );
00124 
00125     success = NCFUNC( close )( fileId );
00126     if( success ) MB_SET_ERR( MB_FAILURE, "Trouble closing file" );
00127 
00128     return MB_SUCCESS;
00129 }
00130 
00131 ErrorCode WriteNC::parse_options( const FileOptions& opts, std::vector< std::string >& var_names,
00132                                   std::vector< std::string >& desired_names, std::vector< int >& tstep_nums,
00133                                   std::vector< double >& tstep_vals )
00134 {
00135     int tmpval;
00136     if( MB_SUCCESS == opts.get_int_option( "DEBUG_IO", 1, tmpval ) )
00137     {
00138         dbgOut.set_verbosity( tmpval );
00139         dbgOut.set_prefix( "NCWrite" );
00140     }
00141 
00142     ErrorCode rval = opts.get_strs_option( "VARIABLE", var_names );
00143     if( MB_TYPE_OUT_OF_RANGE == rval )
00144         noVars = true;
00145     else
00146         noVars = false;
00147 
00148     rval = opts.get_strs_option( "RENAME", desired_names );
00149     if( MB_ENTITY_NOT_FOUND == rval )
00150     {
00151         if( !noVars )
00152         {
00153             desired_names.resize( var_names.size() );
00154             std::copy( var_names.begin(), var_names.end(), desired_names.begin() );
00155         }
00156     }
00157     // Either way
00158     assert( desired_names.size() == var_names.size() );
00159 
00160     opts.get_ints_option( "TIMESTEP", tstep_nums );
00161     opts.get_reals_option( "TIMEVAL", tstep_vals );
00162     rval = opts.get_null_option( "NOMESH" );
00163     if( MB_SUCCESS == rval ) noMesh = true;
00164 
00165     rval = opts.get_null_option( "APPEND" );
00166     if( MB_SUCCESS == rval ) append = true;
00167 
00168     if( 2 <= dbgOut.get_verbosity() )
00169     {
00170         if( !var_names.empty() )
00171         {
00172             std::cerr << "Variables requested: ";
00173             for( unsigned int i = 0; i < var_names.size(); i++ )
00174                 std::cerr << var_names[i];
00175             std::cerr << std::endl;
00176         }
00177         if( !tstep_nums.empty() )
00178         {
00179             std::cerr << "Timesteps requested: ";
00180             for( unsigned int i = 0; i < tstep_nums.size(); i++ )
00181                 std::cerr << tstep_nums[i];
00182             std::cerr << std::endl;
00183         }
00184         if( !tstep_vals.empty() )
00185         {
00186             std::cerr << "Time vals requested: ";
00187             for( unsigned int i = 0; i < tstep_vals.size(); i++ )
00188                 std::cerr << tstep_vals[i];
00189             std::cerr << std::endl;
00190         }
00191     }
00192 
00193 // FIXME: copied from ReadNC, may need revise
00194 #ifdef MOAB_HAVE_MPI
00195     isParallel = ( opts.match_option( "PARALLEL", "WRITE_PART" ) != MB_ENTITY_NOT_FOUND );
00196 
00197     if( !isParallel )
00198         // Return success here, since rval still has _NOT_FOUND from not finding option
00199         // in this case, myPcomm will be NULL, so it can never be used; always check for isParallel
00200         // before any use for myPcomm
00201         return MB_SUCCESS;
00202 
00203     int pcomm_no = 0;
00204     rval         = opts.get_int_option( "PARALLEL_COMM", pcomm_no );
00205     if( MB_TYPE_OUT_OF_RANGE == rval ) { MB_SET_ERR( rval, "Invalid value for PARALLEL_COMM option" ); }
00206 
00207     myPcomm = ParallelComm::get_pcomm( mbImpl, pcomm_no );
00208     if( 0 == myPcomm ) { myPcomm = new ParallelComm( mbImpl, MPI_COMM_WORLD ); }
00209 
00210 #ifndef MOAB_HAVE_PNETCDF
00211     const int procs = myPcomm->proc_config().proc_size();
00212     if( procs > 1 )
00213     {
00214         MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Attempt to launch NC writer in parallel without pnetcdf support" );
00215     }
00216 #endif
00217 
00218     const int rank = myPcomm->proc_config().proc_rank();
00219     dbgOut.set_rank( rank );
00220 #endif
00221 
00222     return MB_SUCCESS;
00223 }
00224 
00225 // This is the inverse process to create conventional tags
00226 // Will look at <pargal_source>/src/core/fileinfo.cpp, init dim, vars, atts
00227 ErrorCode WriteNC::process_conventional_tags( EntityHandle fileSet )
00228 {
00229     ErrorCode rval;
00230 
00231     // Start copy
00232     Tag dimNamesTag      = 0;
00233     std::string tag_name = "__DIM_NAMES";
00234     const void* data     = NULL;
00235     int dimNamesSz       = 0;
00236     rval                 = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, dimNamesTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00237     rval = mbImpl->tag_get_by_ptr( dimNamesTag, &fileSet, 1, &data, &dimNamesSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00238     const char* p = static_cast< const char* >( data );
00239     dbgOut.tprintf( 1, "__DIM_NAMES tag has string length %d\n", dimNamesSz );
00240 
00241     std::size_t start = 0;
00242 
00243     Tag dimLensTag = 0;
00244     tag_name       = "__DIM_LENS";
00245     data           = NULL;
00246     int dimLensSz  = 0;
00247     rval           = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, dimLensTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00248     rval = mbImpl->tag_get_by_ptr( dimLensTag, &fileSet, 1, &data, &dimLensSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00249     const int* int_p = static_cast< const int* >( data );
00250     dbgOut.tprintf( 1, "__DIM_LENS tag has %d values\n", dimLensSz );
00251 
00252     int idxDim = 0;
00253     // Dim names are separated by '\0' in the string of __DIM_NAMES tag
00254     for( std::size_t i = 0; i != static_cast< std::size_t >( dimNamesSz ); i++ )
00255     {
00256         if( p[i] == '\0' )
00257         {
00258             std::string dim_name( &p[start], i - start );
00259             int len = int_p[idxDim];
00260             dimNames.push_back( dim_name );
00261             dimLens.push_back( len );
00262             dbgOut.tprintf( 2, "Dimension %s has length %d\n", dim_name.c_str(), len );
00263             // FIXME: Need info from moab to set unlimited dimension
00264             // Currently assume each file has the same number of time dimensions
00265             /*if ((dim_name == "time") || (dim_name == "Time"))
00266               insert(dim_name, *(new pcdim(dim_name, len * m_file_names.size(), true)));
00267             else
00268               insert(dim_name, *(new pcdim(dim_name, len)));*/
00269             start = i + 1;
00270             idxDim++;
00271         }
00272     }
00273 
00274     Tag meshTypeTag = 0;
00275     tag_name        = "__MESH_TYPE";
00276     data            = NULL;
00277     int meshTypeSz  = 0;
00278     rval            = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, meshTypeTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00279     rval = mbImpl->tag_get_by_ptr( meshTypeTag, &fileSet, 1, &data, &meshTypeSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00280     p         = static_cast< const char* >( data );
00281     grid_type = std::string( &p[0], meshTypeSz );
00282     dbgOut.tprintf( 2, "Mesh type: %s\n", grid_type.c_str() );
00283 
00284     // Read <__VAR_NAMES_LOCATIONS> tag
00285     Tag varNamesLocsTag = 0;
00286     tag_name            = "__VAR_NAMES_LOCATIONS";
00287     data                = NULL;
00288     int varNamesLocsSz  = 0;
00289     rval                = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, varNamesLocsTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00290     rval = mbImpl->tag_get_by_ptr( varNamesLocsTag, &fileSet, 1, &data, &varNamesLocsSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00291     int_p = static_cast< const int* >( data );
00292     std::vector< int > varNamesLocs( varNamesLocsSz );
00293     std::copy( int_p, int_p + varNamesLocsSz, varNamesLocs.begin() );
00294 
00295     Tag varNamesTag = 0;
00296     tag_name        = "__VAR_NAMES";
00297     rval            = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, varNamesTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00298     data           = NULL;
00299     int varNamesSz = 0;
00300     rval           = mbImpl->tag_get_by_ptr( varNamesTag, &fileSet, 1, &data, &varNamesSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00301     dbgOut.tprintf( 2, "__VAR_NAMES tag has string length %d\n", varNamesSz );
00302     p = static_cast< const char* >( data );
00303 
00304     start      = 0;
00305     int idxVar = 0;
00306     int sz;
00307     // Var names are separated by '\0' in the string of __VAR_NAMES tag
00308     for( std::size_t i = 0; i != static_cast< std::size_t >( varNamesSz ); i++ )
00309     {
00310         if( p[i] == '\0' )
00311         {
00312             std::string var_name( &p[start], i - start );
00313 
00314             dbgOut.tprintf( 2, "var name: %s index %d \n", var_name.c_str(), idxVar );
00315             // Process var name:
00316             // This will create/initiate map; we will populate variableDataStruct with info about
00317             // dims, tags, etc reference & is important; otherwise variableDataStruct will go out of
00318             // scope, and deleted :(
00319             VarData& variableDataStruct = varInfo[var_name];
00320             variableDataStruct.varName  = var_name;
00321             variableDataStruct.entLoc   = varNamesLocs[idxVar];
00322 
00323             dbgOut.tprintf( 2, "at var name %s varInfo size %d \n", var_name.c_str(), (int)varInfo.size() );
00324 
00325             sz                    = 0;
00326             Tag dims_tag          = 0;
00327             std::string dim_names = "__" + var_name + "_DIMS";
00328             rval = mbImpl->tag_get_handle( dim_names.c_str(), 0, MB_TYPE_OPAQUE, dims_tag, MB_TAG_ANY );
00329             if( MB_SUCCESS != rval )
00330             {
00331                 if( MB_TAG_NOT_FOUND == rval )
00332                 {
00333                     dbgOut.tprintf( 2, "tag : %s not found, continue \n", dim_names.c_str() );
00334                     start = i + 1;
00335                     idxVar++;
00336                     continue;
00337                 }
00338                 MB_SET_ERR( rval, "Trouble getting conventional tag " << dim_names );
00339             }
00340             rval = mbImpl->tag_get_length( dims_tag, sz );MB_CHK_SET_ERR( rval, "Trouble getting size of dimensions for variable " << var_name );
00341             sz /= sizeof( Tag );  // The type is MB_TYPE_OPAQUE, but it is a list of tags, so we
00342                                   // need to divide by the size of Tag
00343             // sz is used for number of dimension tags in this list
00344             dbgOut.tprintf( 2, "var name: %s has %d dimensions \n", var_name.c_str(), sz );
00345 
00346             variableDataStruct.varDims.resize( sz );
00347             const void* ptr = NULL;
00348             rval            = mbImpl->tag_get_by_ptr( dims_tag, &fileSet, 1, &ptr );
00349 
00350             const Tag* ptags = static_cast< const moab::Tag* >( ptr );
00351             for( std::size_t j = 0; j != static_cast< std::size_t >( sz ); j++ )
00352             {
00353                 std::string dim_name;
00354                 rval = mbImpl->tag_get_name( ptags[j], dim_name );MB_CHK_SET_ERR( rval, "Trouble getting dimension of variable " << var_name );
00355                 dbgOut.tprintf( 2, "var name: %s has %s as dimension \n", var_name.c_str(), dim_name.c_str() );
00356                 std::vector< std::string >::iterator vit = std::find( dimNames.begin(), dimNames.end(), dim_name );
00357                 if( vit == dimNames.end() )
00358                     MB_SET_ERR( MB_FAILURE, "Dimension " << dim_name << " not found for variable " << var_name );
00359                 variableDataStruct.varDims[j] = (int)( vit - dimNames.begin() );  // Will be used for writing
00360                 // This will have to change to actual file dimension, for writing
00361             }
00362 
00363             // Attributes for this variable
00364             std::stringstream ssTagName;
00365             ssTagName << "__" << var_name << "_ATTRIBS";
00366             tag_name      = ssTagName.str();
00367             Tag varAttTag = 0;
00368             rval =
00369                 mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, varAttTag, MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00370             const void* varAttPtr = NULL;
00371             int varAttSz          = 0;
00372             rval                  = mbImpl->tag_get_by_ptr( varAttTag, &fileSet, 1, &varAttPtr, &varAttSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00373             if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag retrieved for variable %s\n", tag_name.c_str() );
00374 
00375             std::string attribString( (char*)varAttPtr, (char*)varAttPtr + varAttSz );
00376             if( attribString == "NO_ATTRIBS" )
00377             {
00378                 // This variable has no attributes
00379                 variableDataStruct.numAtts = 0;
00380             }
00381             else if( attribString == "DUMMY_VAR" )
00382             {
00383                 // This variable is a dummy coordinate variable
00384                 variableDataStruct.numAtts = 0;
00385                 dummyVarNames.insert( variableDataStruct.varName );
00386             }
00387             else
00388             {
00389                 ssTagName << "_LEN";
00390                 tag_name         = ssTagName.str();
00391                 Tag varAttLenTag = 0;
00392                 rval = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, varAttLenTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00393                 int varAttLenSz = 0;
00394                 rval            = mbImpl->tag_get_length( varAttLenTag, varAttLenSz );MB_CHK_SET_ERR( rval, "Trouble getting length of conventional tag " << tag_name );
00395                 std::vector< int > varAttLen( varAttLenSz );
00396                 rval = mbImpl->tag_get_data( varAttLenTag, &fileSet, 1, &varAttLen[0] );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00397 
00398                 rval = process_concatenated_attribute( varAttPtr, varAttSz, varAttLen, variableDataStruct.varAtts );MB_CHK_SET_ERR( rval, "Trouble processing attributes of variable " << var_name );
00399 
00400                 if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag metadata for variable %s\n", tag_name.c_str() );
00401             }
00402             // End attribute
00403 
00404             start = i + 1;
00405             idxVar++;
00406         }  // if (p[i] == '\0')
00407     }
00408 
00409     // Global attributes
00410     tag_name         = "__GLOBAL_ATTRIBS";
00411     Tag globalAttTag = 0;
00412     rval = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, globalAttTag, MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00413     std::vector< int > gattLen;
00414 
00415     const void* gattptr = NULL;
00416     int globalAttSz     = 0;
00417     rval                = mbImpl->tag_get_by_ptr( globalAttTag, &fileSet, 1, &gattptr, &globalAttSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00418 
00419     if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag value retrieved for %s size %d\n", tag_name.c_str(), globalAttSz );
00420 
00421     // <__GLOBAL_ATTRIBS_LEN>
00422     tag_name            = "__GLOBAL_ATTRIBS_LEN";
00423     Tag globalAttLenTag = 0;
00424 
00425     rval = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, globalAttLenTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
00426     int sizeGAtt = 0;
00427     rval         = mbImpl->tag_get_length( globalAttLenTag, sizeGAtt );MB_CHK_SET_ERR( rval, "Trouble getting length of conventional tag " << tag_name );
00428     gattLen.resize( sizeGAtt );
00429     rval = mbImpl->tag_get_data( globalAttLenTag, &fileSet, 1, &gattLen[0] );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00430     if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag retrieved for variable %s\n", tag_name.c_str() );
00431 
00432     rval = process_concatenated_attribute( gattptr, globalAttSz, gattLen, globalAtts );MB_CHK_SET_ERR( rval, "Trouble processing global attributes" );
00433 
00434     return MB_SUCCESS;
00435 }
00436 
00437 // Reverse process from create_attrib_string
00438 ErrorCode WriteNC::process_concatenated_attribute( const void* attPtr, int attSz, std::vector< int >& attLen,
00439                                                    std::map< std::string, AttData >& attributes )
00440 {
00441     std::size_t start       = 0;
00442     std::size_t att_counter = 0;
00443     std::string concatString( (char*)attPtr, (char*)attPtr + attSz );
00444 
00445     for( std::size_t i = 0; i != (size_t)attSz; i++ )
00446     {
00447         if( concatString[i] == '\0' )
00448         {
00449             std::string att_name( &concatString[start], i - start );
00450             start = i + 1;
00451             while( concatString[i] != ';' )
00452                 ++i;
00453             std::string data_type( &concatString[start], i - start );
00454             ++i;
00455             start = i;
00456             i     = attLen[att_counter];
00457             if( concatString[i] != ';' ) MB_SET_ERR( MB_FAILURE, "Error parsing attributes" );
00458 
00459             std::string data_val( &concatString[start], i - start );
00460             start = i + 1;
00461 
00462             AttData& attrib = attributes[att_name];
00463             attrib.attValue = data_val;
00464             attrib.attLen   = data_val.size();
00465 
00466             if( data_type == "char" )
00467                 attrib.attDataType = NC_CHAR;
00468             else if( data_type == "double" )
00469                 attrib.attDataType = NC_DOUBLE;
00470             else if( data_type == "float" )
00471                 attrib.attDataType = NC_FLOAT;
00472             else if( data_type == "int" )
00473                 attrib.attDataType = NC_INT;
00474             else if( data_type == "short" )
00475                 attrib.attDataType = NC_SHORT;
00476 
00477             ++att_counter;
00478             dbgOut.tprintf( 2, "       Process attribute %s with value %s \n", att_name.c_str(), data_val.c_str() );
00479         }
00480     }
00481 
00482     return MB_SUCCESS;
00483 }
00484 
00485 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines