/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * 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 H5G_FRIEND || defined H5G_MODULE)
#error "Do not include this file outside the H5G package!"
#endif

#ifndef H5Gpkg_H
#define H5Gpkg_H

#include "H5Gprivate.h"

#include "H5B2private.h" 
#include "H5FLprivate.h" 
#include "H5HFprivate.h" 
#include "H5HLprivate.h" 
#include "H5Oprivate.h"  

#define H5G_DENSE_FHEAP_ID_LEN 7

#define H5G_NODE_SIZE(f)                                                                                     \
    (                                                                           \
     H5_SIZEOF_MAGIC                                                                        \
     + 1                                                                                        \
     + 1                                                                                       \
     + 2                                                                              \
                                                                                                             \
                                                                                                \
     + ((2 * H5F_SYM_LEAF_K(f)) * (unsigned)H5G_SIZEOF_ENTRY_FILE(f)))

typedef enum H5G_cache_type_t {
    H5G_CACHED_ERROR   = -1, 
    H5G_NOTHING_CACHED = 0,  
    H5G_CACHED_STAB    = 1,  
    H5G_CACHED_SLINK   = 2,  

    H5G_NCACHED 
} H5G_cache_type_t;

typedef union H5G_cache_t {
    struct {
        haddr_t btree_addr; 
        haddr_t heap_addr;  
    } stab;

    struct {
        size_t lval_offset; 
    } slink;
} H5G_cache_t;

struct H5G_entry_t {
    H5G_cache_type_t type;     
    H5G_cache_t      cache;    
    size_t           name_off; 
    haddr_t          header;   
};

typedef struct H5G_node_t {
    H5AC_info_t cache_info; 
                            
    size_t       node_size; 
    unsigned     nsyms;     
    H5G_entry_t *entry;     
} H5G_node_t;

struct H5G_shared_t {
    int  fo_count; 
    bool mounted;  
};

struct H5G_t {
    H5G_shared_t *shared; 
    H5O_loc_t     oloc;   
    H5G_name_t    path;   
};

typedef herr_t (*H5G_lib_iterate_t)(const H5O_link_t *lnk, void *op_data);

typedef struct {
    size_t      nlinks; 
    H5O_link_t *lnks;   
} H5G_link_table_t;

typedef struct H5G_bt_common_t {
    
    const char *name;       
    H5HL_t     *heap;       
    size_t      block_size; 
} H5G_bt_common_t;

typedef struct H5G_bt_ins_t {
    
    H5G_bt_common_t   common;   
    const H5O_link_t *lnk;      
    H5O_type_t        obj_type; 
    const void       *crt_info; 
} H5G_bt_ins_t;

typedef struct H5G_bt_rm_t {
    
    H5G_bt_common_t common;          
    H5RS_str_t     *grp_full_path_r; 
} H5G_bt_rm_t;

typedef herr_t (*H5G_bt_find_op_t)(const H5G_entry_t *ent , void *operator_data );

typedef struct H5G_bt_lkp_t {
    
    H5G_bt_common_t  common;  
    H5G_bt_find_op_t op;      
    void            *op_data; 

    
} H5G_bt_lkp_t;

typedef struct H5G_bt_it_it_t {
    
    H5HL_t           *heap;    
    hsize_t           skip;    
    H5G_lib_iterate_t op;      
    void             *op_data; 

    
    hsize_t *final_ent; 
} H5G_bt_it_it_t;

typedef struct H5G_bt_it_cpy_t {
    const H5O_loc_t  *src_oloc;       
    H5HL_t           *src_heap;       
    size_t            src_block_size; 
    H5F_t            *dst_file;       
    const H5O_stab_t *dst_stab;       
    H5O_copy_t       *cpy_info;       
} H5G_bt_it_cpy_t;

typedef struct H5G_bt_it_idx_common_t {
    
    hsize_t          idx;      
    hsize_t          num_objs; 
    H5G_bt_find_op_t op;       
} H5G_bt_it_idx_common_t;

typedef struct H5G_bt_it_bt_t {
    
    size_t  alloc_nlinks; 
    H5HL_t *heap;         

    
    H5G_link_table_t *ltable; 
} H5G_bt_it_bt_t;

typedef struct H5G_dense_bt2_name_rec_t {
    uint8_t  id[H5G_DENSE_FHEAP_ID_LEN]; 
    uint32_t hash;                       
} H5G_dense_bt2_name_rec_t;

typedef struct H5G_dense_bt2_corder_rec_t {
    uint8_t id[H5G_DENSE_FHEAP_ID_LEN]; 
    int64_t corder;                     
} H5G_dense_bt2_corder_rec_t;

typedef struct H5G_bt2_ud_common_t {
    
    H5F_t       *f;             
    H5HF_t      *fheap;         
    const char  *name;          
    uint32_t     name_hash;     
    int64_t      corder;        
    H5B2_found_t found_op;      
    void        *found_op_data; 
} H5G_bt2_ud_common_t;

typedef struct H5G_bt2_ud_ins_t {
    
    H5G_bt2_ud_common_t common;                     
    uint8_t             id[H5G_DENSE_FHEAP_ID_LEN]; 
} H5G_bt2_ud_ins_t;

struct H5G_obj_create_t {
    hid_t            gcpl_id;    
    H5G_cache_type_t cache_type; 
    H5G_cache_t      cache;      
};

typedef struct H5G_copy_file_ud_t {
    H5O_copy_file_ud_common_t common;     
    H5G_cache_type_t          cache_type; 
    H5G_cache_t               cache;      
} H5G_copy_file_ud_t;

H5_DLLVAR H5B_class_t H5B_SNODE[1];

H5_DLLVAR const H5B2_class_t H5G_BT2_NAME[1];

H5_DLLVAR const H5B2_class_t H5G_BT2_CORDER[1];

H5FL_EXTERN(H5G_t);

H5FL_EXTERN(H5G_shared_t);

H5_DLL H5G_t *H5G__create(H5F_t *file, H5G_obj_create_t *gcrt_info);
H5_DLL H5G_t *H5G__create_named(const H5G_loc_t *loc, const char *name, hid_t lcpl_id, hid_t gcpl_id);
H5_DLL H5G_t *H5G__open_name(const H5G_loc_t *loc, const char *name);
H5_DLL herr_t H5G__get_info_by_name(const H5G_loc_t *loc, const char *name, H5G_info_t *grp_info);
H5_DLL herr_t H5G__get_info_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type,
                                   H5_iter_order_t order, hsize_t n, H5G_info_t *grp_info);

H5_DLL herr_t H5G__traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, unsigned target,
                                    bool last_comp, H5G_loc_t *obj_loc, bool *obj_exists);

H5_DLL const char *H5G__component(const char *name, size_t *size_p);

H5_DLL herr_t H5G__stab_create(H5O_loc_t *grp_oloc, const H5O_ginfo_t *ginfo, H5O_stab_t *stab);
H5_DLL herr_t H5G__stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint);
H5_DLL herr_t H5G__stab_insert(const H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk, H5O_type_t obj_type,
                               const void *crt_info);
H5_DLL herr_t H5G__stab_insert_real(H5F_t *f, const H5O_stab_t *stab, H5O_link_t *obj_lnk,
                                    H5O_type_t obj_type, const void *crt_info);
H5_DLL herr_t H5G__stab_delete(H5F_t *f, const H5O_stab_t *stab);
H5_DLL herr_t H5G__stab_iterate(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
                                H5G_lib_iterate_t op, void *op_data);
H5_DLL herr_t H5G__stab_count(const struct H5O_loc_t *oloc, hsize_t *num_objs);
H5_DLL herr_t H5G__stab_bh_size(H5F_t *f, const H5O_stab_t *stab, H5_ih_info_t *bh_info);
H5_DLL herr_t H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name,
                                        size_t name_size, size_t *name_len);
H5_DLL herr_t H5G__stab_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name);
H5_DLL herr_t H5G__stab_remove_by_idx(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r,
                                      H5_iter_order_t order, hsize_t n);
H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, bool *found, H5O_link_t *lnk);
H5_DLL herr_t H5G__stab_lookup_by_idx(const H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n,
                                      H5O_link_t *lnk);
#ifndef H5_STRICT_FORMAT_CHECKS
H5_DLL herr_t H5G__stab_valid(H5O_loc_t *grp_oloc, H5O_stab_t *alt_stab);
#endif 

H5_DLL void   H5G__ent_copy(H5G_entry_t *dst, H5G_entry_t *src, H5_copy_depth_t depth);
H5_DLL void   H5G__ent_reset(H5G_entry_t *ent);
H5_DLL herr_t H5G__ent_decode_vec(const H5F_t *f, const uint8_t **pp, const uint8_t *p_end, H5G_entry_t *ent,
                                  unsigned n);
H5_DLL herr_t H5G__ent_encode_vec(const H5F_t *f, uint8_t **pp, const H5G_entry_t *ent, unsigned n);
H5_DLL herr_t H5G__ent_to_link(const H5G_entry_t *ent, const H5HL_t *heap, H5O_link_t *lnk);
H5_DLL herr_t H5G__ent_debug(const H5G_entry_t *ent, FILE *stream, int indent, int fwidth,
                             const H5HL_t *heap);

H5_DLL herr_t H5G__node_init(H5F_t *f);
H5_DLL int H5G__node_iterate(H5F_t *f, const void *_lt_key, haddr_t addr, const void *_rt_key, void *_udata);
H5_DLL int H5G__node_sumup(H5F_t *f, const void *_lt_key, haddr_t addr, const void *_rt_key, void *_udata);
H5_DLL int H5G__node_by_idx(H5F_t *f, const void *_lt_key, haddr_t addr, const void *_rt_key, void *_udata);
H5_DLL int H5G__node_copy(H5F_t *f, const void *_lt_key, haddr_t addr, const void *_rt_key, void *_udata);
H5_DLL int H5G__node_build_table(H5F_t *f, const void *_lt_key, haddr_t addr, const void *_rt_key,
                                 void *_udata);
H5_DLL herr_t H5G__node_iterate_size(H5F_t *f, const void *_lt_key, haddr_t addr, const void *_rt_key,
                                     void *_udata);
H5_DLL herr_t H5G__node_free(H5G_node_t *sym);

H5_DLL herr_t H5G__link_to_ent(H5F_t *f, H5HL_t *heap, const H5O_link_t *lnk, H5O_type_t obj_type,
                               const void *crt_info, H5G_entry_t *ent);
H5_DLL herr_t H5G__link_to_loc(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, H5G_loc_t *obj_loc);
H5_DLL herr_t H5G__link_sort_table(H5G_link_table_t *ltable, H5_index_t idx_type, H5_iter_order_t order);
H5_DLL herr_t H5G__link_iterate_table(const H5G_link_table_t *ltable, hsize_t skip, hsize_t *last_lnk,
                                      const H5G_lib_iterate_t op, void *op_data);
H5_DLL herr_t H5G__link_release_table(H5G_link_table_t *ltable);
H5_DLL herr_t H5G__link_name_replace(H5F_t *file, H5RS_str_t *grp_full_path_r, const H5O_link_t *lnk);

H5_DLL herr_t H5G__compact_insert(const H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk);
H5_DLL herr_t H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo,
                                           H5_index_t idx_type, H5_iter_order_t order, hsize_t idx,
                                           char *name, size_t name_size, size_t *name_len);
H5_DLL herr_t H5G__compact_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name);
H5_DLL herr_t H5G__compact_remove_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo,
                                         H5RS_str_t *grp_full_path_r, H5_index_t idx_type,
                                         H5_iter_order_t order, hsize_t n);
H5_DLL herr_t H5G__compact_iterate(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type,
                                   H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
                                   H5G_lib_iterate_t op, void *op_data);
H5_DLL herr_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, bool *found, H5O_link_t *lnk);
H5_DLL herr_t H5G__compact_lookup_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type,
                                         H5_iter_order_t order, hsize_t n, H5O_link_t *lnk);

H5_DLL herr_t H5G__dense_build_table(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type,
                                     H5_iter_order_t order, H5G_link_table_t *ltable);
H5_DLL herr_t H5G__dense_create(H5F_t *f, H5O_linfo_t *linfo, const H5O_pline_t *pline);
H5_DLL herr_t H5G__dense_insert(H5F_t *f, const H5O_linfo_t *linfo, const H5O_link_t *lnk);
H5_DLL herr_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, bool *found,
                                H5O_link_t *lnk);
H5_DLL herr_t H5G__dense_lookup_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type,
                                       H5_iter_order_t order, hsize_t n, H5O_link_t *lnk);
H5_DLL herr_t H5G__dense_iterate(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type,
                                 H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op,
                                 void *op_data);
H5_DLL herr_t H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type,
                                         H5_iter_order_t order, hsize_t n, char *name, size_t name_size,
                                         size_t *name_len);
H5_DLL herr_t H5G__dense_remove(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r,
                                const char *name);
H5_DLL herr_t H5G__dense_remove_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r,
                                       H5_index_t idx_type, H5_iter_order_t order, hsize_t n);
H5_DLL herr_t H5G__dense_delete(H5F_t *f, H5O_linfo_t *linfo, bool adj_link);

H5_DLL herr_t H5G__obj_create(H5F_t *f, H5G_obj_create_t *gcrt_info, H5O_loc_t *oloc );
H5_DLL herr_t H5G__obj_create_real(H5F_t *f, const H5O_ginfo_t *ginfo, const H5O_linfo_t *linfo,
                                   const H5O_pline_t *pline, H5G_obj_create_t *gcrt_info,
                                   H5O_loc_t *oloc );
H5_DLL htri_t H5G__obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo);
H5_DLL herr_t H5G__obj_iterate(const H5O_loc_t *grp_oloc, H5_index_t idx_type, H5_iter_order_t order,
                               hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data);
H5_DLL herr_t H5G__obj_info(const H5O_loc_t *oloc, H5G_info_t *grp_info);
H5_DLL herr_t H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, bool *found, H5O_link_t *lnk);
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5_DLL herr_t H5G__get_objinfo(const H5G_loc_t *loc, const char *name, bool follow_link,
                               H5G_stat_t *statbuf );
#endif 

H5_DLL herr_t H5G__name_init(H5G_name_t *name, const char *path);

H5_DLL herr_t H5G__loc_insert(H5G_loc_t *grp_loc, char *name, H5G_loc_t *obj_loc, H5O_type_t obj_type,
                              const void *crt_info);
H5_DLL herr_t H5G__loc_addr(const H5G_loc_t *loc, const char *name, haddr_t *addr );

#ifdef H5G_TESTING
H5_DLL htri_t H5G__is_empty_test(hid_t gid);
H5_DLL htri_t H5G__has_links_test(hid_t gid, unsigned *nmsgs);
H5_DLL htri_t H5G__has_stab_test(hid_t gid);
H5_DLL htri_t H5G__is_new_dense_test(hid_t gid);
H5_DLL herr_t H5G__new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count);
H5_DLL herr_t H5G__lheap_size_test(hid_t gid, size_t *lheap_size);
H5_DLL herr_t H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len,
                                  unsigned *user_path_hidden);
H5_DLL herr_t H5G__verify_cached_stab_test(H5O_loc_t *grp_oloc, H5G_entry_t *ent);
H5_DLL herr_t H5G__verify_cached_stabs_test(hid_t gid);
#endif 

#endif 
