netcdf 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +34 -0
- data/LICENSE +21 -0
- data/README.md +82 -0
- data/docs/00_introduction.md +34 -0
- data/docs/01_getting_started.md +127 -0
- data/docs/02_buffers.md +95 -0
- data/docs/03_reference.md +410 -0
- data/ext/netcdf/extconf.rb +61 -0
- data/ext/netcdf/internal.h +64 -0
- data/ext/netcdf/nc_att.c +431 -0
- data/ext/netcdf/nc_dim.c +74 -0
- data/ext/netcdf/nc_file.c +349 -0
- data/ext/netcdf/nc_group.c +171 -0
- data/ext/netcdf/nc_io.c +1284 -0
- data/ext/netcdf/nc_types.c +278 -0
- data/ext/netcdf/nc_var.c +551 -0
- data/ext/netcdf/netcdf.c +289 -0
- data/lib/netcdf/version.rb +3 -0
- data/lib/netcdf.rb +29 -0
- data/netcdf.gemspec +30 -0
- metadata +66 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* User-defined NetCDF-4 types.
|
|
3
|
+
*
|
|
4
|
+
* Currently covers opaque, vlen, and enum. Compound types are not yet
|
|
5
|
+
* implemented; see API.md "Deferred features".
|
|
6
|
+
*/
|
|
7
|
+
#include "internal.h"
|
|
8
|
+
|
|
9
|
+
/* ---------------------------------------------------------- */
|
|
10
|
+
/* Generic user-type inquiry */
|
|
11
|
+
/* ---------------------------------------------------------- */
|
|
12
|
+
|
|
13
|
+
/* Returns [name, size, base_type, nfields, class].
|
|
14
|
+
* class is one of NC_VLEN / NC_OPAQUE / NC_ENUM / NC_COMPOUND. */
|
|
15
|
+
static VALUE
|
|
16
|
+
rb_nc_inq_user_type (VALUE self, VALUE rncid, VALUE rtypeid)
|
|
17
|
+
{
|
|
18
|
+
char name[NC_MAX_NAME + 1];
|
|
19
|
+
size_t size, nfields;
|
|
20
|
+
nc_type base;
|
|
21
|
+
int klass;
|
|
22
|
+
|
|
23
|
+
NC_CHECK(nc_inq_user_type(NUM2INT(rncid), NUM2INT(rtypeid),
|
|
24
|
+
name, &size, &base, &nfields, &klass));
|
|
25
|
+
return rb_ary_new_from_args(5,
|
|
26
|
+
rb_utf8_str_new_cstr(name), SIZET2NUM(size),
|
|
27
|
+
INT2NUM(base), SIZET2NUM(nfields), INT2NUM(klass));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Look up a type by name within a group. Returns nil when not found. */
|
|
31
|
+
static VALUE
|
|
32
|
+
rb_nc_inq_typeid (VALUE self, VALUE rncid, VALUE rname)
|
|
33
|
+
{
|
|
34
|
+
nc_type t;
|
|
35
|
+
int st;
|
|
36
|
+
|
|
37
|
+
st = nc_inq_typeid(NUM2INT(rncid), StringValueCStr(rname), &t);
|
|
38
|
+
if ( st == NC_EBADTYPE || st == NC_ENOTNC4 ) {
|
|
39
|
+
return Qnil;
|
|
40
|
+
}
|
|
41
|
+
if ( st != NC_NOERR ) {
|
|
42
|
+
nc_raise(st);
|
|
43
|
+
}
|
|
44
|
+
return INT2NUM(t);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* List user-defined typeids visible in a group. */
|
|
48
|
+
static VALUE
|
|
49
|
+
rb_nc_inq_typeids (VALUE self, VALUE rncid)
|
|
50
|
+
{
|
|
51
|
+
VALUE out;
|
|
52
|
+
int n, st, i;
|
|
53
|
+
int *ids;
|
|
54
|
+
|
|
55
|
+
NC_CHECK(nc_inq_typeids(NUM2INT(rncid), &n, NULL));
|
|
56
|
+
ids = ALLOC_N(int, n > 0 ? n : 1);
|
|
57
|
+
st = nc_inq_typeids(NUM2INT(rncid), NULL, ids);
|
|
58
|
+
if ( st != NC_NOERR ) {
|
|
59
|
+
xfree(ids);
|
|
60
|
+
nc_raise(st);
|
|
61
|
+
}
|
|
62
|
+
out = rb_ary_new_capa(n);
|
|
63
|
+
for (i=0; i<n; i++) {
|
|
64
|
+
rb_ary_push(out, INT2NUM(ids[i]));
|
|
65
|
+
}
|
|
66
|
+
xfree(ids);
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ---------------------------------------------------------- */
|
|
71
|
+
/* Opaque (fixed-size byte type) */
|
|
72
|
+
/* ---------------------------------------------------------- */
|
|
73
|
+
|
|
74
|
+
static VALUE
|
|
75
|
+
rb_nc_def_opaque (VALUE self, VALUE rncid, VALUE rsize, VALUE rname)
|
|
76
|
+
{
|
|
77
|
+
nc_type t;
|
|
78
|
+
|
|
79
|
+
NC_CHECK(nc_def_opaque(NUM2INT(rncid), NUM2SIZET(rsize),
|
|
80
|
+
StringValueCStr(rname), &t));
|
|
81
|
+
return INT2NUM(t);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Returns [name, size]. */
|
|
85
|
+
static VALUE
|
|
86
|
+
rb_nc_inq_opaque (VALUE self, VALUE rncid, VALUE rtypeid)
|
|
87
|
+
{
|
|
88
|
+
char name[NC_MAX_NAME + 1];
|
|
89
|
+
size_t size;
|
|
90
|
+
|
|
91
|
+
NC_CHECK(nc_inq_opaque(NUM2INT(rncid), NUM2INT(rtypeid), name, &size));
|
|
92
|
+
return rb_ary_new_from_args(2, rb_utf8_str_new_cstr(name), SIZET2NUM(size));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* ---------------------------------------------------------- */
|
|
96
|
+
/* Vlen (variable-length sequence) */
|
|
97
|
+
/* ---------------------------------------------------------- */
|
|
98
|
+
|
|
99
|
+
static VALUE
|
|
100
|
+
rb_nc_def_vlen (VALUE self, VALUE rncid, VALUE rname, VALUE rbase_type)
|
|
101
|
+
{
|
|
102
|
+
nc_type t;
|
|
103
|
+
|
|
104
|
+
NC_CHECK(nc_def_vlen(NUM2INT(rncid), StringValueCStr(rname),
|
|
105
|
+
NUM2INT(rbase_type), &t));
|
|
106
|
+
return INT2NUM(t);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Returns [name, datum_size, base_type]. */
|
|
110
|
+
static VALUE
|
|
111
|
+
rb_nc_inq_vlen (VALUE self, VALUE rncid, VALUE rtypeid)
|
|
112
|
+
{
|
|
113
|
+
char name[NC_MAX_NAME + 1];
|
|
114
|
+
size_t datum_size;
|
|
115
|
+
nc_type base;
|
|
116
|
+
|
|
117
|
+
NC_CHECK(nc_inq_vlen(NUM2INT(rncid), NUM2INT(rtypeid),
|
|
118
|
+
name, &datum_size, &base));
|
|
119
|
+
return rb_ary_new_from_args(3,
|
|
120
|
+
rb_utf8_str_new_cstr(name), SIZET2NUM(datum_size),
|
|
121
|
+
INT2NUM(base));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* ---------------------------------------------------------- */
|
|
125
|
+
/* Enum */
|
|
126
|
+
/* ---------------------------------------------------------- */
|
|
127
|
+
|
|
128
|
+
static VALUE
|
|
129
|
+
rb_nc_def_enum (VALUE self, VALUE rncid, VALUE rbase_type, VALUE rname)
|
|
130
|
+
{
|
|
131
|
+
nc_type t;
|
|
132
|
+
|
|
133
|
+
NC_CHECK(nc_def_enum(NUM2INT(rncid), NUM2INT(rbase_type),
|
|
134
|
+
StringValueCStr(rname), &t));
|
|
135
|
+
return INT2NUM(t);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Pack a Ruby integer into a buffer typed per the enum's base nc_type.
|
|
139
|
+
Returns the byte size used; the caller passes the buffer. */
|
|
140
|
+
static size_t
|
|
141
|
+
pack_int_for_base (nc_type base, VALUE v, void *buf)
|
|
142
|
+
{
|
|
143
|
+
switch ( base ) {
|
|
144
|
+
case NC_BYTE: *(signed char *) buf = num_to_schar(v); return 1;
|
|
145
|
+
case NC_UBYTE: *(unsigned char *) buf = num_to_uchar(v); return 1;
|
|
146
|
+
case NC_SHORT: *(short *) buf = num_to_short(v); return 2;
|
|
147
|
+
case NC_USHORT: *(unsigned short *) buf = num_to_ushort(v); return 2;
|
|
148
|
+
case NC_INT: *(int *) buf = NUM2INT(v); return 4;
|
|
149
|
+
case NC_UINT: *(unsigned int *) buf = num_to_uint(v); return 4;
|
|
150
|
+
case NC_INT64: *(long long *) buf = NUM2LL(v); return 8;
|
|
151
|
+
case NC_UINT64: *(unsigned long long *) buf = num_to_ulonglong(v); return 8;
|
|
152
|
+
default:
|
|
153
|
+
rb_raise(rb_eArgError, "enum base type must be an integer nc_type (got %d)", base);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static VALUE
|
|
158
|
+
unpack_int_for_base (nc_type base, const void *buf)
|
|
159
|
+
{
|
|
160
|
+
switch ( base ) {
|
|
161
|
+
case NC_BYTE: return INT2NUM(*(const signed char *) buf);
|
|
162
|
+
case NC_UBYTE: return UINT2NUM(*(const unsigned char *) buf);
|
|
163
|
+
case NC_SHORT: return INT2NUM(*(const short *) buf);
|
|
164
|
+
case NC_USHORT: return UINT2NUM(*(const unsigned short *) buf);
|
|
165
|
+
case NC_INT: return INT2NUM(*(const int *) buf);
|
|
166
|
+
case NC_UINT: return UINT2NUM(*(const unsigned int *) buf);
|
|
167
|
+
case NC_INT64: return LL2NUM(*(const long long *) buf);
|
|
168
|
+
case NC_UINT64: return ULL2NUM(*(const unsigned long long *) buf);
|
|
169
|
+
default:
|
|
170
|
+
rb_raise(rb_eArgError, "enum base type must be an integer nc_type (got %d)", base);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
static VALUE
|
|
175
|
+
rb_nc_insert_enum (VALUE self, VALUE rncid, VALUE rtypeid, VALUE rname, VALUE rvalue)
|
|
176
|
+
{
|
|
177
|
+
int ncid;
|
|
178
|
+
nc_type typeid, base;
|
|
179
|
+
long long buf; /* widest base type the API supports */
|
|
180
|
+
|
|
181
|
+
ncid = NUM2INT(rncid);
|
|
182
|
+
typeid = NUM2INT(rtypeid);
|
|
183
|
+
|
|
184
|
+
NC_CHECK(nc_inq_user_type(ncid, typeid, NULL, NULL, &base, NULL, NULL));
|
|
185
|
+
|
|
186
|
+
buf = 0;
|
|
187
|
+
pack_int_for_base(base, rvalue, &buf);
|
|
188
|
+
NC_CHECK(nc_insert_enum(ncid, typeid, StringValueCStr(rname), &buf));
|
|
189
|
+
return Qnil;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* Returns [name, base_type, base_size, num_members]. */
|
|
193
|
+
static VALUE
|
|
194
|
+
rb_nc_inq_enum (VALUE self, VALUE rncid, VALUE rtypeid)
|
|
195
|
+
{
|
|
196
|
+
char name[NC_MAX_NAME + 1];
|
|
197
|
+
nc_type base;
|
|
198
|
+
size_t base_size, nmembers;
|
|
199
|
+
|
|
200
|
+
NC_CHECK(nc_inq_enum(NUM2INT(rncid), NUM2INT(rtypeid),
|
|
201
|
+
name, &base, &base_size, &nmembers));
|
|
202
|
+
return rb_ary_new_from_args(4,
|
|
203
|
+
rb_utf8_str_new_cstr(name), INT2NUM(base),
|
|
204
|
+
SIZET2NUM(base_size), SIZET2NUM(nmembers));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Returns [name, value] for member at given zero-based index. */
|
|
208
|
+
static VALUE
|
|
209
|
+
rb_nc_inq_enum_member (VALUE self, VALUE rncid, VALUE rtypeid, VALUE ridx)
|
|
210
|
+
{
|
|
211
|
+
char name[NC_MAX_NAME + 1];
|
|
212
|
+
int ncid;
|
|
213
|
+
nc_type typeid, base;
|
|
214
|
+
long long buf;
|
|
215
|
+
|
|
216
|
+
ncid = NUM2INT(rncid);
|
|
217
|
+
typeid = NUM2INT(rtypeid);
|
|
218
|
+
|
|
219
|
+
NC_CHECK(nc_inq_user_type(ncid, typeid, NULL, NULL, &base, NULL, NULL));
|
|
220
|
+
|
|
221
|
+
buf = 0;
|
|
222
|
+
NC_CHECK(nc_inq_enum_member(ncid, typeid, NUM2INT(ridx), name, &buf));
|
|
223
|
+
return rb_ary_new_from_args(2,
|
|
224
|
+
rb_utf8_str_new_cstr(name),
|
|
225
|
+
unpack_int_for_base(base, &buf));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Returns the member name for a given integer value, or nil if not found. */
|
|
229
|
+
static VALUE
|
|
230
|
+
rb_nc_inq_enum_ident (VALUE self, VALUE rncid, VALUE rtypeid, VALUE rvalue)
|
|
231
|
+
{
|
|
232
|
+
char name[NC_MAX_NAME + 1];
|
|
233
|
+
int ncid, st;
|
|
234
|
+
nc_type typeid, base;
|
|
235
|
+
long long v;
|
|
236
|
+
|
|
237
|
+
ncid = NUM2INT(rncid);
|
|
238
|
+
typeid = NUM2INT(rtypeid);
|
|
239
|
+
|
|
240
|
+
NC_CHECK(nc_inq_user_type(ncid, typeid, NULL, NULL, &base, NULL, NULL));
|
|
241
|
+
|
|
242
|
+
/* nc_inq_enum_ident takes the value itself, not base-type bytes: it
|
|
243
|
+
widens each member to long long and compares. An NC_UINT64
|
|
244
|
+
member above LLONG_MAX widens by the same wrap-around cast. */
|
|
245
|
+
v = ( base == NC_UINT64 ) ? (long long) NUM2ULL(rvalue) : NUM2LL(rvalue);
|
|
246
|
+
st = nc_inq_enum_ident(ncid, typeid, v, name);
|
|
247
|
+
if ( st == NC_EINVAL ) {
|
|
248
|
+
return Qnil; /* not a defined member */
|
|
249
|
+
}
|
|
250
|
+
if ( st != NC_NOERR ) {
|
|
251
|
+
nc_raise(st);
|
|
252
|
+
}
|
|
253
|
+
return rb_utf8_str_new_cstr(name);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* ---------------------------------------------------------- */
|
|
257
|
+
/* Init */
|
|
258
|
+
/* ---------------------------------------------------------- */
|
|
259
|
+
|
|
260
|
+
void
|
|
261
|
+
init_nc_types (void)
|
|
262
|
+
{
|
|
263
|
+
rb_define_module_function(mNetCDF, "nc_inq_user_type", rb_nc_inq_user_type, 2);
|
|
264
|
+
rb_define_module_function(mNetCDF, "nc_inq_typeid", rb_nc_inq_typeid, 2);
|
|
265
|
+
rb_define_module_function(mNetCDF, "nc_inq_typeids", rb_nc_inq_typeids, 1);
|
|
266
|
+
|
|
267
|
+
rb_define_module_function(mNetCDF, "nc_def_opaque", rb_nc_def_opaque, 3);
|
|
268
|
+
rb_define_module_function(mNetCDF, "nc_inq_opaque", rb_nc_inq_opaque, 2);
|
|
269
|
+
|
|
270
|
+
rb_define_module_function(mNetCDF, "nc_def_vlen", rb_nc_def_vlen, 3);
|
|
271
|
+
rb_define_module_function(mNetCDF, "nc_inq_vlen", rb_nc_inq_vlen, 2);
|
|
272
|
+
|
|
273
|
+
rb_define_module_function(mNetCDF, "nc_def_enum", rb_nc_def_enum, 3);
|
|
274
|
+
rb_define_module_function(mNetCDF, "nc_insert_enum", rb_nc_insert_enum, 4);
|
|
275
|
+
rb_define_module_function(mNetCDF, "nc_inq_enum", rb_nc_inq_enum, 2);
|
|
276
|
+
rb_define_module_function(mNetCDF, "nc_inq_enum_member", rb_nc_inq_enum_member, 3);
|
|
277
|
+
rb_define_module_function(mNetCDF, "nc_inq_enum_ident", rb_nc_inq_enum_ident, 3);
|
|
278
|
+
}
|