1 #ifndef __H5VOL_ATTR_FUNC
2 #define __H5VOL_ATTR_FUNC
3 
4 #include "H5Vol_def.h"
5 
6 ///
7 // attribute handlers
8 //
H5VL_adios2_attr_create(void * obj,const H5VL_loc_params_t * loc_params,const char * name,hid_t type_id,hid_t space_id,hid_t acpl_id,hid_t aapl_id,hid_t dxpl_id,void ** req)9 void *H5VL_adios2_attr_create(void *obj, const H5VL_loc_params_t *loc_params,
10                               const char *name, hid_t type_id, hid_t space_id,
11                               hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id,
12                               void **req)
13 {
14     REQUIRE_NOT_NULL_ERR(loc_params, NULL);
15     REQUIRE_NOT_NULL_ERR(obj, NULL);
16 
17     H5VL_ObjDef_t *vol = (H5VL_ObjDef_t *)obj;
18 
19     H5VL_AttrDef_t *attrDef = gCreateAttrDef(name, type_id, space_id);
20     return gAttrToVolObj(attrDef, vol);
21 }
22 
H5VL_adios2_attr_open(void * obj,const H5VL_loc_params_t * loc_params,const char * name,hid_t aapl_id,hid_t dxpl_id,void ** req)23 void *H5VL_adios2_attr_open(void *obj, const H5VL_loc_params_t *loc_params,
24                             const char *name, hid_t aapl_id, hid_t dxpl_id,
25                             void **req)
26 {
27     REQUIRE_NOT_NULL_ERR(loc_params, NULL);
28     REQUIRE_NOT_NULL_ERR(obj, NULL);
29 
30     H5VL_ObjDef_t *vol = (H5VL_ObjDef_t *)obj;
31     adios2_attribute *attr = gLocateAttrFrom(vol, name);
32 
33     H5VL_AttrDef_t *attrDef = NULL;
34     if (NULL == attr)
35     {
36         if ('/' == name[0])
37         {
38             SHOW_ERROR_MSG(
39                 "H5VL_ADIOS2: Error: No such ATTRIBUTE: [%s] in file\n ", name);
40             return NULL;
41         }
42         else
43         {
44             char withSlash[strlen(name) + 2];
45             sprintf(withSlash, "/%s", name);
46             withSlash[strlen(name) + 1] = '\0';
47             attr = gLocateAttrFrom(vol, withSlash);
48             if (NULL == attr)
49             {
50                 SHOW_ERROR_MSG("H5VL_ADIOS2: Error: No such ATTRIBUTE: [%s] "
51                                "found in file\n ",
52                                withSlash);
53                 return NULL;
54             }
55             attrDef = gCreateAttrDef(withSlash, -1, -1);
56         }
57     }
58     else
59         attrDef = gCreateAttrDef(name, -1, -1);
60 
61     // H5VL_AttrDef_t *attrDef = gCreateAttrDef(name, -1, -1);
62     attrDef->m_Attribute = attr;
63 
64     gLoadAttrDef(attrDef);
65 
66     return gAttrToVolObj(attrDef, vol);
67 }
68 
H5VL_adios2_attr_read(void * attrObj,hid_t mem_type_id,void * buf,hid_t dxpl_id,void ** req)69 herr_t H5VL_adios2_attr_read(void *attrObj, hid_t mem_type_id, void *buf,
70                              hid_t dxpl_id, void **req)
71 {
72     REQUIRE_NOT_NULL_ERR(attrObj, -1);
73 
74     H5VL_ObjDef_t *vol = (H5VL_ObjDef_t *)attrObj;
75 
76     H5VL_AttrDef_t *attrDef = (H5VL_AttrDef_t *)(vol->m_ObjPtr);
77     adios2_attribute *attr = attrDef->m_Attribute;
78 
79     if (NULL == attr)
80         return -1;
81 
82     if ((!attrDef->m_IsScalar) && (H5Tget_class(mem_type_id) == H5T_STRING))
83     {
84         htri_t isVariableSize = H5Tis_variable_str(mem_type_id);
85         if (!isVariableSize)
86         {
87             size_t strSize = H5Tget_size(mem_type_id);
88             // buf is char* instead of char**, adios2 c api expects char**
89 
90             char **result =
91                 (char **)(malloc(sizeof(char *) * (int)(attrDef->m_Size)));
92             size_t k = 0;
93             for (k = 0; k < attrDef->m_Size; k++)
94                 result[k] = (char *)(malloc(strSize));
95 
96             adios2_attribute_data(result, &(attrDef->m_Size), attr);
97 
98             char *out = (char *)buf;
99 
100             if (strlen(out) > 0)
101             {
102                 buf = result;
103                 return 0;
104             }
105             // from openPMD api.. using char*[n*max_length] to hold result
106             for (k = 0; k < attrDef->m_Size; k++)
107             {
108                 strncpy(out + k * strSize, result[k], strSize);
109                 out[k * strSize + strlen(result[k])] = '\0';
110                 free(result[k]);
111             }
112 
113             free(result);
114             return 0;
115         }
116     }
117 
118     adios2_attribute_data(buf, &(attrDef->m_Size), attr);
119 
120     return 0;
121 }
122 
H5VL_adios2_attr_write(void * attr,hid_t mem_type_id,const void * buf,hid_t dxpl_id,void ** req)123 herr_t H5VL_adios2_attr_write(void *attr, hid_t mem_type_id, const void *buf,
124                               hid_t dxpl_id, void **req)
125 {
126     REQUIRE_NOT_NULL_ERR(attr, -1);
127     H5VL_ObjDef_t *vol = (H5VL_ObjDef_t *)attr;
128 
129     H5VL_AttrDef_t *attrDef = (H5VL_AttrDef_t *)(vol->m_ObjPtr);
130     attrDef->m_Data = (void *)buf;
131     gADIOS2CreateAttr(vol->m_FileIO, attrDef, vol->m_Path);
132 
133     return 0;
134 }
135 
GetFromAttribute(void * attrObj,hid_t * ret_id,H5VL_attr_get_t get_type)136 void GetFromAttribute(void *attrObj, hid_t *ret_id, H5VL_attr_get_t get_type)
137 {
138     H5VL_AttrDef_t *attrDef = (H5VL_AttrDef_t *)attrObj;
139 
140     switch (get_type)
141     {
142     case H5VL_ATTR_GET_SPACE:
143     {
144         *ret_id = H5Scopy(attrDef->m_SpaceID);
145         break;
146     }
147     case H5VL_ATTR_GET_TYPE:
148     {
149         *ret_id = H5Tcopy(attrDef->m_TypeID);
150         break;
151     }
152     default:
153         break;
154     }
155 }
156 
H5VL_adios2_attr_get(void * obj,H5VL_attr_get_t get_type,hid_t dxpl_id,void ** req,va_list arguments)157 herr_t H5VL_adios2_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id,
158                             void **req, va_list arguments)
159 {
160     REQUIRE_NOT_NULL_ERR(obj, -1);
161     H5VL_ObjDef_t *vol = (H5VL_ObjDef_t *)obj;
162 
163     if ((get_type == H5VL_ATTR_GET_SPACE) || (get_type == H5VL_ATTR_GET_TYPE))
164     {
165         hid_t *ret_id = va_arg(arguments, hid_t *);
166         GetFromAttribute((vol->m_ObjPtr), ret_id, get_type);
167         return 0;
168     }
169 
170     const H5VL_loc_params_t *loc_params =
171         va_arg(arguments, const H5VL_loc_params_t *);
172     REQUIRE_NOT_NULL_ERR(loc_params, -1);
173 
174     switch (get_type)
175     {
176     case H5VL_ATTR_GET_NAME:
177     {
178         size_t buf_size = va_arg(arguments, size_t);
179         char *buf = va_arg(arguments, char *);
180         ssize_t *ret_val = va_arg(arguments, ssize_t *);
181 
182         if (H5VL_OBJECT_BY_SELF == loc_params->type)
183         {
184             H5VL_AttrDef_t *attrDef = (H5VL_AttrDef_t *)(vol->m_ObjPtr);
185             *ret_val = strlen(attrDef->m_Name);
186             if (buf)
187             {
188                 strncpy(buf, attrDef->m_Name, *ret_val);
189             }
190         }
191         else if (H5VL_OBJECT_BY_IDX == loc_params->type)
192         {
193             // The  number of attrs is from H5Oget_info(), then iterate each by
194             // calling H5Aget_name_by_idx, to reach here
195             *ret_val =
196                 gGetNameOfNthAttr(vol, loc_params->loc_data.loc_by_idx.n, buf);
197         }
198         return 0;
199     }
200     default:
201         break;
202     }
203 
204     ADIOS_VOL_NOT_SUPPORTED_ERR("UNABLE TO SUPPORT feature at attr_get\n");
205     return -1;
206 }
207 
H5VL_adios2_attr_close(void * attr,hid_t dxpl_id,void ** req)208 herr_t H5VL_adios2_attr_close(void *attr, hid_t dxpl_id, void **req)
209 {
210     REQUIRE_NOT_NULL_ERR(attr, -1);
211     H5VL_ObjDef_t *vol = (H5VL_ObjDef_t *)attr;
212 
213     H5VL_AttrDef_t *attrDef = (H5VL_AttrDef_t *)(vol->m_ObjPtr);
214     free(attrDef->m_Name);
215     if (-1 != attrDef->m_SpaceID)
216         H5Sclose(attrDef->m_SpaceID);
217     free(attrDef);
218     attrDef = NULL;
219 
220     gFreeVol(vol);
221     vol = NULL;
222     return 0;
223 }
224 
H5VL_adios2_attr_specific(void * obj,const H5VL_loc_params_t * loc_params,H5VL_attr_specific_t specific_type,hid_t dxpl_id,void ** req,va_list arguments)225 herr_t H5VL_adios2_attr_specific(void *obj, const H5VL_loc_params_t *loc_params,
226                                  H5VL_attr_specific_t specific_type,
227                                  hid_t dxpl_id, void **req, va_list arguments)
228 {
229     REQUIRE_NOT_NULL_ERR(obj, -1);
230     H5VL_ObjDef_t *vol = (H5VL_ObjDef_t *)obj;
231     const char *attr_name = va_arg(arguments, const char *);
232 
233     adios2_attribute *attr = gLocateAttrFrom(vol, attr_name);
234 
235     switch (specific_type)
236     {
237     case H5VL_ATTR_DELETE:
238     {
239         if (NULL != attr)
240         {
241             if (NULL == vol->m_Path)
242                 gADIOS2RemoveAttr(vol->m_FileIO, attr_name);
243             else
244             {
245                 char fullPath[strlen(vol->m_Path) + 4 + strlen(attr_name)];
246                 gGenerateFullPath(fullPath, vol->m_Path, attr_name);
247                 gADIOS2RemoveAttr(vol->m_FileIO, fullPath);
248             }
249             return 0;
250         }
251     }
252     case H5VL_ATTR_EXISTS:
253     {
254         htri_t *ret = va_arg(arguments, htri_t *);
255         if (NULL == attr)
256         {
257             *ret = 0;
258         }
259         else
260         {
261             *ret = 1;
262         }
263 
264         return 0;
265     }
266     default:
267         break;
268     }
269     return 0;
270 }
271 
272 #endif
273