/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * 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.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#if !(defined H5A_FRIEND || defined H5A_MODULE)
#error "Do not include this file outside the H5A package!"
#endif

#ifndef H5Apkg_H
#define H5Apkg_H

#ifdef NDEBUG
#undef H5A_DEBUG
#endif

#include "H5Aprivate.h"

#include "H5B2private.h" 
#include "H5FLprivate.h" 
#include "H5HFprivate.h" 
#include "H5Oprivate.h"  
#include "H5Sprivate.h"  
#include "H5Tprivate.h"  

#define H5O_ATTR_VERSION_1 1

#define H5O_ATTR_VERSION_2 2

#define H5O_ATTR_VERSION_3 3

#define H5O_ATTR_VERSION_LATEST H5O_ATTR_VERSION_3

typedef struct H5A_shared_t {
    uint8_t version; 

    char      *name;     
    H5T_cset_t encoding; 

    H5T_t *dt;      
    size_t dt_size; 

    H5S_t *ds;      
    size_t ds_size; 

    void             *data;      
    size_t            data_size; 
    H5O_msg_crt_idx_t crt_idx;   
    unsigned          nrefs;     
} H5A_shared_t;

struct H5A_t {
    H5O_shared_t  sh_loc;     
    H5O_loc_t     oloc;       
    bool          obj_opened; 
    H5G_name_t    path;       
    H5A_shared_t *shared;     
};

typedef struct H5A_dense_bt2_name_rec_t {
    H5O_fheap_id_t    id;     
    uint8_t           flags;  
    H5O_msg_crt_idx_t corder; 
    uint32_t          hash;   
} H5A_dense_bt2_name_rec_t;

typedef struct H5A_dense_bt2_corder_rec_t {
    H5O_fheap_id_t    id;     
    uint8_t           flags;  
    H5O_msg_crt_idx_t corder; 
} H5A_dense_bt2_corder_rec_t;

typedef herr_t (*H5A_bt2_found_t)(const H5A_t *attr, bool *took_ownership, void *op_data);

typedef struct H5A_bt2_ud_common_t {
    
    H5F_t            *f;             
    H5HF_t           *fheap;         
    H5HF_t           *shared_fheap;  
    const char       *name;          
    uint32_t          name_hash;     
    uint8_t           flags;         
    H5O_msg_crt_idx_t corder;        
    H5A_bt2_found_t   found_op;      
    void             *found_op_data; 
} H5A_bt2_ud_common_t;

typedef struct H5A_bt2_ud_ins_t {
    
    H5A_bt2_ud_common_t common; 
    H5O_fheap_id_t      id;     
} H5A_bt2_ud_ins_t;

typedef struct {
    size_t  num_attrs; 
    size_t  max_attrs; 
    H5A_t **attrs;     
} H5A_attr_table_t;

H5FL_EXTERN(H5A_t);

H5FL_EXTERN(H5A_shared_t);

H5FL_BLK_EXTERN(attr_buf);

H5_DLLVAR const H5B2_class_t H5A_BT2_NAME[1];

H5_DLLVAR const H5B2_class_t H5A_BT2_CORDER[1];

H5_DLL H5A_t *H5A__create(const H5G_loc_t *loc, const char *attr_name, const H5T_t *type, const H5S_t *space,
                          hid_t acpl_id);
H5_DLL H5A_t *H5A__create_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name,
                                  const H5T_t *type, const H5S_t *space, hid_t acpl_id);
H5_DLL H5A_t *H5A__open(const H5G_loc_t *loc, const char *attr_name);
H5_DLL H5A_t *H5A__open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name);
H5_DLL H5A_t *H5A__open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type,
                               H5_iter_order_t order, hsize_t n);
H5_DLL H5A_t *H5A__copy(H5A_t *new_attr, const H5A_t *old_attr);
H5_DLL hid_t  H5A__get_type(H5A_t *attr);
H5_DLL herr_t H5A__get_info(const H5A_t *attr, H5A_info_t *ainfo);
H5_DLL hid_t  H5A__get_create_plist(H5A_t *attr);
H5_DLL herr_t H5A__shared_free(H5A_t *attr);
H5_DLL herr_t H5A__close(H5A_t *attr);
H5_DLL htri_t H5A__get_ainfo(H5F_t *f, H5O_t *oh, H5O_ainfo_t *ainfo);
H5_DLL herr_t H5A__set_version(const H5F_t *f, H5A_t *attr);
H5_DLL herr_t H5A__rename_by_name(H5G_loc_t loc, const char *obj_name, const char *old_attr_name,
                                  const char *new_attr_name);
H5_DLL herr_t H5A__iterate(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type,
                           H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data);
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5_DLL herr_t H5A__iterate_old(hid_t loc_id, unsigned *attr_num, H5A_operator1_t op, void *op_data);
#endif 
H5_DLL herr_t H5A__delete_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name);
H5_DLL herr_t H5A__delete_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type,
                                 H5_iter_order_t order, hsize_t n);
H5_DLL herr_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name,
                                  bool *attr_exists);
H5_DLL herr_t H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf);
H5_DLL herr_t H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf);
H5_DLL herr_t H5A__get_name(H5A_t *attr, size_t buf_size, char *buf, size_t *attr_name_len);

H5_DLL herr_t H5A__dense_create(H5F_t *f, H5O_ainfo_t *ainfo);
H5_DLL H5A_t *H5A__dense_open(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name);
H5_DLL herr_t H5A__dense_insert(H5F_t *f, const H5O_ainfo_t *ainfo, H5A_t *attr);
H5_DLL herr_t H5A__dense_write(H5F_t *f, const H5O_ainfo_t *ainfo, H5A_t *attr);
H5_DLL herr_t H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name,
                                const char *new_name);
H5_DLL herr_t H5A__dense_iterate(H5F_t *f, hid_t loc_id, const H5O_ainfo_t *ainfo, H5_index_t idx_type,
                                 H5_iter_order_t order, hsize_t skip, hsize_t *last_attr,
                                 const H5A_attr_iter_op_t *attr_op, void *op_data);
H5_DLL herr_t H5A__dense_remove(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name);
H5_DLL herr_t H5A__dense_remove_by_idx(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type,
                                       H5_iter_order_t order, hsize_t n);
H5_DLL herr_t H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name, bool *attr_exists);
H5_DLL herr_t H5A__dense_delete(H5F_t *f, H5O_ainfo_t *ainfo);

H5_DLL herr_t H5A__compact_build_table(H5F_t *f, H5O_t *oh, H5_index_t idx_type, H5_iter_order_t order,
                                       H5A_attr_table_t *atable);
H5_DLL herr_t H5A__dense_build_table(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type,
                                     H5_iter_order_t order, H5A_attr_table_t *atable);
H5_DLL herr_t H5A__attr_iterate_table(const H5A_attr_table_t *atable, hsize_t skip, hsize_t *last_attr,
                                      hid_t loc_id, const H5A_attr_iter_op_t *attr_op, void *op_data);
H5_DLL herr_t H5A__attr_release_table(H5A_attr_table_t *atable);

H5_DLL herr_t H5O__attr_create(const H5O_loc_t *loc, H5A_t *attr);
H5_DLL H5A_t *H5O__attr_open_by_name(const H5O_loc_t *loc, const char *name);
H5_DLL H5A_t *H5O__attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order_t order,
                                    hsize_t n);
H5_DLL herr_t H5O__attr_update_shared(H5F_t *f, H5O_t *oh, H5A_t *attr, H5O_shared_t *sh_mesg);
H5_DLL herr_t H5O__attr_write(const H5O_loc_t *loc, H5A_t *attr);
H5_DLL herr_t H5O__attr_rename(const H5O_loc_t *loc, const char *old_name, const char *new_name);
H5_DLL herr_t H5O__attr_iterate(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
                                hsize_t *last_attr, const H5A_attr_iter_op_t *op, void *op_data);
H5_DLL herr_t H5O__attr_remove(const H5O_loc_t *loc, const char *name);
H5_DLL herr_t H5O__attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order_t order,
                                      hsize_t n);
H5_DLL herr_t H5O__attr_exists(const H5O_loc_t *loc, const char *name, bool *attr_exists);
H5_DLL H5A_t *H5A__attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, bool *recompute_size,
                                  H5O_copy_t *cpy_info);
H5_DLL herr_t H5A__attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *mesg_src, H5O_loc_t *dst_oloc,
                                       const H5A_t *mesg_dst, H5O_copy_t *cpy_info);
H5_DLL herr_t H5A__dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t *ainfo_src,
                                            H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst,
                                            H5O_copy_t *cpy_info);

#ifdef H5A_TESTING
H5_DLL htri_t H5A__is_shared_test(hid_t aid);
H5_DLL herr_t H5A__get_shared_rc_test(hid_t attr_id, hsize_t *ref_count);
#endif 

#endif 
