-
Notifications
You must be signed in to change notification settings - Fork 0
/
grib2_stubs.c
103 lines (83 loc) · 2.4 KB
/
grib2_stubs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
* An OCaml wrapper for NCEP's NCO library
* Hezekiah M. Carty
*
*/
/* The "usual" OCaml includes */
#include <caml/alloc.h>
#include <caml/callback.h>
#include <caml/fail.h>
#include <caml/memory.h>
#include <caml/misc.h>
#include <caml/mlvalues.h>
#include <caml/bigarray.h>
#include <caml/custom.h>
/* Shapelib API include */
#include <grib2.h>
/* For debugging - we want to have access to printf, stderr and such */
#include <stdio.h>
#include <string.h>
// Allow for ridiculously long exception strings.
#define MAX_EXCEPTION_MESSAGE_LENGTH 10000
//
//
// GRIB field handling
//
//
#define Gribfield_val(val) (* ((gribfield **) Data_custom_val(val)))
// OCaml handler to free a GRIB field when it is GC'd
void finalize_gribfield( value ml_field ) {
gribfield *field;
field = Gribfield_val( ml_field );
g2_free( field );
return;
}
// Definition for custom OCaml handler functions
static struct custom_operations gribfield_custom_ops = {
identifier: "grib field handling",
finalize: finalize_gribfield,
compare: custom_compare_default,
hash: custom_hash_default,
serialize: custom_serialize_default,
deserialize: custom_deserialize_default
};
value Val_gribfield( gribfield *field ) {
gribfield **store;
value ret;
ret = caml_alloc_custom(&gribfield_custom_ops, sizeof(store), 0, 1);
store = Data_custom_val(ret);
*store = field;
return ret;
}
//
//
// Unpacking
//
//
// Get GRIB field
value ml_g2_getfld( value message, value field_num, value unpack, value expand ) {
CAMLparam4( message, field_num, unpack, expand );
int result;
gribfield *field;
result = g2_getfld( String_val( message ), Int_val( field_num ), Int_val( unpack ), Int_val( expand ), &field );
// Raise an exception if we fail to extract a field
if ( result != 0 ) {
caml_invalid_argument( "Bad message" );
}
CAMLreturn( Val_gribfield( field ) );
}
// Get grid values from a GRIB field
value ml_get_data( value ml_field ) {
CAMLparam1( ml_field );
CAMLlocal1( ml_data );
int i;
gribfield *field;
field = Gribfield_val( ml_field );
// Allocate an OCaml array and copy the data over
ml_data = caml_alloc( field->ndpts * Double_wosize, Double_array_tag );
for ( i = 0; i < field->ndpts; i++ ) {
Store_double_field( ml_data, i, field->fld[i] );
}
// Return the OCaml-formatted data copy
CAMLreturn( ml_data );
}