module Bindings.HDF5.Datatype ( Datatype , Class(..) , CSet(..) , ByteOrder(..) , Normalization(..) , Pad(..) , StringPad(..) , NativeType(..) , nativeTypeOf , nativeTypeOf1 , module Bindings.HDF5.Datatype ) where import Bindings.HDF5.Raw.H5P import Bindings.HDF5.Raw.H5T import Bindings.HDF5.Core import Bindings.HDF5.Error import Bindings.HDF5.PropertyList.LCPL import Bindings.HDF5.PropertyList.TAPL import Bindings.HDF5.PropertyList.TCPL import qualified Data.ByteString as BS import qualified Data.ByteString.Unsafe as BS import Data.List import Foreign import Foreign.C.Types import Foreign.Ptr.Conventions import Bindings.HDF5.Datatype.Internal -- ieeeF32be = Datatype h5t_IEEE_F32BE -- ieeeF32le = Datatype h5t_IEEE_F32LE -- ieeeF64be = Datatype h5t_IEEE_F64BE -- ieeeF64le = Datatype h5t_IEEE_F64LE -- stdI8be = Datatype h5t_STD_I8BE -- stdI8le = Datatype h5t_STD_I8LE -- stdI16be = Datatype h5t_STD_I16BE -- stdI16le = Datatype h5t_STD_I16LE -- stdI32be = Datatype h5t_STD_I32BE -- stdI32le = Datatype h5t_STD_I32LE -- stdI64be = Datatype h5t_STD_I64BE -- stdI64le = Datatype h5t_STD_I64LE -- stdU8be = Datatype h5t_STD_U8BE -- stdU8le = Datatype h5t_STD_U8LE -- stdU16be = Datatype h5t_STD_U16BE -- stdU16le = Datatype h5t_STD_U16LE -- stdU32be = Datatype h5t_STD_U32BE -- stdU32le = Datatype h5t_STD_U32LE -- stdU64be = Datatype h5t_STD_U64BE -- stdU64le = Datatype h5t_STD_U64LE -- stdB8be = Datatype h5t_STD_B8BE -- stdB8le = Datatype h5t_STD_B8LE -- stdB16be = Datatype h5t_STD_B16BE -- stdB16le = Datatype h5t_STD_B16LE -- stdB32be = Datatype h5t_STD_B32BE -- stdB32le = Datatype h5t_STD_B32LE -- stdB64be = Datatype h5t_STD_B64BE -- stdB64le = Datatype h5t_STD_B64LE -- stdRefObj = Datatype h5t_STD_REF_OBJ -- stdRefDsetreg = Datatype h5t_STD_REF_DSETREG -- unixD32be = Datatype h5t_UNIX_D32BE -- unixD32le = Datatype h5t_UNIX_D32LE -- unixD64be = Datatype h5t_UNIX_D64BE -- unixD64le = Datatype h5t_UNIX_D64LE -- cS1 = Datatype h5t_C_S1 -- fortranS1 = Datatype h5t_FORTRAN_S1 -- intelI8 = Datatype h5t_INTEL_I8 -- intelI16 = Datatype h5t_INTEL_I16 -- intelI32 = Datatype h5t_INTEL_I32 -- intelI64 = Datatype h5t_INTEL_I64 -- intelU8 = Datatype h5t_INTEL_U8 -- intelU16 = Datatype h5t_INTEL_U16 -- intelU32 = Datatype h5t_INTEL_U32 -- intelU64 = Datatype h5t_INTEL_U64 -- intelB8 = Datatype h5t_INTEL_B8 -- intelB16 = Datatype h5t_INTEL_B16 -- intelB32 = Datatype h5t_INTEL_B32 -- intelB64 = Datatype h5t_INTEL_B64 -- intelF32 = Datatype h5t_INTEL_F32 -- intelF64 = Datatype h5t_INTEL_F64 -- alphaI8 = Datatype h5t_ALPHA_I8 -- alphaI16 = Datatype h5t_ALPHA_I16 -- alphaI32 = Datatype h5t_ALPHA_I32 -- alphaI64 = Datatype h5t_ALPHA_I64 -- alphaU8 = Datatype h5t_ALPHA_U8 -- alphaU16 = Datatype h5t_ALPHA_U16 -- alphaU32 = Datatype h5t_ALPHA_U32 -- alphaU64 = Datatype h5t_ALPHA_U64 -- alphaB8 = Datatype h5t_ALPHA_B8 -- alphaB16 = Datatype h5t_ALPHA_B16 -- alphaB32 = Datatype h5t_ALPHA_B32 -- alphaB64 = Datatype h5t_ALPHA_B64 -- alphaF32 = Datatype h5t_ALPHA_F32 -- alphaF64 = Datatype h5t_ALPHA_F64 -- mipsI8 = Datatype h5t_MIPS_I8 -- mipsI16 = Datatype h5t_MIPS_I16 -- mipsI32 = Datatype h5t_MIPS_I32 -- mipsI64 = Datatype h5t_MIPS_I64 -- mipsU8 = Datatype h5t_MIPS_U8 -- mipsU16 = Datatype h5t_MIPS_U16 -- mipsU32 = Datatype h5t_MIPS_U32 -- mipsU64 = Datatype h5t_MIPS_U64 -- mipsB8 = Datatype h5t_MIPS_B8 -- mipsB16 = Datatype h5t_MIPS_B16 -- mipsB32 = Datatype h5t_MIPS_B32 -- mipsB64 = Datatype h5t_MIPS_B64 -- mipsF32 = Datatype h5t_MIPS_F32 -- mipsF64 = Datatype h5t_MIPS_F64 -- vaxF32 = Datatype h5t_VAX_F32 -- vaxF64 = Datatype h5t_VAX_F64 -- * Operations defined on all datatypes createTypeID :: Class -> CSize -> IO Datatype createTypeID cls sz = fmap Datatype $ withErrorCheck $ h5t_create (classCode cls) sz copyTypeID :: Datatype -> IO Datatype copyTypeID (Datatype t) = fmap Datatype $ withErrorCheck $ h5t_copy t closeTypeID :: Datatype -> IO () closeTypeID (Datatype t) = withErrorCheck_ $ h5t_close t typeIDsEqual :: Datatype -> Datatype -> IO Bool typeIDsEqual (Datatype t1) (Datatype t2) = htriToBool $ h5t_equal t1 t2 lockTypeID :: Datatype -> IO () lockTypeID (Datatype t) = withErrorCheck_ $ h5t_lock t commitTypeID :: Location t => t -> BS.ByteString -> Datatype -> Maybe LCPL -> Maybe TCPL -> Maybe TAPL -> IO () commitTypeID loc name typeId lcpl tcpl tapl = withErrorCheck_ $ BS.useAsCString name $ \cname -> h5t_commit2 (hid loc) cname (hid typeId) (maybe h5p_DEFAULT hid lcpl) (maybe h5p_DEFAULT hid tcpl) (maybe h5p_DEFAULT hid tapl) openTypeID :: Location t => t -> BS.ByteString -> Maybe TAPL -> IO Datatype openTypeID loc name tapl = fmap Datatype $ BS.useAsCString name $ \cname -> withErrorCheck $ h5t_open2 (hid loc) cname (maybe h5p_DEFAULT hid tapl) commitTypeIDAnonymously :: Location t => t -> Datatype -> Maybe TCPL -> Maybe TAPL -> IO () commitTypeIDAnonymously loc typeId tcpl tapl = withErrorCheck_ $ h5t_commit_anon (hid loc) (hid typeId) (maybe h5p_DEFAULT hid tcpl) (maybe h5p_DEFAULT hid tapl) getTypeCreationPList :: Datatype -> IO TCPL getTypeCreationPList (Datatype t) = fmap uncheckedFromHId $ withErrorCheck $ h5t_get_create_plist t committedTypeID :: Datatype -> IO Bool committedTypeID (Datatype t) = htriToBool $ h5t_committed t encodeTypeID :: Datatype -> IO BS.ByteString encodeTypeID (Datatype t) = withOutByteString $ \buf bufSz -> withInOut_ bufSz $ \ioBufSz -> withErrorCheck_ $ h5t_encode t buf ioBufSz decodeTypeID :: BS.ByteString -> IO Datatype decodeTypeID bs = fmap Datatype $ BS.unsafeUseAsCString bs $ \buf -> h5t_decode (InArray buf) -- * Operations defined on compound datatypes insertCompoundTypeMember :: Datatype -> BS.ByteString -> CSize -> Datatype -> IO () insertCompoundTypeMember (Datatype parent) name offset (Datatype member) = withErrorCheck_ $ BS.useAsCString name $ \cname -> h5t_insert parent cname offset member packCompoundType :: Datatype -> IO () packCompoundType (Datatype t) = withErrorCheck_ $ h5t_pack t -- * Operations defined on enumeration datatypes -- TODO: figure out good types for these -- createEnumType :: Datatype -> IO Datatype -- createEnumType (Datatype base) = -- fmap Datatype $ -- withErrorCheck $ -- h5t_enum_create base -- h5t_enum_insert -- h5t_enum_nameof -- h5t_enum_valueof -- * Operations defined on variable-length datatypes createVLenType :: Datatype -> IO Datatype createVLenType (Datatype base) = fmap Datatype $ withErrorCheck $ h5t_vlen_create base -- * Operations defined on array datatypes createArrayType :: Datatype -> [HSize] -> IO Datatype createArrayType (Datatype base) dims = fmap Datatype $ withInList (map hSize dims) $ \idims -> withErrorCheck $ h5t_array_create2 base nDims idims where nDims = genericLength dims getArrayTypeNDims :: Datatype -> IO CInt getArrayTypeNDims (Datatype t) = withErrorWhen (< 0) $ h5t_get_array_ndims t getArrayTypeDims :: Datatype -> IO [HSize] getArrayTypeDims (Datatype t) = do nDims <- getArrayTypeNDims (Datatype t) fmap (map HSize . fst) $ withOutList' (fromIntegral nDims) $ \dims -> fmap fromIntegral $ withErrorWhen (< 0) $ h5t_get_array_dims2 t dims -- * Operations defined on opaque datatypes setOpaqueTypeTag :: Datatype -> BS.ByteString -> IO () setOpaqueTypeTag (Datatype t) tag = withErrorCheck_ $ BS.useAsCString tag $ \ctag -> h5t_set_tag t ctag getOpaqueTypeTag :: Datatype -> IO BS.ByteString getOpaqueTypeTag (Datatype t) = do cstr <- withErrorWhen (nullPtr ==) $ h5t_get_tag t BS.unsafePackMallocCString cstr -- * Querying property values getSuperType :: Datatype -> IO Datatype getSuperType (Datatype t) = fmap Datatype $ withErrorCheck $ h5t_get_super t getTypeClass :: Datatype -> IO Class getTypeClass (Datatype t) = fmap classFromCode $ withErrorWhen (\(H5T_class_t c) -> c < 0) $ h5t_get_class t detectTypeClass :: Datatype -> Class -> IO Bool detectTypeClass (Datatype t) cls = htriToBool $ h5t_detect_class t (classCode cls) getTypeSize :: Datatype -> IO CSize getTypeSize (Datatype t) = withErrorWhen (<= 0) $ h5t_get_size t getByteOrder :: Datatype -> IO (Maybe ByteOrder) getByteOrder (Datatype t) = fmap byteOrder $ withErrorCheck $ h5t_get_order t getTypePrecision :: Datatype -> IO CSize getTypePrecision (Datatype t) = withErrorWhen (<= 0) $ h5t_get_precision t getTypeOffset :: Datatype -> IO CInt getTypeOffset (Datatype t) = withErrorWhen (< 0) $ h5t_get_offset t getTypePad :: Datatype -> IO (Pad, Pad) getTypePad (Datatype t) = do (msb, lsb) <- withOut $ \msb -> withOut_ $ \lsb -> withErrorCheck $ h5t_get_pad t msb lsb return (padFromCode msb, padFromCode lsb) getFloatTypeFields :: Datatype -> IO (CSize, CSize, CSize, CSize, CSize) getFloatTypeFields (Datatype t) = do (spos, (epos, (esize, (mpos, msize)))) <- withOut $ \spos -> withOut $ \epos -> withOut $ \esize -> withOut $ \mpos -> withOut_ $ \msize -> withErrorCheck_ $ h5t_get_fields t spos epos esize mpos msize return (spos, epos, esize, mpos, msize) getFloatTypeEBias :: Datatype -> IO CSize getFloatTypeEBias (Datatype t) = withErrorWhen (== 0) (h5t_get_ebias t) getFloatTypeNormalization :: Datatype -> IO (Maybe Normalization) getFloatTypeNormalization (Datatype t) = fmap normalization $ withErrorCheck $ h5t_get_norm t getFloatTypeInternalPad :: Datatype -> IO Pad getFloatTypeInternalPad (Datatype t) = fmap padFromCode $ withErrorCheck $ h5t_get_inpad t getStringPad :: Datatype -> IO StringPad getStringPad (Datatype t) = fmap stringPadFromCode $ withErrorCheck $ h5t_get_strpad t -- type must be enum or compound getTypeNMembers :: Datatype -> IO CInt getTypeNMembers (Datatype t) = withErrorWhen (< 0) $ h5t_get_nmembers t -- type must be enum or compound getMemberName :: Datatype -> CUInt -> IO BS.ByteString getMemberName (Datatype t) i = do cstr <- withErrorWhen (== nullPtr) $ h5t_get_member_name t i bs <- BS.packCString cstr free cstr return bs getMemberIndex :: Datatype -> BS.ByteString -> IO CInt getMemberIndex (Datatype t) bs = withErrorWhen (< 0) $ BS.useAsCString bs $ \name -> h5t_get_member_index t name -- TODO: implement these -- (figure out proper error check for this one, the docs are weird) -- getMemberOffset :: Datatype -> CUInt -> IO CSize -- getMemberOffset (Datatype t) i = -- withErrorWhen (< 0) -- getMemberClass -- getMemberType -- getMemberValue -- getCharSet -- isVariableString -- getNativeType -- * Setting property values setTypeSize :: Datatype -> CSize -> IO () setTypeSize (Datatype t) sz = withErrorCheck_ $ h5t_set_size t sz setByteOrder :: Datatype -> Maybe ByteOrder -> IO () setByteOrder (Datatype t) order = withErrorCheck_ $ h5t_set_order t (byteOrderCode order) setTypePrecision :: Datatype -> CSize -> IO () setTypePrecision (Datatype t) prec = withErrorCheck_ $ h5t_set_precision t prec setTypeOffset :: Datatype -> CSize -> IO () setTypeOffset (Datatype t) offset = withErrorCheck_ $ h5t_set_offset t offset setTypePad :: Datatype -> Pad -> Pad -> IO () setTypePad (Datatype t) msb lsb = withErrorCheck_ $ h5t_set_pad t (padCode msb) (padCode lsb) setFloatTypeFields :: Datatype -> CSize -> CSize -> CSize -> CSize -> CSize -> IO () setFloatTypeFields (Datatype t) spos epos esize mpos msize = withErrorCheck_ $ h5t_set_fields t spos epos esize mpos msize setFloatTypeEBias :: Datatype -> CSize -> IO () setFloatTypeEBias (Datatype t) ebias = withErrorCheck_ $ h5t_set_ebias t ebias -- TODO: implement these -- setFloatTypeNormalization :: -- setFloatTypeInternalPad :: -- setStringPad -- * Type conversion database -- registerTypeConversion -- unregisterTypeConversion -- findTypeConversion -- isCompilerConversion -- convertData