void
WriteStringsT( hid_t iParent,
               const std::string &iAttrName,
               size_t iNumStrings,
               const StringT *iStrings )
{
    // Validate
    ABCA_ASSERT( iNumStrings > 0, "Degenerate num strings in WriteStringsT" );
    ABCA_ASSERT( iStrings, "Degenerate strings buffer in WriteStringsT" );

    // Compact the strings.
    std::vector<CharT> charBuffer;
    CompactStrings( iStrings, iNumStrings, charBuffer );

    // Create the dataspace.
    size_t len = charBuffer.size();
    assert( len >= iNumStrings );
    Dimensions dims( len );
    HDimensions hdims( dims );
    hid_t dspaceId = H5Screate_simple( hdims.rank(), hdims.rootPtr(), NULL );
    DspaceCloser dspaceCloser( dspaceId );

    ABCA_ASSERT( dspaceId >= 0,
                 "WriteStringsT() Failed in dataspace constructor" );

    // Create the attribute.
    WriteDataToAttr( iParent, dspaceId, iAttrName,
                     GetFileDtype<CharT>(), GetNativeDtype<CharT>(),
                     ( const void * )&charBuffer.front() );

    // That's it!
}
Beispiel #2
0
//-*****************************************************************************
// Get the dimensions directly off of the dataspace on the dataset
// This isn't suitable for string and wstring
void
ReadDataSetDimensions( hid_t iParent,
                       const std::string &iName,
                       hsize_t iExtent,
                       Dimensions &oDims )
{
    // Open the data set.
    hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT );
    ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName );
    DsetCloser dsetCloser( dsetId );

    // Read the data space.
    hid_t dspaceId = H5Dget_space( dsetId );
    ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: "
                 << iName );
    DspaceCloser dspaceCloser( dspaceId );

    H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId );
    if ( dspaceClass == H5S_SIMPLE )
    {
        // Get the dimensions
        int rank = H5Sget_simple_extent_ndims( dspaceId );
        ABCA_ASSERT( rank == 1, "H5Sget_simple_extent_ndims() must be 1." );

        hsize_t hdim = 0;
        rank = H5Sget_simple_extent_dims( dspaceId, &hdim, NULL );
        oDims.setRank(1);
        oDims[0] = hdim / iExtent;
    }
    else
    {
        oDims.setRank(1);
        oDims[0] = 0;
    }
}
Beispiel #3
0
//-*****************************************************************************
void
WriteScalar( hid_t iParent,
             const std::string &iAttrName,
             hid_t iFileType,
             hid_t iNativeType,
             const void *iData )
{
    hid_t dspaceId = H5Screate( H5S_SCALAR );
    DspaceCloser dspaceCloser( dspaceId );

    WriteDataToAttr( iParent, dspaceId, iAttrName, iFileType, iNativeType,
                     iData );
}
Beispiel #4
0
void
ReadStringsT( hid_t iParent,
              const std::string &iAttrName,
              size_t iNumStrings,
              StringT *oStrings )
{
    ABCA_ASSERT( iParent >= 0, "Invalid parent in ReadStringsT" );

    // Open the attribute.
    hid_t attrId = H5Aopen( iParent, iAttrName.c_str(), H5P_DEFAULT );
    ABCA_ASSERT( attrId >= 0,
                 "Couldn't open attribute named: " << iAttrName );
    AttrCloser attrCloser( attrId );

    // Checking code.
    {
        hid_t attrFtype = H5Aget_type( attrId );
        DtypeCloser dtypeCloser( attrFtype );

        hid_t nativeDtype = GetNativeDtype<CharT>();
        ABCA_ASSERT( H5Tget_class( attrFtype ) ==
                     H5Tget_class( nativeDtype ) &&

                     H5Tget_sign( attrFtype ) ==
                     H5Tget_sign( nativeDtype ),

                     "Invalid datatype for stringT" );
    }

    hid_t attrSpace = H5Aget_space( attrId );
    ABCA_ASSERT( attrSpace >= 0,
                 "Couldn't get dataspace for attribute: " << iAttrName );
    DspaceCloser dspaceCloser( attrSpace );

    hssize_t numPoints = H5Sget_simple_extent_npoints( attrSpace );
    ABCA_ASSERT( numPoints > 0,
                 "Degenerate string dimensions in ReadStringsT" );

    // Create temporary char storage buffer.
    std::vector<CharT> charStorage( ( size_t )( 1 + numPoints ),
                                    ( CharT )0 );

    // Read into it.
    herr_t status = H5Aread( attrId, GetNativeDtype<CharT>(),
                             ( void * )&charStorage.front() );
    ABCA_ASSERT( status >= 0, "Couldn't read from attribute: " << iAttrName );

    // Extract 'em.
    ExtractStrings( oStrings, ( const CharT * )&charStorage.front(),
                    1 + numPoints, iNumStrings );
}
Beispiel #5
0
//-*****************************************************************************
void
ReadTimeSamples( hid_t iParent,
                 std::vector <  AbcA::TimeSamplingPtr > & oTimeSamples )
{
    oTimeSamples.clear();
    // add the intrinsic default sampling
    AbcA::TimeSamplingPtr ts( new AbcA::TimeSampling() );
    oTimeSamples.push_back( ts );

    uint32_t i = 1;
    AbcA::TimeSamplingType tst;
    std::string tstname = "1";

    // keep trying to read till we can't find anymore
    while ( ReadTimeSamplingType( iParent, tstname, tst ) )
    {
        // try to open the time samples attribute
        std::string timeName = tstname + ".time";
        hid_t aid = H5Aopen( iParent, timeName.c_str(), H5P_DEFAULT );
        ABCA_ASSERT( aid >= 0,
                     "Couldn't open time samples named: " << timeName );
        AttrCloser attrCloser( aid );

        // figure out how big it is
        hid_t sid = H5Aget_space( aid );
        ABCA_ASSERT( sid >= 0,
                     "Couldn't get dataspace for time samples: " << timeName );
        DspaceCloser dspaceCloser( sid );

        hssize_t numPoints = H5Sget_simple_extent_npoints( sid );
        ABCA_ASSERT( numPoints > 0, "No time samples data: " << timeName );
        std::vector < chrono_t > times(numPoints);

        // do the read
        herr_t status = H5Aread( aid, H5T_NATIVE_DOUBLE, &(times.front()) );
        ABCA_ASSERT( status >= 0, "Can't read time samples: " << timeName );

        // create the TimeSampling and add it to our vector
        ts.reset( new AbcA::TimeSampling(tst, times) );
        oTimeSamples.push_back( ts );

        // increment to try and read the next one
        i++;
        std::stringstream strm;
        strm << i;
        tstname = strm.str();
    }
}
Beispiel #6
0
void
ReadStringT<std::string,char>( hid_t iParent,
                               const std::string &iAttrName,
                               std::string &oString )
{
    ABCA_ASSERT( iParent >= 0, "Invalid parent in ReadStringT" );

    // Open the attribute.
    hid_t attrId = H5Aopen( iParent, iAttrName.c_str(), H5P_DEFAULT );
    ABCA_ASSERT( attrId >= 0,
                 "Couldn't open attribute named: " << iAttrName );
    AttrCloser attrCloser( attrId );

    // Checking code.
    hid_t attrFtype = H5Aget_type( attrId );
    DtypeCloser dtypeCloser( attrFtype );

    ssize_t numChars = H5Tget_size( attrFtype );
    ABCA_ASSERT( numChars >= 0,
                 "ReadStringT() H5Aget_size() failed" );

    // Read and check space
    {
        hid_t attrSpace = H5Aget_space( attrId );
        ABCA_ASSERT( attrSpace >= 0,
                     "Couldn't get dataspace for attribute: " << iAttrName );
        DspaceCloser dspaceCloser( attrSpace );
        
        H5S_class_t attrSpaceClass = H5Sget_simple_extent_type( attrSpace );
        ABCA_ASSERT( attrSpaceClass == H5S_SCALAR,
                     "Tried to read non-scalar attribute: " << iAttrName
                     << " as scalar" );
    }

    // Create temporary char storage buffer.
    std::vector<char> charStorage( ( size_t )( 1 + numChars ),
                                   ( char )0 );

    // Read into it.
    herr_t status = H5Aread( attrId, attrFtype,
                             ( void * )&charStorage.front() );
    ABCA_ASSERT( status >= 0, "Couldn't read from attribute: " << iAttrName );

    // Return it.
    oString = ( const char * )&charStorage.front();
}
Beispiel #7
0
//-*****************************************************************************
void
WriteSmallArray( hid_t iParent,
                 const std::string &iAttrName,
                 hid_t iFileType,
                 hid_t iNativeType,
                 size_t iNumVals,
                 const void *iData )
{
    Dimensions dims( iNumVals );
    HDimensions hdims( dims );
    size_t npoints = hdims.numPoints();
    ABCA_ASSERT( npoints > 0,
                  "Cannot create degenerate dataspace" );

    hid_t dspaceId = H5Screate_simple( hdims.rank(), hdims.rootPtr(), NULL );
    DspaceCloser dspaceCloser( dspaceId );

    WriteDataToAttr( iParent, dspaceId, iAttrName, iFileType, iNativeType,
                     iData );
}
Beispiel #8
0
//-*****************************************************************************
void
WriteReferences( hid_t iParent,
                 const std::string& iRefName,
                 size_t iNumRefs,
                 const void *iRefs )
{
    hsize_t dims[1];
    dims[0] = iNumRefs;

    hid_t dspaceId = H5Screate_simple( 1, dims, NULL );
    DspaceCloser dspaceCloser( dspaceId );

    hid_t dsetId = H5Dcreate2( iParent, iRefName.c_str(), H5T_STD_REF_OBJ,
                               dspaceId, H5P_DEFAULT, H5P_DEFAULT,H5P_DEFAULT);
    DsetCloser dsetCloser( dsetId );

    herr_t status = H5Dwrite( dsetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL,
                       H5P_DEFAULT, iRefs);

    ABCA_ASSERT( status >= 0, "Couldn't write reference: " << iRefName );
}
void
WriteStringT<std::string,char>( hid_t iParent,
                                const std::string &iAttrName,
                                const std::string &iString )
{
    // Verify that no NULL characters have been hidden in the string.
    const char NullChar = ( char )0;
    ABCA_ASSERT( iString.find( NullChar ) == std::string::npos,
                 "Illegal NULL character found in string in WriteStringT" );

    size_t len = iString.length();
    if ( len < 1 ) { len = 1; }

    hid_t dtypeId = H5Tcopy( H5T_C_S1 );
    DtypeCloser dtypeCloser( dtypeId );
    H5Tset_size( dtypeId, len );

    hid_t dspaceId = H5Screate( H5S_SCALAR );
    DspaceCloser dspaceCloser( dspaceId );

    WriteDataToAttr( iParent, dspaceId, iAttrName,
                     dtypeId, dtypeId, ( const void * )iString.c_str() );
}
void
WriteStringT( hid_t iParent,
              const std::string &iAttrName,
              const StringT &iString )
{
    // Verify that no NULL characters have been hidden in the string.
    CharT NullChar = ( CharT )0;
    ABCA_ASSERT( iString.find( NullChar ) == StringT::npos,
                 "Illegal NULL character found in string in WriteStringT" );

    // Create the dataspace.
    size_t len = iString.length();
    Dimensions dims( len + 1 );
    HDimensions hdims( dims );
    size_t npoints = hdims.numPoints();
    ABCA_ASSERT( npoints > 0,
                 "Cannot create degenerate dataspace" );

    hid_t dspaceId = H5Screate_simple( hdims.rank(), hdims.rootPtr(), NULL );
    DspaceCloser dspaceCloser( dspaceId );

    // Get the data.
    const CharT *data;
    if ( len == 0 )
    {
        data = &NullChar;
    }
    else
    {
        data = iString.c_str();
    }

    // Write into it.
    WriteDataToAttr( iParent, dspaceId, iAttrName,
                     GetFileDtype<CharT>(), GetNativeDtype<CharT>(),
                     ( const void * )data );
}
WrittenArraySampleIDPtr
WriteStringArrayT( WrittenArraySampleMap &iMap,
                   hid_t iGroup,
                   const std::string &iName,
                   const AbcA::ArraySample &iSamp,
                   const AbcA::ArraySample::Key &iKey,
                   int iCompressionLevel )
{
    // because strings are packed together, always write out the dimensions
    Dimensions dims = iSamp.getDimensions();
    ABCA_ASSERT( dims.rank() > 0,
        "String type can not have a rank-0 array sample" );
    std::string dimsName = iName + ".dims";
    WriteDimensions( iGroup, dimsName, dims );

    // See whether or not we've already stored this.
    WrittenArraySampleIDPtr writeID = iMap.find( iKey );
    if ( writeID )
    {
        CopyWrittenArray( iGroup, iName, writeID );
        return writeID;
    }

    // Okay, need to actually store it.
    // It will be a dataset with an internal attribute for storing
    // the hash id.

    bool hasData = dims.numPoints() > 0;
    hid_t dspaceId = -1;
    Dimensions wdims; // Used to store the "fake" dimensions.
    std::vector<CharT> charBuffer;

    // Get the dimensions, validate sample size.
    if ( hasData )
    {
        size_t extent = iSamp.getDataType().getExtent();
        size_t numStrings = dims.numPoints() * extent;
        ABCA_ASSERT( dims.rank() > 0 && numStrings > 0,
                     "Degenerate array sample in WriteStringArrayT" );

        // Get the data out of the array sample.
        const StringT *strings =
            reinterpret_cast<const StringT *>( iSamp.getData() );
        ABCA_ASSERT( strings,
                     "Degenerate strings in WriteStringArrayT" );

        // Compact the strings in the string array.
        CompactStrings( strings, numStrings, charBuffer );

        // Create the dataspace.
        size_t len = charBuffer.size();
        assert( len >= numStrings );
        wdims = Dimensions( len );
        HDimensions hdims( wdims );

        dspaceId = H5Screate_simple( hdims.rank(),
                                     hdims.rootPtr(), NULL );
    }
    else
    {
        dspaceId = H5Screate( H5S_NULL );
    }

    ABCA_ASSERT( dspaceId >= 0,
                 "WriteStringsT() Failed in dataspace constructor" );
    DspaceCloser dspaceCloser( dspaceId );

    hid_t dsetId = -1;
    if ( iCompressionLevel >= 0 && hasData )
    {
        // Make a compression plist
        hid_t zipPlist = DsetGzipCreatePlist( wdims,
            iCompressionLevel > 9 ? 9 : iCompressionLevel );
        PlistCloser plistCloser( zipPlist );

        //std::cout << "Creating compressed data set named: "
        //          << iName << " in group named: " << iGroup.name()
        //          << std::endl;

        // Make the dataset.
        dsetId = H5Dcreate2( iGroup, iName.c_str(), GetFileDtype<CharT>(),
                             dspaceId, H5P_DEFAULT, zipPlist, H5P_DEFAULT );
    }
    else
    {
        //std::cout << "Creating uncompressed data set named: "
        //          << iName << " in group named: " << iGroup.name()
        //          << std::endl;
        dsetId = H5Dcreate2( iGroup, iName.c_str(), GetFileDtype<CharT>(),
                             dspaceId, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
    }
    DsetCloser dsetCloser(dsetId);

    ABCA_ASSERT( dsetId >= 0,
                 "WriteArray() Failed in dataset constructor" );

    // Write the data.
    if ( hasData )
    {
        H5Dwrite( dsetId, GetNativeDtype<CharT>(), H5S_ALL,
                  H5S_ALL, H5P_DEFAULT, &charBuffer.front() );
    }

    // Write the key
    WriteKey( dsetId, "key", iKey );

    writeID.reset( new WrittenArraySampleID( iKey, dsetId ) );

    iMap.store( writeID );

    // Return the reference.
    return writeID;
}
Beispiel #12
0
//-*****************************************************************************
WrittenArraySampleIDPtr
WriteArray( WrittenArraySampleMap &iMap,
            hid_t iGroup,
            const std::string &iName,
            const AbcA::ArraySample &iSamp,
            const AbcA::ArraySample::Key &iKey,
            hid_t iFileType,
            hid_t iNativeType,
            int iCompressionLevel )
{

    // Dispatch to string writing utils.
    const AbcA::DataType &dataType = iSamp.getDataType();
    if ( dataType.getPod() == kStringPOD )
    {
        return WriteStringArray( iMap, iGroup, iName, iSamp, iKey,
                                 iCompressionLevel );
    }
    else if ( dataType.getPod() == kWstringPOD )
    {
        return WriteWstringArray( iMap, iGroup, iName, iSamp, iKey,
                                  iCompressionLevel );
    }

    // write the dimensions as necessary
    Dimensions dims = iSamp.getDimensions();
    size_t rank = dims.rank();

    ABCA_ASSERT( rank > 0, "Cannot have a rank-0 array sample" );

    // rank 1 is the most common case, and we can easily infer it's size
    // from the dataspace for non-strings, so don't bother writing it out
    if (rank > 1)
    {
        std::string dimsName = iName + ".dims";
        WriteDimensions( iGroup, dimsName, dims );
    }

    // See whether or not we've already stored this.
    WrittenArraySampleIDPtr writeID = iMap.find( iKey );
    if ( writeID )
    {
        CopyWrittenArray( iGroup, iName, writeID );
        return writeID;
    }

    // Okay, need to actually store it.
    // It will be a dataset with an internal attribute for storing
    // the hash id.

    bool hasData = dims.numPoints() > 0;

    hid_t dspaceId = -1;
    if ( hasData )
    {
        hsize_t hdim = dims.numPoints() * dataType.getExtent();
        dspaceId = H5Screate_simple( 1, &hdim, NULL );
    }
    else
    {
        dspaceId = H5Screate( H5S_NULL );
    }

    ABCA_ASSERT( dspaceId >= 0,
                 "WriteArray() Failed in dataspace construction" );
    DspaceCloser dspaceCloser( dspaceId );

    hid_t dsetId = -1;
    if ( iCompressionLevel >= 0 && hasData )
    {
        // Make a compression plist
        hid_t zipPlist = DsetGzipCreatePlist( dims,
            iCompressionLevel > 9 ? 9 : iCompressionLevel );
        PlistCloser plistCloser( zipPlist );

        // Make the dataset.
        dsetId = H5Dcreate2( iGroup, iName.c_str(), iFileType, dspaceId,
                             H5P_DEFAULT, zipPlist, H5P_DEFAULT );
    }
    else
    {
        dsetId = H5Dcreate2( iGroup, iName.c_str(),
                             iFileType, dspaceId,
                             H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
    }
    DsetCloser dsetCloser(dsetId);

    ABCA_ASSERT( dsetId >= 0,
                 "WriteArray() Failed in dataset constructor" );

    // Write the data.
    if ( hasData )
    {
        H5Dwrite( dsetId, iNativeType, H5S_ALL, H5S_ALL, H5P_DEFAULT,
                  iSamp.getData() );
    }

    // Write the array sample key.
    WriteKey( dsetId, "key", iKey );

    writeID.reset( new WrittenArraySampleID( iKey, dsetId ) );
    iMap.store( writeID );

    // Return the reference.
    return writeID;
}
Beispiel #13
0
static AbcA::ArraySamplePtr
ReadStringArrayT( AbcA::ReadArraySampleCachePtr iCache,
                  hid_t iParent,
                  const std::string &iName,
                  const AbcA::DataType &iDataType )
{
    assert( iDataType.getExtent() > 0 );

    // Open the data set.
    hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT );
    ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName );
    DsetCloser dsetCloser( dsetId );

    // Read the digest, if there's a cache.
    AbcA::ArraySample::Key key;
    bool foundDigest = ReadKey( dsetId, "key", key );

    // If we found a digest and there's a cache, see
    // if we're in there, and return it if so.
    if ( foundDigest && iCache )
    {
        AbcA::ReadArraySampleID found = iCache->find( key );
        if ( found )
        {
            AbcA::ArraySamplePtr ret = found.getSample();
            assert( ret );
            if ( ret->getDataType() != iDataType )
            {
                ABCA_THROW( "ERROR: Read data type for dset: " << iName
                            << ": " << ret->getDataType()
                            << " does not match expected data type: "
                            << iDataType );
            }

            // Got it!
            return ret;
        }
    }

    // Okay, we haven't found it in a cache.

    // Read the data type.
    // Checking code.
    {
        hid_t dsetFtype = H5Dget_type( dsetId );
        DtypeCloser dtypeCloser( dsetFtype );

        hid_t nativeDtype = GetNativeDtype<CharT>();
        ABCA_ASSERT( H5Tget_class( dsetFtype ) ==
                     H5Tget_class( nativeDtype ) &&

                     H5Tget_sign( dsetFtype ) ==
                     H5Tget_sign( nativeDtype )

                     // CJH They can now be different
                     // sizes, because wchar_t is sometimes 16-bit,
                     // but we always store 32 bit.
                     // && H5Tget_size( dsetFtype ) ==
                     //H5Tget_size( nativeDtype ),

                     , "Invalid datatype for stringT" );
    }

    // String array datatypes require a "dimensions" to be stored
    // externally, since the strings themselves are stored in a compacted
    // array of rank 1.
    // This is an attribute called "dims" that lives in the dset itself.
    Dimensions realDims;
    ReadDimensions( dsetId, "dims", realDims );
    ABCA_ASSERT( realDims.rank() > 0,
                 "Degenerate rank in Dataset read" );

    // Read the data space.
    hid_t dspaceId = H5Dget_space( dsetId );
    ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: "
                 << iName );
    DspaceCloser dspaceCloser( dspaceId );

    AbcA::ArraySamplePtr ret;

    H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId );

    if ( dspaceClass == H5S_SIMPLE )
    {
        ABCA_ASSERT( realDims.numPoints() > 0,
                     "Degenerate dims in Dataset read" );
        size_t totalNumStrings = realDims.numPoints() * iDataType.getExtent();

        // Get the dimensions
        Dimensions dims;
        int rank = H5Sget_simple_extent_ndims( dspaceId );
        ABCA_ASSERT( rank == realDims.rank(),
                     "H5Sget_simple_extent_ndims() failed." );

        HDimensions hdims;
        hdims.setRank( rank );
        rank = H5Sget_simple_extent_dims( dspaceId, hdims.rootPtr(), NULL );
        ABCA_ASSERT( rank == hdims.rank(),
                     "H5Sget_simple_extent_dims() "
                     "found inconsistent ranks."
                     << std::endl
                     << "Expecting rank: " << hdims.rank()
                     << " instead was: " << rank );
        
        dims = hdims;
        ABCA_ASSERT( dims.numPoints() > 0,
                     "Degenerate dims in Dataset read" );
        

        // Create temporary char storage buffer.
        size_t totalNumChars = dims.numPoints() + 1;
        std::vector<CharT> charStorage( totalNumChars, ( CharT )0 );
        
        // Read into it.
        herr_t status = H5Dread( dsetId, GetNativeDtype<CharT>(),
                                 H5S_ALL, H5S_ALL, H5P_DEFAULT,
                                 ( void * )&charStorage.front() );
        ABCA_ASSERT( status >= 0,
                     "Could not read string array from data set. Weird." );

        // Make an appropriately dimensionalized (and manageable)
        // array of strings using the ArraySamples.
        ret = AbcA::AllocateArraySample( iDataType,
                                         realDims );
        StringT *strings = reinterpret_cast<StringT*>(
            const_cast<void*>( ret->getData() ) );
        assert( strings != NULL );

        // This part is hard. We have to go through the one dimensional
        // array extracting each string.
        ExtractStrings<StringT,CharT>( strings,
                                       ( const CharT * )&charStorage.front(),
                                       totalNumChars,
                                       totalNumStrings );
    }
    else if ( dspaceClass == H5S_NULL )
    {
        // Num points should be zero here.
        ABCA_ASSERT( realDims.numPoints() == 0,
                     "Expecting zero points in dimensions" );

        ret = AbcA::AllocateArraySample( iDataType, realDims );
    }
    else
    {
        ABCA_THROW( "Unexpected scalar dataspace encountered." );
    }

    // Store if there is a cache.
    if ( foundDigest && iCache )
    {
        AbcA::ReadArraySampleID stored = iCache->store( key, ret );
        if ( stored )
        {
            return stored.getSample();
        }
    }

    // Otherwise, just leave! ArraySamplePtr returned by AllocateArraySample
    // already has fancy-dan deleter built in.
    // I REALLY LOVE SMART PTRS.
    return ret;
}
Beispiel #14
0
//-*****************************************************************************
void
ReadArray( void * iIntoLocation,
           hid_t iParent,
           const std::string &iName,
           const AbcA::DataType &iDataType,
           hid_t iType )
{
    // Dispatch string stuff.
    if ( iDataType.getPod() == kStringPOD )
    {
        return ReadStringArray( iIntoLocation, iParent, iName, iDataType );
    }
    else if ( iDataType.getPod() == kWstringPOD )
    {
        return ReadWstringArray( iIntoLocation, iParent, iName, iDataType );
    }
    assert( iDataType.getPod() != kStringPOD &&
            iDataType.getPod() != kWstringPOD );

    // Open the data set.
    hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT );
    ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName );
    DsetCloser dsetCloser( dsetId );

    // Read the data space.
    hid_t dspaceId = H5Dget_space( dsetId );
    ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: "
                 << iName );
    DspaceCloser dspaceCloser( dspaceId );

    // Read the data type.
    hid_t dtypeId = H5Dget_type( dsetId );
    ABCA_ASSERT( dtypeId >= 0, "Could not get datatype for dataSet: "
                 << iName );
    DtypeCloser dtypeCloser( dtypeId );

    H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId );
    if ( dspaceClass == H5S_SIMPLE )
    {
        // Get the dimensions
        int rank = H5Sget_simple_extent_ndims( dspaceId );
        ABCA_ASSERT( rank == 1,
                     "H5Sget_simple_extent_ndims() must be 1." );

        hsize_t hdim = 0;

        rank = H5Sget_simple_extent_dims( dspaceId, &hdim, NULL );

        ABCA_ASSERT( hdim > 0,
                     "Degenerate dims in Dataset read" );

        // And... read into it.
        herr_t status = H5Dread( dsetId, iType,
                                 H5S_ALL, H5S_ALL, H5P_DEFAULT,
                                 iIntoLocation );

        ABCA_ASSERT( status >= 0, "H5Dread() failed." );
    }
    else if ( dspaceClass != H5S_NULL )
    {
        ABCA_THROW( "Unexpected scalar dataspace encountered." );
    }
}
Beispiel #15
0
//-*****************************************************************************
AbcA::ArraySamplePtr
ReadArray( AbcA::ReadArraySampleCachePtr iCache,
           hid_t iParent,
           const std::string &iName,
           const AbcA::DataType &iDataType,
           hid_t iFileType,
           hid_t iNativeType )
{
    // Dispatch string stuff.
    if ( iDataType.getPod() == kStringPOD )
    {
        return ReadStringArray( iCache, iParent, iName, iDataType );
    }
    else if ( iDataType.getPod() == kWstringPOD )
    {
        return ReadWstringArray( iCache, iParent, iName, iDataType );
    }
    assert( iDataType.getPod() != kStringPOD &&
            iDataType.getPod() != kWstringPOD );

    // Open the data set.
    hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT );
    ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName );
    DsetCloser dsetCloser( dsetId );

    // Read the data space.
    hid_t dspaceId = H5Dget_space( dsetId );
    ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: "
                 << iName );
    DspaceCloser dspaceCloser( dspaceId );

    AbcA::ArraySample::Key key;
    bool foundDigest = false;

    // if we are caching, get the key and see if it is being used
    if ( iCache )
    {
        key.origPOD = iDataType.getPod();
        key.readPOD = key.origPOD;

        key.numBytes = Util::PODNumBytes( key.readPOD ) *
            H5Sget_simple_extent_npoints( dspaceId );

        foundDigest = ReadKey( dsetId, "key", key );

        AbcA::ReadArraySampleID found = iCache->find( key );

        if ( found )
        {
            AbcA::ArraySamplePtr ret = found.getSample();
            assert( ret );
            if ( ret->getDataType().getPod() != iDataType.getPod() )
            {
                ABCA_THROW( "ERROR: Read data type for dset: " << iName
                            << ": " << ret->getDataType()
                            << " does not match expected data type: "
                            << iDataType );
            }

            // Got it!
            return ret;
        }
    }

    // Okay, we haven't found it in a cache.

    // Read the data type.
    hid_t dtypeId = H5Dget_type( dsetId );
    ABCA_ASSERT( dtypeId >= 0, "Could not get datatype for dataSet: "
                 << iName );
    DtypeCloser dtypeCloser( dtypeId );

    ABCA_ASSERT( EquivalentDatatypes( iFileType, dtypeId ),
                 "File DataType clash for array dataset: "
                 << iName );

    AbcA::ArraySamplePtr ret;

    H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId );
    if ( dspaceClass == H5S_SIMPLE )
    {
        // Get the dimensions
        int rank = H5Sget_simple_extent_ndims( dspaceId );
        ABCA_ASSERT( rank == 1,
                     "H5Sget_simple_extent_ndims() must be 1." );

        hsize_t hdim = 0;

        rank = H5Sget_simple_extent_dims( dspaceId, &hdim, NULL );

        Dimensions dims;
        std::string dimName = iName + ".dims";
        if ( H5Aexists( iParent, dimName.c_str() ) )
        {
            ReadDimensions( iParent, dimName, dims );
        }
        else
        {
            dims.setRank(1);
            dims[0] = hdim / iDataType.getExtent();
        }

        ABCA_ASSERT( dims.numPoints() > 0,
                     "Degenerate dims in Dataset read" );

        // Create a buffer into which we shall read.
        ret = AbcA::AllocateArraySample( iDataType, dims );
        assert( ret->getData() );

        // And... read into it.
        herr_t status = H5Dread( dsetId, iNativeType,
                                 H5S_ALL, H5S_ALL, H5P_DEFAULT,
                                 const_cast<void*>( ret->getData() ) );

        ABCA_ASSERT( status >= 0, "H5Dread() failed." );
    }
    else if ( dspaceClass == H5S_NULL )
    {
        Dimensions dims;
        std::string dimName = iName + ".dims";
        if ( H5Aexists( iParent, dimName.c_str() ) )
        {
            ReadDimensions( iParent, dimName, dims );
            ABCA_ASSERT( dims.rank() > 0,
                         "Degenerate rank in Dataset read" );
            // Num points should be zero here.
            ABCA_ASSERT( dims.numPoints() == 0,
                         "Expecting zero points in dimensions" );
        }
        else
        {
            dims.setRank(1);
            dims[0] = 0;
        }

        ret = AbcA::AllocateArraySample( iDataType, dims );
    }
    else
    {
        ABCA_THROW( "Unexpected scalar dataspace encountered." );
    }

    // Store if there is a cache.
    if ( foundDigest && iCache )
    {
        AbcA::ReadArraySampleID stored = iCache->store( key, ret );
        if ( stored )
        {
            return stored.getSample();
        }
    }

    // Otherwise, just leave! ArraySamplePtr returned by AllocateArraySample
    // already has fancy-dan deleter built in.
    // I REALLY LOVE SMART PTRS.
    return ret;
}
//-*****************************************************************************
ArImpl::ArImpl( const std::string &iFileName,
                AbcA::ReadArraySampleCachePtr iCache,
                const bool iCacheHierarchy )
  : m_fileName( iFileName )
  , m_file( -1 )
  , m_readArraySampleCache( iCache )
{
    // OPEN THE FILE!
    htri_t exi = H5Fis_hdf5( m_fileName.c_str() );
    ABCA_ASSERT( exi == 1, "Nonexistent or not an Alembic file: "
        << m_fileName );

    m_file = H5Fopen( m_fileName.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT );
    ABCA_ASSERT( m_file >= 0,
                 "Could not open file: " << m_fileName );

    // get the version using HDF5 native calls
    int version = -INT_MAX;
    if (H5Aexists(m_file, "abc_version"))
    {
        size_t numRead = 0;
        ReadSmallArray(m_file, "abc_version",  H5T_STD_I32LE, H5T_NATIVE_INT32,
            1, numRead, &version);
    }
    ABCA_ASSERT(version >= -8 && version <= ALEMBIC_HDF5_FILE_VERSION,
        "Unsupported file version detected: " << version);

    // if it isn't there, it's pre 1.0
    int fileVersion = 9999;
    if (H5Aexists( m_file, "abc_release_version" ))
    {
        size_t numRead = 0;
        ReadSmallArray( m_file, "abc_release_version", H5T_STD_I32LE,
            H5T_NATIVE_INT32, 1, numRead, &fileVersion );
    }
    m_archiveVersion = fileVersion;

    HDF5HierarchyReader reader( m_file, m_H5H, iCacheHierarchy );
    H5Node node = m_H5H.createNode( m_file );
    H5Node abcRoot = OpenGroup( node, "ABC" );

    AbcA::MetaData metaData;
    ReadMetaData( abcRoot, ".prop.meta", metaData );
    m_header.reset( new AbcA::ObjectHeader( "ABC", "/", metaData ) );

    m_data.reset( new OrData( m_header, node, m_archiveVersion ) );
    CloseObject( abcRoot );
    ReadTimeSamples( m_file, m_timeSamples );

    if ( H5Aexists( m_file, "abc_max_samples" ) )
    {
        hid_t aid = H5Aopen( m_file, "abc_max_samples", H5P_DEFAULT );

        if ( aid < 0 )
        {
            return;
        }

        AttrCloser attrCloser( aid );

        // figure out how big it is
        hid_t sid = H5Aget_space( aid );

        if ( sid < 0 )
        {
            return;
        }

        DspaceCloser dspaceCloser( sid );

        hssize_t numPoints = H5Sget_simple_extent_npoints( sid );

        if ( numPoints < 1 )
        {
            return;
        }

        m_maxSamples.resize( numPoints );

        // do the read
        H5Aread( aid, H5T_NATIVE_LLONG, &( m_maxSamples.front() ) );

    }
}