/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the LICENSE file, which can be found at the root of the source code       *
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef H5Oshared_H
#define H5Oshared_H

static inline void *
H5O_SHARED_DECODE(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags, unsigned *ioflags, size_t p_size,
                  const uint8_t *p)
{
    void *ret_value = NULL; 

    
    FUNC_ENTER_PACKAGE

#ifndef H5O_SHARED_TYPE
#error "Need to define H5O_SHARED_TYPE macro!"
#endif 
#ifndef H5O_SHARED_DECODE
#error "Need to define H5O_SHARED_DECODE macro!"
#endif 
#ifndef H5O_SHARED_DECODE_REAL
#error "Need to define H5O_SHARED_DECODE_REAL macro!"
#endif 

    
    if (mesg_flags & H5O_MSG_FLAG_SHARED) {
        
        if (NULL == (ret_value = H5O__shared_decode(f, open_oh, ioflags, p_size, p, H5O_SHARED_TYPE)))
            HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message");

            
#ifdef H5_STRICT_FORMAT_CHECKS
        if (*ioflags & H5O_DECODEIO_DIRTY)
            HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, NULL, "unable to mark shared message dirty");
#else  
        *ioflags &= ~H5O_DECODEIO_DIRTY;
#endif 
    }  
    else {
        
        if (NULL == (ret_value = H5O_SHARED_DECODE_REAL(f, open_oh, mesg_flags, ioflags, p_size, p)))
            HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode native message");
    } 

done:
    FUNC_LEAVE_NOAPI(ret_value)
} 

static inline herr_t
H5O_SHARED_ENCODE(H5F_t *f, bool disable_shared, size_t H5_ATTR_UNUSED p_size, uint8_t *p, const void *_mesg)
{
    const H5O_shared_t *sh_mesg =
        (const H5O_shared_t *)_mesg; 
    herr_t ret_value = SUCCEED;      

    
    FUNC_ENTER_PACKAGE

#ifndef H5O_SHARED_TYPE
#error "Need to define H5O_SHARED_TYPE macro!"
#endif 
#ifndef H5O_SHARED_ENCODE
#error "Need to define H5O_SHARED_ENCODE macro!"
#endif 
#ifndef H5O_SHARED_ENCODE_REAL
#error "Need to define H5O_SHARED_ENCODE_REAL macro!"
#endif 

    
    assert(sh_mesg->type == H5O_SHARE_TYPE_UNSHARED || sh_mesg->msg_type_id == H5O_SHARED_TYPE->id);

    
    if (H5O_IS_STORED_SHARED(sh_mesg->type) && !disable_shared) {
        
        if (H5O__shared_encode(f, p, sh_mesg) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode shared message");
    } 
    else {
        
        if (H5O_SHARED_ENCODE_REAL(f, p, _mesg) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode native message");
    } 

done:
    FUNC_LEAVE_NOAPI(ret_value)
} 

static inline size_t
H5O_SHARED_SIZE(const H5F_t *f, bool disable_shared, const void *_mesg)
{
    const H5O_shared_t *sh_mesg =
        (const H5O_shared_t *)_mesg; 
    size_t ret_value = 0;            

    
    FUNC_ENTER_PACKAGE

#ifndef H5O_SHARED_TYPE
#error "Need to define H5O_SHARED_TYPE macro!"
#endif 
#ifndef H5O_SHARED_SIZE
#error "Need to define H5O_SHARED_SIZE macro!"
#endif 
#ifndef H5O_SHARED_SIZE_REAL
#error "Need to define H5O_SHARED_SIZE_REAL macro!"
#endif 

    
    if (H5O_IS_STORED_SHARED(sh_mesg->type) && !disable_shared) {
        
        if (0 == (ret_value = H5O__shared_size(f, sh_mesg)))
            HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, 0, "unable to retrieve encoded size of shared message");
    } 
    else {
        
        if (0 == (ret_value = H5O_SHARED_SIZE_REAL(f, _mesg)))
            HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, 0, "unable to retrieve encoded size of native message");
    } 

done:
    FUNC_LEAVE_NOAPI(ret_value)
} 

static inline herr_t
H5O_SHARED_DELETE(H5F_t *f, H5O_t *open_oh, void *_mesg)
{
    H5O_shared_t *sh_mesg   = (H5O_shared_t *)_mesg; 
    herr_t        ret_value = SUCCEED;               

    
    FUNC_ENTER_PACKAGE

#ifndef H5O_SHARED_TYPE
#error "Need to define H5O_SHARED_TYPE macro!"
#endif 
#ifndef H5O_SHARED_DELETE
#error "Need to define H5O_SHARED_DELETE macro!"
#endif 

    
    if (H5O_IS_TRACKED_SHARED(sh_mesg->type)) {
        
        if (H5O__shared_delete(f, open_oh, H5O_SHARED_TYPE, sh_mesg) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement ref count for shared message");
    } 
#ifdef H5O_SHARED_DELETE_REAL
    else {
        
        if (H5O_SHARED_DELETE_REAL(f, open_oh, _mesg) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement ref count for native message");
    }  
#endif 

done:
    FUNC_LEAVE_NOAPI(ret_value)
} 

static inline herr_t
H5O_SHARED_LINK(H5F_t *f, H5O_t *open_oh, void *_mesg)
{
    H5O_shared_t *sh_mesg   = (H5O_shared_t *)_mesg; 
    herr_t        ret_value = SUCCEED;               

    
    FUNC_ENTER_PACKAGE

#ifndef H5O_SHARED_TYPE
#error "Need to define H5O_SHARED_TYPE macro!"
#endif 
#ifndef H5O_SHARED_LINK
#error "Need to define H5O_SHARED_LINK macro!"
#endif 

    
    if (H5O_IS_TRACKED_SHARED(sh_mesg->type)) {
        
        if (H5O__shared_link(f, open_oh, H5O_SHARED_TYPE, sh_mesg) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "unable to increment ref count for shared message");
    } 
#ifdef H5O_SHARED_LINK_REAL
    else {
        
        if (H5O_SHARED_LINK_REAL(f, open_oh, _mesg) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "unable to increment ref count for native message");
    }  
#endif 

done:
    FUNC_LEAVE_NOAPI(ret_value)
} 

static inline void *
H5O_SHARED_COPY_FILE(H5F_t *file_src, void *_native_src, H5F_t *file_dst, bool *recompute_size,
                     unsigned *mesg_flags, H5O_copy_t *cpy_info, void *udata)
{
    void *dst_mesg  = NULL; 
    void *ret_value = NULL; 

    
    FUNC_ENTER_PACKAGE

#ifndef H5O_SHARED_TYPE
#error "Need to define H5O_SHARED_TYPE macro!"
#endif 
#ifndef H5O_SHARED_COPY_FILE
#error "Need to define H5O_SHARED_COPY_FILE macro!"
#endif 

#ifdef H5O_SHARED_COPY_FILE_REAL
    
    if (NULL == (dst_mesg = H5O_SHARED_COPY_FILE_REAL(file_src, H5O_SHARED_TYPE, _native_src, file_dst,
                                                      recompute_size, cpy_info, udata)))
        HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy native message to another file");
#else  
    
    if (NULL == (dst_mesg = (H5O_SHARED_TYPE->copy)(_native_src, NULL)))
        HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy native message");
#endif 

    
    memset(dst_mesg, 0, sizeof(H5O_shared_t));

    
    if (H5O__shared_copy_file(file_src, file_dst, H5O_SHARED_TYPE, _native_src, dst_mesg, recompute_size,
                              mesg_flags, cpy_info, udata) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "unable to determine if message should be shared");

    
    ret_value = dst_mesg;

done:
    if (!ret_value)
        if (dst_mesg)
            H5O_msg_free(H5O_SHARED_TYPE->id, dst_mesg);

    FUNC_LEAVE_NOAPI(ret_value)
} 

static inline herr_t
H5O_SHARED_POST_COPY_FILE(const H5O_loc_t H5_ATTR_NDEBUG_UNUSED *oloc_src, const void *mesg_src,
                          H5O_loc_t *oloc_dst, void *mesg_dst, unsigned *mesg_flags, H5O_copy_t *cpy_info)
{
    const H5O_shared_t *shared_src =
        (const H5O_shared_t *)mesg_src;                  
    H5O_shared_t *shared_dst = (H5O_shared_t *)mesg_dst; 
    herr_t        ret_value  = SUCCEED;                  

    
    FUNC_ENTER_PACKAGE

    assert(oloc_src->file);
    assert(oloc_dst->file);
    assert(mesg_src);
    assert(mesg_dst);
    assert(cpy_info);

#ifndef H5O_SHARED_TYPE
#error "Need to define H5O_SHARED_TYPE macro!"
#endif 
#ifndef H5O_SHARED_POST_COPY_FILE
#error "Need to define H5O_SHARED_POST_COPY_FILE macro!"
#endif 

#ifdef H5O_SHARED_POST_COPY_FILE_REAL
    
    if (H5O_SHARED_POST_COPY_FILE_REAL(oloc_src, mesg_src, oloc_dst, mesg_dst, cpy_info) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy native message to another file");
#endif 

    
    if (H5O__shared_post_copy_file(oloc_dst->file, H5O_SHARED_TYPE, shared_src, shared_dst, mesg_flags,
                                   cpy_info) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to fix shared message in post copy");

#ifdef H5O_SHARED_POST_COPY_FILE_UPD
    
    if (H5O_SHARED_POST_COPY_FILE_UPD(oloc_src, mesg_src, oloc_dst, mesg_dst, cpy_info) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to update native message");
#endif 

    
    assert((shared_src->type == H5O_SHARE_TYPE_COMMITTED) == (shared_dst->type == H5O_SHARE_TYPE_COMMITTED));

done:
    FUNC_LEAVE_NOAPI(ret_value)
} 

static inline herr_t
H5O_SHARED_DEBUG(H5F_t *f, const void *_mesg, FILE *stream, int indent, int fwidth)
{
    const H5O_shared_t *sh_mesg =
        (const H5O_shared_t *)_mesg; 
    herr_t ret_value = SUCCEED;      

    
    FUNC_ENTER_PACKAGE

#ifndef H5O_SHARED_TYPE
#error "Need to define H5O_SHARED_TYPE macro!"
#endif 
#ifndef H5O_SHARED_DEBUG
#error "Need to define H5O_SHARED_DEBUG macro!"
#endif 
#ifndef H5O_SHARED_DEBUG_REAL
#error "Need to define H5O_SHARED_DEBUG_REAL macro!"
#endif 

    
    if (H5O_IS_STORED_SHARED(sh_mesg->type)) {
        
        if (H5O__shared_debug(sh_mesg, stream, indent, fwidth) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to display shared message info");
    } 

    
    if (H5O_SHARED_DEBUG_REAL(f, _mesg, stream, indent, fwidth) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to display native message info");

done:
    FUNC_LEAVE_NOAPI(ret_value)
} 

#endif 
