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

#ifndef H5Spkg_H
#define H5Spkg_H

#include "H5Sprivate.h"

#include "H5Oprivate.h" 

#define H5S_VALID_MAX  0x01
#define H5S_VALID_PERM 0x02

#define H5S_HYPER_REGULAR    0x01
#define H5S_SELECT_FLAG_BITS (H5S_HYPER_REGULAR)

#define H5S_HYPER_VERSION_1      1
#define H5S_HYPER_VERSION_2      2
#define H5S_HYPER_VERSION_3      3
#define H5S_HYPER_VERSION_LATEST H5S_HYPER_VERSION_3

#define H5S_POINT_VERSION_1      1
#define H5S_POINT_VERSION_2      2
#define H5S_POINT_VERSION_LATEST H5S_POINT_VERSION_2

#define H5S_NONE_VERSION_1      1
#define H5S_NONE_VERSION_LATEST H5S_NONE_VERSION_1

#define H5S_ALL_VERSION_1      1
#define H5S_ALL_VERSION_LATEST H5S_ALL_VERSION_1

#define H5S_SELECT_INFO_ENC_SIZE_2 0x02 
#define H5S_SELECT_INFO_ENC_SIZE_4 0x04 
#define H5S_SELECT_INFO_ENC_SIZE_8 0x08 
#define H5S_SELECT_INFO_ENC_SIZE_BITS                                                                        \
    (H5S_SELECT_INFO_ENC_SIZE_2 | H5S_SELECT_INFO_ENC_SIZE_4 | H5S_SELECT_INFO_ENC_SIZE_8)

#define H5S_UINT16_MAX 0x0000FFFF       
#define H5S_UINT32_MAX 0xFFFFFFFF       
#define H5S_UINT64_MAX ((hsize_t)(-1L)) 

#define H5S_PROJECT_INTERSECT_NSEQS 256

#define H5S_SEL_ITER_API_CALL 0x1000 

#define H5O_SDSPACE_VERSION_1 1

#define H5O_SDSPACE_VERSION_2 2

#define H5O_SDSPACE_VERSION_LATEST H5O_SDSPACE_VERSION_2

#define H5S_MAX_SIZE ((hsize_t)(hssize_t)(-2))

struct H5S_extent_t {
    H5O_shared_t sh_loc; 

    H5S_class_t type;    
    unsigned    version; 
    hsize_t     nelem;   

    unsigned rank; 
    hsize_t *size; 
    hsize_t *max;  
};

struct H5S_pnt_node_t {
    struct H5S_pnt_node_t *next;  
    hsize_t                pnt[]; 
                                  
};

struct H5S_pnt_list_t {
    
    hsize_t low_bounds[H5S_MAX_RANK];  
    hsize_t high_bounds[H5S_MAX_RANK]; 

    H5S_pnt_node_t *head; 
    H5S_pnt_node_t *tail; 

    hsize_t last_idx; 
    H5S_pnt_node_t *last_idx_pnt; 
};

struct H5S_hyper_span_t {
    hsize_t                       low, high; 
    struct H5S_hyper_span_info_t *down;      
    struct H5S_hyper_span_t      *next;      
};

typedef struct H5S_hyper_op_info_t {
    uint64_t op_gen; 
    union {
        struct H5S_hyper_span_info_t *copied;  
        hsize_t                       nelmts;  
        hsize_t                       nblocks; 
#ifdef H5_HAVE_PARALLEL
        MPI_Datatype down_type; 
#endif                          
    } u;
} H5S_hyper_op_info_t;

struct H5S_hyper_span_info_t {
    unsigned count; 

    
    
    hsize_t *low_bounds;  
    hsize_t *high_bounds; 

    
    
    
    H5S_hyper_op_info_t op_info[2];

    struct H5S_hyper_span_t *head; 
    struct H5S_hyper_span_t *tail; 
    hsize_t                  bounds[]; 
                                       
};

typedef enum {
    H5S_DIMINFO_VALID_IMPOSSIBLE, 
    H5S_DIMINFO_VALID_NO,         
    H5S_DIMINFO_VALID_YES         
} H5S_diminfo_valid_t;

typedef struct {
    
    H5S_hyper_dim_t app[H5S_MAX_RANK]; 
    H5S_hyper_dim_t opt[H5S_MAX_RANK]; 

    
    
    hsize_t low_bounds[H5S_MAX_RANK];  
    hsize_t high_bounds[H5S_MAX_RANK]; 
} H5S_hyper_diminfo_t;

typedef struct {
    H5S_diminfo_valid_t diminfo_valid; 

    H5S_hyper_diminfo_t diminfo;            
    int                 unlim_dim;          
    hsize_t             num_elem_non_unlim; 
    H5S_hyper_span_info_t *span_lst;        
} H5S_hyper_sel_t;

typedef herr_t (*H5S_sel_copy_func_t)(H5S_t *dst, const H5S_t *src, bool share_selection);

typedef herr_t (*H5S_sel_release_func_t)(H5S_t *space);

typedef htri_t (*H5S_sel_is_valid_func_t)(const H5S_t *space);

typedef hssize_t (*H5S_sel_serial_size_func_t)(H5S_t *space);

typedef herr_t (*H5S_sel_serialize_func_t)(H5S_t *space, uint8_t **p);

typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t **space, const uint8_t **p, const size_t p_size,
                                             bool skip);

typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hsize_t *start, hsize_t *end);

typedef herr_t (*H5S_sel_offset_func_t)(const H5S_t *space, hsize_t *offset);

typedef int (*H5S_sel_unlim_dim_func_t)(const H5S_t *space);

typedef herr_t (*H5S_sel_num_elem_non_unlim_func_t)(const H5S_t *space, hsize_t *num_elem_non_unlim);

typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space);

typedef htri_t (*H5S_sel_is_single_func_t)(const H5S_t *space);

typedef htri_t (*H5S_sel_is_regular_func_t)(H5S_t *space);

typedef htri_t (*H5S_sel_shape_same_func_t)(H5S_t *space1, H5S_t *space2);

typedef htri_t (*H5S_sel_intersect_block_func_t)(H5S_t *space, const hsize_t *start, const hsize_t *end);

typedef herr_t (*H5S_sel_adjust_u_func_t)(H5S_t *space, const hsize_t *offset);

typedef herr_t (*H5S_sel_adjust_s_func_t)(H5S_t *space, const hssize_t *offset);

typedef herr_t (*H5S_sel_project_scalar)(const H5S_t *space, hsize_t *offset);

typedef herr_t (*H5S_sel_project_simple)(const H5S_t *space, H5S_t *new_space, hsize_t *offset);

typedef herr_t (*H5S_sel_iter_init_func_t)(H5S_t *space, H5S_sel_iter_t *sel_iter);

typedef struct {
    H5S_sel_type type; 

    
    H5S_sel_copy_func_t     copy;     
    H5S_sel_release_func_t  release;  
    H5S_sel_is_valid_func_t is_valid; 
    H5S_sel_serial_size_func_t
        serial_size; 
    H5S_sel_serialize_func_t serialize;     
    H5S_sel_deserialize_func_t deserialize; 
    H5S_sel_bounds_func_t
        bounds; 
    H5S_sel_offset_func_t
        offset; 
    H5S_sel_unlim_dim_func_t unlim_dim; 
    H5S_sel_num_elem_non_unlim_func_t num_elem_non_unlim; 
    H5S_sel_is_contiguous_func_t is_contiguous; 
    H5S_sel_is_single_func_t     is_single;  
    H5S_sel_is_regular_func_t    is_regular; 
    H5S_sel_shape_same_func_t
        shape_same; 
    H5S_sel_intersect_block_func_t
        intersect_block;               
    H5S_sel_adjust_u_func_t  adjust_u; 
    H5S_sel_adjust_s_func_t  adjust_s; 
    H5S_sel_project_scalar   project_scalar; 
    H5S_sel_project_simple   project_simple; 
    H5S_sel_iter_init_func_t iter_init;      
} H5S_select_class_t;

typedef struct {
    const H5S_select_class_t *type; 

    bool     offset_changed;       
    hssize_t offset[H5S_MAX_RANK]; 

    hsize_t num_elem; 

    union {
        H5S_pnt_list_t  *pnt_lst; 
        H5S_hyper_sel_t *hslab;   
    } sel_info;
} H5S_select_t;

struct H5S_t {
    H5S_extent_t extent; 
    H5S_select_t select; 
};

typedef herr_t (*H5S_sel_iter_coords_func_t)(const H5S_sel_iter_t *iter, hsize_t *coords);

typedef herr_t (*H5S_sel_iter_block_func_t)(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end);

typedef hsize_t (*H5S_sel_iter_nelmts_func_t)(const H5S_sel_iter_t *iter);

typedef htri_t (*H5S_sel_iter_has_next_block_func_t)(const H5S_sel_iter_t *iter);

typedef herr_t (*H5S_sel_iter_next_func_t)(H5S_sel_iter_t *iter, size_t nelem);

typedef herr_t (*H5S_sel_iter_next_block_func_t)(H5S_sel_iter_t *iter);

typedef herr_t (*H5S_sel_iter_get_seq_list_func_t)(H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes,
                                                   size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len);

typedef herr_t (*H5S_sel_iter_release_func_t)(H5S_sel_iter_t *iter);

typedef struct H5S_sel_iter_class_t {
    H5S_sel_type type; 

    
    H5S_sel_iter_coords_func_t
        iter_coords; 
    H5S_sel_iter_block_func_t
        iter_block; 
    H5S_sel_iter_nelmts_func_t
        iter_nelmts; 
    H5S_sel_iter_has_next_block_func_t
        iter_has_next_block; 
    H5S_sel_iter_next_func_t
        iter_next; 
    H5S_sel_iter_next_block_func_t
        iter_next_block; 
    H5S_sel_iter_get_seq_list_func_t
        iter_get_seq_list; 
    H5S_sel_iter_release_func_t iter_release; 
} H5S_sel_iter_class_t;

H5_DLLVAR const H5S_select_class_t H5S_sel_all[1];

H5_DLLVAR const H5S_select_class_t H5S_sel_hyper[1];

H5_DLLVAR const H5S_select_class_t H5S_sel_none[1];

H5_DLLVAR const H5S_select_class_t H5S_sel_point[1];

H5_DLLVAR const unsigned H5O_sdspace_ver_bounds[H5F_LIBVER_NBOUNDS + 1];

H5_DLL herr_t H5S__extent_release(H5S_extent_t *extent);
H5_DLL herr_t H5S__extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, bool copy_max);

H5_DLL uint64_t H5S__hyper_get_op_gen(void);
H5_DLL void     H5S__hyper_rebuild(H5S_t *space);
H5_DLL herr_t   H5S__modify_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2);
H5_DLL herr_t H5S__hyper_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_intersect_space,
                                              H5S_t *proj_space, bool share_space);

H5_DLL herr_t H5S__sel_iter_close_cb(H5S_sel_iter_t *_sel_iter, void **request);

#ifdef H5S_TESTING
H5_DLL herr_t H5S__get_rebuild_status_test(hid_t space_id, H5S_diminfo_valid_t *status1,
                                           H5S_diminfo_valid_t *status2);
H5_DLL herr_t H5S__get_diminfo_status_test(hid_t space_id, H5S_diminfo_valid_t *status);
H5_DLL htri_t H5S__internal_consistency_test(hid_t space_id);
H5_DLL herr_t H5S__verify_offsets(hid_t space_id, const hssize_t *offset);
#endif 

#endif 
