1 /*
2 * (C) Copyright 2005- ECMWF.
3 *
4 * This software is licensed under the terms of the Apache Licence Version 2.0
5 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6 *
7 * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
8 * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
9 */
10
11 /***************************************************************************
12 * Jean Baptiste Filippi - 01.11.2005
13 * Enrico Fucile
14 * *
15 ***************************************************************************/
16
17 #include "grib_api_internal.h"
18
19 /* Note: A fast cut-down version of strcmp which does NOT return -1 */
20 /* 0 means input strings are equal and 1 means not equal */
grib_inline_strcmp(const char * a,const char * b)21 GRIB_INLINE static int grib_inline_strcmp(const char* a, const char* b)
22 {
23 if (*a != *b)
24 return 1;
25 while ((*a != 0 && *b != 0) && *(a) == *(b)) {
26 a++;
27 b++;
28 }
29 return (*a == 0 && *b == 0) ? 0 : 1;
30 }
31
grib_accessor_dump(grib_accessor * a,grib_dumper * f)32 void grib_accessor_dump(grib_accessor* a, grib_dumper* f)
33 {
34 grib_accessor_class* c = a->cclass;
35 while (c) {
36 if (c->dump) {
37 c->dump(a, f);
38 return;
39 }
40 c = c->super ? *(c->super) : NULL;
41 }
42 DebugAssert(0);
43 }
44
grib_pack_missing(grib_accessor * a)45 int grib_pack_missing(grib_accessor* a)
46 {
47 grib_accessor_class* c = a->cclass;
48 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (double) %g",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
49 while (c) {
50 if (c->pack_missing) {
51 return c->pack_missing(a);
52 }
53 c = c->super ? *(c->super) : NULL;
54 }
55 DebugAssert(0);
56 return 0;
57 }
58
grib_pack_zero(grib_accessor * a)59 int grib_pack_zero(grib_accessor* a)
60 {
61 grib_accessor_class* c = a->cclass;
62 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (double) %g",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
63 while (c) {
64 if (c->clear) {
65 return c->clear(a);
66 }
67 c = c->super ? *(c->super) : NULL;
68 }
69 DebugAssert(0);
70 return 0;
71 }
72
grib_is_missing_internal(grib_accessor * a)73 int grib_is_missing_internal(grib_accessor* a)
74 {
75 grib_accessor_class* c = a->cclass;
76 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (double) %g",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
77 while (c) {
78 if (c->is_missing) {
79 return c->is_missing(a);
80 }
81 c = c->super ? *(c->super) : NULL;
82 }
83 DebugAssert(0);
84 return 0;
85 }
86
grib_pack_double(grib_accessor * a,const double * v,size_t * len)87 int grib_pack_double(grib_accessor* a, const double* v, size_t* len)
88 {
89 grib_accessor_class* c = a->cclass;
90 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (double) %g",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
91 while (c) {
92 if (c->pack_double) {
93 return c->pack_double(a, v, len);
94 }
95 c = c->super ? *(c->super) : NULL;
96 }
97 DebugAssert(0);
98 return 0;
99 }
100
grib_pack_expression(grib_accessor * a,grib_expression * e)101 int grib_pack_expression(grib_accessor* a, grib_expression* e)
102 {
103 grib_accessor_class* c = a->cclass;
104 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (double) %g",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
105 while (c) {
106 if (c->pack_expression) {
107 return c->pack_expression(a, e);
108 }
109 c = c->super ? *(c->super) : NULL;
110 }
111 DebugAssert(0);
112 return 0;
113 }
114
grib_pack_string(grib_accessor * a,const char * v,size_t * len)115 int grib_pack_string(grib_accessor* a, const char* v, size_t* len)
116 {
117 grib_accessor_class* c = a->cclass;
118 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (string) %s",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?v:"(null)");*/
119 while (c) {
120 if (c->pack_string) {
121 return c->pack_string(a, v, len);
122 }
123 c = c->super ? *(c->super) : NULL;
124 }
125 DebugAssert(0);
126 return 0;
127 }
128
grib_pack_string_array(grib_accessor * a,const char ** v,size_t * len)129 int grib_pack_string_array(grib_accessor* a, const char** v, size_t* len)
130 {
131 grib_accessor_class* c = a->cclass;
132 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (string) %s",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?v:"(null)");*/
133 while (c) {
134 if (c->pack_string_array) {
135 return c->pack_string_array(a, v, len);
136 }
137 c = c->super ? *(c->super) : NULL;
138 }
139 DebugAssert(0);
140 return 0;
141 }
142
grib_pack_long(grib_accessor * a,const long * v,size_t * len)143 int grib_pack_long(grib_accessor* a, const long* v, size_t* len)
144 {
145 grib_accessor_class* c = a->cclass;
146 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (long) %d",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
147 while (c) {
148 if (c->pack_long) {
149 return c->pack_long(a, v, len);
150 }
151 c = c->super ? *(c->super) : NULL;
152 }
153 DebugAssert(0);
154 return 0;
155 }
156
grib_pack_bytes(grib_accessor * a,const unsigned char * v,size_t * len)157 int grib_pack_bytes(grib_accessor* a, const unsigned char* v, size_t* len)
158 {
159 grib_accessor_class* c = a->cclass;
160 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (bytes) %d",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
161 while (c) {
162 if (c->pack_bytes) {
163 return c->pack_bytes(a, v, len);
164 }
165 c = c->super ? *(c->super) : NULL;
166 }
167 DebugAssert(0);
168 return 0;
169 }
170
grib_unpack_bytes(grib_accessor * a,unsigned char * v,size_t * len)171 int grib_unpack_bytes(grib_accessor* a, unsigned char* v, size_t* len)
172 {
173 grib_accessor_class* c = a->cclass;
174 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is unpacking (bytes)",(a->parent->owner)?(a->parent->owner->name):"root", a->name ); */
175 while (c) {
176 if (c->unpack_bytes) {
177 return c->unpack_bytes(a, v, len);
178 }
179 c = c->super ? *(c->super) : NULL;
180 }
181 DebugAssert(0);
182 return 0;
183 }
184
grib_unpack_double_subarray(grib_accessor * a,double * v,size_t start,size_t len)185 int grib_unpack_double_subarray(grib_accessor* a, double* v, size_t start, size_t len)
186 {
187 grib_accessor_class* c = a->cclass;
188 while (c) {
189 if (c->unpack_double_subarray) {
190 return c->unpack_double_subarray(a, v, start, len);
191 }
192 c = c->super ? *(c->super) : NULL;
193 }
194 DebugAssert(0);
195 return 0;
196 }
197
grib_unpack_double(grib_accessor * a,double * v,size_t * len)198 int grib_unpack_double(grib_accessor* a, double* v, size_t* len)
199 {
200 grib_accessor_class* c = a->cclass;
201 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is unpacking (double)",(a->parent->owner)?(a->parent->owner->name):"root", a->name ); */
202 while (c) {
203 if (c->unpack_double) {
204 return c->unpack_double(a, v, len);
205 }
206 c = c->super ? *(c->super) : NULL;
207 }
208 DebugAssert(0);
209 return 0;
210 }
211
grib_unpack_double_element(grib_accessor * a,size_t i,double * v)212 int grib_unpack_double_element(grib_accessor* a, size_t i, double* v)
213 {
214 grib_accessor_class* c = a->cclass;
215 while (c) {
216 if (c->unpack_double_element) {
217 return c->unpack_double_element(a, i, v);
218 }
219 c = c->super ? *(c->super) : NULL;
220 }
221 return GRIB_NOT_IMPLEMENTED;
222 }
223
grib_unpack_string(grib_accessor * a,char * v,size_t * len)224 int grib_unpack_string(grib_accessor* a, char* v, size_t* len)
225 {
226 grib_accessor_class* c = a->cclass;
227 /* grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is unpacking (string)",(a->parent->owner)?(a->parent->owner->name):"root", a->name ); */
228 while (c) {
229 if (c->unpack_string) {
230 return c->unpack_string(a, v, len);
231 }
232 c = c->super ? *(c->super) : NULL;
233 }
234 DebugAssert(0);
235 return 0;
236 }
237
grib_unpack_string_array(grib_accessor * a,char ** v,size_t * len)238 int grib_unpack_string_array(grib_accessor* a, char** v, size_t* len)
239 {
240 grib_accessor_class* c = a->cclass;
241 while (c) {
242 if (c->unpack_string_array) {
243 return c->unpack_string_array(a, v, len);
244 }
245 c = c->super ? *(c->super) : NULL;
246 }
247 DebugAssert(0);
248 return 0;
249 }
250
grib_accessors_list_unpack_long(grib_accessors_list * al,long * val,size_t * buffer_len)251 int grib_accessors_list_unpack_long(grib_accessors_list* al, long* val, size_t* buffer_len)
252 {
253 int err = GRIB_SUCCESS;
254 size_t unpacked_len = 0;
255 size_t len = 0;
256
257 while (al && err == GRIB_SUCCESS) {
258 len = *buffer_len - unpacked_len;
259 err = grib_unpack_long(al->accessor, val + unpacked_len, &len);
260 unpacked_len += len;
261 al = al->next;
262 }
263
264 *buffer_len = unpacked_len;
265 return err;
266 }
267
grib_accessors_list_unpack_double(grib_accessors_list * al,double * val,size_t * buffer_len)268 int grib_accessors_list_unpack_double(grib_accessors_list* al, double* val, size_t* buffer_len)
269 {
270 int err = GRIB_SUCCESS;
271 size_t unpacked_len = 0;
272 size_t len = 0;
273
274 while (al && err == GRIB_SUCCESS) {
275 len = *buffer_len - unpacked_len;
276 err = grib_unpack_double(al->accessor, val + unpacked_len, &len);
277 unpacked_len += len;
278 al = al->next;
279 }
280
281 *buffer_len = unpacked_len;
282 return err;
283 }
284
grib_accessors_list_unpack_string(grib_accessors_list * al,char ** val,size_t * buffer_len)285 int grib_accessors_list_unpack_string(grib_accessors_list* al, char** val, size_t* buffer_len)
286 {
287 int err = GRIB_SUCCESS;
288 size_t unpacked_len = 0;
289 size_t len = 0;
290
291 while (al && err == GRIB_SUCCESS) {
292 len = *buffer_len - unpacked_len;
293 err = grib_unpack_string_array(al->accessor, val + unpacked_len, &len);
294 unpacked_len += len;
295 al = al->next;
296 }
297
298 *buffer_len = unpacked_len;
299 return err;
300 }
301
grib_unpack_long(grib_accessor * a,long * v,size_t * len)302 int grib_unpack_long(grib_accessor* a, long* v, size_t* len)
303 {
304 grib_accessor_class* c = a->cclass;
305 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is unpacking (long)",(a->parent->owner)?(a->parent->owner->name):"root", a->name ); */
306 while (c) {
307 if (c->unpack_long) {
308 return c->unpack_long(a, v, len);
309 }
310 c = c->super ? *(c->super) : NULL;
311 }
312 DebugAssert(0);
313 return 0;
314 }
315
grib_accessor_get_native_type(grib_accessor * a)316 long grib_accessor_get_native_type(grib_accessor* a)
317 {
318 grib_accessor_class* c = NULL;
319 if (a)
320 c = a->cclass;
321
322 while (c) {
323 if (c->get_native_type)
324 return c->get_native_type(a);
325 c = c->super ? *(c->super) : NULL;
326 }
327 DebugAssert(0);
328 return 0;
329 }
330
grib_get_next_position_offset(grib_accessor * a)331 long grib_get_next_position_offset(grib_accessor* a)
332 {
333 grib_accessor_class* c = NULL;
334 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is checking next (long)",(a->parent->owner)?(a->parent->owner->name):"root", a->name ); */
335 if (a)
336 c = a->cclass;
337
338 while (c) {
339 if (c->next_offset)
340 return c->next_offset(a);
341 c = c->super ? *(c->super) : NULL;
342 }
343 DebugAssert(0);
344 return 0;
345 }
346
grib_string_length(grib_accessor * a)347 long grib_string_length(grib_accessor* a)
348 {
349 grib_accessor_class* c = NULL;
350 if (a)
351 c = a->cclass;
352
353 while (c) {
354 if (c->string_length)
355 return c->string_length(a);
356 c = c->super ? *(c->super) : NULL;
357 }
358 DebugAssert(0);
359 return 0;
360 }
361
grib_byte_offset(grib_accessor * a)362 long grib_byte_offset(grib_accessor* a)
363 {
364 grib_accessor_class* c = NULL;
365 if (a)
366 c = a->cclass;
367
368 while (c) {
369 if (c->byte_offset)
370 return c->byte_offset(a);
371 c = c->super ? *(c->super) : NULL;
372 }
373 DebugAssert(0);
374 return 0;
375 }
376
grib_byte_count(grib_accessor * a)377 long grib_byte_count(grib_accessor* a)
378 {
379 grib_accessor_class* c = NULL;
380 if (a)
381 c = a->cclass;
382
383 while (c) {
384 if (c->byte_count)
385 return c->byte_count(a);
386 c = c->super ? *(c->super) : NULL;
387 }
388 DebugAssert(0);
389 return 0;
390 }
391
grib_value_count(grib_accessor * a,long * count)392 int grib_value_count(grib_accessor* a, long* count)
393 {
394 grib_accessor_class* c = NULL;
395 int err = 0;
396 if (a)
397 c = a->cclass;
398
399 while (c) {
400 if (c->value_count) {
401 err = c->value_count(a, count);
402 return err;
403 }
404 c = c->super ? *(c->super) : NULL;
405 }
406 DebugAssert(0);
407 return 0;
408 }
409
grib_accessors_list_value_count(grib_accessors_list * al,size_t * count)410 int grib_accessors_list_value_count(grib_accessors_list* al, size_t* count)
411 {
412 long lcount = 0;
413 *count = 0;
414 while (al) {
415 grib_value_count(al->accessor, &lcount);
416 *count += lcount;
417 al = al->next;
418 }
419 return 0;
420 }
421
grib_accessor_notify_change(grib_accessor * a,grib_accessor * changed)422 int grib_accessor_notify_change(grib_accessor* a, grib_accessor* changed)
423 {
424 grib_accessor_class* c = NULL;
425 if (a)
426 c = a->cclass;
427
428 while (c) {
429 if (c->notify_change)
430 return c->notify_change(a, changed);
431 c = c->super ? *(c->super) : NULL;
432 }
433 if (a && a->cclass)
434 printf("notify_change not implemented for %s %s\n", a->cclass->name, a->name);
435 DebugAssert(0);
436 return 0;
437 }
438
439 /* For this one, ALL init are called */
440
init_accessor(grib_accessor_class * c,grib_accessor * a,const long len,grib_arguments * args)441 static void init_accessor(grib_accessor_class* c, grib_accessor* a, const long len, grib_arguments* args)
442 {
443 if (c) {
444 grib_accessor_class* s = c->super ? *(c->super) : NULL;
445 init_accessor(s, a, len, args);
446 if (c->init)
447 c->init(a, len, args);
448 }
449 }
450
grib_init_accessor(grib_accessor * a,const long len,grib_arguments * args)451 void grib_init_accessor(grib_accessor* a, const long len, grib_arguments* args)
452 {
453 init_accessor(a->cclass, a, len, args);
454 }
455
456 #if 0
457 static void post_init_accessor(grib_accessor_class* c,grib_accessor* a)
458 {
459 if(c) {
460 grib_accessor_class *s = c->super ? *(c->super) : NULL;
461 post_init_accessor(s,a);
462 if(c->post_init) c->post_init(a);
463 }
464 }
465 #endif
466
467 /* For this one, ALL destroy are called */
468
grib_accessor_delete(grib_context * ct,grib_accessor * a)469 void grib_accessor_delete(grib_context* ct, grib_accessor* a)
470 {
471 grib_accessor_class* c = a->cclass;
472 while (c) {
473 grib_accessor_class* s = c->super ? *(c->super) : NULL;
474 /*printf("grib_accessor_delete: before destroy a=%p c->name=%s ==> a->name=%s\n", (void*)a, c->name, a->name);*/
475 if (c->destroy) {
476 c->destroy(ct, a);
477 }
478 c = s;
479 }
480 /*printf("grib_accessor_delete before free a=%p\n", (void*)a);*/
481 grib_context_free(ct, a);
482 }
483
grib_accessor_clone(grib_accessor * a,grib_section * s,int * err)484 grib_accessor* grib_accessor_clone(grib_accessor* a, grib_section* s, int* err)
485 {
486 grib_accessor_class* c = a->cclass;
487 grib_context* ct = a->context;
488 while (c) {
489 grib_accessor_class* super = c->super ? *(c->super) : NULL;
490 grib_context_log(ct, GRIB_LOG_DEBUG, "clone %s ==> %s", c->name, a->name);
491 if (c->make_clone) {
492 return c->make_clone(a, s, err);
493 }
494 c = super;
495 }
496 return 0;
497 }
498
grib_update_size(grib_accessor * a,size_t len)499 void grib_update_size(grib_accessor* a, size_t len)
500 {
501 grib_accessor_class* c = a->cclass;
502 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (double) %g",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
503 while (c) {
504 if (c->update_size) {
505 c->update_size(a, len);
506 return;
507 }
508 c = c->super ? *(c->super) : NULL;
509 }
510 DebugAssert(0);
511 }
512
grib_nearest_smaller_value(grib_accessor * a,double val,double * nearest)513 int grib_nearest_smaller_value(grib_accessor* a, double val, double* nearest)
514 {
515 grib_accessor_class* c = a->cclass;
516 while (c) {
517 if (c->nearest_smaller_value) {
518 return c->nearest_smaller_value(a, val, nearest);
519 }
520 c = c->super ? *(c->super) : NULL;
521 }
522 DebugAssert(0);
523 return 0;
524 }
525
526
grib_preferred_size(grib_accessor * a,int from_handle)527 size_t grib_preferred_size(grib_accessor* a, int from_handle)
528 {
529 grib_accessor_class* c = a->cclass;
530 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (long) %d",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
531 while (c) {
532 if (c->preferred_size) {
533 return c->preferred_size(a, from_handle);
534 }
535 c = c->super ? *(c->super) : NULL;
536 }
537 DebugAssert(0);
538 return 0;
539 }
540
grib_next_accessor(grib_accessor * a)541 grib_accessor* grib_next_accessor(grib_accessor* a)
542 {
543 grib_accessor_class* c = a->cclass;
544 while (c) {
545 if (c->next) {
546 return c->next(a, 1);
547 }
548 c = c->super ? *(c->super) : NULL;
549 }
550 DebugAssert(0);
551 return 0;
552 }
553
grib_resize(grib_accessor * a,size_t new_size)554 void grib_resize(grib_accessor* a, size_t new_size)
555 {
556 grib_accessor_class* c = a->cclass;
557 /*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (long) %d",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
558 while (c) {
559 if (c->resize) {
560 c->resize(a, new_size);
561 return;
562 }
563 c = c->super ? *(c->super) : NULL;
564 }
565 DebugAssert(0);
566 return;
567 }
568
grib_compare_accessors(grib_accessor * a1,grib_accessor * a2,int compare_flags)569 int grib_compare_accessors(grib_accessor* a1, grib_accessor* a2, int compare_flags)
570 {
571 int ret = 0;
572 long type1 = 0;
573 long type2 = 0;
574 int type_mismatch = 0;
575 grib_accessor_class* c1 = NULL;
576
577 if ((compare_flags & GRIB_COMPARE_NAMES) && grib_inline_strcmp(a1->name, a2->name))
578 return GRIB_NAME_MISMATCH;
579
580 if (compare_flags & GRIB_COMPARE_TYPES) {
581 type1 = grib_accessor_get_native_type(a1);
582 type2 = grib_accessor_get_native_type(a2);
583
584 type_mismatch = type1 != type2 ? 1 : 0;
585 }
586
587 ret = GRIB_UNABLE_TO_COMPARE_ACCESSORS;
588 c1 = a1->cclass;
589 while (c1) {
590 if (c1->compare) {
591 ret = c1->compare(a1, a2);
592 break;
593 }
594 c1 = c1->super ? *(c1->super) : NULL;
595 }
596
597 if (ret == GRIB_VALUE_MISMATCH && type_mismatch)
598 ret = GRIB_TYPE_AND_VALUE_MISMATCH;
599
600 return ret;
601 }
602
grib_get_type_name(int type)603 const char* grib_get_type_name(int type)
604 {
605 switch (type) {
606 case GRIB_TYPE_LONG:
607 return "long";
608 case GRIB_TYPE_STRING:
609 return "string";
610 case GRIB_TYPE_BYTES:
611 return "bytes";
612 case GRIB_TYPE_DOUBLE:
613 return "double";
614 case GRIB_TYPE_LABEL:
615 return "label";
616 case GRIB_TYPE_SECTION:
617 return "section";
618 }
619 return "unknown";
620 }
621
622 /*
623 int grib_accessor_clear_attributes(grib_accessor* a)
624 {
625 int id;
626 for (id=0;id<MAX_ACCESSOR_ATTRIBUTES;id++) {
627 a->attributes[id]=NULL;
628 }
629 return 0;
630 }
631 */
632
grib_accessor_add_attribute(grib_accessor * a,grib_accessor * attr,int nest_if_clash)633 int grib_accessor_add_attribute(grib_accessor* a, grib_accessor* attr, int nest_if_clash)
634 {
635 int id = 0;
636 int idx = 0;
637 grib_accessor* same = NULL;
638 grib_accessor* aloc = a;
639
640 if (grib_accessor_has_attributes(a)) {
641 same = _grib_accessor_get_attribute(a, attr->name, &id);
642 }
643
644 if (same) {
645 if (nest_if_clash == 0)
646 return GRIB_ATTRIBUTE_CLASH;
647 aloc = same;
648 }
649
650 for (id = 0; id < MAX_ACCESSOR_ATTRIBUTES; id++) {
651 if (aloc->attributes[id] == NULL) {
652 /* attr->parent=a->parent; */
653 aloc->attributes[id] = attr;
654 attr->parent_as_attribute = aloc;
655 if (aloc->same)
656 attr->same = _grib_accessor_get_attribute(aloc->same, attr->name, &idx);
657
658 grib_context_log(a->context, GRIB_LOG_DEBUG, "added attribute %s->%s", a->name, attr->name);
659 return GRIB_SUCCESS;
660 }
661 }
662 return GRIB_TOO_MANY_ATTRIBUTES;
663 }
664
grib_accessor_replace_attribute(grib_accessor * a,grib_accessor * attr)665 int grib_accessor_replace_attribute(grib_accessor* a, grib_accessor* attr)
666 {
667 int id = 0;
668 int idx = 0;
669 if (_grib_accessor_get_attribute(a, attr->name, &id) != NULL) {
670 grib_accessor_delete(a->context, a->attributes[id]);
671 a->attributes[id] = attr;
672 attr->parent_as_attribute = a;
673 if (a->same)
674 attr->same = _grib_accessor_get_attribute(a->same, attr->name, &idx);
675 }
676 else {
677 grib_accessor_add_attribute(a, attr, 0);
678 }
679 return GRIB_SUCCESS;
680 }
681
grib_accessor_delete_attribute(grib_accessor * a,const char * name)682 int grib_accessor_delete_attribute(grib_accessor* a, const char* name)
683 {
684 int id = 0;
685 if (_grib_accessor_get_attribute(a, name, &id) != NULL) {
686 grib_accessor_delete(a->context, a->attributes[id]);
687 a->attributes[id] = NULL;
688 return GRIB_SUCCESS;
689 }
690 else {
691 return GRIB_NOT_FOUND;
692 }
693 }
694
grib_accessor_get_attribute_by_index(grib_accessor * a,int index)695 grib_accessor* grib_accessor_get_attribute_by_index(grib_accessor* a, int index)
696 {
697 if (index < MAX_ACCESSOR_ATTRIBUTES)
698 return a->attributes[index];
699
700 return NULL;
701 }
702
grib_accessor_get_name(grib_accessor * a)703 const char* grib_accessor_get_name(grib_accessor* a)
704 {
705 return a->name;
706 }
707
_grib_accessor_get_attribute(grib_accessor * a,const char * name,int * index)708 grib_accessor* _grib_accessor_get_attribute(grib_accessor* a, const char* name, int* index)
709 {
710 int i = 0;
711 while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes[i]) {
712 if (!grib_inline_strcmp(a->attributes[i]->name, name)) {
713 *index = i;
714 return a->attributes[i];
715 }
716 i++;
717 }
718 return NULL;
719 }
720
grib_accessor_has_attributes(grib_accessor * a)721 int grib_accessor_has_attributes(grib_accessor* a)
722 {
723 return a->attributes[0] ? 1 : 0;
724 }
725
grib_accessor_get_attribute(grib_accessor * a,const char * name)726 grib_accessor* grib_accessor_get_attribute(grib_accessor* a, const char* name)
727 {
728 int index = 0;
729 const char* p = 0;
730 char* basename = NULL;
731 const char* attribute_name = NULL;
732 grib_accessor* acc = NULL;
733 p = name;
734 while (*(p + 1) != '\0' && (*p != '-' || *(p + 1) != '>'))
735 p++;
736 if (*(p + 1) == '\0') {
737 return _grib_accessor_get_attribute(a, name, &index);
738 }
739 else {
740 size_t size = p - name;
741 attribute_name = p + 2;
742 basename = (char*)grib_context_malloc_clear(a->context, size + 1);
743 basename = (char*)memcpy(basename, name, size);
744 acc = _grib_accessor_get_attribute(a, basename, &index);
745 grib_context_free(a->context, basename);
746 if (acc)
747 return grib_accessor_get_attribute(acc, attribute_name);
748 else
749 return NULL;
750 }
751 }
752
grib_accessors_list_create(grib_context * c)753 grib_accessors_list* grib_accessors_list_create(grib_context* c)
754 {
755 return (grib_accessors_list*)grib_context_malloc_clear(c, sizeof(grib_accessors_list));
756 }
757
grib_accessors_list_push(grib_accessors_list * al,grib_accessor * a,int rank)758 void grib_accessors_list_push(grib_accessors_list* al, grib_accessor* a, int rank)
759 {
760 grib_accessors_list* last;
761 grib_context* c = a->context;
762
763 last = grib_accessors_list_last(al);
764 if (last && last->accessor) {
765 last->next = (grib_accessors_list*)grib_context_malloc_clear(c, sizeof(grib_accessors_list));
766 last->next->accessor = a;
767 last->next->prev = last;
768 last->next->rank = rank;
769 al->last = last->next;
770 }
771 else {
772 al->accessor = a;
773 al->rank = rank;
774 al->last = al;
775 }
776 }
777
grib_accessors_list_last(grib_accessors_list * al)778 grib_accessors_list* grib_accessors_list_last(grib_accessors_list* al)
779 {
780 /*grib_accessors_list* last=al;*/
781 /*grib_accessors_list* next=al->next;*/
782
783 /*
784 while(next) {
785 last=next;
786 next=last->next;
787 }
788 */
789 return al->last;
790 }
791
grib_accessors_list_find(grib_accessors_list * al,grib_accessor * a)792 grib_accessors_list* grib_accessors_list_find(grib_accessors_list* al, grib_accessor* a)
793 {
794 grib_accessors_list* last = al;
795 grib_accessors_list* next = al->next;
796
797 while (next) {
798 if (last->accessor == a)
799 return last;
800 last = next;
801 next = last->next;
802 }
803
804 return NULL;
805 }
806
grib_accessors_list_delete(grib_context * c,grib_accessors_list * al)807 void grib_accessors_list_delete(grib_context* c, grib_accessors_list* al)
808 {
809 grib_accessors_list* tmp;
810
811 while (al) {
812 tmp = al->next;
813 /*grib_accessor_delete(c, al->accessor);*/
814 grib_context_free(c, al);
815 al = tmp;
816 }
817 }
818
819
820 #if 0
821 void grib_print_accessor_flags(const grib_accessor* acc)
822 {
823 const unsigned long f = acc->flags;
824 if (f & GRIB_ACCESSOR_FLAG_READ_ONLY) printf("READ_ONLY ");
825 if (f & GRIB_ACCESSOR_FLAG_DUMP) printf("DUMP ");
826 if (f & GRIB_ACCESSOR_FLAG_EDITION_SPECIFIC) printf("EDITION_SPECIFIC ");
827 if (f & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) printf("CAN_BE_MISSING ");
828 if (f & GRIB_ACCESSOR_FLAG_LOWERCASE) printf("LOWERCASE ");
829 if (f & GRIB_ACCESSOR_FLAG_HIDDEN) printf("HIDDEN ");
830 /* TODO: the rest */
831 }
832 #endif
833