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 * Jean Baptiste Filippi - 01.11.2005
12 * Enrico Fucile *
13 ***************************************************************************/
14 #include "grib_api_internal.h"
15 #include <float.h>
16
17 /* Note: A fast cut-down version of strcmp which does NOT return -1 */
18 /* 0 means input strings are equal and 1 means not equal */
grib_inline_strcmp(const char * a,const char * b)19 GRIB_INLINE static int grib_inline_strcmp(const char* a, const char* b)
20 {
21 if (*a != *b)
22 return 1;
23 while ((*a != 0 && *b != 0) && *(a) == *(b)) {
24 a++;
25 b++;
26 }
27 return (*a == 0 && *b == 0) ? 0 : 1;
28 }
29
grib_set_expression(grib_handle * h,const char * name,grib_expression * e)30 int grib_set_expression(grib_handle* h, const char* name, grib_expression* e)
31 {
32 grib_accessor* a = grib_find_accessor(h, name);
33 int ret = GRIB_SUCCESS;
34
35 if (a) {
36 if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
37 return GRIB_READ_ONLY;
38
39 ret = grib_pack_expression(a, e);
40 if (ret == GRIB_SUCCESS) {
41 return grib_dependency_notify_change(a);
42 }
43 return ret;
44 }
45 return GRIB_NOT_FOUND;
46 }
47
grib_set_expression_internal(grib_handle * h,const char * name,grib_expression * e)48 int grib_set_expression_internal(grib_handle* h, const char* name, grib_expression* e)
49 {
50 grib_accessor* a = grib_find_accessor(h, name);
51
52 int ret = GRIB_SUCCESS;
53 if (a) {
54 ret = grib_pack_expression(a, e);
55 if (ret == GRIB_SUCCESS) {
56 return grib_dependency_notify_change(a);
57 }
58 return ret;
59 }
60 return GRIB_NOT_FOUND;
61 }
62
grib_set_long_internal(grib_handle * h,const char * name,long val)63 int grib_set_long_internal(grib_handle* h, const char* name, long val)
64 {
65 grib_context* c = h->context;
66 int ret = GRIB_SUCCESS;
67 grib_accessor* a = NULL;
68 size_t l = 1;
69
70 a = grib_find_accessor(h, name);
71
72 if (h->context->debug)
73 fprintf(stderr, "ECCODES DEBUG grib_set_long_internal %s=%ld\n", name, (long)val);
74
75 if (a) {
76 ret = grib_pack_long(a, &val, &l);
77 if (ret == GRIB_SUCCESS) {
78 return grib_dependency_notify_change(a);
79 }
80
81 grib_context_log(c, GRIB_LOG_ERROR, "unable to set %s=%ld as long (%s)",
82 name, val, grib_get_error_message(ret));
83 return ret;
84 }
85
86 grib_context_log(c, GRIB_LOG_ERROR, "unable to find accessor %s", name);
87 return GRIB_NOT_FOUND;
88 }
89
grib_set_long(grib_handle * h,const char * name,long val)90 int grib_set_long(grib_handle* h, const char* name, long val)
91 {
92 int ret = GRIB_SUCCESS;
93 grib_accessor* a = NULL;
94 size_t l = 1;
95
96 a = grib_find_accessor(h, name);
97
98 if (a) {
99 if (h->context->debug) {
100 if (strcmp(name, a->name)!=0)
101 fprintf(stderr, "ECCODES DEBUG grib_set_long %s=%ld (a->name=%s)\n", name, (long)val, a->name);
102 else
103 fprintf(stderr, "ECCODES DEBUG grib_set_long %s=%ld\n", name, (long)val);
104 }
105
106 if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
107 return GRIB_READ_ONLY;
108
109 ret = grib_pack_long(a, &val, &l);
110 if (ret == GRIB_SUCCESS)
111 return grib_dependency_notify_change(a);
112
113 return ret;
114 }
115 return GRIB_NOT_FOUND;
116 }
117
grib_set_double_internal(grib_handle * h,const char * name,double val)118 int grib_set_double_internal(grib_handle* h, const char* name, double val)
119 {
120 int ret = GRIB_SUCCESS;
121 grib_accessor* a = NULL;
122 size_t l = 1;
123
124 a = grib_find_accessor(h, name);
125
126 if (h->context->debug)
127 fprintf(stderr, "ECCODES DEBUG grib_set_double_internal %s=%g\n", name, val);
128
129 if (a) {
130 ret = grib_pack_double(a, &val, &l);
131 if (ret == GRIB_SUCCESS) {
132 return grib_dependency_notify_change(a);
133 }
134
135 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to set %s=%g as double (%s)",
136 name, val, grib_get_error_message(ret));
137 return ret;
138 }
139
140 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to find accessor %s", name);
141 return GRIB_NOT_FOUND;
142 }
143
144 typedef struct grib_key_err grib_key_err;
145 struct grib_key_err
146 {
147 char* name;
148 int err;
149 grib_key_err* next;
150 };
151
grib_copy_namespace(grib_handle * dest,const char * name,grib_handle * src)152 int grib_copy_namespace(grib_handle* dest, const char* name, grib_handle* src)
153 {
154 int* err = NULL;
155 int type, error_code = 0;
156 size_t len;
157 char* sval = NULL;
158 unsigned char* uval = NULL;
159 double* dval = NULL;
160 long* lval = NULL;
161 grib_key_err* key_err = NULL;
162 grib_key_err* first = NULL;
163 int todo = 1, count = 0;
164
165 grib_keys_iterator* iter = NULL;
166
167 if (!dest || !src)
168 return GRIB_NULL_HANDLE;
169
170 iter = grib_keys_iterator_new(src, 0, name);
171
172 if (!iter) {
173 grib_context_log(src->context, GRIB_LOG_ERROR, "grib_copy_namespace: unable to get iterator for %s", name);
174 return GRIB_INTERNAL_ERROR;
175 }
176
177 while (grib_keys_iterator_next(iter)) {
178 grib_key_err* k = (grib_key_err*)grib_context_malloc_clear(src->context, sizeof(grib_key_err));
179 k->err = GRIB_NOT_FOUND;
180 k->name = grib_context_strdup(src->context, grib_keys_iterator_get_name(iter));
181 if (key_err == NULL) {
182 key_err = k;
183 first = k;
184 }
185 else {
186 key_err->next = k;
187 key_err = key_err->next;
188 }
189 }
190
191 count = 0;
192 todo = 1;
193 while (todo && count < 4) {
194 grib_accessor* a = NULL;
195 key_err = first;
196 while (key_err) {
197 char* key = key_err->name;
198 err = &(key_err->err);
199
200 if (*err == GRIB_SUCCESS) {
201 key_err = key_err->next;
202 continue;
203 }
204
205 if ((a = grib_find_accessor(dest, key)) == NULL) {
206 key_err->err = GRIB_NOT_FOUND;
207 key_err = key_err->next;
208 continue;
209 }
210
211 if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) {
212 key_err->err = GRIB_SUCCESS;
213 key_err = key_err->next;
214 continue;
215 }
216
217 if (grib_is_missing(src, key, err) && *err == 0 && (*err = grib_set_missing(dest, key))) {
218 if (*err != GRIB_SUCCESS && *err != GRIB_NOT_FOUND)
219 return *err;
220 key_err = key_err->next;
221 continue;
222 }
223
224 if ((*err = grib_get_native_type(dest, key, &type)) != GRIB_SUCCESS) {
225 if (*err != GRIB_SUCCESS && *err != GRIB_NOT_FOUND)
226 return *err;
227 key_err = key_err->next;
228 continue;
229 }
230
231 if ((*err = grib_get_size(src, key, &len)) != GRIB_SUCCESS)
232 return *err;
233
234 switch (type) {
235 case GRIB_TYPE_STRING:
236 len = 512;
237 sval = (char*)grib_context_malloc(src->context, len * sizeof(char));
238
239 if ((*err = grib_get_string(src, key, sval, &len)) != GRIB_SUCCESS)
240 return *err;
241
242 if ((*err = grib_set_string(dest, key, sval, &len)) != GRIB_SUCCESS)
243 return *err;
244
245 grib_context_free(src->context, sval);
246 break;
247
248 case GRIB_TYPE_LONG:
249 lval = (long*)grib_context_malloc(src->context, len * sizeof(long));
250
251 if ((*err = grib_get_long_array(src, key, lval, &len)) != GRIB_SUCCESS)
252 return *err;
253
254 if ((*err = grib_set_long_array(dest, key, lval, len)) != GRIB_SUCCESS)
255 return *err;
256
257 grib_context_free(src->context, lval);
258 break;
259
260 case GRIB_TYPE_DOUBLE:
261 dval = (double*)grib_context_malloc(src->context, len * sizeof(double));
262
263 if ((*err = grib_get_double_array(src, key, dval, &len)) != GRIB_SUCCESS)
264 return *err;
265
266 if ((*err = grib_set_double_array(dest, key, dval, len)) != GRIB_SUCCESS)
267 return *err;
268
269 grib_context_free(src->context, dval);
270 break;
271
272 case GRIB_TYPE_BYTES:
273 if (len == 0)
274 len = 512;
275 uval = (unsigned char*)grib_context_malloc(src->context, len * sizeof(unsigned char));
276
277 if ((*err = grib_get_bytes(src, key, uval, &len)) != GRIB_SUCCESS)
278 return *err;
279
280 if ((*err = grib_get_bytes(dest, key, uval, &len)) != GRIB_SUCCESS)
281 return *err;
282
283 grib_context_free(src->context, uval);
284
285 break;
286
287 default:
288 break;
289 }
290 key_err = key_err->next;
291 }
292 count++;
293 key_err = first;
294 todo = 0;
295 while (key_err) {
296 if (key_err->err == GRIB_NOT_FOUND) {
297 todo = 1;
298 break;
299 }
300 key_err = key_err->next;
301 }
302 }
303 if (err)
304 error_code = *err; /* copy the error code before cleanup */
305 grib_keys_iterator_delete(iter);
306 key_err = first;
307 while (key_err) {
308 grib_key_err* next = key_err->next;
309 grib_context_free(src->context, key_err->name);
310 grib_context_free(src->context, key_err);
311 key_err = next;
312 }
313
314 return error_code;
315 }
316
grib_set_double(grib_handle * h,const char * name,double val)317 int grib_set_double(grib_handle* h, const char* name, double val)
318 {
319 int ret = GRIB_SUCCESS;
320 grib_accessor* a = NULL;
321 size_t l = 1;
322
323 a = grib_find_accessor(h, name);
324
325 if (a) {
326 if (h->context->debug) {
327 if (strcmp(name, a->name)!=0)
328 fprintf(stderr, "ECCODES DEBUG grib_set_double %s=%g (a->name=%s)\n", name, val, a->name);
329 else
330 fprintf(stderr, "ECCODES DEBUG grib_set_double %s=%g\n", name, val);
331 }
332
333 if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
334 return GRIB_READ_ONLY;
335
336 ret = grib_pack_double(a, &val, &l);
337 if (ret == GRIB_SUCCESS)
338 return grib_dependency_notify_change(a);
339
340 return ret;
341 }
342 return GRIB_NOT_FOUND;
343 }
344
grib_set_string_internal(grib_handle * h,const char * name,const char * val,size_t * length)345 int grib_set_string_internal(grib_handle* h, const char* name,
346 const char* val, size_t* length)
347 {
348 int ret = GRIB_SUCCESS;
349 grib_accessor* a = NULL;
350
351 a = grib_find_accessor(h, name);
352
353 if (h->context->debug)
354 fprintf(stderr, "ECCODES DEBUG grib_set_string_internal %s=%s\n", name, val);
355
356 if (a) {
357 ret = grib_pack_string(a, val, length);
358 if (ret == GRIB_SUCCESS) {
359 return grib_dependency_notify_change(a);
360 }
361
362 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to set %s=%s as string (%s)",
363 name, val, grib_get_error_message(ret));
364 return ret;
365 }
366
367 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to find accessor %s", name);
368 return GRIB_NOT_FOUND;
369 }
370
grib_set_string(grib_handle * h,const char * name,const char * val,size_t * length)371 int grib_set_string(grib_handle* h, const char* name, const char* val, size_t* length)
372 {
373 int ret = 0;
374 grib_accessor* a = NULL;
375
376 /* Second order doesn't have a proper representation for constant fields.
377 So best not to do the change of packing type.
378 Use strncmp to catch all flavours of second order packing e.g. grid_second_order_boustrophedonic
379 */
380 if (!grib_inline_strcmp(name, "packingType") && !strncmp(val, "grid_second_order", 17)) {
381 long bitsPerValue = 0;
382 size_t numCodedVals = 0;
383 grib_get_long(h, "bitsPerValue", &bitsPerValue);
384 if (bitsPerValue == 0) {
385 /* ECC-1219: packingType conversion from grid_ieee to grid_second_order */
386 /* Normally having a bitsPerValue of 0 means a constant field but this is
387 * not so for IEEE packing which can be non-constant but always has bitsPerValue==0!
388 */
389 char input_packing_type[100] = {0,};
390 size_t len = sizeof(input_packing_type);
391 grib_get_string(h, "packingType", input_packing_type, &len);
392 if (strcmp(input_packing_type, "grid_ieee") != 0) {
393 /* If it's not IEEE, then bitsPerValue==0 means constant field */
394 if (h->context->debug) {
395 fprintf(stderr, "ECCODES DEBUG grib_set_string packingType: Constant field cannot be encoded in second order. Packing not changed\n");
396 }
397 return 0;
398 }
399 }
400
401 /* GRIB-883: check if there are enough coded values */
402 ret = grib_get_size(h, "codedValues", &numCodedVals);
403 if (ret == GRIB_SUCCESS && numCodedVals < 3) {
404 if (h->context->debug) {
405 fprintf(stderr, "ECCODES DEBUG grib_set_string packingType: not enough coded values for second order. Packing not changed\n");
406 }
407 return 0;
408 }
409 }
410
411 a = grib_find_accessor(h, name);
412
413 if (a) {
414 if (h->context->debug) {
415 if (strcmp(name, a->name)!=0)
416 fprintf(stderr, "ECCODES DEBUG grib_set_string %s=|%s| (a->name=%s)\n", name, val, a->name);
417 else
418 fprintf(stderr, "ECCODES DEBUG grib_set_string %s=|%s|\n", name, val);
419 }
420
421 if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
422 return GRIB_READ_ONLY;
423
424 ret = grib_pack_string(a, val, length);
425 if (ret == GRIB_SUCCESS) {
426 return grib_dependency_notify_change(a);
427 }
428 return ret;
429 }
430 return GRIB_NOT_FOUND;
431 }
432
grib_set_string_array(grib_handle * h,const char * name,const char ** val,size_t length)433 int grib_set_string_array(grib_handle* h, const char* name, const char** val, size_t length)
434 {
435 int ret = 0;
436 grib_accessor* a;
437
438 a = grib_find_accessor(h, name);
439
440 if (h->context->debug) {
441 fprintf(stderr, "ECCODES DEBUG grib_set_string_array key=%s %ld values\n", name, (long)length);
442 }
443
444 if (a) {
445 if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
446 return GRIB_READ_ONLY;
447
448 ret = grib_pack_string_array(a, val, &length);
449 if (ret == GRIB_SUCCESS) {
450 return grib_dependency_notify_change(a);
451 }
452 return ret;
453 }
454 return GRIB_NOT_FOUND;
455 }
456
grib_set_bytes_internal(grib_handle * h,const char * name,const unsigned char * val,size_t * length)457 int grib_set_bytes_internal(grib_handle* h, const char* name, const unsigned char* val, size_t* length)
458 {
459 int ret = GRIB_SUCCESS;
460 grib_accessor* a = NULL;
461
462 a = grib_find_accessor(h, name);
463
464 if (a) {
465 ret = grib_pack_bytes(a, val, length);
466 if (ret == GRIB_SUCCESS) {
467 return grib_dependency_notify_change(a);
468 }
469
470 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to set %s=%ld as bytes (%s)",
471 name, val, grib_get_error_message(ret));
472 return ret;
473 }
474
475 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to find accessor %s", name);
476 return GRIB_NOT_FOUND;
477 }
478
grib_set_bytes(grib_handle * h,const char * name,const unsigned char * val,size_t * length)479 int grib_set_bytes(grib_handle* h, const char* name, const unsigned char* val, size_t* length)
480 {
481 int ret = 0;
482 grib_accessor* a = grib_find_accessor(h, name);
483
484 if (a) {
485 /* if(a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) */
486 /* return GRIB_READ_ONLY; */
487
488 ret = grib_pack_bytes(a, val, length);
489 if (ret == GRIB_SUCCESS) {
490 return grib_dependency_notify_change(a);
491 }
492 return ret;
493 }
494 return GRIB_NOT_FOUND;
495 }
496
grib_clear(grib_handle * h,const char * name)497 int grib_clear(grib_handle* h, const char* name)
498 {
499 int ret = 0;
500 grib_accessor* a = NULL;
501
502 a = grib_find_accessor(h, name);
503
504 if (a) {
505 if (a->length == 0)
506 return 0;
507 if ((ret = grib_pack_zero(a)) != GRIB_SUCCESS)
508 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to clear %s (%s)",
509 name, grib_get_error_message(ret));
510 return ret;
511 }
512
513 /*grib_context_log(h->context,GRIB_LOG_ERROR,"unable to find accessor %s",name);*/
514 return GRIB_NOT_FOUND;
515 }
516
grib_set_missing_internal(grib_handle * h,const char * name)517 int grib_set_missing_internal(grib_handle* h, const char* name)
518 {
519 int ret = 0;
520 grib_accessor* a = NULL;
521
522 a = grib_find_accessor(h, name);
523
524 if (a) {
525 if (a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) {
526 ret = grib_pack_missing(a);
527 if (ret == GRIB_SUCCESS)
528 return grib_dependency_notify_change(a);
529 }
530 else
531 ret = GRIB_VALUE_CANNOT_BE_MISSING;
532
533 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to set %s=missing (%s)",
534 name, grib_get_error_message(ret));
535 return ret;
536 }
537
538 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to find accessor %s", name);
539 return GRIB_NOT_FOUND;
540 }
541
grib_set_missing(grib_handle * h,const char * name)542 int grib_set_missing(grib_handle* h, const char* name)
543 {
544 int ret = 0;
545 grib_accessor* a = NULL;
546
547 a = grib_find_accessor(h, name);
548
549 if (a) {
550 if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
551 return GRIB_READ_ONLY;
552
553 if (a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) {
554 if (h->context->debug)
555 fprintf(stderr, "ECCODES DEBUG grib_set_missing %s\n", name);
556
557 ret = grib_pack_missing(a);
558 if (ret == GRIB_SUCCESS)
559 return grib_dependency_notify_change(a);
560 }
561 else
562 ret = GRIB_VALUE_CANNOT_BE_MISSING;
563
564 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to set %s=missing (%s)",
565 name, grib_get_error_message(ret));
566 return ret;
567 }
568
569 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to find accessor %s", name);
570 return GRIB_NOT_FOUND;
571 }
572
grib_is_missing_long(grib_accessor * a,long x)573 int grib_is_missing_long(grib_accessor* a, long x)
574 {
575 int ret = (a == NULL || (a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING)) && (x == GRIB_MISSING_LONG) ? 1 : 0;
576 return ret;
577 }
grib_is_missing_double(grib_accessor * a,double x)578 int grib_is_missing_double(grib_accessor* a, double x)
579 {
580 int ret = (a == NULL || (a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING)) && (x == GRIB_MISSING_DOUBLE) ? 1 : 0;
581 return ret;
582 }
583
grib_is_missing_string(grib_accessor * a,unsigned char * x,size_t len)584 int grib_is_missing_string(grib_accessor* a, unsigned char* x, size_t len)
585 {
586 /* For a string value to be missing, every character has to be */
587 /* all 1's (i.e. 0xFF) */
588 /* Note: An empty string is also classified as missing */
589 int ret;
590 size_t i = 0;
591
592 if (len == 0)
593 return 1; /* empty string */
594 ret = 1;
595 for (i = 0; i < len; i++) {
596 if (x[i] != 0xFF) {
597 ret = 0;
598 break;
599 }
600 }
601
602 ret = (a == NULL || ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) && ret == 1)) ? 1 : 0;
603 return ret;
604 }
605
grib_accessor_is_missing(grib_accessor * a,int * err)606 int grib_accessor_is_missing(grib_accessor* a, int* err)
607 {
608 *err = GRIB_SUCCESS;
609 if (a) {
610 if (a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING)
611 return grib_is_missing_internal(a);
612 else
613 return 0;
614 }
615 else {
616 *err = GRIB_NOT_FOUND;
617 return 1;
618 }
619 }
620
grib_is_missing(const grib_handle * h,const char * name,int * err)621 int grib_is_missing(const grib_handle* h, const char* name, int* err)
622 {
623 grib_accessor* a = grib_find_accessor(h, name);
624 return grib_accessor_is_missing(a, err);
625 }
626
627 /* Return true if the given key exists (is defined) in our grib message */
grib_is_defined(const grib_handle * h,const char * name)628 int grib_is_defined(const grib_handle* h, const char* name)
629 {
630 grib_accessor* a = grib_find_accessor(h, name);
631 return (a ? 1 : 0);
632 }
633
grib_set_flag(grib_handle * h,const char * name,unsigned long flag)634 int grib_set_flag(grib_handle* h, const char* name, unsigned long flag)
635 {
636 grib_accessor* a = grib_find_accessor(h, name);
637
638 if (!a)
639 return GRIB_NOT_FOUND;
640
641 a->flags |= flag;
642
643 return GRIB_SUCCESS;
644 }
645
_grib_set_double_array_internal(grib_handle * h,grib_accessor * a,const double * val,size_t buffer_len,size_t * encoded_length,int check)646 static int _grib_set_double_array_internal(grib_handle* h, grib_accessor* a,
647 const double* val, size_t buffer_len, size_t* encoded_length, int check)
648 {
649 if (a) {
650 int err = _grib_set_double_array_internal(h, a->same, val, buffer_len, encoded_length, check);
651
652 if (check && (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY))
653 return GRIB_READ_ONLY;
654
655 if (err == GRIB_SUCCESS) {
656 size_t len = buffer_len - *encoded_length;
657 if (len) {
658 err = grib_pack_double(a, val + *encoded_length, &len);
659 *encoded_length += len;
660 if (err == GRIB_SUCCESS) {
661 /* See ECC-778 */
662 return _grib_dependency_notify_change(h, a);
663 }
664 }
665 else {
666 grib_get_size(h, a->name, encoded_length);
667 err = GRIB_WRONG_ARRAY_SIZE;
668 }
669 }
670
671 return err;
672 }
673 else {
674 return GRIB_SUCCESS;
675 }
676 }
677
_grib_set_double_array(grib_handle * h,const char * name,const double * val,size_t length,int check)678 static int _grib_set_double_array(grib_handle* h, const char* name,
679 const double* val, size_t length, int check)
680 {
681 size_t encoded = 0;
682 grib_accessor* a = grib_find_accessor(h, name);
683 int err = 0;
684
685 if (!a)
686 return GRIB_NOT_FOUND;
687 if (name[0] == '/' || name[0] == '#') {
688 if (check && (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY))
689 return GRIB_READ_ONLY;
690 err = grib_pack_double(a, val, &length);
691 encoded = length;
692 }
693 else
694 err = _grib_set_double_array_internal(h, a, val, length, &encoded, check);
695
696 if (err == GRIB_SUCCESS && length > encoded)
697 err = GRIB_ARRAY_TOO_SMALL;
698
699 if (err == GRIB_SUCCESS)
700 return _grib_dependency_notify_change(h, a); /* See ECC-778 */
701
702 return err;
703 }
704
grib_set_double_array_internal(grib_handle * h,const char * name,const double * val,size_t length)705 int grib_set_double_array_internal(grib_handle* h, const char* name, const double* val, size_t length)
706 {
707 int ret = 0;
708
709 if (h->context->debug)
710 fprintf(stderr, "ECCODES DEBUG grib_set_double_array_internal key=%s %ld values\n", name, (long)length);
711
712 if (length == 0) {
713 grib_accessor* a = grib_find_accessor(h, name);
714 ret = grib_pack_double(a, val, &length);
715 }
716 else {
717 ret = _grib_set_double_array(h, name, val, length, 0);
718 }
719
720 if (ret != GRIB_SUCCESS)
721 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to set double array %s (%s)",
722 name, grib_get_error_message(ret));
723 /*if (h->context->debug) fprintf(stderr,"ECCODES DEBUG grib_set_double_array_internal key=%s --DONE\n",name);*/
724 return ret;
725 }
726
__grib_set_double_array(grib_handle * h,const char * name,const double * val,size_t length,int check)727 static int __grib_set_double_array(grib_handle* h, const char* name, const double* val, size_t length, int check)
728 {
729 double v = 0;
730 size_t i = 0;
731
732 if (h->context->debug) {
733 size_t N = 5;
734 /*double minVal = DBL_MAX, maxVal = -DBL_MAX;*/
735 if (length <= N)
736 N = length;
737 fprintf(stderr, "ECCODES DEBUG grib_set_double_array key=%s %ld values (", name, (long)length);
738 for (i = 0; i < N; ++i)
739 fprintf(stderr, " %g,", val[i]);
740 if (N >= length) fprintf(stderr, " )\n");
741 else fprintf(stderr, " ... )\n");
742 /*
743 * if (N >= length)
744 * fprintf(stderr, " )\t");
745 * else
746 * fprintf(stderr, " ... )\t");
747 * for (i = 0; i < length; ++i) {
748 * if (val[i] < minVal) minVal = val[i];
749 * if (val[i] > maxVal) maxVal = val[i];
750 * }
751 * fprintf(stderr, "min=%g, max=%g\n",minVal,maxVal);
752 */
753 }
754
755 if (length == 0) {
756 grib_accessor* a = grib_find_accessor(h, name);
757 return grib_pack_double(a, val, &length);
758 }
759
760 /*second order doesn't have a proper representation for constant fields
761 the best is not to do the change of packing type if the field is constant
762 */
763 if (!strcmp(name, "values") || !strcmp(name, "codedValues")) {
764 double missingValue;
765 int ret = 0;
766 int constant = 0;
767
768 ret = grib_get_double(h, "missingValue", &missingValue);
769 if (ret)
770 missingValue = 9999;
771
772 v = missingValue;
773 constant = 1;
774 for (i = 0; i < length; i++) {
775 if (val[i] != missingValue) {
776 if (v == missingValue) {
777 v = val[i];
778 }
779 else if (v != val[i]) {
780 constant = 0;
781 break;
782 }
783 }
784 }
785 if (constant) {
786 char packingType[50] = {0,};
787 size_t slen = 50;
788
789 grib_get_string(h, "packingType", packingType, &slen);
790 if (!strcmp(packingType, "grid_second_order") ||
791 !strcmp(packingType, "grid_second_order_no_SPD") ||
792 !strcmp(packingType, "grid_second_order_SPD1") ||
793 !strcmp(packingType, "grid_second_order_SPD2") ||
794 !strcmp(packingType, "grid_second_order_SPD3")) {
795 slen = 11; /*length of 'grid_simple' */
796 if (h->context->debug) {
797 fprintf(stderr, "ECCODES DEBUG __grib_set_double_array: Cannot use second order packing for constant fields. Using simple packing\n");
798 }
799 ret = grib_set_string(h, "packingType", "grid_simple", &slen);
800 if (ret != GRIB_SUCCESS) {
801 if (h->context->debug) {
802 fprintf(stderr, "ECCODES DEBUG __grib_set_double_array: could not switch to simple packing!\n");
803 }
804 }
805 }
806 }
807 }
808
809 return _grib_set_double_array(h, name, val, length, check);
810 }
811
grib_set_force_double_array(grib_handle * h,const char * name,const double * val,size_t length)812 int grib_set_force_double_array(grib_handle* h, const char* name, const double* val, size_t length)
813 {
814 /* GRIB-285: Same as grib_set_double_array but allows setting of READ-ONLY keys like codedValues */
815 /* Use with great caution!! */
816 return __grib_set_double_array(h, name, val, length, /*check=*/0);
817 }
818
grib_set_double_array(grib_handle * h,const char * name,const double * val,size_t length)819 int grib_set_double_array(grib_handle* h, const char* name, const double* val, size_t length)
820 {
821 return __grib_set_double_array(h, name, val, length, /*check=*/1);
822 }
823
_grib_set_long_array_internal(grib_handle * h,grib_accessor * a,const long * val,size_t buffer_len,size_t * encoded_length,int check)824 static int _grib_set_long_array_internal(grib_handle* h, grib_accessor* a, const long* val, size_t buffer_len, size_t* encoded_length, int check)
825 {
826 if (a) {
827 int err = _grib_set_long_array_internal(h, a->same, val, buffer_len, encoded_length, check);
828
829 if (check && (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY))
830 return GRIB_READ_ONLY;
831
832 if (err == GRIB_SUCCESS) {
833 size_t len = buffer_len - *encoded_length;
834 if (len) {
835 err = grib_pack_long(a, val + *encoded_length, &len);
836 *encoded_length += len;
837 }
838 else {
839 grib_get_size(h, a->name, encoded_length);
840 err = GRIB_WRONG_ARRAY_SIZE;
841 }
842 }
843
844 return err;
845 }
846 else {
847 return GRIB_SUCCESS;
848 }
849 }
850
_grib_set_long_array(grib_handle * h,const char * name,const long * val,size_t length,int check)851 static int _grib_set_long_array(grib_handle* h, const char* name, const long* val, size_t length, int check)
852 {
853 size_t encoded = 0;
854 grib_accessor* a = grib_find_accessor(h, name);
855 int err = 0;
856
857 if (!a)
858 return GRIB_NOT_FOUND;
859
860 if (h->context->debug) {
861 size_t i = 0;
862 size_t N = 5;
863 if (length <= N)
864 N = length;
865 fprintf(stderr, "ECCODES DEBUG _grib_set_long_array key=%s %ld values (", name, (long)length);
866 for (i = 0; i < N; ++i)
867 fprintf(stderr, " %ld,", val[i]);
868 if (N >= length)
869 fprintf(stderr, " )\n");
870 else
871 fprintf(stderr, " ... )\n");
872 }
873
874 if (name[0] == '/' || name[0] == '#') {
875 if (check && (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY))
876 return GRIB_READ_ONLY;
877 err = grib_pack_long(a, val, &length);
878 encoded = length;
879 }
880 else
881 err = _grib_set_long_array_internal(h, a, val, length, &encoded, check);
882
883 if (err == GRIB_SUCCESS && length > encoded)
884 err = GRIB_ARRAY_TOO_SMALL;
885
886 if (err == GRIB_SUCCESS)
887 return grib_dependency_notify_change(a);
888
889 return err;
890 }
891
grib_set_long_array_internal(grib_handle * h,const char * name,const long * val,size_t length)892 int grib_set_long_array_internal(grib_handle* h, const char* name, const long* val, size_t length)
893 {
894 int ret = _grib_set_long_array(h, name, val, length, 0);
895 if (ret != GRIB_SUCCESS)
896 grib_context_log(h->context, GRIB_LOG_ERROR, "unable to set long array %s (%s)",
897 name, grib_get_error_message(ret));
898 return ret;
899 }
900
grib_set_long_array(grib_handle * h,const char * name,const long * val,size_t length)901 int grib_set_long_array(grib_handle* h, const char* name, const long* val, size_t length)
902 {
903 return _grib_set_long_array(h, name, val, length, 1);
904 }
905
grib_get_long_internal(grib_handle * h,const char * name,long * val)906 int grib_get_long_internal(grib_handle* h, const char* name, long* val)
907 {
908 int ret = grib_get_long(h, name, val);
909
910 if (ret != GRIB_SUCCESS) {
911 grib_context_log(h->context, GRIB_LOG_ERROR,
912 "unable to get %s as long (%s)",
913 name, grib_get_error_message(ret));
914 }
915
916 return ret;
917 }
918
grib_is_in_dump(grib_handle * h,const char * name)919 int grib_is_in_dump(grib_handle* h, const char* name)
920 {
921 grib_accessor* a = grib_find_accessor(h, name);
922 if (a != NULL && (a->flags & GRIB_ACCESSOR_FLAG_DUMP))
923 return 1;
924 else
925 return 0;
926 }
927
grib_attributes_count(grib_accessor * a,size_t * size)928 int grib_attributes_count(grib_accessor* a, size_t* size)
929 {
930 if (a) {
931 *size = 0;
932 while (a->attributes[*size] != NULL) {
933 (*size)++;
934 }
935 return GRIB_SUCCESS;
936 }
937
938 return GRIB_NOT_FOUND;
939 }
940
grib_get_long(const grib_handle * h,const char * name,long * val)941 int grib_get_long(const grib_handle* h, const char* name, long* val)
942 {
943 size_t length = 1;
944 grib_accessor* a = NULL;
945 grib_accessors_list* al = NULL;
946 int ret = 0;
947
948 if (name[0] == '/') {
949 al = grib_find_accessors_list(h, name);
950 if (!al)
951 return GRIB_NOT_FOUND;
952 ret = grib_unpack_long(al->accessor, val, &length);
953 grib_context_free(h->context, al);
954 }
955 else {
956 a = grib_find_accessor(h, name);
957 if (!a)
958 return GRIB_NOT_FOUND;
959 ret = grib_unpack_long(a, val, &length);
960 }
961 return ret;
962 }
963
grib_get_double_internal(grib_handle * h,const char * name,double * val)964 int grib_get_double_internal(grib_handle* h, const char* name, double* val)
965 {
966 int ret = grib_get_double(h, name, val);
967
968 if (ret != GRIB_SUCCESS)
969 grib_context_log(h->context, GRIB_LOG_ERROR,
970 "unable to get %s as double (%s)",
971 name, grib_get_error_message(ret));
972
973 return ret;
974 }
975
grib_get_double(const grib_handle * h,const char * name,double * val)976 int grib_get_double(const grib_handle* h, const char* name, double* val)
977 {
978 size_t length = 1;
979 grib_accessor* a = NULL;
980 grib_accessors_list* al = NULL;
981 int ret = 0;
982
983 if (name[0] == '/') {
984 al = grib_find_accessors_list(h, name);
985 if (!al)
986 return GRIB_NOT_FOUND;
987 ret = grib_unpack_double(al->accessor, val, &length);
988 grib_context_free(h->context, al);
989 }
990 else {
991 a = grib_find_accessor(h, name);
992 if (!a)
993 return GRIB_NOT_FOUND;
994 ret = grib_unpack_double(a, val, &length);
995 }
996 return ret;
997 }
998
grib_get_double_element_internal(grib_handle * h,const char * name,int i,double * val)999 int grib_get_double_element_internal(grib_handle* h, const char* name, int i, double* val)
1000 {
1001 int ret = grib_get_double_element(h, name, i, val);
1002
1003 if (ret != GRIB_SUCCESS)
1004 grib_context_log(h->context, GRIB_LOG_ERROR,
1005 "unable to get %s as double element (%s)",
1006 name, grib_get_error_message(ret));
1007
1008 return ret;
1009 }
1010
grib_get_double_element(const grib_handle * h,const char * name,int i,double * val)1011 int grib_get_double_element(const grib_handle* h, const char* name, int i, double* val)
1012 {
1013 grib_accessor* act = grib_find_accessor(h, name);
1014
1015 if (act) {
1016 return grib_unpack_double_element(act, i, val);
1017 }
1018 return GRIB_NOT_FOUND;
1019 }
1020
grib_points_get_values(grib_handle * h,grib_points * points,double * val)1021 int grib_points_get_values(grib_handle* h, grib_points* points, double* val)
1022 {
1023 int i, ret;
1024 grib_accessor* a = NULL;
1025
1026 a = grib_find_accessor(h, "values");
1027
1028 for (i = 0; i < points->n_groups; i++) {
1029 ret = grib_unpack_double_subarray(a, val, points->group_start[i], points->group_len[i]);
1030 if (ret)
1031 return ret;
1032 val += points->group_len[i];
1033 }
1034 return GRIB_SUCCESS;
1035 }
1036
grib_get_double_elements(const grib_handle * h,const char * name,int * index_array,long len,double * val_array)1037 int grib_get_double_elements(const grib_handle* h, const char* name, int* index_array, long len, double* val_array)
1038 {
1039 double* values = 0;
1040 int err = 0;
1041 size_t size = 0, num_bytes = 0;
1042 long j = 0;
1043 grib_accessor* act = NULL;
1044
1045 act = grib_find_accessor(h, name);
1046 if (!act)
1047 return GRIB_NOT_FOUND;
1048
1049 err = _grib_get_size(h, act, &size);
1050
1051 if (err != GRIB_SUCCESS) {
1052 grib_context_log(h->context, GRIB_LOG_ERROR, "grib_get_double_elements: cannot get size of %s\n", name);
1053 return err;
1054 }
1055
1056 /* Check index array has valid values */
1057 for (j = 0; j < len; j++) {
1058 const int anIndex = index_array[j];
1059 if (anIndex < 0 || anIndex >= size) {
1060 grib_context_log(h->context, GRIB_LOG_ERROR,
1061 "grib_get_double_elements: index out of range: %d (should be between 0 and %ld)", anIndex, size - 1);
1062 return GRIB_INVALID_ARGUMENT;
1063 }
1064 }
1065
1066 num_bytes = size * sizeof(double);
1067 values = (double*)grib_context_malloc(h->context, num_bytes);
1068 if (!values) {
1069 grib_context_log(h->context, GRIB_LOG_ERROR, "grib_get_double_elements: unable to allocate %ld bytes\n", num_bytes);
1070 return GRIB_OUT_OF_MEMORY;
1071 }
1072
1073 err = grib_unpack_double(act, values, &size);
1074 if (!err) {
1075 for (j = 0; j < len; j++) {
1076 val_array[j] = values[index_array[j]];
1077 }
1078 }
1079
1080 grib_context_free(h->context, values);
1081
1082 return err;
1083 }
1084
grib_get_string_internal(grib_handle * h,const char * name,char * val,size_t * length)1085 int grib_get_string_internal(grib_handle* h, const char* name, char* val, size_t* length)
1086 {
1087 int ret = grib_get_string(h, name, val, length);
1088
1089 if (ret != GRIB_SUCCESS)
1090 grib_context_log(h->context, GRIB_LOG_ERROR,
1091 "unable to get %s as string (%s)",
1092 name, grib_get_error_message(ret));
1093
1094 return ret;
1095 }
1096
grib_get_string(const grib_handle * h,const char * name,char * val,size_t * length)1097 int grib_get_string(const grib_handle* h, const char* name, char* val, size_t* length)
1098 {
1099 grib_accessor* a = NULL;
1100 grib_accessors_list* al = NULL;
1101 int ret = 0;
1102
1103 if (name[0] == '/') {
1104 al = grib_find_accessors_list(h, name);
1105 if (!al)
1106 return GRIB_NOT_FOUND;
1107 ret = grib_unpack_string(al->accessor, val, length);
1108 grib_context_free(h->context, al);
1109 return ret;
1110 }
1111 else {
1112 a = grib_find_accessor(h, name);
1113 if (!a)
1114 return GRIB_NOT_FOUND;
1115 return grib_unpack_string(a, val, length);
1116 }
1117 }
1118
grib_get_bytes_internal(const grib_handle * h,const char * name,unsigned char * val,size_t * length)1119 int grib_get_bytes_internal(const grib_handle* h, const char* name, unsigned char* val, size_t* length)
1120 {
1121 int ret = grib_get_bytes(h, name, val, length);
1122
1123 if (ret != GRIB_SUCCESS)
1124 grib_context_log(h->context, GRIB_LOG_ERROR,
1125 "unable to get %s as bytes (%s)",
1126 name, grib_get_error_message(ret));
1127
1128 return ret;
1129 }
1130
grib_get_bytes(const grib_handle * h,const char * name,unsigned char * val,size_t * length)1131 int grib_get_bytes(const grib_handle* h, const char* name, unsigned char* val, size_t* length)
1132 {
1133 int err = 0;
1134 grib_accessor* act = grib_find_accessor(h, name);
1135 err = act ? grib_unpack_bytes(act, val, length) : GRIB_NOT_FOUND;
1136 if (err)
1137 grib_context_log(h->context, GRIB_LOG_ERROR,
1138 "grib_get_bytes %s failed %s", name, grib_get_error_message(err));
1139 return err;
1140 }
1141
grib_get_native_type(const grib_handle * h,const char * name,int * type)1142 int grib_get_native_type(const grib_handle* h, const char* name, int* type)
1143 {
1144 grib_accessors_list* al = NULL;
1145 grib_accessor* a = NULL;
1146 *type = GRIB_TYPE_UNDEFINED;
1147
1148 DebugAssert(name != NULL && strlen(name) > 0);
1149
1150 if (name[0] == '/') {
1151 al = grib_find_accessors_list(h, name);
1152 if (!al)
1153 return GRIB_NOT_FOUND;
1154 *type = grib_accessor_get_native_type(al->accessor);
1155 grib_context_free(h->context, al);
1156 }
1157 else {
1158 a = grib_find_accessor(h, name);
1159 if (!a)
1160 return GRIB_NOT_FOUND;
1161 *type = grib_accessor_get_native_type(a);
1162 }
1163
1164 return GRIB_SUCCESS;
1165 }
1166
grib_get_accessor_class_name(grib_handle * h,const char * name)1167 const char* grib_get_accessor_class_name(grib_handle* h, const char* name)
1168 {
1169 grib_accessor* act = grib_find_accessor(h, name);
1170 return act ? act->cclass->name : NULL;
1171 }
1172
_grib_get_double_array_internal(const grib_handle * h,grib_accessor * a,double * val,size_t buffer_len,size_t * decoded_length)1173 int _grib_get_double_array_internal(const grib_handle* h, grib_accessor* a, double* val, size_t buffer_len, size_t* decoded_length)
1174 {
1175 if (a) {
1176 int err = _grib_get_double_array_internal(h, a->same, val, buffer_len, decoded_length);
1177
1178 if (err == GRIB_SUCCESS) {
1179 size_t len = buffer_len - *decoded_length;
1180 err = grib_unpack_double(a, val + *decoded_length, &len);
1181 *decoded_length += len;
1182 }
1183
1184 return err;
1185 }
1186 else {
1187 return GRIB_SUCCESS;
1188 }
1189 }
1190
grib_get_double_array_internal(const grib_handle * h,const char * name,double * val,size_t * length)1191 int grib_get_double_array_internal(const grib_handle* h, const char* name, double* val, size_t* length)
1192 {
1193 int ret = grib_get_double_array(h, name, val, length);
1194
1195 if (ret != GRIB_SUCCESS)
1196 grib_context_log(h->context, GRIB_LOG_ERROR,
1197 "unable to get %s as double array (%s)",
1198 name, grib_get_error_message(ret));
1199
1200 return ret;
1201 }
1202
grib_get_double_array(const grib_handle * h,const char * name,double * val,size_t * length)1203 int grib_get_double_array(const grib_handle* h, const char* name, double* val, size_t* length)
1204 {
1205 size_t len = *length;
1206 grib_accessor* a = NULL;
1207 grib_accessors_list* al = NULL;
1208 int ret = 0;
1209
1210 if (name[0] == '/') {
1211 al = grib_find_accessors_list(h, name);
1212 if (!al)
1213 return GRIB_NOT_FOUND;
1214 ret = grib_accessors_list_unpack_double(al, val, length);
1215 grib_accessors_list_delete(h->context, al);
1216 return ret;
1217 }
1218 else {
1219 a = grib_find_accessor(h, name);
1220 if (!a)
1221 return GRIB_NOT_FOUND;
1222 if (name[0] == '#') {
1223 return grib_unpack_double(a, val, length);
1224 }
1225 else {
1226 *length = 0;
1227 return _grib_get_double_array_internal(h, a, val, len, length);
1228 }
1229 }
1230 }
1231
_grib_get_string_length(grib_accessor * a,size_t * size)1232 int _grib_get_string_length(grib_accessor* a, size_t* size)
1233 {
1234 size_t s = 0;
1235
1236 *size = 0;
1237 while (a) {
1238 s = grib_string_length(a);
1239 if (s > *size)
1240 *size = s;
1241 a = a->same;
1242 }
1243 (*size) += 1;
1244
1245 return GRIB_SUCCESS;
1246 }
1247
grib_get_string_length(const grib_handle * h,const char * name,size_t * size)1248 int grib_get_string_length(const grib_handle* h, const char* name, size_t* size)
1249 {
1250 grib_accessor* a = NULL;
1251 grib_accessors_list* al = NULL;
1252 int ret = 0;
1253
1254 if (name[0] == '/') {
1255 al = grib_find_accessors_list(h, name);
1256 if (!al)
1257 return GRIB_NOT_FOUND;
1258 ret = _grib_get_string_length(al->accessor, size);
1259 grib_context_free(h->context, al);
1260 return ret;
1261 }
1262 else {
1263 a = grib_find_accessor(h, name);
1264 if (!a)
1265 return GRIB_NOT_FOUND;
1266 return _grib_get_string_length(a, size);
1267 }
1268 }
1269
_grib_get_size(const grib_handle * h,grib_accessor * a,size_t * size)1270 int _grib_get_size(const grib_handle* h, grib_accessor* a, size_t* size)
1271 {
1272 long count = 0;
1273 int err = 0;
1274
1275 if (!a)
1276 return GRIB_NOT_FOUND;
1277
1278 *size = 0;
1279 while (a) {
1280 if (err == 0) {
1281 err = grib_value_count(a, &count);
1282 if (err)
1283 return err;
1284 *size += count;
1285 }
1286 a = a->same;
1287 }
1288 return GRIB_SUCCESS;
1289 }
1290
grib_get_size(const grib_handle * ch,const char * name,size_t * size)1291 int grib_get_size(const grib_handle* ch, const char* name, size_t* size)
1292 {
1293 grib_handle* h = (grib_handle*)ch;
1294 grib_accessor* a = NULL;
1295 grib_accessors_list* al = NULL;
1296 int ret = 0;
1297 *size = 0;
1298
1299 if (name[0] == '/') {
1300 al = grib_find_accessors_list(h, name);
1301 if (!al)
1302 return GRIB_NOT_FOUND;
1303 ret = grib_accessors_list_value_count(al, size);
1304 grib_accessors_list_delete(h->context, al);
1305 return ret;
1306 }
1307 else {
1308 a = grib_find_accessor(h, name);
1309 if (!a)
1310 return GRIB_NOT_FOUND;
1311 if (name[0] == '#') {
1312 long count = *size;
1313 ret = grib_value_count(a, &count);
1314 *size = count;
1315 return ret;
1316 }
1317 else
1318 return _grib_get_size(h, a, size);
1319 }
1320 }
1321
grib_get_length(const grib_handle * h,const char * name,size_t * length)1322 int grib_get_length(const grib_handle* h, const char* name, size_t* length)
1323 {
1324 return grib_get_string_length(h, name, length);
1325 }
1326
grib_get_count(grib_handle * h,const char * name,size_t * size)1327 int grib_get_count(grib_handle* h, const char* name, size_t* size)
1328 {
1329 grib_accessor* a = grib_find_accessor(h, name);
1330 if (!a)
1331 return GRIB_NOT_FOUND;
1332
1333 *size = 0;
1334 while (a) {
1335 (*size)++;
1336 a = a->same;
1337 }
1338 return GRIB_SUCCESS;
1339 }
1340
grib_get_offset(const grib_handle * ch,const char * key,size_t * val)1341 int grib_get_offset(const grib_handle* ch, const char* key, size_t* val)
1342 {
1343 grib_handle* h = (grib_handle*)ch;
1344 grib_accessor* act = grib_find_accessor(h, key);
1345 if (act) {
1346 *val = (size_t)grib_byte_offset(act);
1347 return GRIB_SUCCESS;
1348 }
1349 return GRIB_NOT_FOUND;
1350 }
1351
_grib_get_string_array_internal(const grib_handle * h,grib_accessor * a,char ** val,size_t buffer_len,size_t * decoded_length)1352 int _grib_get_string_array_internal(const grib_handle* h, grib_accessor* a, char** val, size_t buffer_len, size_t* decoded_length)
1353 {
1354 if (a) {
1355 int err = _grib_get_string_array_internal(h, a->same, val, buffer_len, decoded_length);
1356
1357 if (err == GRIB_SUCCESS) {
1358 size_t len = buffer_len - *decoded_length;
1359 err = grib_unpack_string_array(a, val + *decoded_length, &len);
1360 *decoded_length += len;
1361 }
1362
1363 return err;
1364 }
1365 else {
1366 return GRIB_SUCCESS;
1367 }
1368 }
1369
grib_get_string_array(const grib_handle * h,const char * name,char ** val,size_t * length)1370 int grib_get_string_array(const grib_handle* h, const char* name, char** val, size_t* length)
1371 {
1372 size_t len = *length;
1373 grib_accessor* a = NULL;
1374 grib_accessors_list* al = NULL;
1375 int ret = 0;
1376
1377 if (name[0] == '/') {
1378 al = grib_find_accessors_list(h, name);
1379 if (!al)
1380 return GRIB_NOT_FOUND;
1381 ret = grib_accessors_list_unpack_string(al, val, length);
1382 grib_context_free(h->context, al);
1383 return ret;
1384 }
1385 else {
1386 a = grib_find_accessor(h, name);
1387 if (!a)
1388 return GRIB_NOT_FOUND;
1389 if (name[0] == '#') {
1390 return grib_unpack_string_array(a, val, length);
1391 }
1392 else {
1393 *length = 0;
1394 return _grib_get_string_array_internal(h, a, val, len, length);
1395 }
1396 }
1397 }
1398
_grib_get_long_array_internal(const grib_handle * h,grib_accessor * a,long * val,size_t buffer_len,size_t * decoded_length)1399 int _grib_get_long_array_internal(const grib_handle* h, grib_accessor* a, long* val, size_t buffer_len, size_t* decoded_length)
1400 {
1401 if (a) {
1402 int err = _grib_get_long_array_internal(h, a->same, val, buffer_len, decoded_length);
1403
1404 if (err == GRIB_SUCCESS) {
1405 size_t len = buffer_len - *decoded_length;
1406 err = grib_unpack_long(a, val + *decoded_length, &len);
1407 *decoded_length += len;
1408 }
1409
1410 return err;
1411 }
1412 else {
1413 return GRIB_SUCCESS;
1414 }
1415 }
1416
grib_get_long_array_internal(grib_handle * h,const char * name,long * val,size_t * length)1417 int grib_get_long_array_internal(grib_handle* h, const char* name, long* val, size_t* length)
1418 {
1419 int ret = grib_get_long_array(h, name, val, length);
1420
1421 if (ret != GRIB_SUCCESS)
1422 grib_context_log(h->context, GRIB_LOG_ERROR,
1423 "unable to get %s as long array (%s)",
1424 name, grib_get_error_message(ret));
1425
1426 return ret;
1427 }
1428
grib_get_long_array(const grib_handle * h,const char * name,long * val,size_t * length)1429 int grib_get_long_array(const grib_handle* h, const char* name, long* val, size_t* length)
1430 {
1431 size_t len = *length;
1432 grib_accessor* a = NULL;
1433 grib_accessors_list* al = NULL;
1434 int ret = 0;
1435
1436 if (name[0] == '/') {
1437 al = grib_find_accessors_list(h, name);
1438 if (!al)
1439 return GRIB_NOT_FOUND;
1440 ret = grib_accessors_list_unpack_long(al, val, length);
1441 grib_context_free(h->context, al);
1442 }
1443 else {
1444 a = grib_find_accessor(h, name);
1445 if (!a)
1446 return GRIB_NOT_FOUND;
1447 if (name[0] == '#') {
1448 return grib_unpack_long(a, val, length);
1449 }
1450 else {
1451 *length = 0;
1452 return _grib_get_long_array_internal(h, a, val, len, length);
1453 }
1454 }
1455 return ret;
1456 }
1457
grib_clean_key_value(grib_context * c,grib_key_value_list * kv)1458 static void grib_clean_key_value(grib_context* c, grib_key_value_list* kv)
1459 {
1460 if (kv->long_value)
1461 grib_context_free(c, kv->long_value);
1462 kv->long_value = NULL;
1463 if (kv->double_value)
1464 grib_context_free(c, kv->double_value);
1465 kv->double_value = NULL;
1466 if (kv->string_value)
1467 grib_context_free(c, kv->string_value);
1468 kv->string_value = NULL;
1469 if (kv->namespace_value)
1470 grib_key_value_list_delete(c, kv->namespace_value);
1471 kv->namespace_value = NULL;
1472 kv->error = 0;
1473 kv->has_value = 0;
1474 kv->size = 0;
1475 }
1476
grib_get_key_value(grib_handle * h,grib_key_value_list * kv)1477 static int grib_get_key_value(grib_handle* h, grib_key_value_list* kv)
1478 {
1479 int err = 0;
1480 size_t size = 0;
1481 grib_keys_iterator* iter = NULL;
1482 grib_key_value_list* list = NULL;
1483
1484 if (kv->has_value)
1485 grib_clean_key_value(h->context, kv);
1486
1487 err = grib_get_size(h, kv->name, &size);
1488 if (err) {
1489 kv->error = err;
1490 return err;
1491 }
1492 if (size == 0)
1493 size = 512;
1494
1495 switch (kv->type) {
1496 case GRIB_TYPE_LONG:
1497 kv->long_value = (long*)grib_context_malloc_clear(h->context, size * sizeof(long));
1498 err = grib_get_long_array(h, kv->name, kv->long_value, &size);
1499 kv->error = err;
1500 break;
1501 case GRIB_TYPE_DOUBLE:
1502 kv->double_value = (double*)grib_context_malloc_clear(h->context, size * sizeof(double));
1503 err = grib_get_double_array(h, kv->name, kv->double_value, &size);
1504 kv->error = err;
1505 break;
1506 case GRIB_TYPE_STRING:
1507 grib_get_string_length(h, kv->name, &size);
1508 kv->string_value = (char*)grib_context_malloc_clear(h->context, size * sizeof(char));
1509 err = grib_get_string(h, kv->name, kv->string_value, &size);
1510 kv->error = err;
1511 break;
1512 case GRIB_TYPE_BYTES:
1513 kv->string_value = (char*)grib_context_malloc_clear(h->context, size * sizeof(char));
1514 err = grib_get_bytes(h, kv->name, (unsigned char*)kv->string_value, &size);
1515 kv->error = err;
1516 break;
1517 case GRIB_NAMESPACE:
1518 iter = grib_keys_iterator_new(h, 0, kv->name);
1519 list = (grib_key_value_list*)grib_context_malloc_clear(h->context, sizeof(grib_key_value_list));
1520 kv->namespace_value = list;
1521 while (grib_keys_iterator_next(iter)) {
1522 list->name = grib_keys_iterator_get_name(iter);
1523 err = grib_get_native_type(h, list->name, &(list->type));
1524 if (err)
1525 return err;
1526 err = grib_get_key_value(h, list);
1527 if (err)
1528 return err;
1529 list->next = (grib_key_value_list*)grib_context_malloc_clear(h->context, sizeof(grib_key_value_list));
1530 list = list->next;
1531 }
1532 grib_keys_iterator_delete(iter);
1533 break;
1534
1535 default:
1536 err = grib_get_native_type(h, kv->name, &(kv->type));
1537 if (err)
1538 return err;
1539 err = grib_get_key_value(h, kv);
1540 break;
1541 }
1542 kv->has_value = 1;
1543 return err;
1544 }
1545
grib_key_value_list_clone(grib_context * c,grib_key_value_list * list)1546 grib_key_value_list* grib_key_value_list_clone(grib_context* c, grib_key_value_list* list)
1547 {
1548 grib_key_value_list* next = list;
1549 grib_key_value_list* the_clone = (grib_key_value_list*)grib_context_malloc_clear(c, sizeof(grib_key_value_list));
1550 grib_key_value_list* p = the_clone;
1551
1552 while (next && next->name) {
1553 p->name = grib_context_strdup(c, next->name);
1554 p->type = next->type;
1555 next = next->next;
1556 }
1557 return the_clone;
1558 }
1559
grib_key_value_list_delete(grib_context * c,grib_key_value_list * kvl)1560 void grib_key_value_list_delete(grib_context* c, grib_key_value_list* kvl)
1561 {
1562 grib_key_value_list* next = kvl;
1563 grib_key_value_list* p = NULL;
1564 while (next) {
1565 p = next->next;
1566 if (next->type == GRIB_NAMESPACE)
1567 grib_key_value_list_delete(c, next->namespace_value);
1568
1569 grib_clean_key_value(c, next);
1570 grib_context_free(c, next);
1571 next = p;
1572 }
1573 }
1574
grib_get_key_value_list(grib_handle * h,grib_key_value_list * list)1575 int grib_get_key_value_list(grib_handle* h, grib_key_value_list* list)
1576 {
1577 int ret = 0;
1578 grib_key_value_list* kvl = list;
1579 while (kvl) {
1580 ret = grib_get_key_value(h, kvl);
1581 kvl = kvl->next;
1582 }
1583 return ret;
1584 }
1585
grib_get_values(grib_handle * h,grib_values * args,size_t count)1586 int grib_get_values(grib_handle* h, grib_values* args, size_t count)
1587 {
1588 int ret = 0;
1589 int i = 0;
1590
1591 for (i = 0; i < count; i++) {
1592 char buff[1024] = {0,};
1593 size_t len = sizeof(buff) / sizeof(*buff);
1594
1595 if (!args[i].name) {
1596 args[i].error = GRIB_INVALID_ARGUMENT;
1597 continue;
1598 }
1599
1600 if (args[i].type == 0) {
1601 args[i].error = grib_get_native_type(h, args[i].name, &(args[i].type));
1602 if (args[i].error != GRIB_SUCCESS)
1603 ret = args[i].error;
1604 }
1605
1606 switch (args[i].type) {
1607 case GRIB_TYPE_LONG:
1608 args[i].error = grib_get_long(h, args[i].name, &(args[i].long_value));
1609 if (args[i].error != GRIB_SUCCESS)
1610 ret = args[i].error;
1611 break;
1612
1613 case GRIB_TYPE_DOUBLE:
1614 args[i].error = grib_get_double(h, args[i].name, &(args[i].double_value));
1615 if (args[i].error != GRIB_SUCCESS)
1616 ret = args[i].error;
1617 break;
1618
1619 case GRIB_TYPE_STRING:
1620 args[i].error = grib_get_string(h, args[i].name, buff, &len);
1621 args[i].string_value = strdup(buff);
1622 if (args[i].error != GRIB_SUCCESS)
1623 ret = args[i].error;
1624 break;
1625
1626 default:
1627 args[i].error = grib_get_string(h, args[i].name, buff, &len);
1628 args[i].string_value = strdup(buff);
1629 if (args[i].error != GRIB_SUCCESS)
1630 ret = args[i].error;
1631 break;
1632 }
1633 }
1634
1635 return ret;
1636 }
1637
grib_set_values(grib_handle * h,grib_values * args,size_t count)1638 int grib_set_values(grib_handle* h, grib_values* args, size_t count)
1639 {
1640 int i, error = 0;
1641 int err = 0;
1642 size_t len;
1643 int more = 1;
1644 int stack = h->values_stack++;
1645
1646 Assert(h->values_stack < MAX_SET_VALUES - 1);
1647
1648 h->values[stack] = args;
1649 h->values_count[stack] = count;
1650
1651 for (i = 0; i < count; i++)
1652 args[i].error = GRIB_NOT_FOUND;
1653
1654 while (more) {
1655 more = 0;
1656 for (i = 0; i < count; i++) {
1657 if (args[i].error != GRIB_NOT_FOUND)
1658 continue;
1659
1660 switch (args[i].type) {
1661 case GRIB_TYPE_LONG:
1662 error = grib_set_long(h, args[i].name, args[i].long_value);
1663 args[i].error = error;
1664 if (args[i].error == GRIB_SUCCESS)
1665 more = 1;
1666 break;
1667
1668 case GRIB_TYPE_DOUBLE:
1669 args[i].error = grib_set_double(h, args[i].name, args[i].double_value);
1670 if (args[i].error == GRIB_SUCCESS)
1671 more = 1;
1672 break;
1673
1674 case GRIB_TYPE_STRING:
1675 len = strlen(args[i].string_value);
1676 args[i].error = grib_set_string(h, args[i].name, args[i].string_value, &len);
1677 if (args[i].error == GRIB_SUCCESS)
1678 more = 1;
1679 break;
1680
1681 case GRIB_TYPE_MISSING:
1682 args[i].error = grib_set_missing(h, args[i].name);
1683 if (args[i].error == GRIB_SUCCESS)
1684 more = 1;
1685 break;
1686
1687 default:
1688 grib_context_log(h->context, GRIB_LOG_ERROR, "grib_set_values[%d] %s invalid type %d", i, args[i].name, args[i].type);
1689 args[i].error = GRIB_INVALID_ARGUMENT;
1690 break;
1691 }
1692 /*if (args[i].error != GRIB_SUCCESS)
1693 grib_context_log(h->context,GRIB_LOG_ERROR,"unable to set %s (%s)",
1694 args[i].name,grib_get_error_message(args[i].error)); */
1695 }
1696 }
1697
1698 h->values[stack] = NULL;
1699 h->values_count[stack] = 0;
1700
1701 h->values_stack--;
1702
1703 for (i = 0; i < count; i++) {
1704 if (args[i].error != GRIB_SUCCESS) {
1705 grib_context_log(h->context, GRIB_LOG_ERROR,
1706 "grib_set_values[%d] %s (type=%s) failed: %s",
1707 i, args[i].name, grib_get_type_name(args[i].type),
1708 grib_get_error_message(args[i].error));
1709 err = err == GRIB_SUCCESS ? args[i].error : err;
1710 }
1711 }
1712
1713 return err;
1714 }
1715
grib_get_nearest_smaller_value(grib_handle * h,const char * name,double val,double * nearest)1716 int grib_get_nearest_smaller_value(grib_handle* h, const char* name,
1717 double val, double* nearest)
1718 {
1719 grib_accessor* act = grib_find_accessor(h, name);
1720 Assert(act);
1721 return grib_nearest_smaller_value(act, val, nearest);
1722 }
1723
grib_print_values(grib_values * values,int count)1724 void grib_print_values(grib_values* values, int count)
1725 {
1726 int i;
1727 for (i = 0; i < count; i++) {
1728 printf("%s = ", values[i].name);
1729 switch (values[i].type) {
1730 case GRIB_TYPE_LONG:
1731 printf("%ld", values[i].long_value);
1732 break;
1733 case GRIB_TYPE_DOUBLE:
1734 printf("%g", values[i].double_value);
1735 break;
1736 case GRIB_TYPE_STRING:
1737 printf("%s", values[i].string_value);
1738 break;
1739 }
1740 printf("\n");
1741 }
1742 }
1743
grib_values_check(grib_handle * h,grib_values * values,int count)1744 int grib_values_check(grib_handle* h, grib_values* values, int count)
1745 {
1746 int i = 0;
1747 long long_value;
1748 double double_value;
1749 unsigned char ubuff[1024] = {0,};
1750 char buff[1024] = {0,};
1751 size_t len = 1024;
1752
1753 for (i = 0; i < count; i++) {
1754 if (values[i].type == 0) {
1755 values[i].error = GRIB_INVALID_TYPE;
1756 return values[i].error;
1757 }
1758
1759 switch (values[i].type) {
1760 case GRIB_TYPE_LONG:
1761 values[i].error = grib_get_long(h, values[i].name, &long_value);
1762 if (values[i].error != GRIB_SUCCESS)
1763 return values[i].error;
1764 if (long_value != values[i].long_value) {
1765 values[i].error = GRIB_VALUE_DIFFERENT;
1766 return values[i].error;
1767 }
1768 break;
1769
1770 case GRIB_TYPE_DOUBLE:
1771 values[i].error = grib_get_double(h, values[i].name, &double_value);
1772 if (values[i].error != GRIB_SUCCESS)
1773 return values[i].error;
1774 if (double_value != values[i].double_value) {
1775 values[i].error = GRIB_VALUE_DIFFERENT;
1776 return values[i].error;
1777 }
1778 break;
1779
1780 case GRIB_TYPE_STRING:
1781 values[i].error = grib_get_string(h, values[i].name, buff, &len);
1782 if (values[i].error != GRIB_SUCCESS)
1783 return values[i].error;
1784 if (strcmp(values[i].string_value, buff)) {
1785 values[i].error = GRIB_VALUE_DIFFERENT;
1786 return values[i].error;
1787 }
1788 break;
1789
1790 case GRIB_TYPE_BYTES:
1791 values[i].error = grib_get_bytes(h, values[i].name, ubuff, &len);
1792 if (values[i].error != GRIB_SUCCESS)
1793 return values[i].error;
1794 if (memcmp(values[i].string_value, ubuff, len)) {
1795 values[i].error = GRIB_VALUE_DIFFERENT;
1796 return values[i].error;
1797 }
1798 break;
1799
1800 default:
1801 values[i].error = GRIB_INVALID_TYPE;
1802 return values[i].error;
1803 }
1804 }
1805
1806 return 0;
1807 }
1808
grib_key_equal(grib_handle * h1,grib_handle * h2,const char * key,int type,int * err)1809 int grib_key_equal(grib_handle* h1, grib_handle* h2, const char* key, int type, int* err)
1810 {
1811 double d1 = 0, d2 = 0;
1812 long l1 = 0, l2 = 0;
1813 char s1[500] = {0,};
1814 char s2[500] = {0,};
1815 size_t len1, len2;
1816
1817 if (type != GRIB_TYPE_DOUBLE &&
1818 type != GRIB_TYPE_LONG &&
1819 type != GRIB_TYPE_STRING) {
1820 *err = grib_get_native_type(h1, key, &type);
1821 }
1822 switch (type) {
1823 case GRIB_TYPE_DOUBLE:
1824 *err = grib_get_double(h1, key, &d1);
1825 *err = grib_get_double(h2, key, &d2);
1826 if (d1 != d2)
1827 return 0;
1828 break;
1829 case GRIB_TYPE_LONG:
1830 *err = grib_get_long(h1, key, &l1);
1831 *err = grib_get_long(h2, key, &l2);
1832 if (l1 != l2)
1833 return 0;
1834 break;
1835 default:
1836 len1 = sizeof(s1) / sizeof(*s1);
1837 len2 = sizeof(s2) / sizeof(*s2);
1838 *err = grib_get_string(h1, key, s1, &len1);
1839 *err = grib_get_string(h2, key, s2, &len2);
1840 if (grib_inline_strcmp(s1, s2))
1841 return 0;
1842 break;
1843 }
1844 return 1;
1845 }
1846
codes_copy_key(grib_handle * h1,grib_handle * h2,const char * key,int type)1847 int codes_copy_key(grib_handle* h1, grib_handle* h2, const char* key, int type)
1848 {
1849 double d;
1850 double* ad;
1851 long l;
1852 long* al;
1853 char* s = 0;
1854 char** as = 0;
1855 size_t len1 = 0, len = 0;
1856 int err = 0;
1857
1858 if (type != GRIB_TYPE_DOUBLE &&
1859 type != GRIB_TYPE_LONG &&
1860 type != GRIB_TYPE_STRING) {
1861 err = grib_get_native_type(h1, key, &type);
1862 if (err)
1863 return err;
1864 }
1865
1866 err = grib_get_size(h1, key, &len1);
1867 if (err)
1868 return err;
1869
1870 switch (type) {
1871 case GRIB_TYPE_DOUBLE:
1872 if (len1 == 1) {
1873 err = grib_get_double(h1, key, &d);
1874 if (err)
1875 return err;
1876 grib_context_log(h1->context, GRIB_LOG_DEBUG, "codes_copy_key double: %s=%g\n", key, d);
1877 err = grib_set_double(h2, key, d);
1878 return err;
1879 }
1880 else {
1881 ad = (double*)grib_context_malloc_clear(h1->context, len1 * sizeof(double));
1882 err = grib_get_double_array(h1, key, ad, &len1);
1883 if (err)
1884 return err;
1885 err = grib_set_double_array(h2, key, ad, len1);
1886 grib_context_free(h1->context, ad);
1887 return err;
1888 }
1889 break;
1890 case GRIB_TYPE_LONG:
1891 if (len1 == 1) {
1892 err = grib_get_long(h1, key, &l);
1893 if (err)
1894 return err;
1895 grib_context_log(h1->context, GRIB_LOG_DEBUG, "codes_copy_key long: %s=%ld\n", key, l);
1896 err = grib_set_long(h2, key, l);
1897 return err;
1898 }
1899 else {
1900 al = (long*)grib_context_malloc_clear(h1->context, len1 * sizeof(long));
1901 err = grib_get_long_array(h1, key, al, &len1);
1902 if (err)
1903 return err;
1904 err = grib_set_long_array(h2, key, al, len1);
1905 grib_context_free(h1->context, al);
1906 return err;
1907 }
1908 break;
1909 case GRIB_TYPE_STRING:
1910 err = grib_get_string_length(h1, key, &len);
1911 if (err)
1912 return err;
1913 if (len1 == 1) {
1914 s = (char*)grib_context_malloc_clear(h1->context, len);
1915 err = grib_get_string(h1, key, s, &len);
1916 if (err)
1917 return err;
1918 grib_context_log(h1->context, GRIB_LOG_DEBUG, "codes_copy_key str: %s=%s\n", key, s);
1919 err = grib_set_string(h2, key, s, &len);
1920 grib_context_free(h1->context, s);
1921 return err;
1922 }
1923 else {
1924 as = (char**)grib_context_malloc_clear(h1->context, len1 * sizeof(char*));
1925 err = grib_get_string_array(h1, key, as, &len1);
1926 if (err)
1927 return err;
1928 err = grib_set_string_array(h2, key, (const char**)as, len1);
1929 return err;
1930 }
1931 break;
1932 default:
1933 return GRIB_INVALID_TYPE;
1934 }
1935 }
1936