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 /***************************************************************************
12 * Jean Baptiste Filippi - 01.11.2005
13 * Enrico Fucile
14 * *
15 ***************************************************************************/
16 #include "grib_api_internal.h"
17
18 #if 0
19 /* #if GRIB_PTHREADS */
20 static pthread_once_t once = PTHREAD_ONCE_INIT;
21 static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
22 static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
23 static void init() {
24 pthread_mutexattr_t attr;
25 pthread_mutexattr_init(&attr);
26 pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
27 pthread_mutex_init(&mutex1,&attr);
28 pthread_mutex_init(&mutex2,&attr);
29 pthread_mutexattr_destroy(&attr);
30 }
31 /* #elif GRIB_OMP_THREADS */
32 static int once = 0;
33 static omp_nest_lock_t mutex1;
34 static omp_nest_lock_t mutex2;
35 static void init()
36 {
37 GRIB_OMP_CRITICAL(lock_grib_handle_c)
38 {
39 if (once == 0)
40 {
41 omp_init_nest_lock(&mutex1);
42 omp_init_nest_lock(&mutex2);
43 once = 1;
44 }
45 }
46 }
47 #endif
48
49 static grib_handle* grib_handle_new_from_file_no_multi ( grib_context* c, FILE* f,int headers_only,int *error );
50 static grib_handle* grib_handle_new_from_file_multi ( grib_context* c, FILE* f,int *error );
51 static int grib2_get_next_section ( unsigned char* msgbegin,size_t msglen,unsigned char** secbegin,size_t* seclen,int* secnum,int* err );
52 static int grib2_has_next_section ( unsigned char* msgbegin,size_t msglen,unsigned char* secbegin,size_t seclen,int* err );
53 static void grib2_build_message ( grib_context* context,unsigned char* sections[],size_t sections_len[],void** data,size_t* msglen );
54 static grib_multi_support* grib_get_multi_support ( grib_context* c, FILE* f );
55 static grib_multi_support* grib_multi_support_new ( grib_context* c );
56 static grib_handle* grib_handle_new_multi ( grib_context* c,unsigned char** idata,size_t *buflen,int* error );
57
grib_section_create(grib_handle * h,grib_accessor * owner)58 grib_section* grib_section_create ( grib_handle* h,grib_accessor* owner )
59 {
60 grib_section* s = ( grib_section* ) grib_context_malloc_clear ( h->context,sizeof ( grib_section ) );
61 s->owner = owner;
62 s->aclength = NULL;
63 s->h = h;
64 s->block = ( grib_block_of_accessors* ) grib_context_malloc_clear ( h->context, sizeof ( grib_block_of_accessors ) );
65 return s;
66 }
67
update_sections(grib_section * s,grib_handle * h,long offset)68 static void update_sections ( grib_section *s,grib_handle* h,long offset )
69 {
70 grib_accessor *a = s?s->block->first:NULL;
71 if ( s ) s->h = h;
72 while ( a )
73 {
74 a->offset += offset;
75 /* update_sections ( grib_get_sub_section ( a ),h,offset ); */
76 update_sections ( a->sub_section,h,offset );
77 a = a->next;
78 }
79 }
80
grib_swap_sections(grib_section * the_old,grib_section * the_new)81 void grib_swap_sections ( grib_section* the_old, grib_section *the_new )
82 {
83 grib_accessor* a;
84 grib_block_of_accessors* b = the_old->block;
85
86 /* printf("SWAPPING -----\n"); grib_dump_section_content(new,stdout); */
87 the_old->block = the_new->block;
88 the_new->block = b;
89
90 a = the_old->aclength;
91 the_old->aclength = the_new->aclength;
92 the_new->aclength = a;
93
94 a = the_old->block->first;
95 while ( a )
96 {
97 a->parent = the_old;
98 a = a->next;
99 }
100
101 update_sections ( the_old, the_old->h, the_old->owner->offset );
102 /* update_sections(new,new->h,new->owner->offset); */
103
104 /* printf("SWAPPING -----\n"); grib_dump_section_content(old,stdout); */
105
106 }
107
grib_empty_section(grib_context * c,grib_section * b)108 void grib_empty_section ( grib_context *c,grib_section* b )
109 {
110 grib_accessor* current = NULL;
111 if ( !b ) return;
112
113 b->aclength = NULL;
114
115 current = b->block->first;
116
117 while ( current )
118 {
119 grib_accessor* next = current->next;
120 grib_accessor_delete ( c,current );
121 current = next;
122 }
123 b->block->first = b->block->last = 0;
124 }
125
grib_section_delete(grib_context * c,grib_section * b)126 void grib_section_delete ( grib_context *c, grib_section* b )
127 {
128 if ( !b ) return;
129
130 grib_empty_section ( c,b );
131 grib_context_free ( c,b->block );
132 grib_context_free ( c,b );
133 }
134
grib_handle_delete(grib_handle * h)135 int grib_handle_delete ( grib_handle* h )
136 {
137 if ( h != NULL )
138 {
139 grib_context *ct =h->context;
140 grib_dependency *d = h->dependencies;
141 grib_dependency *n;
142
143 Assert ( h->kid == NULL );
144
145 while ( d )
146 {
147 n = d->next;
148 grib_context_free ( ct,d );
149 d = n;
150 }
151 h->dependencies=0;
152
153 grib_buffer_delete ( ct,h->buffer );
154 grib_section_delete ( ct,h->root );
155
156 grib_context_log ( ct,GRIB_LOG_DEBUG,"grib_handle_delete: deleting handle %p",h );
157 grib_context_free ( ct,h );
158 h=NULL;
159 }
160 return GRIB_SUCCESS;
161 }
162
grib_new_handle(grib_context * c)163 grib_handle* grib_new_handle ( grib_context* c )
164 {
165 grib_handle *g = NULL;
166 if ( c == NULL ) c = grib_context_get_default();
167 g = ( grib_handle* ) grib_context_malloc_clear ( c,sizeof ( grib_handle ) );
168
169 if ( g == NULL ) {
170 grib_context_log ( c,GRIB_LOG_ERROR,"grib_new_handle: cannot allocate handle" );
171 } else {
172 g->context = c;
173 }
174
175 grib_context_log ( c,GRIB_LOG_DEBUG,"grib_new_handle: allocated handle %p",g );
176
177 return g;
178 }
179
grib_handle_create(grib_handle * gl,grib_context * c,void * data,size_t buflen)180 static grib_handle* grib_handle_create ( grib_handle *gl, grib_context* c,void* data, size_t buflen )
181 {
182 grib_action* next = NULL;
183 int err = 0;
184
185 if ( gl == NULL )
186 return NULL;
187
188 gl->use_trie = 1;
189 gl->trie_invalid=0;
190 gl->buffer = grib_new_buffer ( gl->context,(unsigned char*)data,buflen );
191
192 if ( gl->buffer == NULL )
193 {
194 grib_handle_delete ( gl );
195 return NULL;
196 }
197
198 gl->root = grib_create_root_section ( gl->context,gl );
199
200 if ( !gl->root )
201 {
202 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_message: cannot create root section" );
203 grib_handle_delete ( gl );
204 return NULL;
205 }
206
207 if ( !gl->context->grib_reader || !gl->context->grib_reader->first )
208 {
209 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_message: cannot create handle, no definitions found" );
210 grib_handle_delete ( gl );
211 return NULL;
212 }
213
214 gl->buffer->property = GRIB_USER_BUFFER;
215
216 next = gl->context->grib_reader->first->root;
217 while ( next )
218 {
219 if ( grib_create_accessor ( gl->root, next, NULL ) != GRIB_SUCCESS )
220 break;
221 next = next->next;
222 }
223
224 err = grib_section_adjust_sizes ( gl->root,0,0 );
225 if (err)
226 {
227 grib_handle_delete ( gl );
228 return NULL;
229 }
230
231 grib_section_post_init ( gl->root );
232
233 return gl;
234 }
235
grib_handle_new_from_template(grib_context * c,const char * name)236 grib_handle* grib_handle_new_from_template ( grib_context* c, const char* name )
237 {
238 if ( !c ) c=grib_context_get_default();
239 /*grib_context_log(c,GRIB_LOG_WARNING,"grib_handle_new_from_template function is deprecated, please use grib_handle_new_from_samples\n");*/
240 return grib_handle_new_from_samples ( c,name );
241 }
242
grib_handle_new_from_samples(grib_context * c,const char * name)243 grib_handle* grib_handle_new_from_samples ( grib_context* c, const char* name )
244 {
245 grib_handle* g = 0;
246 if ( c == NULL ) c = grib_context_get_default();
247 grib_context_set_handle_file_count(c,0);
248 grib_context_set_handle_total_count(c,0);
249
250 /*
251 g = grib_internal_template(c,name);
252 if(g) return g;
253 */
254 if (c->debug) {
255 printf("GRIB_API DEBUG: grib_handle_new_from_samples '%s'\n", name);
256 }
257
258 g=grib_external_template ( c,name );
259 if ( !g )
260 grib_context_log ( c,GRIB_LOG_ERROR,"Unable to load sample file %s.tmpl\n in %s",
261 name, c->grib_samples_path );
262
263 return g;
264 }
265
grib_write_message(grib_handle * h,const char * file,const char * mode)266 int grib_write_message(grib_handle* h,const char* file,const char* mode)
267 {
268 FILE* fh=0;
269 int err;
270 const void *buffer; size_t size;
271
272 fh=fopen(file,mode);
273 if (!fh) {
274 perror(file);
275 return GRIB_IO_PROBLEM;
276 }
277 err=grib_get_message(h,&buffer,&size);
278 if (err) {
279 fclose(fh);
280 return err;
281 }
282
283 if(fwrite(buffer,1,size,fh) != size) {
284 perror(file);
285 fclose(fh);
286 return GRIB_IO_PROBLEM;
287 }
288 if (fclose(fh) != 0) {
289 perror(file);
290 return GRIB_IO_PROBLEM;
291 }
292 return 0;
293 }
294
grib_handle_clone(grib_handle * h)295 grib_handle* grib_handle_clone ( grib_handle* h )
296 {
297 return grib_handle_new_from_message_copy ( h->context, h->buffer->data, h->buffer->ulength );
298 }
299
grib_handle_new_from_message_copy(grib_context * c,const void * data,size_t size)300 grib_handle* grib_handle_new_from_message_copy ( grib_context* c, const void* data, size_t size )
301 {
302 grib_handle *g = NULL;
303 void* copy =NULL;
304 if ( c == NULL ) c = grib_context_get_default();
305
306 grib_context_set_handle_file_count(c,0);
307 grib_context_set_handle_total_count(c,0);
308 copy = grib_context_malloc ( c,size );
309 if ( !copy ) {
310 return NULL;
311 }
312
313 memcpy ( copy,data,size );
314
315 g = grib_handle_new_from_message ( c,copy, size );
316 g->buffer->property = GRIB_MY_BUFFER;
317
318 return g;
319 }
320
grib_handle_new_from_partial_message_copy(grib_context * c,const void * data,size_t size)321 grib_handle* grib_handle_new_from_partial_message_copy ( grib_context* c, const void* data, size_t size )
322 {
323 grib_handle *g = NULL;
324 void* copy =NULL;
325 if ( c == NULL ) c = grib_context_get_default();
326 grib_context_set_handle_file_count(c,0);
327 grib_context_set_handle_total_count(c,0);
328 copy = grib_context_malloc ( c,size );
329 if ( !copy )
330 return NULL;
331
332 memcpy ( copy,data,size );
333
334 g = grib_handle_new_from_partial_message ( c,copy, size );
335 g->buffer->property = GRIB_MY_BUFFER;
336
337 return g;
338 }
339
grib_handle_new_from_partial_message(grib_context * c,void * data,size_t buflen)340 grib_handle* grib_handle_new_from_partial_message ( grib_context* c,void* data, size_t buflen )
341 {
342 grib_handle *gl = NULL;
343 if ( c == NULL ) c = grib_context_get_default();
344 grib_context_set_handle_file_count(c,0);
345 grib_context_set_handle_total_count(c,0);
346 gl = grib_new_handle ( c );
347 gl->partial = 1;
348 return grib_handle_create ( gl, c, data, buflen );
349 }
350
grib_handle_new_from_message(grib_context * c,void * data,size_t buflen)351 grib_handle* grib_handle_new_from_message ( grib_context* c,void* data, size_t buflen )
352 {
353 grib_handle *gl = NULL;
354 grib_handle *h = NULL;
355 if ( c == NULL ) c = grib_context_get_default();
356 gl = grib_new_handle ( c );
357 h=grib_handle_create ( gl, c, data, buflen );
358 return h;
359 }
360
grib_handle_new_from_multi_message(grib_context * c,void ** data,size_t * buflen,int * error)361 grib_handle* grib_handle_new_from_multi_message ( grib_context* c,void** data,
362 size_t *buflen,int* error )
363 {
364 grib_handle *h = NULL;
365 unsigned char** d= ( unsigned char** ) data;
366 if ( c == NULL ) c = grib_context_get_default();
367
368 if ( c->multi_support_on ) h=grib_handle_new_multi ( c,d, buflen,error );
369 else
370 {
371 size_t olen=0;
372 void * message=NULL;
373 *error = grib_read_any_from_memory_alloc ( c, d,buflen,&message, &olen );
374 if ( message==NULL ) return NULL;
375 h = grib_new_handle ( c );
376 grib_handle_create ( h, c, message, olen );
377 }
378
379 return h;
380 }
381
grib_handle_new_from_file(grib_context * c,FILE * f,int * error)382 grib_handle* grib_handle_new_from_file ( grib_context* c, FILE* f,int *error )
383 {
384 return eccode_grib_new_from_file(c,f,0,error);
385 }
386
grib_handle_new_multi(grib_context * c,unsigned char ** data,size_t * buflen,int * error)387 static grib_handle* grib_handle_new_multi ( grib_context* c,unsigned char** data,
388 size_t *buflen,int* error )
389 {
390 void * message=NULL;
391 size_t olen = 0,len=0;
392 grib_handle *gl = NULL;
393 long edition=0;
394 size_t seclen=0;
395 unsigned char* secbegin=0;
396 int secnum=0,seccount=0;
397 int err=0,i=0;
398 grib_multi_support* gm=NULL;
399
400 if ( c == NULL ) c = grib_context_get_default();
401
402 gm=grib_get_multi_support ( c,0 );
403
404 if ( !gm->message )
405 {
406 *error = grib_read_any_from_memory_alloc ( c, data,buflen,&message, &olen );
407 gm->message_length=olen;
408 gm->message=(unsigned char*)message;
409 if ( *error != GRIB_SUCCESS || !message )
410 {
411 if ( *error == GRIB_END_OF_FILE ) *error = GRIB_SUCCESS;
412 gm->message_length = 0;
413 return NULL;
414 }
415 }
416 else
417 {
418 message=gm->message;
419 }
420
421 edition=grib_decode_unsigned_byte_long ( (const unsigned char*)message,7,1 );
422
423 if ( edition == 2 )
424 {
425 olen=gm->message_length;
426 if ( gm->section_number == 0 )
427 {
428 gm->sections[0]=(unsigned char*)message;
429 }
430 secbegin=gm->sections[gm->section_number];
431 seclen=gm->sections_length[gm->section_number];
432 secnum=gm->section_number;
433 seccount=0;
434 while ( grib2_get_next_section ( (unsigned char*)message,olen,&secbegin,&seclen,&secnum,&err ) )
435 {
436 seccount++;
437 /*printf(" - %d - section %d length=%d\n",(int)seccount,(int)secnum,(int)seclen);*/
438
439 gm->sections[secnum]=secbegin;
440 gm->sections_length[secnum]=seclen;
441
442 if ( secnum == 6 )
443 {
444 /* Special case for inherited bitmaps */
445 if ( grib_decode_unsigned_byte_long ( secbegin,5,1 ) == 254 )
446 {
447 if ( !gm->bitmap_section )
448 {
449 grib_context_log ( c, GRIB_LOG_ERROR,
450 "grib_handle_new_from_file : cannot create handle, missing bitmap\n" );
451 return NULL;
452 }
453 gm->sections[secnum]= gm->bitmap_section;
454 gm->sections_length[secnum]=gm->bitmap_section_length;
455 }
456 else
457 {
458 if ( gm->bitmap_section )
459 {
460 grib_context_free ( c,gm->bitmap_section );
461 gm->bitmap_section=NULL;
462 }
463 gm->bitmap_section = ( unsigned char* ) grib_context_malloc ( c,seclen );
464 gm->bitmap_section = (unsigned char*)memcpy ( gm->bitmap_section,secbegin,seclen );
465 gm->bitmap_section_length=seclen;
466 }
467 }
468
469 if ( secnum == 7 )
470 {
471 void* p=message;
472 len=olen;
473 grib2_build_message ( c,gm->sections,gm->sections_length,&message,&len );
474
475 if ( grib2_has_next_section ( (unsigned char*)p,olen,secbegin,seclen,&err ) )
476 {
477 gm->message=(unsigned char*)p;
478 gm->section_number=secnum;
479 olen=len;
480 }
481 else
482 {
483 grib_context_free ( c,gm->message );
484 gm->message=NULL;
485 for ( i=0;i<8;i++ ) gm->sections[i]=NULL;
486 gm->section_number=0;
487 gm->message_length=0;
488 olen=len;
489 }
490
491 break;
492 }
493 }
494
495 }
496 else
497 {
498 gm->message_length=0;
499 gm->message=NULL;
500 }
501
502 gl = grib_handle_new_from_message ( c, message, olen );
503 if ( !gl )
504 {
505 *error = GRIB_DECODING_ERROR;
506 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_file : cannot create handle \n" );
507 return NULL;
508 }
509
510 gl->buffer->property = GRIB_MY_BUFFER;
511 grib_context_increment_handle_file_count(c);
512 grib_context_increment_handle_total_count(c);
513
514 return gl;
515 }
516
grib_handle_new_from_file_multi(grib_context * c,FILE * f,int * error)517 static grib_handle* grib_handle_new_from_file_multi ( grib_context* c, FILE* f,int *error )
518 {
519 void* data = NULL,*old_data=NULL;
520 size_t olen = 0,len=0;
521 grib_handle *gl = NULL;
522 long edition=0;
523 size_t seclen=0;
524 unsigned char* secbegin=0;
525 int secnum=0,seccount=0;
526 int err=0,i=0;
527 grib_multi_support* gm=NULL;
528 off_t gts_header_offset=0;
529 off_t end_msg_offset=0,offset=0;
530 char *gts_header=0,*save_gts_header=0;
531 int gtslen=0;
532
533 if ( c == NULL ) c = grib_context_get_default();
534
535 gm=grib_get_multi_support ( c,f );
536
537 if ( !gm->message )
538 {
539 gts_header_offset=grib_context_tell( c,f);
540 data = wmo_read_grib_from_file_malloc ( f,0, &olen,&offset,error );
541 end_msg_offset=grib_context_tell ( c,f );
542
543 gm->message_length=olen;
544 gm->message=(unsigned char*)data;
545 gm->offset=offset;
546 if ( *error != GRIB_SUCCESS || !data )
547 {
548 if ( data ) grib_context_free ( c,data );
549
550 if ( *error == GRIB_END_OF_FILE ) *error = GRIB_SUCCESS;
551 gm->message_length = 0;
552 gm->message=NULL;
553 return NULL;
554 }
555 if ( c->gts_header_on )
556 {
557 int g=0;
558 grib_context_seek ( c,gts_header_offset,SEEK_SET,f );
559 gtslen=offset-gts_header_offset;
560 gts_header=(char *)grib_context_malloc_clear ( c,sizeof ( unsigned char ) *gtslen );
561 save_gts_header=gts_header;
562 grib_context_read ( c,gts_header,gtslen,f );
563 g=gtslen;
564 while ( gts_header!=NULL && g != 0 && *gts_header != '\03' )
565 {
566 /*printf("--------%d %X \n",gtslen,*gts_header);*/
567 gts_header++;
568 g--;
569 }
570 if ( g>8 ) {gts_header++;gtslen=g-1;}
571 else gts_header=save_gts_header;
572 grib_context_seek ( c,end_msg_offset,SEEK_SET,f );
573 }
574
575 }
576 else
577 data=gm->message;
578
579 edition=grib_decode_unsigned_byte_long ( (const unsigned char*)data,7,1 );
580
581 if ( edition == 2 )
582 {
583 olen=gm->message_length;
584 if ( gm->section_number == 0 )
585 {
586 gm->sections[0]=(unsigned char*)data;
587 }
588 secbegin=gm->sections[gm->section_number];
589 seclen=gm->sections_length[gm->section_number];
590 secnum=gm->section_number;
591 seccount=0;
592 while ( grib2_get_next_section ( (unsigned char*)data,olen,&secbegin,&seclen,&secnum,&err ) )
593 {
594 seccount++;
595 /*printf(" - %d - section %d length=%d\n",(int)seccount,(int)secnum,(int)seclen);*/
596
597 gm->sections[secnum]=secbegin;
598 gm->sections_length[secnum]=seclen;
599
600 if ( secnum == 6 )
601 {
602 /* Special case for inherited bitmaps */
603 if ( grib_decode_unsigned_byte_long ( secbegin,5,1 ) == 254 )
604 {
605 if ( !gm->bitmap_section )
606 {
607 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_file : cannot create handle, missing bitmap\n" );
608 grib_context_free ( c,data );
609 return NULL;
610 }
611 gm->sections[secnum]= gm->bitmap_section;
612 gm->sections_length[secnum]=gm->bitmap_section_length;
613 }
614 else
615 {
616 if ( gm->bitmap_section )
617 {
618 grib_context_free ( c,gm->bitmap_section );
619 gm->bitmap_section=NULL;
620 }
621 gm->bitmap_section = ( unsigned char* ) grib_context_malloc ( c,seclen );
622 gm->bitmap_section = (unsigned char*)memcpy ( gm->bitmap_section,secbegin,seclen );
623 gm->bitmap_section_length=seclen;
624 }
625 }
626
627 if ( secnum == 7 )
628 {
629 old_data=data;
630 len=olen;
631 grib2_build_message ( c,gm->sections,gm->sections_length,&data,&len );
632
633 if ( grib2_has_next_section ( (unsigned char*)old_data,olen,secbegin,seclen,&err ) )
634 {
635 gm->message=(unsigned char*)old_data;
636 gm->section_number=secnum;
637 olen=len;
638 }
639 else
640 {
641 if ( gm->message ) grib_context_free ( c,gm->message );
642 gm->message=NULL;
643 for ( i=0;i<8;i++ ) gm->sections[i]=NULL;
644 gm->section_number=0;
645 gm->message_length=0;
646 olen=len;
647 }
648 break;
649 }
650 }
651
652 }
653 else
654 {
655 gm->message_length=0;
656 gm->message=NULL;
657 }
658
659 gl = grib_handle_new_from_message ( c, data, olen );
660 if ( !gl )
661 {
662 *error = GRIB_DECODING_ERROR;
663 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_file : cannot create handle \n" );
664 grib_context_free ( c,data );
665 return NULL;
666 }
667
668 gl->offset=gm->offset;
669 gl->buffer->property = GRIB_MY_BUFFER;
670 grib_context_increment_handle_file_count(c);
671 grib_context_increment_handle_total_count(c);
672
673 if ( c->gts_header_on && gtslen >=8 )
674 {
675 gl->gts_header=(char*)grib_context_malloc_clear ( c,sizeof ( unsigned char ) *gtslen );
676 memcpy ( gl->gts_header,gts_header,gtslen );
677 gl->gts_header_len=gtslen;
678 grib_context_free ( c,save_gts_header );
679 gtslen=0;
680 } else gl->gts_header=NULL;
681
682 return gl;
683 }
684
eccode_grib_new_from_file(grib_context * c,FILE * f,int headers_only,int * error)685 grib_handle* eccode_grib_new_from_file ( grib_context* c, FILE* f,int headers_only,int *error )
686 {
687 grib_handle* h=0;
688 if (!f) {*error=GRIB_IO_PROBLEM; return NULL;}
689
690 if ( c == NULL ) c = grib_context_get_default();
691
692 if ( c->multi_support_on ) h=grib_handle_new_from_file_multi ( c,f,error );
693 else h=grib_handle_new_from_file_no_multi ( c,f,headers_only,error );
694
695 if ( h && h->offset == 0 ) grib_context_set_handle_file_count(c,1);
696
697 if ( !c->no_fail_on_wrong_length && *error == GRIB_WRONG_LENGTH )
698 {
699 grib_handle_delete ( h );
700 h=NULL;
701 }
702
703 return h;
704 }
705
eccode_gts_new_from_file(grib_context * c,FILE * f,int headers_only,int * error)706 grib_handle* eccode_gts_new_from_file ( grib_context* c, FILE* f,int headers_only,int *error )
707 {
708 void *data = NULL;
709 size_t olen = 0;
710 grib_handle *gl = NULL;
711 off_t offset=0;
712
713 if ( c == NULL ) c = grib_context_get_default();
714
715 data = wmo_read_gts_from_file_malloc ( f, headers_only,&olen,&offset,error );
716
717 if ( *error != GRIB_SUCCESS )
718 {
719 if ( data ) grib_context_free ( c,data );
720
721 if ( *error == GRIB_END_OF_FILE ) *error = GRIB_SUCCESS;
722 return NULL;
723 }
724
725 if (headers_only) {
726 gl = grib_handle_new_from_partial_message ( c, data, olen );
727 } else {
728 gl = grib_handle_new_from_message ( c, data, olen );
729 }
730
731 if ( !gl )
732 {
733 *error = GRIB_DECODING_ERROR;
734 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_file : cannot create handle \n" );
735 grib_context_free ( c,data );
736 return NULL;
737 }
738
739 gl->offset=offset;
740 gl->buffer->property = GRIB_MY_BUFFER;
741 grib_context_increment_handle_file_count(c);
742 grib_context_increment_handle_total_count(c);
743
744 return gl;
745 }
746
eccode_bufr_new_from_file(grib_context * c,FILE * f,int headers_only,int * error)747 grib_handle* eccode_bufr_new_from_file ( grib_context* c, FILE* f,int headers_only,int *error )
748 {
749 void *data = NULL;
750 size_t olen = 0;
751 grib_handle *gl = NULL;
752 off_t offset=0;
753
754 if ( c == NULL ) c = grib_context_get_default();
755
756 data = wmo_read_bufr_from_file_malloc ( f, headers_only,&olen,&offset,error );
757
758 if ( *error != GRIB_SUCCESS )
759 {
760 if ( data ) grib_context_free ( c,data );
761
762 if ( *error == GRIB_END_OF_FILE ) *error = GRIB_SUCCESS;
763 return NULL;
764 }
765
766 if (headers_only) {
767 gl = grib_handle_new_from_partial_message ( c, data, olen );
768 } else {
769 gl = grib_handle_new_from_message ( c, data, olen );
770 }
771
772 if ( !gl )
773 {
774 *error = GRIB_DECODING_ERROR;
775 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_file : cannot create handle \n" );
776 grib_context_free ( c,data );
777 return NULL;
778 }
779
780 gl->offset=offset;
781 gl->buffer->property = GRIB_MY_BUFFER;
782 grib_context_increment_handle_file_count(c);
783 grib_context_increment_handle_total_count(c);
784
785 return gl;
786 }
787
eccode_any_new_from_file(grib_context * c,FILE * f,int headers_only,int * error)788 grib_handle* eccode_any_new_from_file ( grib_context* c, FILE* f,int headers_only,int *error )
789 {
790 void *data = NULL;
791 size_t olen = 0;
792 grib_handle *gl = NULL;
793 off_t offset=0;
794
795 if ( c == NULL ) c = grib_context_get_default();
796
797 data = wmo_read_any_from_file_malloc ( f, headers_only,&olen,&offset,error );
798
799 if ( *error != GRIB_SUCCESS )
800 {
801 if ( data ) grib_context_free ( c,data );
802
803 if ( *error == GRIB_END_OF_FILE ) *error = GRIB_SUCCESS;
804 return NULL;
805 }
806
807 if (headers_only) {
808 gl = grib_handle_new_from_partial_message ( c, data, olen );
809 } else {
810 gl = grib_handle_new_from_message ( c, data, olen );
811 }
812
813 if ( !gl )
814 {
815 *error = GRIB_DECODING_ERROR;
816 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_file : cannot create handle \n" );
817 grib_context_free ( c,data );
818 return NULL;
819 }
820
821 gl->offset=offset;
822 gl->buffer->property = GRIB_MY_BUFFER;
823 grib_context_increment_handle_file_count(c);
824 grib_context_increment_handle_total_count(c);
825
826 return gl;
827 }
828
grib_handle_new_from_file_no_multi(grib_context * c,FILE * f,int headers_only,int * error)829 static grib_handle* grib_handle_new_from_file_no_multi ( grib_context* c,FILE* f,int headers_only,int *error )
830 {
831 void *data = NULL;
832 size_t olen = 0;
833 grib_handle *gl = NULL;
834 off_t gts_header_offset=0;
835 off_t offset=0,end_msg_offset=0;
836 char *gts_header=0,*save_gts_header=0;
837 int gtslen=0;
838
839 if ( c == NULL ) c = grib_context_get_default();
840 data = wmo_read_grib_from_file_malloc ( f, headers_only,&olen,&offset,error );
841 end_msg_offset=offset+olen;
842
843 if ( *error != GRIB_SUCCESS )
844 {
845 if ( data ) grib_context_free ( c,data );
846
847 if ( *error == GRIB_END_OF_FILE ) *error = GRIB_SUCCESS;
848 return NULL;
849 }
850
851 if ( c->gts_header_on )
852 {
853 int g=0;
854 grib_context_seek ( c,gts_header_offset,SEEK_SET,f );
855 gtslen=offset-gts_header_offset;
856 gts_header=(char*)grib_context_malloc ( c,sizeof ( unsigned char ) *gtslen );
857 save_gts_header=gts_header;
858 grib_context_read ( c,gts_header,gtslen,f );
859 g=gtslen;
860 while ( gts_header!=NULL && g != 0 && *gts_header != '\03' )
861 {
862 /*printf("--------%d %X \n",gtslen,*gts_header);*/
863 gts_header++;
864 g--;
865 }
866 if ( g>8 ) {gts_header++;gtslen=g-1;}
867 else gts_header=save_gts_header;
868 grib_context_seek ( c,end_msg_offset,SEEK_SET,f );
869 }
870
871 if (headers_only) {
872 gl = grib_handle_new_from_partial_message ( c, data, olen );
873 } else {
874 gl = grib_handle_new_from_message ( c, data, olen );
875 }
876
877 if ( !gl )
878 {
879 *error = GRIB_DECODING_ERROR;
880 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_file : cannot create handle \n" );
881 grib_context_free ( c,data );
882 return NULL;
883 }
884
885 gl->offset=offset;
886 gl->buffer->property = GRIB_MY_BUFFER;
887
888 grib_context_increment_handle_file_count(c);
889 grib_context_increment_handle_total_count(c);
890
891 if ( c->gts_header_on && gtslen >=8 )
892 {
893 gl->gts_header=(char*)grib_context_malloc ( c,sizeof ( unsigned char ) *gtslen );
894 memcpy ( gl->gts_header,gts_header,gtslen );
895 gl->gts_header_len=gtslen;
896 grib_context_free ( c,save_gts_header );
897 gtslen=0;
898 }
899
900 return gl;
901 }
902
grib_multi_handle_new(grib_context * c)903 grib_multi_handle* grib_multi_handle_new ( grib_context* c )
904 {
905 grib_multi_handle* h;
906 if ( c==NULL ) c=grib_context_get_default();
907 if ( !c->multi_support_on ) c->multi_support_on=1;
908
909 h= ( grib_multi_handle* ) grib_context_malloc_clear ( c,sizeof ( grib_multi_handle ) );
910 if ( h==NULL )
911 {
912 grib_context_log ( c,GRIB_LOG_ERROR,
913 "grib_multi_handle_new: unable to allocate memory. %s",
914 grib_get_error_message ( GRIB_OUT_OF_MEMORY ) );
915 return NULL;
916 }
917 h->buffer = grib_create_growable_buffer ( c );
918 h->buffer->ulength=0;
919 h->context=c;
920
921 return h;
922 }
923
grib_multi_handle_delete(grib_multi_handle * h)924 int grib_multi_handle_delete ( grib_multi_handle* h )
925 {
926 if ( h==NULL ) return GRIB_SUCCESS;
927
928 grib_buffer_delete ( h->context,h->buffer );
929 grib_context_free ( h->context,h );
930 return GRIB_SUCCESS;
931 }
932
grib_multi_handle_append(grib_handle * h,int start_section,grib_multi_handle * mh)933 int grib_multi_handle_append ( grib_handle* h,int start_section,grib_multi_handle* mh )
934 {
935 const void* mess=NULL;
936 unsigned char* p=NULL;
937 int err=0;
938 size_t mess_len = 0;
939 size_t total_len=0;
940
941 if ( !h ) return GRIB_NULL_HANDLE;
942 if ( !mh ) return GRIB_NULL_HANDLE;
943
944 if ( start_section==0 || mh->buffer->ulength==0 )
945 {
946 err=grib_get_message ( h,&mess,&mess_len );
947 if ( err!=0 ) return err;
948 total_len=mh->buffer->ulength+mess_len;
949
950 if ( total_len > mh->buffer->length )
951 grib_grow_buffer ( h->context,mh->buffer,total_len );
952
953 p=mh->buffer->data+mh->buffer->ulength;
954 memcpy ( p,mess,mess_len );
955 mh->offset=mh->buffer->ulength;
956 mh->buffer->ulength=total_len;
957 mh->length=mess_len;
958
959 }
960 else
961 {
962 long off=0;
963 err=grib_get_partial_message ( h,&mess,&mess_len,start_section );
964 if ( err!=0 ) return err;
965 total_len=mh->buffer->ulength+mess_len-4;
966
967 while ( total_len > mh->buffer->length )
968 grib_grow_buffer ( h->context,mh->buffer,total_len );
969
970 p=mh->buffer->data+mh->buffer->ulength-4;
971 memcpy ( p,mess,mess_len );
972 mh->length+=mess_len-4;
973
974 off=mh->offset+64;
975
976 grib_encode_unsigned_long ( mh->buffer->data, mh->length, &off, 64 );
977 mh->buffer->ulength=total_len;
978 }
979 return err;
980 }
981
grib_multi_handle_write(grib_multi_handle * h,FILE * f)982 int grib_multi_handle_write ( grib_multi_handle* h,FILE* f )
983 {
984 if ( f==NULL ) return GRIB_INVALID_FILE;
985 if ( h==NULL ) return GRIB_INVALID_GRIB;
986
987 if ( fwrite ( h->buffer->data,1,h->buffer->ulength,f ) != h->buffer->ulength )
988 {
989 grib_context_log ( h->context,GRIB_LOG_PERROR,"grib_multi_handle_write writing on file" );
990 return GRIB_IO_PROBLEM;
991 }
992
993 return 0;
994 }
995
grib_get_partial_message(grib_handle * h,const void ** msg,size_t * len,int start_section)996 int grib_get_partial_message ( grib_handle* h,const void** msg,size_t* len,int start_section )
997 {
998 size_t partial_len=0;
999 long section_offset=0;
1000 if ( !h ) return GRIB_NULL_HANDLE;
1001
1002 if ( start_section>h->sections_count )
1003 return GRIB_INVALID_SECTION_NUMBER;
1004
1005 grib_get_long ( h,h->section_offset[start_section],§ion_offset );
1006 partial_len=h->buffer->ulength-section_offset;
1007
1008 *len=partial_len;
1009 *msg = h->buffer->data+section_offset;
1010
1011 return GRIB_SUCCESS;
1012 }
1013
grib_get_partial_message_copy(grib_handle * h,void * message,size_t * len,int start_section)1014 int grib_get_partial_message_copy ( grib_handle* h , void* message,size_t *len,
1015 int start_section )
1016 {
1017 size_t partial_len=0;
1018 long section_offset=0;
1019 if ( !h ) return GRIB_NULL_HANDLE;
1020
1021 if ( start_section>h->sections_count )
1022 return GRIB_INVALID_SECTION_NUMBER;
1023
1024 grib_get_long ( h,h->section_offset[start_section],§ion_offset );
1025 partial_len=h->buffer->ulength-section_offset;
1026
1027 if ( *len < partial_len ) return GRIB_BUFFER_TOO_SMALL;
1028
1029 *len=partial_len;
1030
1031 memcpy ( message,h->buffer->data+section_offset,*len );
1032 return GRIB_SUCCESS;
1033 }
1034
grib_get_message_copy(grib_handle * h,void * message,size_t * len)1035 int grib_get_message_copy ( grib_handle* h , void* message,size_t *len )
1036 {
1037 if ( !h )
1038 return GRIB_NOT_FOUND;
1039
1040 if ( *len < h->buffer->ulength )
1041 return GRIB_BUFFER_TOO_SMALL;
1042
1043 *len=h->buffer->ulength;
1044
1045 memcpy ( message,h->buffer->data,*len );
1046 return GRIB_SUCCESS;
1047 }
1048
grib_get_message_offset(grib_handle * h,off_t * offset)1049 int grib_get_message_offset ( grib_handle* h,off_t* offset )
1050 {
1051 if (h) *offset=h->offset;
1052 else return GRIB_INTERNAL_ERROR;
1053
1054 return 0;
1055 }
1056
grib_get_message_size(grib_handle * h,size_t * size)1057 int grib_get_message_size ( grib_handle* h,size_t* size )
1058 {
1059 long totalLength=0;
1060 int ret=0;
1061 *size = h->buffer->ulength;
1062 ret=grib_get_long(h,"totalLength",&totalLength);
1063 if (!ret) *size=totalLength;
1064 return ret;
1065 }
1066
grib_get_message(grib_handle * h,const void ** msg,size_t * size)1067 int grib_get_message ( grib_handle* h,const void** msg,size_t* size )
1068 {
1069 long totalLength=0;
1070 int ret=0;
1071 *msg = h->buffer->data;
1072 *size = h->buffer->ulength;
1073
1074 ret=grib_get_long(h,"totalLength",&totalLength);
1075 if (!ret) *size=totalLength;
1076
1077 if ( h->context->gts_header_on && h->gts_header )
1078 {
1079 char strbuf[10];
1080 sprintf ( strbuf,"%.8d", ( int ) ( h->buffer->ulength+h->gts_header_len-6 ) );
1081 memcpy ( h->gts_header,strbuf,8 );
1082 }
1083 return 0;
1084 }
1085
grib_get_message_headers(grib_handle * h,const void ** msg,size_t * size)1086 int grib_get_message_headers ( grib_handle* h,const void** msg,size_t* size )
1087 {
1088 int ret=0;
1089 size_t endOfHeadersMaker;
1090 *msg = h->buffer->data;
1091 *size = h->buffer->ulength;
1092
1093 if ((ret=grib_get_offset(h,"endOfHeadersMaker",&endOfHeadersMaker))!=GRIB_SUCCESS) {
1094 grib_context_log(h->context,GRIB_LOG_FATAL,
1095 "grib_get_message_headers unable to get offset of endOfHeadersMaker");
1096 return ret;
1097 }
1098
1099 *size=endOfHeadersMaker;
1100
1101 return ret;
1102 }
1103
grib_handle_new(grib_context * c)1104 grib_handle *grib_handle_new ( grib_context* c )
1105 {
1106 grib_handle* h;
1107
1108 if ( !c ) c = grib_context_get_default();
1109 h = grib_new_handle ( c );
1110 h->buffer = grib_create_growable_buffer ( c );
1111 if ( h->buffer == NULL )
1112 {
1113 grib_handle_delete ( h );
1114 return NULL;
1115 }
1116 h->root = grib_create_root_section ( h->context,h );
1117
1118 if ( !h->root )
1119 {
1120 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_message: cannot create root section" );
1121 grib_handle_delete ( h );
1122 return NULL;
1123 }
1124
1125 if ( !h->context->grib_reader || !h->context->grib_reader->first )
1126 {
1127 grib_context_log ( c, GRIB_LOG_ERROR, "grib_handle_new_from_message: cannot create handle, no definitions found" );
1128 grib_handle_delete ( h );
1129 return NULL;
1130 }
1131
1132 h->buffer->property = GRIB_USER_BUFFER;
1133
1134 h->header_mode=1;
1135
1136 return h;
1137 }
1138
grib_action_from_filter(const char * filter)1139 grib_action* grib_action_from_filter ( const char* filter )
1140 {
1141 grib_action* a = NULL;
1142 grib_context* context=grib_context_get_default();
1143 a = grib_parse_file ( context, filter );
1144 context->grib_reader=NULL;
1145 return a;
1146 }
1147
grib_handle_apply_action(grib_handle * h,grib_action * a)1148 int grib_handle_apply_action ( grib_handle* h,grib_action* a )
1149 {
1150 int err;
1151 grib_action* ao = a;
1152
1153 if ( !a ) return GRIB_SUCCESS; /* TODO: return error */
1154
1155 while ( a )
1156 {
1157 err = grib_action_execute ( a,h );
1158 if ( err != GRIB_SUCCESS )
1159 return err;
1160 a = a->next;
1161 }
1162
1163 a=ao;
1164
1165 return GRIB_SUCCESS;
1166 }
1167
grib_handle_prepare_action(grib_handle * h,grib_action * a)1168 int grib_handle_prepare_action ( grib_handle* h,grib_action* a )
1169 {
1170 int err;
1171 grib_action* ao = a;
1172
1173 if ( !a ) return GRIB_SUCCESS; /* TODO: return error */
1174
1175 while ( a )
1176 {
1177 err = grib_action_execute ( a,h );
1178 if ( err != GRIB_SUCCESS )
1179 return err;
1180 a = a->next;
1181 }
1182
1183 a=ao;
1184
1185 return GRIB_SUCCESS;
1186 }
1187
grib2_get_next_section(unsigned char * msgbegin,size_t msglen,unsigned char ** secbegin,size_t * seclen,int * secnum,int * err)1188 static int grib2_get_next_section ( unsigned char* msgbegin,size_t msglen,unsigned char** secbegin,size_t* seclen,int* secnum,int* err )
1189 {
1190 if ( !grib2_has_next_section ( msgbegin,msglen,*secbegin,*seclen,err ) )
1191 return 0;
1192
1193 *secbegin+=*seclen;
1194 *seclen=grib_decode_unsigned_byte_long ( *secbegin,0,4 );
1195 *secnum=grib_decode_unsigned_byte_long ( *secbegin,4,1 );
1196
1197 if ( *secnum < 1 || *secnum > 7 )
1198 {
1199 *err=GRIB_INVALID_SECTION_NUMBER;
1200 return 0;
1201 }
1202 return 1;
1203 }
1204
grib2_has_next_section(unsigned char * msgbegin,size_t msglen,unsigned char * secbegin,size_t seclen,int * err)1205 static int grib2_has_next_section ( unsigned char* msgbegin,size_t msglen,unsigned char* secbegin,size_t seclen,int* err )
1206 {
1207 long next_seclen;
1208 *err=0;
1209
1210 next_seclen= ( msgbegin+msglen )- ( secbegin+seclen );
1211
1212 if ( next_seclen < 5 )
1213 {
1214 if ( ( next_seclen > 3 ) && !strncmp ( ( char* ) secbegin,"7777",4 ) )
1215 *err=GRIB_SUCCESS;
1216 else *err=GRIB_7777_NOT_FOUND;
1217 return 0;
1218 }
1219
1220 secbegin+=seclen;
1221
1222 return 1;
1223 }
1224
grib2_build_message(grib_context * context,unsigned char * sections[],size_t sections_len[],void ** data,size_t * len)1225 static void grib2_build_message ( grib_context* context,unsigned char* sections[],size_t sections_len[],void** data,size_t* len )
1226 {
1227 int i=0;
1228 char* theEnd="7777";
1229 unsigned char* p=0;
1230 size_t msglen=0;
1231 long bitp=64;
1232 if ( !sections[0] )
1233 {
1234 *data=NULL;
1235 return;
1236 }
1237
1238 for ( i=0;i<8;i++ ) msglen+= sections_len[i];
1239 msglen+=4;
1240 if ( *len<msglen ) msglen=*len;
1241
1242 *data= ( unsigned char* ) grib_context_malloc ( context,msglen );
1243 p=(unsigned char*)*data;
1244
1245 for ( i=0;i<8;i++ )
1246 {
1247 if ( sections[i] )
1248 {
1249 memcpy ( p,sections[i],sections_len[i] );
1250 p+=sections_len[i];
1251 }
1252 }
1253
1254 memcpy ( p,theEnd,4 );
1255
1256 grib_encode_unsigned_long ( (unsigned char*)*data,msglen,&bitp,64 );
1257
1258 *len=msglen;
1259 }
1260
grib_multi_support_on(grib_context * c)1261 void grib_multi_support_on ( grib_context* c )
1262 {
1263 if ( !c ) c=grib_context_get_default();
1264 c->multi_support_on=1;
1265 }
1266
grib_multi_support_off(grib_context * c)1267 void grib_multi_support_off ( grib_context* c )
1268 {
1269 if ( !c ) c=grib_context_get_default();
1270 c->multi_support_on=0;
1271 }
1272
1273 /* For multi support mode: Reset all file handles equal to f. See GRIB-249 */
grib_multi_support_reset_file(grib_context * c,FILE * f)1274 void grib_multi_support_reset_file(grib_context* c, FILE* f)
1275 {
1276 grib_multi_support* gm = NULL;
1277 if ( !c ) c = grib_context_get_default();
1278 gm = c->multi_support;
1279 while ( gm ) {
1280 if ( gm->file == f ) {
1281 gm->file = NULL;
1282 }
1283 gm=gm->next;
1284 }
1285 }
1286
grib_gts_header_on(grib_context * c)1287 void grib_gts_header_on ( grib_context* c )
1288 {
1289 if ( !c ) c=grib_context_get_default();
1290 c->gts_header_on=1;
1291 }
1292
grib_gts_header_off(grib_context * c)1293 void grib_gts_header_off ( grib_context* c )
1294 {
1295 if ( !c ) c=grib_context_get_default();
1296 c->gts_header_on=0;
1297 }
1298
grib_get_gribex_mode(grib_context * c)1299 int grib_get_gribex_mode ( grib_context* c)
1300 {
1301 if ( !c ) c=grib_context_get_default();
1302 return c->gribex_mode_on;
1303 }
1304
grib_gribex_mode_on(grib_context * c)1305 void grib_gribex_mode_on ( grib_context* c )
1306 {
1307 if ( !c ) c=grib_context_get_default();
1308 c->gribex_mode_on=1;
1309 }
1310
grib_gribex_mode_off(grib_context * c)1311 void grib_gribex_mode_off ( grib_context* c )
1312 {
1313 if ( !c ) c=grib_context_get_default();
1314 c->gribex_mode_on=0;
1315 }
1316
grib_get_multi_support(grib_context * c,FILE * f)1317 static grib_multi_support* grib_get_multi_support ( grib_context* c, FILE* f )
1318 {
1319 int i=0;
1320 grib_multi_support* gm=c->multi_support;
1321 grib_multi_support* prev=NULL;
1322
1323 while ( gm )
1324 {
1325 if ( gm->file == f ) return gm;
1326 prev=gm;
1327 gm=gm->next;
1328 }
1329
1330 if ( !gm )
1331 {
1332 gm=grib_multi_support_new ( c );
1333 if ( !c->multi_support ) c->multi_support=gm;
1334 else prev->next=gm;
1335 }
1336
1337 gm->next=0;
1338 if ( gm->message ) grib_context_free ( c,gm->message );
1339 gm->message=NULL;
1340 gm->section_number=0;
1341 gm->sections_length[0]=16;
1342 for ( i=1;i<8;i++ ) gm->sections_length[i]=0;
1343 gm->sections_length[8]=4;
1344 gm->file=f;
1345
1346 return gm;
1347 }
1348
grib_multi_support_reset(grib_context * c)1349 void grib_multi_support_reset ( grib_context* c )
1350 {
1351 grib_multi_support* gm=c->multi_support;
1352 grib_multi_support* next=NULL;
1353 int i=0;
1354 while ( next )
1355 {
1356 next=gm->next;
1357 if ( gm->file ) fclose ( gm->file );
1358 if ( gm->message ) grib_context_free ( c,gm->message );
1359 gm->message=NULL;
1360 for ( i=0;i<8;i++ ) gm->sections[i]=0;
1361 if ( gm->bitmap_section ) grib_context_free ( c,gm->bitmap_section );
1362 gm->bitmap_section=NULL;
1363 grib_context_free ( c,gm );
1364 gm=NULL;
1365 }
1366 }
1367
grib_multi_support_new(grib_context * c)1368 static grib_multi_support* grib_multi_support_new ( grib_context* c )
1369 {
1370 int i=0;
1371 grib_multi_support* gm=
1372 ( grib_multi_support* ) grib_context_malloc_clear ( c,sizeof ( grib_multi_support ) );
1373 gm->file=NULL;
1374 gm->message=NULL;
1375 gm->message_length=0;
1376 gm->bitmap_section=NULL;
1377 gm->bitmap_section_length=0;
1378 gm->section_number=0;
1379 gm->next=0;
1380 gm->sections_length[0]=16;
1381 for ( i=1;i<8;i++ ) gm->sections_length[i]=0;
1382 gm->sections_length[8]=4;
1383
1384 return gm;
1385 }
1386