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