예제 #1
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 );
}
예제 #2
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();
}
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() );
}
예제 #4
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;
}
예제 #5
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." );
    }
}
예제 #6
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;
}