MOAB: Mesh Oriented datABase  (version 5.2.1)
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     { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Attempt to launch NC writer in parallel without pnetcdf support" ); }
00214 #endif
00215 
00216     const int rank = myPcomm->proc_config().proc_rank();
00217     dbgOut.set_rank( rank );
00218 #endif
00219 
00220     return MB_SUCCESS;
00221 }
00222 
00223 // This is the inverse process to create conventional tags
00224 // Will look at <pargal_source>/src/core/fileinfo.cpp, init dim, vars, atts
00225 ErrorCode WriteNC::process_conventional_tags( EntityHandle fileSet )
00226 {
00227     ErrorCode rval;
00228 
00229     // Start copy
00230     Tag dimNamesTag      = 0;
00231     std::string tag_name = "__DIM_NAMES";
00232     const void* data     = NULL;
00233     int dimNamesSz       = 0;
00234     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 );
00235     rval = mbImpl->tag_get_by_ptr( dimNamesTag, &fileSet, 1, &data, &dimNamesSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00236     const char* p = static_cast< const char* >( data );
00237     dbgOut.tprintf( 1, "__DIM_NAMES tag has string length %d\n", dimNamesSz );
00238 
00239     std::size_t start = 0;
00240 
00241     Tag dimLensTag = 0;
00242     tag_name       = "__DIM_LENS";
00243     data           = NULL;
00244     int dimLensSz  = 0;
00245     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 );
00246     rval = mbImpl->tag_get_by_ptr( dimLensTag, &fileSet, 1, &data, &dimLensSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00247     const int* int_p = static_cast< const int* >( data );
00248     dbgOut.tprintf( 1, "__DIM_LENS tag has %d values\n", dimLensSz );
00249 
00250     int idxDim = 0;
00251     // Dim names are separated by '\0' in the string of __DIM_NAMES tag
00252     for( std::size_t i = 0; i != static_cast< std::size_t >( dimNamesSz ); i++ )
00253     {
00254         if( p[i] == '\0' )
00255         {
00256             std::string dim_name( &p[start], i - start );
00257             int len = int_p[idxDim];
00258             dimNames.push_back( dim_name );
00259             dimLens.push_back( len );
00260             dbgOut.tprintf( 2, "Dimension %s has length %d\n", dim_name.c_str(), len );
00261             // FIXME: Need info from moab to set unlimited dimension
00262             // Currently assume each file has the same number of time dimensions
00263             /*if ((dim_name == "time") || (dim_name == "Time"))
00264               insert(dim_name, *(new pcdim(dim_name, len * m_file_names.size(), true)));
00265             else
00266               insert(dim_name, *(new pcdim(dim_name, len)));*/
00267             start = i + 1;
00268             idxDim++;
00269         }
00270     }
00271 
00272     Tag meshTypeTag = 0;
00273     tag_name        = "__MESH_TYPE";
00274     data            = NULL;
00275     int meshTypeSz  = 0;
00276     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 );
00277     rval = mbImpl->tag_get_by_ptr( meshTypeTag, &fileSet, 1, &data, &meshTypeSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00278     p         = static_cast< const char* >( data );
00279     grid_type = std::string( &p[0], meshTypeSz );
00280     dbgOut.tprintf( 2, "Mesh type: %s\n", grid_type.c_str() );
00281 
00282     // Read <__VAR_NAMES_LOCATIONS> tag
00283     Tag varNamesLocsTag = 0;
00284     tag_name            = "__VAR_NAMES_LOCATIONS";
00285     data                = NULL;
00286     int varNamesLocsSz  = 0;
00287     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 );
00288     rval = mbImpl->tag_get_by_ptr( varNamesLocsTag, &fileSet, 1, &data, &varNamesLocsSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00289     int_p = static_cast< const int* >( data );
00290     std::vector< int > varNamesLocs( varNamesLocsSz );
00291     std::copy( int_p, int_p + varNamesLocsSz, varNamesLocs.begin() );
00292 
00293     Tag varNamesTag = 0;
00294     tag_name        = "__VAR_NAMES";
00295     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 );
00296     data           = NULL;
00297     int varNamesSz = 0;
00298     rval           = mbImpl->tag_get_by_ptr( varNamesTag, &fileSet, 1, &data, &varNamesSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00299     dbgOut.tprintf( 2, "__VAR_NAMES tag has string length %d\n", varNamesSz );
00300     p = static_cast< const char* >( data );
00301 
00302     start      = 0;
00303     int idxVar = 0;
00304     int sz;
00305     // Var names are separated by '\0' in the string of __VAR_NAMES tag
00306     for( std::size_t i = 0; i != static_cast< std::size_t >( varNamesSz ); i++ )
00307     {
00308         if( p[i] == '\0' )
00309         {
00310             std::string var_name( &p[start], i - start );
00311 
00312             dbgOut.tprintf( 2, "var name: %s index %d \n", var_name.c_str(), idxVar );
00313             // Process var name:
00314             // This will create/initiate map; we will populate variableDataStruct with info about
00315             // dims, tags, etc reference & is important; otherwise variableDataStruct will go out of
00316             // scope, and deleted :(
00317             VarData& variableDataStruct = varInfo[var_name];
00318             variableDataStruct.varName  = var_name;
00319             variableDataStruct.entLoc   = varNamesLocs[idxVar];
00320 
00321             dbgOut.tprintf( 2, "at var name %s varInfo size %d \n", var_name.c_str(), (int)varInfo.size() );
00322 
00323             sz                    = 0;
00324             Tag dims_tag          = 0;
00325             std::string dim_names = "__" + var_name + "_DIMS";
00326             rval = mbImpl->tag_get_handle( dim_names.c_str(), 0, MB_TYPE_OPAQUE, dims_tag, MB_TAG_ANY );
00327             if( MB_SUCCESS != rval )
00328             {
00329                 if( MB_TAG_NOT_FOUND == rval )
00330                 {
00331                     dbgOut.tprintf( 2, "tag : %s not found, continue \n", dim_names.c_str() );
00332                     start = i + 1;
00333                     idxVar++;
00334                     continue;
00335                 }
00336                 MB_SET_ERR( rval, "Trouble getting conventional tag " << dim_names );
00337             }
00338             rval = mbImpl->tag_get_length( dims_tag, sz );MB_CHK_SET_ERR( rval, "Trouble getting size of dimensions for variable " << var_name );
00339             sz /= sizeof( Tag );  // The type is MB_TYPE_OPAQUE, but it is a list of tags, so we
00340                                   // need to divide by the size of Tag
00341             // sz is used for number of dimension tags in this list
00342             dbgOut.tprintf( 2, "var name: %s has %d dimensions \n", var_name.c_str(), sz );
00343 
00344             variableDataStruct.varDims.resize( sz );
00345             const void* ptr = NULL;
00346             rval            = mbImpl->tag_get_by_ptr( dims_tag, &fileSet, 1, &ptr );
00347 
00348             const Tag* ptags = static_cast< const moab::Tag* >( ptr );
00349             for( std::size_t j = 0; j != static_cast< std::size_t >( sz ); j++ )
00350             {
00351                 std::string dim_name;
00352                 rval = mbImpl->tag_get_name( ptags[j], dim_name );MB_CHK_SET_ERR( rval, "Trouble getting dimension of variable " << var_name );
00353                 dbgOut.tprintf( 2, "var name: %s has %s as dimension \n", var_name.c_str(), dim_name.c_str() );
00354                 std::vector< std::string >::iterator vit = std::find( dimNames.begin(), dimNames.end(), dim_name );
00355                 if( vit == dimNames.end() )
00356                     MB_SET_ERR( MB_FAILURE, "Dimension " << dim_name << " not found for variable " << var_name );
00357                 variableDataStruct.varDims[j] = (int)( vit - dimNames.begin() );  // Will be used for writing
00358                 // This will have to change to actual file dimension, for writing
00359             }
00360 
00361             // Attributes for this variable
00362             std::stringstream ssTagName;
00363             ssTagName << "__" << var_name << "_ATTRIBS";
00364             tag_name      = ssTagName.str();
00365             Tag varAttTag = 0;
00366             rval =
00367                 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 );
00368             const void* varAttPtr = NULL;
00369             int varAttSz          = 0;
00370             rval                  = mbImpl->tag_get_by_ptr( varAttTag, &fileSet, 1, &varAttPtr, &varAttSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00371             if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag retrieved for variable %s\n", tag_name.c_str() );
00372 
00373             std::string attribString( (char*)varAttPtr, (char*)varAttPtr + varAttSz );
00374             if( attribString == "NO_ATTRIBS" )
00375             {
00376                 // This variable has no attributes
00377                 variableDataStruct.numAtts = 0;
00378             }
00379             else if( attribString == "DUMMY_VAR" )
00380             {
00381                 // This variable is a dummy coordinate variable
00382                 variableDataStruct.numAtts = 0;
00383                 dummyVarNames.insert( variableDataStruct.varName );
00384             }
00385             else
00386             {
00387                 ssTagName << "_LEN";
00388                 tag_name         = ssTagName.str();
00389                 Tag varAttLenTag = 0;
00390                 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 );
00391                 int varAttLenSz = 0;
00392                 rval            = mbImpl->tag_get_length( varAttLenTag, varAttLenSz );MB_CHK_SET_ERR( rval, "Trouble getting length of conventional tag " << tag_name );
00393                 std::vector< int > varAttLen( varAttLenSz );
00394                 rval = mbImpl->tag_get_data( varAttLenTag, &fileSet, 1, &varAttLen[0] );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00395 
00396                 rval = process_concatenated_attribute( varAttPtr, varAttSz, varAttLen, variableDataStruct.varAtts );MB_CHK_SET_ERR( rval, "Trouble processing attributes of variable " << var_name );
00397 
00398                 if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag metadata for variable %s\n", tag_name.c_str() );
00399             }
00400             // End attribute
00401 
00402             start = i + 1;
00403             idxVar++;
00404         }  // if (p[i] == '\0')
00405     }
00406 
00407     // Global attributes
00408     tag_name         = "__GLOBAL_ATTRIBS";
00409     Tag globalAttTag = 0;
00410     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 );
00411     std::vector< int > gattLen;
00412 
00413     const void* gattptr = NULL;
00414     int globalAttSz     = 0;
00415     rval                = mbImpl->tag_get_by_ptr( globalAttTag, &fileSet, 1, &gattptr, &globalAttSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00416 
00417     if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag value retrieved for %s size %d\n", tag_name.c_str(), globalAttSz );
00418 
00419     // <__GLOBAL_ATTRIBS_LEN>
00420     tag_name            = "__GLOBAL_ATTRIBS_LEN";
00421     Tag globalAttLenTag = 0;
00422 
00423     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 );
00424     int sizeGAtt = 0;
00425     rval         = mbImpl->tag_get_length( globalAttLenTag, sizeGAtt );MB_CHK_SET_ERR( rval, "Trouble getting length of conventional tag " << tag_name );
00426     gattLen.resize( sizeGAtt );
00427     rval = mbImpl->tag_get_data( globalAttLenTag, &fileSet, 1, &gattLen[0] );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
00428     if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag retrieved for variable %s\n", tag_name.c_str() );
00429 
00430     rval = process_concatenated_attribute( gattptr, globalAttSz, gattLen, globalAtts );MB_CHK_SET_ERR( rval, "Trouble processing global attributes" );
00431 
00432     return MB_SUCCESS;
00433 }
00434 
00435 // Reverse process from create_attrib_string
00436 ErrorCode WriteNC::process_concatenated_attribute( const void* attPtr, int attSz, std::vector< int >& attLen,
00437                                                    std::map< std::string, AttData >& attributes )
00438 {
00439     std::size_t start       = 0;
00440     std::size_t att_counter = 0;
00441     std::string concatString( (char*)attPtr, (char*)attPtr + attSz );
00442 
00443     for( std::size_t i = 0; i != (size_t)attSz; i++ )
00444     {
00445         if( concatString[i] == '\0' )
00446         {
00447             std::string att_name( &concatString[start], i - start );
00448             start = i + 1;
00449             while( concatString[i] != ';' )
00450                 ++i;
00451             std::string data_type( &concatString[start], i - start );
00452             ++i;
00453             start = i;
00454             i     = attLen[att_counter];
00455             if( concatString[i] != ';' ) MB_SET_ERR( MB_FAILURE, "Error parsing attributes" );
00456 
00457             std::string data_val( &concatString[start], i - start );
00458             start = i + 1;
00459 
00460             AttData& attrib = attributes[att_name];
00461             attrib.attValue = data_val;
00462             attrib.attLen   = data_val.size();
00463 
00464             if( data_type == "char" )
00465                 attrib.attDataType = NC_CHAR;
00466             else if( data_type == "double" )
00467                 attrib.attDataType = NC_DOUBLE;
00468             else if( data_type == "float" )
00469                 attrib.attDataType = NC_FLOAT;
00470             else if( data_type == "int" )
00471                 attrib.attDataType = NC_INT;
00472             else if( data_type == "short" )
00473                 attrib.attDataType = NC_SHORT;
00474 
00475             ++att_counter;
00476             dbgOut.tprintf( 2, "       Process attribute %s with value %s \n", att_name.c_str(), data_val.c_str() );
00477         }
00478     }
00479 
00480     return MB_SUCCESS;
00481 }
00482 
00483 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines