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 #include "grib_api_internal.h"
12 #include "assert.h"
13
14 #if HAVE_SYS_TYPES_H
15 #include <sys/types.h>
16 #endif
17
18 #if HAVE_SYS_STAT_H
19 #include <sys/stat.h>
20 #endif
21
22 #ifdef HAVE_FCNTL_H
23 #include <fcntl.h>
24 #endif
25
26 #include <ctype.h>
27 #include <errno.h>
28
29 #if GRIB_PTHREADS
30 static pthread_once_t once = PTHREAD_ONCE_INIT;
31 static pthread_mutex_t handle_mutex = PTHREAD_MUTEX_INITIALIZER;
32 static pthread_mutex_t index_mutex = PTHREAD_MUTEX_INITIALIZER;
33 static pthread_mutex_t multi_handle_mutex = PTHREAD_MUTEX_INITIALIZER;
34 static pthread_mutex_t iterator_mutex = PTHREAD_MUTEX_INITIALIZER;
35 static pthread_mutex_t keys_iterator_mutex = PTHREAD_MUTEX_INITIALIZER;
36
init()37 static void init()
38 {
39 pthread_mutexattr_t attr;
40
41 pthread_mutexattr_init(&attr);
42 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
43 pthread_mutex_init(&handle_mutex, &attr);
44 pthread_mutex_init(&index_mutex, &attr);
45 pthread_mutex_init(&multi_handle_mutex, &attr);
46 pthread_mutex_init(&iterator_mutex, &attr);
47 pthread_mutex_init(&keys_iterator_mutex, &attr);
48 pthread_mutexattr_destroy(&attr);
49 }
50 #elif GRIB_OMP_THREADS
51 static int once = 0;
52 static omp_nest_lock_t handle_mutex;
53 static omp_nest_lock_t index_mutex;
54 static omp_nest_lock_t multi_handle_mutex;
55 static omp_nest_lock_t iterator_mutex;
56 static omp_nest_lock_t keys_iterator_mutex;
57
init()58 static void init()
59 {
60 GRIB_OMP_CRITICAL(lock_python)
61 {
62 if (once == 0) {
63 omp_init_nest_lock(&handle_mutex);
64 omp_init_nest_lock(&index_mutex);
65 omp_init_nest_lock(&multi_handle_mutex);
66 omp_init_nest_lock(&iterator_mutex);
67 omp_init_nest_lock(&keys_iterator_mutex);
68 once = 1;
69 }
70 }
71 }
72 #endif
73
74 int GRIB_NULL = -1;
75 int GRIB_NULL_NEAREST = -1;
76
77 typedef struct l_grib_file l_grib_file;
78
79 struct l_grib_file
80 {
81 int id;
82 FILE* f;
83 l_grib_file* next;
84 };
85
86 typedef struct l_grib_handle l_grib_handle;
87
88 struct l_grib_handle
89 {
90 int id;
91 grib_handle* h;
92 l_grib_handle* next;
93 };
94
95 typedef struct l_grib_index l_grib_index;
96
97 struct l_grib_index
98 {
99 int id;
100 grib_index* h;
101 l_grib_index* next;
102 };
103
104 typedef struct l_grib_multi_handle l_grib_multi_handle;
105
106 struct l_grib_multi_handle
107 {
108 int id;
109 grib_multi_handle* h;
110 l_grib_multi_handle* next;
111 };
112
113 typedef struct l_grib_iterator l_grib_iterator;
114
115 struct l_grib_iterator
116 {
117 int id;
118 grib_iterator* i;
119 l_grib_iterator* next;
120 };
121
122 typedef struct l_grib_keys_iterator l_grib_keys_iterator;
123 struct l_grib_keys_iterator
124 {
125 int id;
126 grib_keys_iterator* i;
127 l_grib_keys_iterator* next;
128 };
129
130 typedef struct l_bufr_keys_iterator l_bufr_keys_iterator;
131 struct l_bufr_keys_iterator
132 {
133 int id;
134 bufr_keys_iterator* i;
135 l_bufr_keys_iterator* next;
136 };
137
138 static l_grib_handle* handle_set = NULL;
139 static l_grib_index* index_set = NULL;
140 static l_grib_multi_handle* multi_handle_set = NULL;
141 static l_grib_file* file_set = NULL;
142 static l_grib_iterator* iterator_set = NULL;
143 static l_grib_keys_iterator* keys_iterator_set = NULL;
144 static l_bufr_keys_iterator* bufr_keys_iterator_set = NULL;
145
push_file(FILE * f)146 static int push_file(FILE* f)
147 {
148 l_grib_file* current = file_set;
149 l_grib_file* previous = file_set;
150 l_grib_file* new = NULL;
151 int myindex = 1;
152
153 if (!file_set) {
154 file_set = malloc(sizeof(l_grib_file));
155 file_set->id = myindex;
156 file_set->f = f;
157 file_set->next = NULL;
158 return myindex;
159 }
160
161 while (current) {
162 if (current->id < 0) {
163 current->id = -(current->id);
164 current->f = f;
165 return current->id;
166 }
167 else {
168 myindex++;
169 previous = current;
170 current = current->next;
171 }
172 }
173
174 new = malloc(sizeof(l_grib_file));
175 new->id = myindex;
176 new->f = f;
177 new->next = current;
178 previous->next = new;
179 return myindex;
180 }
181
_push_handle(grib_handle * h,int * gid)182 static void _push_handle(grib_handle* h, int* gid)
183 {
184 l_grib_handle* current = handle_set;
185 l_grib_handle* previous = handle_set;
186 l_grib_handle* new = NULL;
187 int myindex = 1;
188
189 if (*gid > 0) {
190 while (current) {
191 if (current->id == *gid) break;
192 current = current->next;
193 }
194 if (current) {
195 grib_handle_delete(current->h);
196 current->h = h;
197 return;
198 }
199 }
200
201 current = handle_set;
202
203 if (!handle_set) {
204 handle_set = malloc(sizeof(l_grib_handle));
205 handle_set->id = myindex;
206 handle_set->h = h;
207 handle_set->next = NULL;
208 *gid = myindex;
209 return;
210 }
211
212 while (current) {
213 if (current->id < 0) {
214 current->id = -(current->id);
215 current->h = h;
216 *gid = current->id;
217 return;
218 }
219 else {
220 myindex++;
221 previous = current;
222 current = current->next;
223 }
224 }
225
226 new = malloc(sizeof(l_grib_handle));
227 new->id = myindex;
228 new->h = h;
229 new->next = current;
230 previous->next = new;
231
232 *gid = myindex;
233 return;
234 }
235
_push_index(grib_index * h,int * gid)236 static void _push_index(grib_index* h, int* gid)
237 {
238 l_grib_index* current = index_set;
239 l_grib_index* previous = index_set;
240 l_grib_index* new = NULL;
241 int myindex = 1;
242
243 if (*gid > 0) {
244 while (current) {
245 if (current->id == *gid) break;
246 current = current->next;
247 }
248 if (current) {
249 grib_index_delete(current->h);
250 current->h = h;
251 return;
252 }
253 }
254
255 current = index_set;
256
257 if (!index_set) {
258 index_set = malloc(sizeof(l_grib_index));
259 index_set->id = myindex;
260 index_set->h = h;
261 index_set->next = NULL;
262 *gid = myindex;
263 return;
264 }
265
266 while (current) {
267 if (current->id < 0) {
268 current->id = -(current->id);
269 current->h = h;
270 *gid = current->id;
271 return;
272 }
273 else {
274 myindex++;
275 previous = current;
276 current = current->next;
277 }
278 }
279
280 new = malloc(sizeof(l_grib_index));
281 new->id = myindex;
282 new->h = h;
283 new->next = current;
284 previous->next = new;
285
286 *gid = myindex;
287 return;
288 }
289
_push_multi_handle(grib_multi_handle * h,int * gid)290 static void _push_multi_handle(grib_multi_handle* h, int* gid)
291 {
292 l_grib_multi_handle* current = multi_handle_set;
293 l_grib_multi_handle* previous = multi_handle_set;
294 l_grib_multi_handle* new = NULL;
295 int myindex = 1;
296
297 if (*gid > 0) {
298 while (current) {
299 if (current->id == *gid) break;
300 current = current->next;
301 }
302 if (current) {
303 grib_multi_handle_delete(current->h);
304 current->h = h;
305 return;
306 }
307 }
308
309 current = multi_handle_set;
310
311 if (!multi_handle_set) {
312 multi_handle_set = malloc(sizeof(l_grib_multi_handle));
313 multi_handle_set->id = myindex;
314 multi_handle_set->h = h;
315 multi_handle_set->next = NULL;
316 *gid = myindex;
317 return;
318 }
319
320 while (current) {
321 if (current->id < 0) {
322 current->id = -(current->id);
323 current->h = h;
324 *gid = current->id;
325 return;
326 }
327 else {
328 myindex++;
329 previous = current;
330 current = current->next;
331 }
332 }
333
334 new = malloc(sizeof(l_grib_multi_handle));
335 new->id = myindex;
336 new->h = h;
337 new->next = current;
338 previous->next = new;
339
340 *gid = myindex;
341 return;
342 }
343
push_handle(grib_handle * h,int * gid)344 static void push_handle(grib_handle* h, int* gid)
345 {
346 GRIB_MUTEX_INIT_ONCE(&once, &init)
347 GRIB_MUTEX_LOCK(&handle_mutex)
348 _push_handle(h, gid);
349 GRIB_MUTEX_UNLOCK(&handle_mutex)
350 return;
351 }
352
push_index(grib_index * h,int * gid)353 static void push_index(grib_index* h, int* gid)
354 {
355 GRIB_MUTEX_INIT_ONCE(&once, &init)
356 GRIB_MUTEX_LOCK(&index_mutex)
357 _push_index(h, gid);
358 GRIB_MUTEX_UNLOCK(&index_mutex)
359 return;
360 }
361
push_multi_handle(grib_multi_handle * h,int * gid)362 static void push_multi_handle(grib_multi_handle* h, int* gid)
363 {
364 GRIB_MUTEX_INIT_ONCE(&once, &init)
365 GRIB_MUTEX_LOCK(&multi_handle_mutex)
366 _push_multi_handle(h, gid);
367 GRIB_MUTEX_UNLOCK(&multi_handle_mutex)
368 return;
369 }
370
_push_iterator(grib_iterator * i)371 static int _push_iterator(grib_iterator* i)
372 {
373 l_grib_iterator* current = iterator_set;
374 l_grib_iterator* previous = iterator_set;
375 l_grib_iterator* new = NULL;
376 int myindex = 1;
377
378 if (!iterator_set) {
379 iterator_set = malloc(sizeof(l_grib_iterator));
380 iterator_set->id = myindex;
381 iterator_set->i = i;
382 iterator_set->next = NULL;
383 return myindex;
384 }
385
386 while (current) {
387 if (current->id < 0) {
388 current->id = -(current->id);
389 current->i = i;
390 return current->id;
391 }
392 else {
393 myindex++;
394 previous = current;
395 current = current->next;
396 }
397 }
398
399 new = malloc(sizeof(l_grib_iterator));
400 new->id = myindex;
401 new->i = i;
402 new->next = current;
403 previous->next = new;
404
405 return myindex;
406 }
407
push_iterator(grib_iterator * i)408 static int push_iterator(grib_iterator* i)
409 {
410 int ret = 0;
411 GRIB_MUTEX_INIT_ONCE(&once, &init)
412 GRIB_MUTEX_LOCK(&iterator_mutex)
413 ret = _push_iterator(i);
414 GRIB_MUTEX_UNLOCK(&iterator_mutex)
415 return ret;
416 }
417
_push_keys_iterator(grib_keys_iterator * i)418 static int _push_keys_iterator(grib_keys_iterator* i)
419 {
420 l_grib_keys_iterator* current = keys_iterator_set;
421 l_grib_keys_iterator* previous = keys_iterator_set;
422 l_grib_keys_iterator* new = NULL;
423 int myindex = 1;
424
425 if (!keys_iterator_set) {
426 keys_iterator_set = malloc(sizeof(l_grib_keys_iterator));
427 keys_iterator_set->id = myindex;
428 keys_iterator_set->i = i;
429 keys_iterator_set->next = NULL;
430 return myindex;
431 }
432
433 while (current) {
434 if (current->id < 0) {
435 current->id = -(current->id);
436 current->i = i;
437 return current->id;
438 }
439 else {
440 myindex++;
441 previous = current;
442 current = current->next;
443 }
444 }
445 if (!previous) return -1;
446
447 new = malloc(sizeof(l_grib_keys_iterator));
448 new->id = myindex;
449 new->i = i;
450 new->next = current;
451 previous->next = new;
452
453 return myindex;
454 }
push_keys_iterator(grib_keys_iterator * i)455 static int push_keys_iterator(grib_keys_iterator* i)
456 {
457 int ret = 0;
458 GRIB_MUTEX_INIT_ONCE(&once, &init)
459 GRIB_MUTEX_LOCK(&keys_iterator_mutex)
460 ret = _push_keys_iterator(i);
461 GRIB_MUTEX_UNLOCK(&keys_iterator_mutex)
462 return ret;
463 }
464
465 //BUFR keys iterator
_push_bufr_keys_iterator(bufr_keys_iterator * i)466 static int _push_bufr_keys_iterator(bufr_keys_iterator* i)
467 {
468 l_bufr_keys_iterator* current = bufr_keys_iterator_set;
469 l_bufr_keys_iterator* previous = bufr_keys_iterator_set;
470 l_bufr_keys_iterator* the_new = NULL;
471 int myindex = 1;
472
473 if (!bufr_keys_iterator_set) {
474 bufr_keys_iterator_set = (l_bufr_keys_iterator*)malloc(sizeof(l_bufr_keys_iterator));
475 Assert(bufr_keys_iterator_set);
476 bufr_keys_iterator_set->id = myindex;
477 bufr_keys_iterator_set->i = i;
478 bufr_keys_iterator_set->next = NULL;
479 return myindex;
480 }
481
482 while (current) {
483 if (current->id < 0) {
484 current->id = -(current->id);
485 current->i = i;
486 return current->id;
487 }
488 else {
489 myindex++;
490 previous = current;
491 current = current->next;
492 }
493 }
494 if (!previous) return -1;
495
496 the_new = (l_bufr_keys_iterator*)malloc(sizeof(l_bufr_keys_iterator));
497 Assert(the_new);
498 the_new->id = myindex;
499 the_new->i = i;
500 the_new->next = current;
501 previous->next = the_new;
502
503 return myindex;
504 }
push_bufr_keys_iterator(bufr_keys_iterator * i)505 static int push_bufr_keys_iterator(bufr_keys_iterator* i)
506 {
507 int ret = 0;
508 GRIB_MUTEX_INIT_ONCE(&once, &init);
509 GRIB_MUTEX_LOCK(&keys_iterator_mutex);
510 ret = _push_bufr_keys_iterator(i);
511 GRIB_MUTEX_UNLOCK(&keys_iterator_mutex);
512 return ret;
513 }
514
515
_get_handle(int handle_id)516 static grib_handle* _get_handle(int handle_id)
517 {
518 l_grib_handle* current = handle_set;
519
520 while (current) {
521 if (current->id == handle_id) return current->h;
522 current = current->next;
523 }
524
525 return NULL;
526 }
527
_get_index(int index_id)528 static grib_index* _get_index(int index_id)
529 {
530 l_grib_index* current = index_set;
531
532 while (current) {
533 if (current->id == index_id) return current->h;
534 current = current->next;
535 }
536
537 return NULL;
538 }
539
_get_multi_handle(int multi_handle_id)540 static grib_multi_handle* _get_multi_handle(int multi_handle_id)
541 {
542 l_grib_multi_handle* current = multi_handle_set;
543
544 while (current) {
545 if (current->id == multi_handle_id) return current->h;
546 current = current->next;
547 }
548
549 return NULL;
550 }
551
get_handle(int handle_id)552 static grib_handle* get_handle(int handle_id)
553 {
554 grib_handle* h = NULL;
555 GRIB_MUTEX_INIT_ONCE(&once, &init)
556 GRIB_MUTEX_LOCK(&handle_mutex)
557 h = _get_handle(handle_id);
558 GRIB_MUTEX_UNLOCK(&handle_mutex)
559 return h;
560 }
561
get_index(int index_id)562 static grib_index* get_index(int index_id)
563 {
564 grib_index* h = NULL;
565 GRIB_MUTEX_INIT_ONCE(&once, &init)
566 GRIB_MUTEX_LOCK(&index_mutex)
567 h = _get_index(index_id);
568 GRIB_MUTEX_UNLOCK(&index_mutex)
569 return h;
570 }
571
get_multi_handle(int multi_handle_id)572 static grib_multi_handle* get_multi_handle(int multi_handle_id)
573 {
574 grib_multi_handle* h = NULL;
575 GRIB_MUTEX_INIT_ONCE(&once, &init)
576 GRIB_MUTEX_LOCK(&multi_handle_mutex)
577 h = _get_multi_handle(multi_handle_id);
578 GRIB_MUTEX_UNLOCK(&multi_handle_mutex)
579 return h;
580 }
581
get_file(int file_id)582 static FILE* get_file(int file_id)
583 {
584 l_grib_file* current = file_set;
585 while (current) {
586 if (current->id == file_id) return current->f;
587 current = current->next;
588 }
589 return NULL;
590 }
591
_get_iterator(int iterator_id)592 static grib_iterator* _get_iterator(int iterator_id)
593 {
594 l_grib_iterator* current = iterator_set;
595
596 while (current) {
597 if (current->id == iterator_id) return current->i;
598 current = current->next;
599 }
600 return NULL;
601 }
get_iterator(int iterator_id)602 static grib_iterator* get_iterator(int iterator_id)
603 {
604 grib_iterator* i = NULL;
605 GRIB_MUTEX_INIT_ONCE(&once, &init)
606 GRIB_MUTEX_LOCK(&iterator_mutex)
607 i = _get_iterator(iterator_id);
608 GRIB_MUTEX_UNLOCK(&iterator_mutex)
609 return i;
610 }
611
_get_keys_iterator(int keys_iterator_id)612 static grib_keys_iterator* _get_keys_iterator(int keys_iterator_id)
613 {
614 l_grib_keys_iterator* current = keys_iterator_set;
615
616 while (current) {
617 if (current->id == keys_iterator_id) return current->i;
618 current = current->next;
619 }
620 return NULL;
621 }
get_keys_iterator(int keys_iterator_id)622 static grib_keys_iterator* get_keys_iterator(int keys_iterator_id)
623 {
624 grib_keys_iterator* i = NULL;
625 GRIB_MUTEX_INIT_ONCE(&once, &init)
626 GRIB_MUTEX_LOCK(&keys_iterator_mutex)
627 i = _get_keys_iterator(keys_iterator_id);
628 GRIB_MUTEX_UNLOCK(&keys_iterator_mutex)
629 return i;
630 }
631
632 //BUFR keys iterator
_get_bufr_keys_iterator(int keys_iterator_id)633 static bufr_keys_iterator* _get_bufr_keys_iterator(int keys_iterator_id)
634 {
635 l_bufr_keys_iterator* current = bufr_keys_iterator_set;
636
637 while (current) {
638 if (current->id == keys_iterator_id) return current->i;
639 current = current->next;
640 }
641 return NULL;
642 }
get_bufr_keys_iterator(int keys_iterator_id)643 static bufr_keys_iterator* get_bufr_keys_iterator(int keys_iterator_id)
644 {
645 bufr_keys_iterator* i = NULL;
646 GRIB_MUTEX_INIT_ONCE(&once, &init)
647 GRIB_MUTEX_LOCK(&keys_iterator_mutex)
648 i = _get_bufr_keys_iterator(keys_iterator_id);
649 GRIB_MUTEX_UNLOCK(&keys_iterator_mutex)
650 return i;
651 }
652
653
clear_file(int file_id)654 static int clear_file(int file_id)
655 {
656 l_grib_file* current = file_set;
657 int ret = 0;
658 while (current) {
659 if (current->id == file_id) {
660 current->id = -(current->id);
661 if (current->f) {
662 ret = fclose(current->f);
663 if (0 == ret) {
664 return GRIB_SUCCESS;
665 }
666 else {
667 return GRIB_IO_PROBLEM;
668 }
669 }
670 return GRIB_SUCCESS;
671 }
672 current = current->next;
673 }
674 return GRIB_INVALID_FILE;
675 }
676
_clear_handle(int handle_id)677 static int _clear_handle(int handle_id)
678 {
679 l_grib_handle* current = handle_set;
680
681 /* look for the input grib id to release it */
682 while (current) {
683 if (current->id == handle_id) {
684 current->id = -(current->id);
685 if (current->h) return grib_handle_delete(current->h);
686 }
687 current = current->next;
688 }
689
690 /* fail with invalid grib id if not found */
691 return GRIB_INVALID_GRIB;
692 }
693
_clear_index(int index_id)694 static int _clear_index(int index_id)
695 {
696 l_grib_index* current = index_set;
697
698 while (current) {
699 if (current->id == index_id) {
700 current->id = -(current->id);
701 if (current->h) {
702 grib_index_delete(current->h);
703 return GRIB_SUCCESS;
704 }
705 }
706 current = current->next;
707 }
708 return GRIB_SUCCESS;
709 }
710
_clear_multi_handle(int multi_handle_id)711 static int _clear_multi_handle(int multi_handle_id)
712 {
713 l_grib_multi_handle* current = multi_handle_set;
714
715 while (current) {
716 if (current->id == multi_handle_id) {
717 current->id = -(current->id);
718 if (current->h) return grib_multi_handle_delete(current->h);
719 }
720 current = current->next;
721 }
722 return GRIB_SUCCESS;
723 }
724
clear_handle(int handle_id)725 static int clear_handle(int handle_id)
726 {
727 int ret = 0;
728 GRIB_MUTEX_INIT_ONCE(&once, &init)
729 GRIB_MUTEX_LOCK(&handle_mutex)
730 ret = _clear_handle(handle_id);
731 GRIB_MUTEX_UNLOCK(&handle_mutex)
732 return ret;
733 }
734
clear_index(int index_id)735 static int clear_index(int index_id)
736 {
737 int ret = 0;
738 GRIB_MUTEX_INIT_ONCE(&once, &init)
739 GRIB_MUTEX_LOCK(&index_mutex)
740 ret = _clear_index(index_id);
741 GRIB_MUTEX_UNLOCK(&index_mutex)
742 return ret;
743 }
744
clear_multi_handle(int multi_handle_id)745 static int clear_multi_handle(int multi_handle_id)
746 {
747 int ret = 0;
748 GRIB_MUTEX_INIT_ONCE(&once, &init)
749 GRIB_MUTEX_LOCK(&multi_handle_mutex)
750 ret = _clear_multi_handle(multi_handle_id);
751 GRIB_MUTEX_UNLOCK(&multi_handle_mutex)
752 return ret;
753 }
754
_clear_iterator(int iterator_id)755 static int _clear_iterator(int iterator_id)
756 {
757 l_grib_iterator* current = iterator_set;
758
759 while (current) {
760 if (current->id == iterator_id) {
761 current->id = -(current->id);
762 return grib_iterator_delete(current->i);
763 }
764 current = current->next;
765 }
766 return GRIB_INVALID_ITERATOR;
767 }
768
clear_iterator(int iterator_id)769 static int clear_iterator(int iterator_id)
770 {
771 int ret = 0;
772 GRIB_MUTEX_INIT_ONCE(&once, &init)
773 GRIB_MUTEX_LOCK(&iterator_mutex)
774 ret = _clear_iterator(iterator_id);
775 GRIB_MUTEX_UNLOCK(&iterator_mutex)
776 return ret;
777 }
778
_clear_keys_iterator(int keys_iterator_id)779 static int _clear_keys_iterator(int keys_iterator_id)
780 {
781 l_grib_keys_iterator* current = keys_iterator_set;
782
783 while (current) {
784 if (current->id == keys_iterator_id) {
785 current->id = -(current->id);
786 return grib_keys_iterator_delete(current->i);
787 }
788 current = current->next;
789 }
790 return GRIB_INVALID_KEYS_ITERATOR;
791 }
clear_keys_iterator(int keys_iterator_id)792 static int clear_keys_iterator(int keys_iterator_id)
793 {
794 int ret = 0;
795 GRIB_MUTEX_INIT_ONCE(&once, &init)
796 GRIB_MUTEX_LOCK(&keys_iterator_mutex)
797 ret = _clear_keys_iterator(keys_iterator_id);
798 GRIB_MUTEX_UNLOCK(&keys_iterator_mutex)
799 return ret;
800 }
801
802 //BUFR keys iterator
_clear_bufr_keys_iterator(int keys_iterator_id)803 static int _clear_bufr_keys_iterator(int keys_iterator_id)
804 {
805 l_bufr_keys_iterator* current = bufr_keys_iterator_set;
806
807 while (current) {
808 if (current->id == keys_iterator_id) {
809 current->id = -(current->id);
810 return codes_bufr_keys_iterator_delete(current->i);
811 }
812 current = current->next;
813 }
814 return GRIB_INVALID_KEYS_ITERATOR;
815 }
clear_bufr_keys_iterator(int keys_iterator_id)816 static int clear_bufr_keys_iterator(int keys_iterator_id)
817 {
818 int ret = 0;
819 GRIB_MUTEX_INIT_ONCE(&once, &init);
820 GRIB_MUTEX_LOCK(&keys_iterator_mutex);
821 ret = _clear_bufr_keys_iterator(keys_iterator_id);
822 GRIB_MUTEX_UNLOCK(&keys_iterator_mutex);
823 return ret;
824 }
825
grib_c_read_any_from_file(int * fid,char * buffer,int * nbytes)826 int grib_c_read_any_from_file(int* fid, char* buffer, int* nbytes)
827 {
828 grib_context* c;
829 int err = 0;
830 size_t size = (size_t)nbytes;
831 FILE* f = get_file(*fid);
832
833 if (f) {
834 c = grib_context_get_default();
835 err = grib_read_any_from_file(c, f, buffer, &size);
836 *nbytes = size;
837 return err;
838 }
839 else {
840 return GRIB_INVALID_FILE;
841 }
842 }
843
grib_c_write_file(int * fid,char * buffer,int * nbytes)844 int grib_c_write_file(int* fid, char* buffer, int* nbytes)
845 {
846 grib_context* c;
847 FILE* f = get_file(*fid);
848
849 if (f) {
850 int ioerr;
851 c = grib_context_get_default();
852 if (fwrite(buffer, 1, *nbytes, f) != *nbytes) {
853 ioerr = errno;
854 grib_context_log(c, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR), "IO ERROR: %s", strerror(ioerr));
855 return GRIB_IO_PROBLEM;
856 }
857 return GRIB_SUCCESS;
858 }
859 else {
860 return GRIB_INVALID_FILE;
861 }
862 }
863
grib_c_read_file(int * fid,char * buffer,int * nbytes)864 int grib_c_read_file(int* fid, char* buffer, int* nbytes)
865 {
866 grib_context* c;
867 FILE* f = get_file(*fid);
868
869 if (f) {
870 int ioerr;
871 c = grib_context_get_default();
872 if (fread(buffer, 1, *nbytes, f) != *nbytes) {
873 ioerr = errno;
874 grib_context_log(c, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR), "IO ERROR: %s", strerror(ioerr));
875 return GRIB_IO_PROBLEM;
876 }
877 return GRIB_SUCCESS;
878 }
879 else {
880 return GRIB_INVALID_FILE;
881 }
882 }
883
grib_c_open_file(int * fid,char * name,char * op)884 int grib_c_open_file(int* fid, char* name, char* op)
885 {
886 FILE* f = NULL;
887 int ioerr = 0;
888 int ret = GRIB_SUCCESS;
889
890 /*TODO Proper context passed as external parameter */
891 grib_context* context = grib_context_get_default();
892
893 f = fopen(name, op);
894
895 if (!f) {
896 ioerr = errno;
897 grib_context_log(context, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR), "IO ERROR: %s: %s", strerror(ioerr), name);
898 *fid = -1;
899 ret = GRIB_IO_PROBLEM;
900 }
901 else {
902 *fid = push_file(f);
903 ret = GRIB_SUCCESS;
904 }
905 return ret;
906 }
907
grib_c_close_file(int * fid)908 int grib_c_close_file(int* fid)
909 {
910 return clear_file(*fid);
911 }
912
grib_c_multi_support_on(void)913 int grib_c_multi_support_on(void)
914 {
915 grib_multi_support_on(0);
916 return GRIB_SUCCESS;
917 }
918
grib_c_multi_support_off(void)919 int grib_c_multi_support_off(void)
920 {
921 grib_multi_support_off(0);
922 return GRIB_SUCCESS;
923 }
924
_grib_c_iterator_new_(int * gid,int * iterid,int * mode)925 static int _grib_c_iterator_new_(int* gid, int* iterid, int* mode)
926 {
927 int err = 0;
928 grib_handle* h;
929 grib_iterator* iter;
930
931 h = get_handle(*gid);
932 if (!h) {
933 *iterid = -1;
934 return GRIB_NULL_HANDLE;
935 }
936 iter = grib_iterator_new(h, *mode, &err);
937 if (iter)
938 *iterid = push_iterator(iter);
939 else
940 *iterid = -1;
941 return err;
942 }
943
grib_c_iterator_new(int * gid,int * iterid,int * mode)944 int grib_c_iterator_new(int* gid, int* iterid, int* mode)
945 {
946 int ret = 0;
947 GRIB_MUTEX_INIT_ONCE(&once, &init)
948 GRIB_MUTEX_LOCK(&iterator_mutex)
949 ret = _grib_c_iterator_new_(gid, iterid, mode);
950 GRIB_MUTEX_UNLOCK(&iterator_mutex)
951 return ret;
952 }
953
grib_c_iterator_next(int * iterid,double * lat,double * lon,double * value)954 int grib_c_iterator_next(int* iterid, double* lat, double* lon, double* value)
955 {
956 grib_iterator* iter = get_iterator(*iterid);
957 if (!iter) return GRIB_INVALID_ITERATOR;
958 return grib_iterator_next(iter, lat, lon, value);
959 }
960
grib_c_iterator_delete(int * iterid)961 int grib_c_iterator_delete(int* iterid)
962 {
963 return clear_iterator(*iterid);
964 }
965
_grib_c_keys_iterator_new_(int * gid,int * iterid,char * name_space)966 static int _grib_c_keys_iterator_new_(int* gid, int* iterid, char* name_space)
967 {
968 int err = 0;
969 grib_handle* h;
970 grib_keys_iterator* iter;
971
972 h = get_handle(*gid);
973 if (!h) {
974 *iterid = -1;
975 return GRIB_NULL_HANDLE;
976 }
977 iter = grib_keys_iterator_new(h, 0, name_space);
978 if (iter)
979 *iterid = push_keys_iterator(iter);
980 else
981 *iterid = -1;
982 return err;
983 }
grib_c_keys_iterator_new(int * gid,int * iterid,char * name_space)984 int grib_c_keys_iterator_new(int* gid, int* iterid, char* name_space)
985 {
986 int ret = 0;
987 GRIB_MUTEX_INIT_ONCE(&once, &init)
988 GRIB_MUTEX_LOCK(&keys_iterator_mutex)
989 ret = _grib_c_keys_iterator_new_(gid, iterid, name_space);
990 GRIB_MUTEX_UNLOCK(&keys_iterator_mutex)
991 return ret;
992 }
grib_c_keys_iterator_next(int * iterid)993 int grib_c_keys_iterator_next(int* iterid)
994 {
995 int ret = 0;
996
997 grib_keys_iterator* iter = get_keys_iterator(*iterid);
998
999 if (!iter) return GRIB_INVALID_KEYS_ITERATOR;
1000
1001 ret = grib_keys_iterator_next(iter);
1002
1003 return ret;
1004 }
grib_c_keys_iterator_delete(int * iterid)1005 int grib_c_keys_iterator_delete(int* iterid)
1006 {
1007 return clear_keys_iterator(*iterid);
1008 }
grib_c_keys_iterator_get_name(int * iterid,char * name,int len)1009 int grib_c_keys_iterator_get_name(int* iterid, char* name, int len)
1010 {
1011 size_t lsize = len;
1012 char buf[1024] = {0,};
1013
1014 grib_keys_iterator* kiter = get_keys_iterator(*iterid);
1015
1016 if (!kiter) return GRIB_INVALID_KEYS_ITERATOR;
1017 if (grib_keys_iterator_get_accessor(kiter) == NULL)
1018 return GRIB_INVALID_KEYS_ITERATOR;
1019
1020 sprintf(buf, "%s", grib_keys_iterator_get_name(kiter));
1021 lsize = strlen(buf);
1022
1023 if (len < lsize) return GRIB_ARRAY_TOO_SMALL;
1024
1025 memcpy(name, buf, lsize);
1026 name[lsize] = '\0';
1027
1028 return 0;
1029 }
grib_c_keys_iterator_rewind(int * kiter)1030 int grib_c_keys_iterator_rewind(int* kiter)
1031 {
1032 grib_keys_iterator* i = get_keys_iterator(*kiter);
1033
1034 if (!i) return GRIB_INVALID_KEYS_ITERATOR;
1035 return grib_keys_iterator_rewind(i);
1036 }
1037
1038 /*BUFR keys iterator*/
_codes_c_bufr_keys_iterator_new_(int * gid,int * iterid)1039 static int _codes_c_bufr_keys_iterator_new_(int* gid, int* iterid)
1040 {
1041 int err = 0;
1042 grib_handle* h;
1043 bufr_keys_iterator* iter;
1044
1045 h = get_handle(*gid);
1046 if (!h) {
1047 *iterid = -1;
1048 return GRIB_NULL_HANDLE;
1049 }
1050 iter = codes_bufr_keys_iterator_new(h, 0);
1051 if (iter)
1052 *iterid = push_bufr_keys_iterator(iter);
1053 else
1054 *iterid = -1;
1055 return err;
1056 }
codes_c_bufr_keys_iterator_new(int * gid,int * iterid)1057 int codes_c_bufr_keys_iterator_new(int* gid, int* iterid)
1058 {
1059 int ret = 0;
1060 GRIB_MUTEX_INIT_ONCE(&once, &init)
1061 GRIB_MUTEX_LOCK(&keys_iterator_mutex)
1062 ret = _codes_c_bufr_keys_iterator_new_(gid, iterid);
1063 GRIB_MUTEX_UNLOCK(&keys_iterator_mutex)
1064 return ret;
1065 }
1066
codes_c_bufr_keys_iterator_next(int * iterid)1067 int codes_c_bufr_keys_iterator_next(int* iterid)
1068 {
1069 int ret = 0;
1070 bufr_keys_iterator* iter = get_bufr_keys_iterator(*iterid);
1071
1072 if (!iter) return GRIB_INVALID_KEYS_ITERATOR;
1073
1074 ret = codes_bufr_keys_iterator_next(iter);
1075 return ret;
1076 }
1077
codes_c_bufr_keys_iterator_get_name(int * iterid,char * name,int len)1078 int codes_c_bufr_keys_iterator_get_name(int* iterid, char* name, int len)
1079 {
1080 size_t lsize = len;
1081 char buf[1024] = {0,};
1082
1083 bufr_keys_iterator* kiter = get_bufr_keys_iterator(*iterid);
1084
1085 if (!kiter) return GRIB_INVALID_KEYS_ITERATOR;
1086 if (codes_bufr_keys_iterator_get_accessor(kiter) == NULL)
1087 return GRIB_INVALID_KEYS_ITERATOR;
1088
1089 sprintf(buf, "%s", codes_bufr_keys_iterator_get_name(kiter));
1090 lsize = strlen(buf);
1091
1092 if (len < lsize) return GRIB_ARRAY_TOO_SMALL;
1093
1094 memcpy(name, buf, lsize);
1095 name[lsize] = '\0';
1096
1097 return 0;
1098 }
1099
codes_c_bufr_keys_iterator_rewind(int * kiter)1100 int codes_c_bufr_keys_iterator_rewind(int* kiter)
1101 {
1102 bufr_keys_iterator* i = get_bufr_keys_iterator(*kiter);
1103
1104 if (!i) return GRIB_INVALID_KEYS_ITERATOR;
1105 return codes_bufr_keys_iterator_rewind(i);
1106 }
1107
codes_c_bufr_keys_iterator_delete(int * iterid)1108 int codes_c_bufr_keys_iterator_delete(int* iterid)
1109 {
1110 return clear_bufr_keys_iterator(*iterid);
1111 }
1112
1113
grib_c_gribex_mode_on(void)1114 int grib_c_gribex_mode_on(void)
1115 {
1116 grib_gribex_mode_on(0);
1117 return GRIB_SUCCESS;
1118 }
1119
grib_c_gribex_mode_off(void)1120 int grib_c_gribex_mode_off(void)
1121 {
1122 grib_gribex_mode_off(0);
1123 return GRIB_SUCCESS;
1124 }
1125
grib_c_skip_computed(int * iterid)1126 int grib_c_skip_computed(int* iterid)
1127 {
1128 grib_keys_iterator* iter = get_keys_iterator(*iterid);
1129 if (!iter) return GRIB_INVALID_KEYS_ITERATOR;
1130 return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_COMPUTED);
1131 }
1132
grib_c_skip_coded(int * iterid)1133 int grib_c_skip_coded(int* iterid)
1134 {
1135 grib_keys_iterator* iter = get_keys_iterator(*iterid);
1136 if (!iter) return GRIB_INVALID_KEYS_ITERATOR;
1137 return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_CODED);
1138 }
1139
grib_c_skip_edition_specific(int * iterid)1140 int grib_c_skip_edition_specific(int* iterid)
1141 {
1142 grib_keys_iterator* iter = get_keys_iterator(*iterid);
1143 if (!iter) return GRIB_INVALID_KEYS_ITERATOR;
1144 return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_EDITION_SPECIFIC);
1145 }
1146
grib_c_skip_duplicates(int * iterid)1147 int grib_c_skip_duplicates(int* iterid)
1148 {
1149 grib_keys_iterator* iter = get_keys_iterator(*iterid);
1150 if (!iter) return GRIB_INVALID_KEYS_ITERATOR;
1151 return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_DUPLICATES);
1152 }
1153
grib_c_skip_read_only(int * iterid)1154 int grib_c_skip_read_only(int* iterid)
1155 {
1156 grib_keys_iterator* iter = get_keys_iterator(*iterid);
1157 if (!iter) return GRIB_INVALID_KEYS_ITERATOR;
1158 return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_READ_ONLY);
1159 }
1160
grib_c_skip_function(int * iterid)1161 int grib_c_skip_function(int* iterid)
1162 {
1163 grib_keys_iterator* iter = get_keys_iterator(*iterid);
1164 if (!iter) return GRIB_INVALID_KEYS_ITERATOR;
1165 return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_FUNCTION);
1166 }
1167
grib_c_new_from_message(int * gid,void * buffer,size_t * bufsize)1168 int grib_c_new_from_message(int* gid, void* buffer, size_t* bufsize)
1169 {
1170 grib_handle* h = NULL;
1171 h = grib_handle_new_from_message_copy(0, buffer, *bufsize);
1172 if (h) {
1173 push_handle(h, gid);
1174 return GRIB_SUCCESS;
1175 }
1176
1177 *gid = -1;
1178 return GRIB_INTERNAL_ERROR;
1179 }
1180
grib_c_new_from_message_copy(int * gid,void * buffer,size_t * bufsize)1181 int grib_c_new_from_message_copy(int* gid, void* buffer, size_t* bufsize)
1182 {
1183 grib_handle* h = NULL;
1184 h = grib_handle_new_from_message_copy(0, buffer, *bufsize);
1185 if (h) {
1186 push_handle(h, gid);
1187 return GRIB_SUCCESS;
1188 }
1189
1190 *gid = -1;
1191 return GRIB_INTERNAL_ERROR;
1192 }
1193
grib_c_grib_new_from_samples(int * gid,char * name)1194 int grib_c_grib_new_from_samples(int* gid, char* name)
1195 {
1196 grib_handle* h = NULL;
1197
1198 h = grib_handle_new_from_samples(NULL, name);
1199 /* grib_context_set_debug(h->context,1);*/
1200
1201 if (h) {
1202 push_handle(h, gid);
1203 return GRIB_SUCCESS;
1204 }
1205
1206 *gid = -1;
1207 return GRIB_FILE_NOT_FOUND;
1208 }
1209
grib_c_bufr_new_from_samples(int * gid,char * name)1210 int grib_c_bufr_new_from_samples(int* gid, char* name)
1211 {
1212 grib_handle* h = NULL;
1213
1214 h = codes_bufr_handle_new_from_samples(NULL, name);
1215 /* grib_context_set_debug(h->context,1);*/
1216
1217 if (h) {
1218 push_handle(h, gid);
1219 return GRIB_SUCCESS;
1220 }
1221
1222 *gid = -1;
1223 return GRIB_FILE_NOT_FOUND;
1224 }
1225
grib_c_clone(int * gidsrc,int * giddest)1226 int grib_c_clone(int* gidsrc, int* giddest)
1227 {
1228 grib_handle* src = get_handle(*gidsrc);
1229 grib_handle* dest = NULL;
1230
1231 if (src) {
1232 dest = grib_handle_clone(src);
1233 if (dest) {
1234 push_handle(dest, giddest);
1235 return GRIB_SUCCESS;
1236 }
1237 }
1238
1239 *giddest = -1;
1240 return GRIB_INVALID_GRIB;
1241 }
1242
grib_c_copy_namespace(int * gidsrc,char * name,int * giddest)1243 int grib_c_copy_namespace(int* gidsrc, char* name, int* giddest)
1244 {
1245 grib_handle* src = get_handle(*gidsrc);
1246 grib_handle* dest = get_handle(*giddest);
1247
1248 if (src && dest)
1249 return grib_copy_namespace(dest, name, src);
1250
1251 return GRIB_INVALID_GRIB;
1252 }
1253
grib_c_count_in_file(FILE * f,int * n)1254 int grib_c_count_in_file(FILE* f, int* n)
1255 {
1256 int err = 0;
1257 if (f) err = grib_count_in_file(0, f, n);
1258 return err;
1259 }
1260
grib_c_new_gts_from_file(FILE * f,int headers_only,int * gid)1261 int grib_c_new_gts_from_file(FILE* f, int headers_only, int* gid)
1262 {
1263 grib_handle* h = NULL;
1264 int err = 0;
1265
1266 if (f) {
1267 h = gts_new_from_file(0, f, &err);
1268
1269 if (h) {
1270 push_handle(h, gid);
1271 return GRIB_SUCCESS;
1272 }
1273 else {
1274 *gid = -1;
1275 return GRIB_END_OF_FILE;
1276 }
1277 }
1278
1279 *gid = -1;
1280 return GRIB_INVALID_FILE;
1281 }
1282
grib_c_new_metar_from_file(FILE * f,int headers_only,int * gid)1283 int grib_c_new_metar_from_file(FILE* f, int headers_only, int* gid)
1284 {
1285 grib_handle* h = NULL;
1286 int err = 0;
1287
1288 if (f) {
1289 h = metar_new_from_file(0, f, &err);
1290
1291 if (h) {
1292 push_handle(h, gid);
1293 return GRIB_SUCCESS;
1294 }
1295 else {
1296 *gid = -1;
1297 return GRIB_END_OF_FILE;
1298 }
1299 }
1300
1301 *gid = -1;
1302 return GRIB_INVALID_FILE;
1303 }
1304
grib_c_new_any_from_file(FILE * f,int headers_only,int * gid)1305 int grib_c_new_any_from_file(FILE* f, int headers_only, int* gid)
1306 {
1307 grib_handle* h = NULL;
1308 int err = 0;
1309 if (f) {
1310 h = codes_handle_new_from_file(0, f, PRODUCT_ANY, &err);
1311 if (h) {
1312 push_handle(h, gid);
1313 return GRIB_SUCCESS;
1314 }
1315 else {
1316 *gid = -1;
1317 return GRIB_END_OF_FILE;
1318 }
1319 }
1320
1321 *gid = -1;
1322 return GRIB_INVALID_FILE;
1323 }
1324
grib_c_new_bufr_from_file(FILE * f,int headers_only,int * gid)1325 int grib_c_new_bufr_from_file(FILE* f, int headers_only, int* gid)
1326 {
1327 grib_handle* h = NULL;
1328 int err = 0;
1329
1330 if (f) {
1331 /* h = bufr_new_from_file(0,f,headers_only,&err); */
1332 h = codes_handle_new_from_file(0, f, PRODUCT_BUFR, &err);
1333
1334 if (h) {
1335 push_handle(h, gid);
1336 return GRIB_SUCCESS;
1337 }
1338 else {
1339 *gid = -1;
1340 return GRIB_END_OF_FILE;
1341 }
1342 }
1343
1344 *gid = -1;
1345 return GRIB_INVALID_FILE;
1346 }
1347
grib_c_new_from_file(FILE * f,int * gid,int headers_only)1348 int grib_c_new_from_file(FILE* f, int* gid, int headers_only)
1349 {
1350 grib_handle* h = NULL;
1351 int err = 0;
1352
1353 if (f) {
1354 h = grib_new_from_file(0, f, headers_only, &err);
1355
1356 if (h) {
1357 push_handle(h, gid);
1358 return GRIB_SUCCESS;
1359 }
1360 else {
1361 *gid = -1;
1362 if (err == GRIB_SUCCESS) {
1363 return GRIB_END_OF_FILE;
1364 }
1365 else {
1366 /* A real error occurred */
1367 return err;
1368 }
1369 }
1370 }
1371
1372 *gid = -1;
1373 return GRIB_INVALID_FILE;
1374 }
1375
grib_c_new_from_index(int * iid,int * gid)1376 int grib_c_new_from_index(int* iid, int* gid)
1377 {
1378 int err = 0;
1379 grib_index* i = get_index(*iid);
1380
1381 grib_handle* h = NULL;
1382
1383 if (i) {
1384 h = grib_handle_new_from_index(i, &err);
1385 if (h) {
1386 push_handle(h, gid);
1387 return GRIB_SUCCESS;
1388 }
1389 else {
1390 *gid = -1;
1391 return GRIB_END_OF_INDEX;
1392 }
1393 }
1394
1395 *gid = -1;
1396 return GRIB_INVALID_INDEX;
1397 }
1398
grib_c_index_new_from_file(char * file,char * keys,int * gid)1399 int grib_c_index_new_from_file(char* file, char* keys, int* gid)
1400 {
1401 int err = 0;
1402 grib_index* i = NULL;
1403
1404 if (*file) {
1405 i = grib_index_new_from_file(0, file, keys, &err);
1406 if (i) {
1407 push_index(i, gid);
1408 return GRIB_SUCCESS;
1409 }
1410 else {
1411 *gid = -1;
1412 return GRIB_END_OF_FILE;
1413 }
1414 }
1415
1416 *gid = -1;
1417 return GRIB_INVALID_FILE;
1418 }
1419
grib_c_index_add_file(int * iid,char * file)1420 int grib_c_index_add_file(int* iid, char* file)
1421 {
1422 grib_index* i = get_index(*iid);
1423 int err = GRIB_SUCCESS;
1424
1425 if (!i) {
1426 return GRIB_INVALID_INDEX;
1427 }
1428 else {
1429 err = grib_index_add_file(i, file);
1430 return err;
1431 }
1432 }
1433
grib_c_index_release(int * hid)1434 int grib_c_index_release(int* hid)
1435 {
1436 return clear_index(*hid);
1437 }
1438
grib_c_multi_release(int * hid)1439 int grib_c_multi_release(int* hid)
1440 {
1441 return clear_multi_handle(*hid);
1442 }
1443
grib_c_release(int * hid)1444 int grib_c_release(int* hid)
1445 {
1446 return clear_handle(*hid);
1447 }
1448
grib_c_dump(int * gid)1449 int grib_c_dump(int* gid)
1450 {
1451 grib_handle* h = get_handle(*gid);
1452
1453 if (!h)
1454 return GRIB_INVALID_GRIB;
1455 else
1456 grib_dump_content(h, stdout, "wmo", 0, NULL);
1457
1458 return GRIB_SUCCESS;
1459 }
1460
grib_c_print(int * gid,char * key)1461 int grib_c_print(int* gid, char* key)
1462 {
1463 grib_handle* h = get_handle(*gid);
1464 int err = GRIB_SUCCESS;
1465 grib_dumper* d = NULL;
1466
1467 if (!h) {
1468 return GRIB_INVALID_GRIB;
1469 }
1470 else {
1471 d = grib_dumper_factory("serialize", h, stdout, 0, 0);
1472 err = grib_print(h, key, d);
1473 grib_dumper_delete(d);
1474 return err;
1475 }
1476 }
1477
grib_c_get_error_string(int * err,char * buf,int len)1478 int grib_c_get_error_string(int* err, char* buf, int len)
1479 {
1480 const char* err_msg = grib_get_error_message(*err);
1481 size_t erlen = strlen(err_msg);
1482 if (len <= erlen) return GRIB_ARRAY_TOO_SMALL;
1483
1484 strncpy(buf, err_msg, (size_t)erlen);
1485 buf[erlen] = '\0';
1486
1487 return GRIB_SUCCESS;
1488 }
1489
grib_c_get_size_int(int * gid,char * key,int * val)1490 int grib_c_get_size_int(int* gid, char* key, int* val)
1491 {
1492 grib_handle* h = get_handle(*gid);
1493 int err = GRIB_SUCCESS;
1494 size_t tsize = 0;
1495
1496 if (!h) {
1497 return GRIB_INVALID_GRIB;
1498 }
1499 else {
1500 err = grib_get_size(h, key, &tsize);
1501 *val = tsize;
1502 return err;
1503 }
1504 }
1505
grib_c_get_message_offset(int * gid,size_t * offset)1506 int grib_c_get_message_offset(int* gid, size_t* offset)
1507 {
1508 int err = GRIB_SUCCESS;
1509 off_t myoffset;
1510 grib_handle* h = get_handle(*gid);
1511
1512 if (!h)
1513 return GRIB_INVALID_GRIB;
1514 else {
1515 err = grib_get_message_offset(h, &myoffset);
1516 *offset = myoffset;
1517 return err;
1518 }
1519 }
1520
grib_c_get_message_size(int * gid,size_t * size)1521 int grib_c_get_message_size(int* gid, size_t* size)
1522 {
1523 grib_handle* h = get_handle(*gid);
1524
1525 if (!h)
1526 return GRIB_INVALID_GRIB;
1527 else
1528 return grib_get_message_size(h, size);
1529 }
1530
grib_c_get_string_length(int * gid,char * key,size_t * val)1531 int grib_c_get_string_length(int* gid, char* key, size_t* val)
1532 {
1533 grib_handle* h = get_handle(*gid);
1534
1535 if (!h)
1536 return GRIB_INVALID_GRIB;
1537 else
1538 return grib_get_string_length(h, key, val);
1539 }
1540
grib_c_get_size_long(int * gid,char * key,long * val)1541 int grib_c_get_size_long(int* gid, char* key, long* val)
1542 {
1543 grib_handle* h = get_handle(*gid);
1544 int err = GRIB_SUCCESS;
1545 size_t tsize = 0;
1546
1547 if (!h) {
1548 return GRIB_INVALID_GRIB;
1549 }
1550 else {
1551 err = grib_get_size(h, key, &tsize);
1552 *val = tsize;
1553 return err;
1554 }
1555 }
1556
grib_c_index_get_size_int(int * gid,char * key,int * val)1557 int grib_c_index_get_size_int(int* gid, char* key, int* val)
1558 {
1559 grib_index* h = get_index(*gid);
1560 int err = GRIB_SUCCESS;
1561 size_t tsize = 0;
1562
1563 if (!h) {
1564 return GRIB_INVALID_GRIB;
1565 }
1566 else {
1567 err = grib_index_get_size(h, key, &tsize);
1568 *val = tsize;
1569 return err;
1570 }
1571 }
1572
grib_c_index_get_size_long(int * gid,char * key,long * val)1573 int grib_c_index_get_size_long(int* gid, char* key, long* val)
1574 {
1575 grib_index* h = get_index(*gid);
1576 int err = GRIB_SUCCESS;
1577 size_t tsize = 0;
1578
1579 if (!h) {
1580 return GRIB_INVALID_GRIB;
1581 }
1582 else {
1583 err = grib_index_get_size(h, key, &tsize);
1584 *val = tsize;
1585 return err;
1586 }
1587 }
1588
grib_c_get_int(int * gid,char * key,int * val)1589 int grib_c_get_int(int* gid, char* key, int* val)
1590 {
1591 grib_handle* h = get_handle(*gid);
1592 long long_val;
1593 int err = GRIB_SUCCESS;
1594
1595 if (!h) return GRIB_INVALID_GRIB;
1596 err = grib_get_long(h, key, &long_val);
1597 *val = long_val;
1598 return err;
1599 }
1600
grib_c_get_long(int * gid,char * key,long * val)1601 int grib_c_get_long(int* gid, char* key, long* val)
1602 {
1603 grib_handle* h = get_handle(*gid);
1604 int err = GRIB_SUCCESS;
1605
1606 if (!h) return GRIB_INVALID_GRIB;
1607 err = grib_get_long(h, key, val);
1608 return err;
1609 }
1610
grib_c_get_double(int * gid,char * key,double * val)1611 int grib_c_get_double(int* gid, char* key, double* val)
1612 {
1613 grib_handle* h = get_handle(*gid);
1614 int err = GRIB_SUCCESS;
1615
1616 if (!h) return GRIB_INVALID_GRIB;
1617 err = grib_get_double(h, key, val);
1618 return err;
1619 }
1620
grib_c_get_int_array(int * gid,char * key,int * val,int * size)1621 int grib_c_get_int_array(int* gid, char* key, int* val, int* size)
1622 {
1623 grib_handle* h = get_handle(*gid);
1624 long* long_val = NULL;
1625 int err = GRIB_SUCCESS;
1626 size_t lsize = *size;
1627
1628 if (!h) return GRIB_INVALID_GRIB;
1629
1630 if (sizeof(long) == sizeof(int)) {
1631 long_val = (long*)val;
1632 err = grib_get_long_array(h, key, long_val, &lsize);
1633 *size = lsize;
1634 return err;
1635 }
1636 if (*size)
1637 long_val = grib_context_malloc(h->context, (*size) * (sizeof(long)));
1638 else
1639 long_val = grib_context_malloc(h->context, (sizeof(long)));
1640
1641 if (!long_val) return GRIB_OUT_OF_MEMORY;
1642 err = grib_get_long_array(h, key, long_val, &lsize);
1643
1644 for (*size = 0; *size < lsize; (*size)++)
1645 val[*size] = long_val[*size];
1646
1647 grib_context_free(h->context, long_val);
1648 return err;
1649 }
1650
grib_c_get_long_array(int * gid,char * key,long * val,int * size)1651 int grib_c_get_long_array(int* gid, char* key, long* val, int* size)
1652 {
1653 grib_handle* h = get_handle(*gid);
1654 int err = GRIB_SUCCESS;
1655 size_t lsize = *size;
1656
1657 if (!h) return GRIB_INVALID_GRIB;
1658
1659 err = grib_get_long_array(h, key, val, &lsize);
1660 *size = lsize;
1661
1662 return err;
1663 }
1664
grib_c_index_get_string(int * gid,char * key,char * val,int * eachsize,int * size)1665 int grib_c_index_get_string(int* gid, char* key, char* val, int* eachsize, int* size)
1666 {
1667 grib_index* h = get_index(*gid);
1668 int err = GRIB_SUCCESS;
1669 int i;
1670 size_t lsize = *size;
1671 char** bufval;
1672 char* p = val;
1673
1674 if (!h) return GRIB_INVALID_GRIB;
1675
1676 bufval = (char**)grib_context_malloc_clear(h->context, sizeof(char*) * *size);
1677
1678 err = grib_index_get_string(h, key, bufval, &lsize);
1679 *size = lsize;
1680
1681 if (err) return err;
1682
1683 for (i = 0; i < lsize; i++) {
1684 int l = strlen(bufval[i]);
1685 int j;
1686 if (*eachsize < l) {
1687 grib_context_free(h->context, bufval);
1688 printf("eachsize=%d strlen(bufval[i])=%d\n", *eachsize, (unsigned int)strlen(bufval[i]));
1689 return GRIB_ARRAY_TOO_SMALL;
1690 }
1691 memcpy(p, bufval[i], l);
1692 p += l;
1693 for (j = 0; j < *eachsize - l; j++)
1694 *(p++) = ' ';
1695 }
1696 grib_context_free(h->context, bufval);
1697
1698 return err;
1699 }
1700
grib_c_index_get_long(int * gid,char * key,long * val,int * size)1701 int grib_c_index_get_long(int* gid, char* key, long* val, int* size)
1702 {
1703 grib_index* h = get_index(*gid);
1704 int err = GRIB_SUCCESS;
1705 size_t lsize = *size;
1706
1707 if (!h) return GRIB_INVALID_GRIB;
1708 err = grib_index_get_long(h, key, val, &lsize);
1709 *size = lsize;
1710 return err;
1711 }
1712
grib_c_index_get_int(int * gid,char * key,int * val,int * size)1713 int grib_c_index_get_int(int* gid, char* key, int* val, int* size)
1714 {
1715 grib_index* h = get_index(*gid);
1716 int err = GRIB_SUCCESS;
1717 size_t lsize = *size;
1718 long* lval = 0;
1719 int i;
1720
1721 if (!h) return GRIB_INVALID_GRIB;
1722
1723 lval = grib_context_malloc(h->context, sizeof(long) * *size);
1724 if (!lval) return GRIB_OUT_OF_MEMORY;
1725
1726 err = grib_index_get_long(h, key, lval, &lsize);
1727 for (i = 0; i < lsize; i++)
1728 val[i] = lval[i];
1729
1730 *size = lsize;
1731 return err;
1732 }
1733
grib_c_index_get_real8(int * gid,char * key,double * val,int * size)1734 int grib_c_index_get_real8(int* gid, char* key, double* val, int* size)
1735 {
1736 grib_index* h = get_index(*gid);
1737 int err = GRIB_SUCCESS;
1738 size_t lsize = *size;
1739
1740 if (!h) return GRIB_INVALID_GRIB;
1741 err = grib_index_get_double(h, key, val, &lsize);
1742 *size = lsize;
1743 return err;
1744 }
1745
grib_c_set_int_array(int * gid,char * key,int * val,int * size)1746 int grib_c_set_int_array(int* gid, char* key, int* val, int* size)
1747 {
1748 grib_handle* h = get_handle(*gid);
1749 int err = GRIB_SUCCESS;
1750 long* long_val = NULL;
1751 size_t lsize = *size;
1752
1753 if (!h) return GRIB_INVALID_GRIB;
1754
1755 if (sizeof(long) == sizeof(int)) {
1756 long_val = (long*)val;
1757 return grib_set_long_array(h, key, long_val, lsize);
1758 }
1759
1760 if (lsize)
1761 long_val = grib_context_malloc(h->context, (lsize) * (sizeof(long)));
1762 else
1763 long_val = grib_context_malloc(h->context, (sizeof(long)));
1764
1765 if (!long_val) return GRIB_OUT_OF_MEMORY;
1766
1767 for (lsize = 0; lsize < (*size); lsize++)
1768 long_val[lsize] = val[lsize];
1769
1770 err = grib_set_long_array(h, key, long_val, lsize);
1771
1772 grib_context_free(h->context, long_val);
1773 return err;
1774 }
1775
grib_c_set_long_array(int * gid,char * key,long * val,int * size)1776 int grib_c_set_long_array(int* gid, char* key, long* val, int* size)
1777 {
1778 grib_handle* h = get_handle(*gid);
1779 int err = GRIB_SUCCESS;
1780 size_t lsize = *size;
1781
1782 if (!h) return GRIB_INVALID_GRIB;
1783
1784 return grib_set_long_array(h, key, val, lsize);
1785
1786 return err;
1787 }
1788
grib_c_set_int(int * gid,char * key,int * val)1789 int grib_c_set_int(int* gid, char* key, int* val)
1790 {
1791 grib_handle* h = get_handle(*gid);
1792 long long_val = *val;
1793 if (!h) return GRIB_INVALID_GRIB;
1794 return grib_set_long(h, key, long_val);
1795 }
1796
grib_c_set_long(int * gid,char * key,long * val)1797 int grib_c_set_long(int* gid, char* key, long* val)
1798 {
1799 grib_handle* h = get_handle(*gid);
1800 if (!h) return GRIB_INVALID_GRIB;
1801 return grib_set_long(h, key, *val);
1802 }
1803
grib_c_set_missing(int * gid,char * key)1804 int grib_c_set_missing(int* gid, char* key)
1805 {
1806 grib_handle* h = get_handle(*gid);
1807 if (!h) return GRIB_INVALID_GRIB;
1808
1809 return grib_set_missing(h, key);
1810 }
1811
1812 /*
1813 * Submits all keys with the given values in one go.
1814 * 'keyvals' is a string of the form:
1815 * key1=val1,key2=val2,key3=val3
1816 */
grib_c_set_key_vals(int * gid,char * keyvals)1817 int grib_c_set_key_vals(int* gid, char* keyvals)
1818 {
1819 grib_handle* h = get_handle(*gid);
1820 if (!h) return GRIB_INVALID_GRIB;
1821 {
1822 int err = GRIB_SUCCESS;
1823 grib_values values[1024] = {{0,},};
1824 int count = 1000; /* max. num key/val pairs */
1825 if ((err = parse_keyval_string(NULL, keyvals, 1, GRIB_TYPE_UNDEFINED, values, &count)) != GRIB_SUCCESS) {
1826 return err;
1827 }
1828 if ((err = grib_set_values(h, values, count)) != GRIB_SUCCESS) {
1829 return err;
1830 }
1831 }
1832 return GRIB_SUCCESS;
1833 }
1834
grib_c_is_missing(int * gid,char * key,int * isMissing)1835 int grib_c_is_missing(int* gid, char* key, int* isMissing)
1836 {
1837 int err = 0;
1838 grib_handle* h = get_handle(*gid);
1839 if (!h) return GRIB_INVALID_GRIB;
1840
1841 *isMissing = grib_is_missing(h, key, &err);
1842 return err;
1843 }
1844
grib_c_is_defined(int * gid,char * key,int * isDefined)1845 int grib_c_is_defined(int* gid, char* key, int* isDefined)
1846 {
1847 grib_handle* h = get_handle(*gid);
1848 if (!h) return GRIB_INVALID_GRIB;
1849
1850 *isDefined = grib_is_defined(h, key);
1851 return GRIB_SUCCESS;
1852 }
1853
grib_c_set_real4(int * gid,char * key,float * val)1854 int grib_c_set_real4(int* gid, char* key, float* val)
1855 {
1856 grib_handle* h = get_handle(*gid);
1857 double val8 = *val;
1858 if (!h) return GRIB_INVALID_GRIB;
1859
1860 return grib_set_double(h, key, val8);
1861 }
1862
grib_c_get_real4_element(int * gid,char * key,int * index,float * val)1863 int grib_c_get_real4_element(int* gid, char* key, int* index, float* val)
1864 {
1865 grib_handle* h = get_handle(*gid);
1866 int err = GRIB_SUCCESS;
1867 double val8 = 0;
1868
1869 if (!h) return GRIB_INVALID_GRIB;
1870
1871 err = grib_get_double_element(h, key, *index, &val8);
1872 *val = val8;
1873 return err;
1874 }
1875
grib_c_get_real4_elements(int * gid,char * key,int * index,float * val,int * size)1876 int grib_c_get_real4_elements(int* gid, char* key, int* index, float* val, int* size)
1877 {
1878 grib_handle* h = get_handle(*gid);
1879 int err = GRIB_SUCCESS;
1880 size_t lsize = *size;
1881 long i = 0;
1882 double* val8 = NULL;
1883
1884 if (!h) return GRIB_INVALID_GRIB;
1885
1886 if (*size)
1887 val8 = grib_context_malloc(h->context, (*size) * (sizeof(double)));
1888 else
1889 val8 = grib_context_malloc(h->context, sizeof(double));
1890
1891 if (!val8) return GRIB_OUT_OF_MEMORY;
1892
1893
1894 err = grib_get_double_elements(h, key, index, (long)lsize, val8);
1895
1896 for (i = 0; i < lsize; (i)++)
1897 val[i] = val8[i];
1898
1899 grib_context_free(h->context, val8);
1900
1901 return err;
1902 }
1903
grib_c_get_real4(int * gid,char * key,float * val)1904 int grib_c_get_real4(int* gid, char* key, float* val)
1905 {
1906 grib_handle* h = get_handle(*gid);
1907 int err = GRIB_SUCCESS;
1908 double val8 = 0;
1909
1910 if (!h) return GRIB_INVALID_GRIB;
1911
1912 err = grib_get_double(h, key, &val8);
1913 *val = val8;
1914 return err;
1915 }
1916
grib_c_get_real4_array(int * gid,char * key,float * val,int * size)1917 int grib_c_get_real4_array(int* gid, char* key, float* val, int* size)
1918 {
1919 grib_handle* h = get_handle(*gid);
1920 int err = GRIB_SUCCESS;
1921 size_t lsize = *size;
1922 double* val8 = NULL;
1923
1924 if (!h) return GRIB_INVALID_GRIB;
1925
1926 if (*size)
1927 val8 = grib_context_malloc(h->context, (*size) * (sizeof(double)));
1928 else
1929 val8 = grib_context_malloc(h->context, sizeof(double));
1930
1931 if (!val8) return GRIB_OUT_OF_MEMORY;
1932
1933 err = grib_get_double_array(h, key, val8, &lsize);
1934
1935 for (*size = 0; *size < lsize; (*size)++)
1936 val[*size] = val8[*size];
1937
1938 grib_context_free(h->context, val8);
1939
1940 return err;
1941 }
1942
grib_c_set_real4_array(int * gid,char * key,float * val,int * size)1943 int grib_c_set_real4_array(int* gid, char* key, float* val, int* size)
1944 {
1945 grib_handle* h = get_handle(*gid);
1946 int err = GRIB_SUCCESS;
1947 size_t lsize = *size;
1948 double* val8 = NULL;
1949
1950 if (!h) return GRIB_INVALID_GRIB;
1951
1952 if (*size)
1953 val8 = grib_context_malloc(h->context, lsize * (sizeof(double)));
1954 else
1955 val8 = grib_context_malloc(h->context, sizeof(double));
1956
1957 if (!val8) return GRIB_OUT_OF_MEMORY;
1958
1959 for (lsize = 0; lsize < *size; lsize++)
1960 val8[lsize] = val[lsize];
1961
1962 err = grib_set_double_array(h, key, val8, lsize);
1963 grib_context_free(h->context, val8);
1964 return err;
1965 }
1966
grib_c_index_select_real8(int * gid,char * key,double * val)1967 int grib_c_index_select_real8(int* gid, char* key, double* val)
1968 {
1969 grib_index* h = get_index(*gid);
1970
1971 if (!h) return GRIB_INVALID_GRIB;
1972 return grib_index_select_double(h, key, *val);
1973 }
1974
grib_c_index_select_string(int * gid,char * key,char * val)1975 int grib_c_index_select_string(int* gid, char* key, char* val)
1976 {
1977 grib_index* h = get_index(*gid);
1978
1979 if (!h) return GRIB_INVALID_GRIB;
1980 return grib_index_select_string(h, key, val);
1981 }
1982
grib_c_index_select_int(int * gid,char * key,int * val)1983 int grib_c_index_select_int(int* gid, char* key, int* val)
1984 {
1985 grib_index* h = get_index(*gid);
1986 long lval = *val;
1987
1988 if (!h) return GRIB_INVALID_GRIB;
1989 return grib_index_select_long(h, key, lval);
1990 }
1991
grib_c_index_select_long(int * gid,char * key,long * val)1992 int grib_c_index_select_long(int* gid, char* key, long* val)
1993 {
1994 grib_index* h = get_index(*gid);
1995
1996 if (!h) return GRIB_INVALID_GRIB;
1997 return grib_index_select_long(h, key, *val);
1998 }
1999
grib_c_set_real8(int * gid,char * key,double * val)2000 int grib_c_set_real8(int* gid, char* key, double* val)
2001 {
2002 grib_handle* h = get_handle(*gid);
2003
2004 if (!h) return GRIB_INVALID_GRIB;
2005 return grib_set_double(h, key, *val);
2006 }
2007
grib_c_get_real8(int * gid,char * key,double * val)2008 int grib_c_get_real8(int* gid, char* key, double* val)
2009 {
2010 grib_handle* h = get_handle(*gid);
2011
2012 if (!h) return GRIB_INVALID_GRIB;
2013
2014 return grib_get_double(h, key, val);
2015 }
2016
grib_c_set_double(int * gid,char * key,double * val)2017 int grib_c_set_double(int* gid, char* key, double* val)
2018 {
2019 grib_handle* h = get_handle(*gid);
2020
2021 if (!h) return GRIB_INVALID_GRIB;
2022
2023 return grib_set_double(h, key, *val);
2024 }
2025
grib_c_get_real8_element(int * gid,char * key,int * index,double * val)2026 int grib_c_get_real8_element(int* gid, char* key, int* index, double* val)
2027 {
2028 grib_handle* h = get_handle(*gid);
2029
2030 if (!h) return GRIB_INVALID_GRIB;
2031
2032 return grib_get_double_element(h, key, *index, val);
2033 }
2034
grib_c_get_real8_elements(int * gid,char * key,int * index,double * val,int * size)2035 int grib_c_get_real8_elements(int* gid, char* key, int* index, double* val, int* size)
2036 {
2037 grib_handle* h = get_handle(*gid);
2038
2039 if (!h) return GRIB_INVALID_GRIB;
2040
2041 return grib_get_double_elements(h, key, index, *size, val);
2042 }
2043
grib_c_find_nearest_four_single(int * gid,int * is_lsm,double * inlat,double * inlon,double * outlats,double * outlons,double * values,double * distances,int * indexes)2044 int grib_c_find_nearest_four_single(int* gid, int* is_lsm,
2045 double* inlat, double* inlon,
2046 double* outlats, double* outlons,
2047 double* values, double* distances,
2048 int* indexes)
2049 {
2050 grib_nearest* nearest = NULL;
2051 int err = 0, result = 0;
2052 unsigned long flags = 0;
2053 size_t len = 4;
2054 grib_handle* h = get_handle(*gid);
2055
2056 if (!h) return GRIB_INVALID_GRIB;
2057
2058 nearest = grib_nearest_new(h, &err);
2059 if (err != GRIB_SUCCESS) return err;
2060
2061 result = grib_nearest_find(nearest, h, *inlat, *inlon,
2062 flags, outlats, outlons, values, distances, indexes, &len);
2063 grib_nearest_delete(nearest);
2064 return result;
2065 }
2066
grib_c_find_nearest_single(int * gid,int * is_lsm,double * inlats,double * inlons,double * outlats,double * outlons,double * values,double * distances,int * indexes)2067 int grib_c_find_nearest_single(int* gid, int* is_lsm,
2068 double* inlats, double* inlons,
2069 double* outlats, double* outlons,
2070 double* values, double* distances,
2071 int* indexes)
2072 {
2073 grib_handle* h = get_handle(*gid);
2074
2075 if (!h) return GRIB_INVALID_GRIB;
2076
2077 return grib_nearest_find_multiple(h, *is_lsm,
2078 inlats, inlons, 1, outlats, outlons,
2079 values, distances, indexes);
2080 }
2081
grib_c_find_nearest_multiple(int * gid,int * is_lsm,double * inlats,double * inlons,double * outlats,double * outlons,double * values,double * distances,int * indexes,int * npoints)2082 int grib_c_find_nearest_multiple(int* gid, int* is_lsm,
2083 double* inlats, double* inlons,
2084 double* outlats, double* outlons,
2085 double* values, double* distances,
2086 int* indexes, int* npoints)
2087 {
2088 grib_handle* h = get_handle(*gid);
2089
2090 if (!h) return GRIB_INVALID_GRIB;
2091
2092 return grib_nearest_find_multiple(h, *is_lsm,
2093 inlats, inlons, *npoints, outlats, outlons,
2094 values, distances, indexes);
2095 }
2096
grib_c_get_real8_array(int * gid,char * key,double * val,int * size)2097 int grib_c_get_real8_array(int* gid, char* key, double* val, int* size)
2098 {
2099 grib_handle* h = get_handle(*gid);
2100 int err = GRIB_SUCCESS;
2101 size_t lsize = *size;
2102
2103 if (!h) {
2104 return GRIB_INVALID_GRIB;
2105 }
2106 else {
2107 err = grib_get_double_array(h, key, val, &lsize);
2108 *size = lsize;
2109 return err;
2110 }
2111 }
2112
grib_c_set_real8_array(int * gid,char * key,double * val,int * size)2113 int grib_c_set_real8_array(int* gid, char* key, double* val, int* size)
2114 {
2115 grib_handle* h = get_handle(*gid);
2116
2117 size_t lsize = *size;
2118
2119 if (!h) return GRIB_INVALID_GRIB;
2120
2121 return grib_set_double_array(h, key, val, lsize);
2122 }
2123
grib_c_set_double_array(int * gid,char * key,double * val,int * size)2124 int grib_c_set_double_array(int* gid, char* key, double* val, int* size)
2125 {
2126 grib_handle* h = get_handle(*gid);
2127
2128 size_t lsize = *size;
2129
2130 if (!h) return GRIB_INVALID_GRIB;
2131
2132 return grib_set_double_array(h, key, val, lsize);
2133 }
2134
grib_c_get_string(int * gid,char * key,char * val,size_t * lsize)2135 int grib_c_get_string(int* gid, char* key, char* val, size_t* lsize)
2136 {
2137 grib_handle* h = get_handle(*gid);
2138 int err = GRIB_SUCCESS;
2139
2140 if (!h) return GRIB_INVALID_GRIB;
2141
2142 err = grib_get_string(h, key, val, lsize);
2143
2144 return err;
2145 }
2146
grib_c_get_string_array(int * gid,char * key,char ** val,size_t * lsize)2147 int grib_c_get_string_array(int* gid, char* key, char** val, size_t* lsize)
2148 {
2149 grib_handle* h = get_handle(*gid);
2150 int err = GRIB_SUCCESS;
2151
2152 if (!h) return GRIB_INVALID_GRIB;
2153
2154 err = grib_get_string_array(h, key, val, lsize);
2155
2156 return err;
2157 }
2158
grib_c_set_string(int * gid,char * key,char * val,int len2)2159 int grib_c_set_string(int* gid, char* key, char* val, int len2)
2160 {
2161 grib_handle* h = get_handle(*gid);
2162
2163 size_t lsize = len2;
2164
2165 if (!h) return GRIB_INVALID_GRIB;
2166
2167 return grib_set_string(h, key, val, &lsize);
2168 }
2169
grib_c_set_string_array(int * gid,char * key,const char ** val)2170 int grib_c_set_string_array(int* gid, char* key, const char** val)
2171 {
2172 grib_handle* h = get_handle(*gid);
2173 int err = GRIB_SUCCESS;
2174 size_t lsize = 0;
2175
2176 if (!h) return GRIB_INVALID_GRIB;
2177
2178 /* Note: The array passed in will have its final entry as NULL */
2179 /* so to find its size we just iterate thru it. */
2180 /* See typemap for char** in swig interface file */
2181 while (val[lsize]) {
2182 ++lsize;
2183 }
2184 err = grib_set_string_array(h, key, val, lsize);
2185 return err;
2186 }
2187
grib_c_get_data_real4(int * gid,float * lats,float * lons,float * values,size_t * size)2188 int grib_c_get_data_real4(int* gid, float* lats, float* lons, float* values, size_t* size)
2189 {
2190 grib_handle* h = get_handle(*gid);
2191 int err = GRIB_SUCCESS;
2192 double *lat8 = NULL, *lon8 = NULL, *val8 = NULL;
2193 size_t i = 0;
2194
2195 if (!h) return GRIB_INVALID_GRIB;
2196
2197 val8 = grib_context_malloc(h->context, (*size) * (sizeof(double)));
2198 if (!val8) return GRIB_OUT_OF_MEMORY;
2199 lon8 = grib_context_malloc(h->context, (*size) * (sizeof(double)));
2200 if (!lon8) return GRIB_OUT_OF_MEMORY;
2201 lat8 = grib_context_malloc(h->context, (*size) * (sizeof(double)));
2202 if (!lat8) return GRIB_OUT_OF_MEMORY;
2203
2204 err = grib_get_data(h, lat8, lon8, val8);
2205
2206 for (i = 0; i < *size; i++) {
2207 values[i] = val8[i];
2208 lats[i] = lat8[i];
2209 lons[i] = lon8[i];
2210 }
2211
2212 grib_context_free(h->context, val8);
2213 grib_context_free(h->context, lat8);
2214 grib_context_free(h->context, lon8);
2215
2216 return err;
2217 }
2218 /*
2219 int grib_c_get_data_real8(int* gid,double* lats, double* lons,double* values,size_t* size)
2220 {
2221 grib_handle *h = get_handle(*gid);
2222 return grib_get_data(h,lats,lons,values);
2223 }
2224 */
grib_c_copy_message(int * gid,void * mess,size_t * len)2225 int grib_c_copy_message(int* gid, void* mess, size_t* len)
2226 {
2227 grib_handle* h = get_handle(*gid);
2228 if (!h)
2229 return GRIB_INVALID_GRIB;
2230
2231 if (*len < h->buffer->ulength) {
2232 grib_context_log(h->context, GRIB_LOG_ERROR, "grib_copy_message: buffer=%ld message size=%ld", *len, h->buffer->ulength);
2233 return GRIB_BUFFER_TOO_SMALL;
2234 }
2235
2236 memcpy(mess, h->buffer->data, h->buffer->ulength);
2237 *len = h->buffer->ulength;
2238 return GRIB_SUCCESS;
2239 }
2240
grib_c_bufr_copy_data(int * msgid_src,int * msgid_dst)2241 int grib_c_bufr_copy_data(int* msgid_src, int* msgid_dst)
2242 {
2243 int err = 0;
2244 grib_handle* src = get_handle(*msgid_src);
2245 grib_handle* dest = get_handle(*msgid_dst);
2246 if (!src || !dest) {
2247 return GRIB_INVALID_GRIB;
2248 }
2249
2250 err = codes_bufr_copy_data(src, dest);
2251 return err;
2252 }
2253
grib_c_check(int * err,char * call,char * str)2254 void grib_c_check(int* err, char* call, char* str)
2255 {
2256 grib_context* c = grib_context_get_default();
2257 if (*err == GRIB_SUCCESS || *err == GRIB_END_OF_FILE) return;
2258 grib_context_log(c, GRIB_LOG_ERROR, "%s: %s %s",
2259 call, str, grib_get_error_message(*err));
2260 exit(*err);
2261 }
2262
grib_c_write(int * gid,FILE * f)2263 int grib_c_write(int* gid, FILE* f)
2264 {
2265 grib_handle* h = get_handle(*gid);
2266 const void* mess = NULL;
2267 size_t mess_len = 0;
2268
2269 if (!f) return GRIB_INVALID_FILE;
2270 if (!h) return GRIB_INVALID_GRIB;
2271
2272 grib_get_message(h, &mess, &mess_len);
2273 if (fwrite(mess, 1, mess_len, f) != mess_len) {
2274 perror("grib_write");
2275 return GRIB_IO_PROBLEM;
2276 }
2277
2278 return GRIB_SUCCESS;
2279 }
2280
grib_c_multi_new(int * mgid)2281 int grib_c_multi_new(int* mgid)
2282 {
2283 grib_multi_handle* mh = grib_multi_handle_new(0);
2284 if (!mh) return GRIB_INVALID_GRIB;
2285 push_multi_handle(mh, mgid);
2286 return GRIB_SUCCESS;
2287 }
2288
grib_c_multi_write(int * gid,FILE * f)2289 int grib_c_multi_write(int* gid, FILE* f)
2290 {
2291 grib_multi_handle* h = get_multi_handle(*gid);
2292
2293 if (!f) return GRIB_INVALID_FILE;
2294 if (!h) return GRIB_INVALID_GRIB;
2295
2296 return grib_multi_handle_write(h, f);
2297 }
2298
grib_c_multi_append(int * ingid,int * sec,int * mgid)2299 int grib_c_multi_append(int* ingid, int* sec, int* mgid)
2300 {
2301 grib_handle* h = get_handle(*ingid);
2302 grib_multi_handle* mh = get_multi_handle(*mgid);
2303
2304 if (!h) return GRIB_INVALID_GRIB;
2305
2306 if (!mh) {
2307 mh = grib_multi_handle_new(h->context);
2308 push_multi_handle(mh, mgid);
2309 }
2310
2311 return grib_multi_handle_append(h, *sec, mh);
2312 }
2313
grib_c_get_native_type(int * gid,char * key,int * type)2314 int grib_c_get_native_type(int* gid, char* key, int* type)
2315 {
2316 grib_handle* h = get_handle(*gid);
2317
2318 if (!h) return GRIB_INVALID_GRIB;
2319
2320 return grib_get_native_type(h, key, type);
2321 }
2322
grib_c_index_write(int * gid,char * file)2323 int grib_c_index_write(int* gid, char* file)
2324 {
2325 grib_index* i = get_index(*gid);
2326 int err = GRIB_SUCCESS;
2327
2328 if (!i) {
2329 return GRIB_INVALID_GRIB;
2330 }
2331 else {
2332 err = grib_index_write(i, file);
2333 return err;
2334 }
2335 }
2336
grib_c_index_read(char * file,int * gid)2337 int grib_c_index_read(char* file, int* gid)
2338 {
2339 int err = 0;
2340 grib_index* i = NULL;
2341
2342 if (*file) {
2343 i = grib_index_read(0, file, &err);
2344 if (i) {
2345 push_index(i, gid);
2346 return GRIB_SUCCESS;
2347 }
2348 else {
2349 *gid = -1;
2350 return GRIB_END_OF_FILE;
2351 }
2352 }
2353
2354 *gid = -1;
2355 return GRIB_INVALID_FILE;
2356 }
2357
no_fail_on_wrong_length(int flag)2358 void no_fail_on_wrong_length(int flag)
2359 {
2360 grib_context* c = grib_context_get_default();
2361 int value;
2362 assert(c != NULL);
2363 value = (flag != 0) ? 1 : 0;
2364 c->no_fail_on_wrong_length = value;
2365 }
2366
grib_c_gts_header_on(void)2367 void grib_c_gts_header_on(void)
2368 {
2369 grib_context* c = grib_context_get_default();
2370 assert(c != NULL);
2371 grib_gts_header_on(c);
2372 }
2373
grib_c_gts_header_off(void)2374 void grib_c_gts_header_off(void)
2375 {
2376 grib_context* c = grib_context_get_default();
2377 assert(c != NULL);
2378 grib_gts_header_off(c);
2379 }
2380
grib_c_get_api_version(void)2381 long grib_c_get_api_version(void)
2382 {
2383 return grib_get_api_version();
2384 }
2385
grib_c_get_message(int * gid,const void ** msg,size_t * size)2386 int grib_c_get_message(int* gid, const void** msg, size_t* size)
2387 {
2388 grib_handle* h = get_handle(*gid);
2389 return grib_get_message(h, msg, size);
2390 }
2391
grib_c_set_definitions_path(const char * path)2392 void grib_c_set_definitions_path(const char* path)
2393 {
2394 grib_context* c = grib_context_get_default();
2395 grib_context_set_definitions_path(c, path);
2396 }
2397
grib_c_set_samples_path(const char * path)2398 void grib_c_set_samples_path(const char* path)
2399 {
2400 grib_context* c = grib_context_get_default();
2401 grib_context_set_samples_path(c, path);
2402 }
2403
2404
codes_c_bufr_multi_element_constant_arrays_on(void)2405 int codes_c_bufr_multi_element_constant_arrays_on(void)
2406 {
2407 codes_bufr_multi_element_constant_arrays_on(NULL);
2408 return GRIB_SUCCESS;
2409 }
codes_c_bufr_multi_element_constant_arrays_off(void)2410 int codes_c_bufr_multi_element_constant_arrays_off(void)
2411 {
2412 codes_bufr_multi_element_constant_arrays_off(NULL);
2413 return GRIB_SUCCESS;
2414 }
2415