rb-grib 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,7 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ ext/Makefile
6
+ ext/mkmf.log
7
+ ext/*.o
8
+ ext/*.so
data/BSDL ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (C) 2011 Seiya Nishizawa and GFD Dennou Club. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in rb-grib.gemspec
4
4
  gemspec
5
+
6
+ group :development do
7
+ gem "rspec"
8
+ end
data/LICENSE.txt CHANGED
@@ -1,8 +1,7 @@
1
- Ruby-GRIB is copyrighted free software by Seiya Nishizawa and the
2
- GFD Dennou Club.
1
+ rb-GRIB is copyrighted free software by Seiya Nishizawa <seiya@gfd-dennou.org>
2
+ and GFD Dennou Club.
3
3
  You can redistribute it and/or modify it under either the terms of the
4
- GPL, or the conditions below, which is idential to Ruby's license
5
- (http://www.ruby-lang.org/en/LICENSE.txt):
4
+ 2-clause BSDL (see the file BSDL), or the conditions below:
6
5
 
7
6
  1. You may make and give away verbatim copies of the source form of the
8
7
  software without restriction, provided that you duplicate all of the
@@ -19,31 +18,33 @@ GPL, or the conditions below, which is idential to Ruby's license
19
18
  b) use the modified software only within your corporation or
20
19
  organization.
21
20
 
22
- c) rename any non-standard executables so the names do not conflict
23
- with standard executables, which must also be provided.
21
+ c) give non-standard binaries non-standard names, with
22
+ instructions on where to get the original software distribution.
24
23
 
25
24
  d) make other distribution arrangements with the author.
26
25
 
27
- 3. You may distribute the software in object code or executable
28
- form, provided that you do at least ONE of the following:
26
+ 3. You may distribute the software in object code or binary form,
27
+ provided that you do at least ONE of the following:
29
28
 
30
- a) distribute the executables and library files of the software,
29
+ a) distribute the binaries and library files of the software,
31
30
  together with instructions (in the manual page or equivalent)
32
31
  on where to get the original distribution.
33
32
 
34
33
  b) accompany the distribution with the machine-readable source of
35
34
  the software.
36
35
 
37
- c) give non-standard executables non-standard names, with
36
+ c) give non-standard binaries non-standard names, with
38
37
  instructions on where to get the original software distribution.
39
38
 
40
39
  d) make other distribution arrangements with the author.
41
40
 
42
41
  4. You may modify and include the part of the software into any other
43
42
  software (possibly commercial). But some files in the distribution
44
- are not written by the author, so that they are not under this terms.
43
+ are not written by the authors, so that they are not under these terms.
45
44
 
46
- See each file for the copying condition.
45
+ The data files in the "data" directory are provided by GRIB API
46
+ (http://www.ecmwf.int/products/data/software/grib_api.html)
47
+ under the GNU Lesser General Public License.
47
48
 
48
49
  5. The scripts and library files supplied as input to or produced as
49
50
  output from the software do not automatically fall under the
data/README.rdoc CHANGED
@@ -2,16 +2,31 @@
2
2
 
3
3
  rb-GRIB is a class library to handle GRIB file.
4
4
 
5
+
6
+ = rb-GRIB home-page
7
+
8
+ The URL of the rb-GRIB home-page is:
9
+ http://ruby.gfd-dennou.org/products/rb-grib/
10
+
11
+
5
12
  = Requires
6
13
 
7
14
  * Ruby (http://www.ruby-lang.org/)
8
15
  * NArray (http://narray.rubyforge.org/index.html.en)
16
+ * NArrayMiss (http://ruby.gfd-dennou.org/products/narray_miss/)
9
17
  * GRIB API (http://www.ecmwf.int/products/data/software/grib_api.html)
10
18
 
19
+
11
20
  = Install
12
21
 
13
22
  # gem install rb-grib
14
23
 
24
+
25
+ = Copying
26
+
27
+ See the file LICENSE.txt.
28
+
29
+
15
30
  = Usage
16
31
 
17
32
  To use this library, put the following in your script.
@@ -32,3 +47,11 @@ To use this library, put the following in your script.
32
47
  ary = var.get # => NArray
33
48
  end
34
49
  grib.close
50
+
51
+
52
+ = The Author
53
+
54
+ Feel free to send comments and bug reports to the author.
55
+ The author's e-mail addess is
56
+
57
+ seiya@gfd-dennou.org
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ desc "Run all spec"
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task :default => :spec
Binary file
data/ext/grib.c CHANGED
@@ -7,63 +7,264 @@
7
7
 
8
8
  #define MAX_VALUE_LENGTH 1024
9
9
 
10
+ // error check
11
+ static void
12
+ check_error(int code)
13
+ {
14
+ if (code) rb_raise(rb_eRuntimeError, grib_get_error_message(code));
15
+ };
16
+
17
+
18
+
19
+
20
+ // flexible length array
21
+ #define BUF_SIZE 256
22
+ #define MAX_BUF_NUM 1000
23
+ typedef struct {
24
+ grib_handle ***buffer;
25
+ size_t size;
26
+ size_t len;
27
+ } msg_array;
28
+ static msg_array*
29
+ alloc_msg_array(void)
30
+ {
31
+ msg_array *ary = ALLOC(msg_array);
32
+ if (ary) {
33
+ ary->buffer = (grib_handle***) malloc(sizeof(grib_handle**)*MAX_BUF_NUM);
34
+ if (ary->buffer) {
35
+ ary->buffer[0] = (grib_handle**) malloc(sizeof(grib_handle*)*BUF_SIZE);
36
+ if (ary->buffer[0]) {
37
+ ary->size = BUF_SIZE;
38
+ ary->len = 0;
39
+ return ary;
40
+ }
41
+ free(ary->buffer);
42
+ }
43
+ free(ary);
44
+ }
45
+ return NULL;
46
+ }
47
+ static
48
+ void free_msg_array(msg_array *ary)
49
+ {
50
+ int i, j;
51
+ int num = ary->size/BUF_SIZE;
52
+ int len;
53
+ for (i=0; i<num; i++) {
54
+ len = i==num-1 ? ary->len%BUF_SIZE : BUF_SIZE;
55
+ for (j=0; j<len; j++) grib_handle_delete(ary->buffer[i][j]);
56
+ free(ary->buffer[i]);
57
+ }
58
+ free(ary->buffer);
59
+ free(ary);
60
+ }
61
+ static void
62
+ push_msg(msg_array *ary, grib_handle *handle)
63
+ {
64
+ int idx = ary->size/BUF_SIZE-1;
65
+ if (ary->len >= ary->size) {
66
+ idx += 1;
67
+ if (idx < MAX_BUF_NUM) {
68
+ ary->buffer[idx] = (grib_handle**)malloc(sizeof(grib_handle*)*BUF_SIZE);
69
+ if (ary->buffer[idx]) {
70
+ ary->size += BUF_SIZE;
71
+ } else {
72
+ rb_raise(rb_eRuntimeError, "cannot allocate memory");
73
+ }
74
+ } else {
75
+ rb_raise(rb_eRuntimeError, "cannot allocate memory");
76
+ }
77
+ }
78
+ ary->buffer[idx][ary->len%BUF_SIZE] = handle;
79
+ ary->len += 1;
80
+ }
81
+ static grib_handle*
82
+ get_msg(msg_array *ary, size_t index)
83
+ {
84
+ if (index < ary->len) {
85
+ return ary->buffer[index/BUF_SIZE][index%BUF_SIZE];
86
+ } else {
87
+ rb_raise(rb_eRuntimeError, "index exceed size of array");
88
+ }
89
+ return NULL;
90
+ }
91
+
92
+
93
+ // variable list
94
+ typedef struct var_list var_list;
95
+ struct var_list {
96
+ char *vname;
97
+ long ni;
98
+ long nj;
99
+ char *gtype;
100
+ long ltype_id;
101
+ char *ltype;
102
+ msg_array *ary;
103
+ var_list *next;
104
+ VALUE file;
105
+ };
106
+ static var_list*
107
+ var_list_alloc(VALUE file)
108
+ {
109
+ var_list *var = ALLOC(var_list);
110
+ if (var) {
111
+ var->ary = alloc_msg_array();
112
+ if (var->ary) {
113
+ var->vname = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH*2);
114
+ if (var->vname) {
115
+ var->gtype = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH);
116
+ if (var->gtype) {
117
+ var->ltype = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH);
118
+ if (var->ltype) {
119
+ var->next = NULL;
120
+ var->file = file;
121
+ return var;
122
+ }
123
+ free(var->gtype);
124
+ }
125
+ free(var->vname);
126
+ }
127
+ free_msg_array(var->ary);
128
+ }
129
+ free(var);
130
+ }
131
+ return NULL;
132
+ }
133
+ static void
134
+ var_list_free(var_list *var)
135
+ {
136
+ var_list *next;
137
+ while(var) {
138
+ free_msg_array(var->ary);
139
+ free(var->vname);
140
+ free(var->gtype);
141
+ free(var->ltype);
142
+ var->file = Qnil;
143
+ next = var->next;
144
+ free(var);
145
+ var = next;
146
+ }
147
+ }
148
+ static void
149
+ push_msg_var(var_list **pvar, grib_handle *handle, VALUE file)
150
+ {
151
+ size_t len = MAX_VALUE_LENGTH;
152
+ char vname[MAX_VALUE_LENGTH];
153
+ bzero(vname, len);
154
+ if (grib_get_string(handle, "shortName", vname, &len) != GRIB_SUCCESS ||
155
+ strcmp("unknown", vname) == 0) {
156
+ long id;
157
+ if (grib_get_long(handle, "indicatorOfParameter", &id) == GRIB_SUCCESS ||
158
+ grib_get_long(handle, "parameterNumber", &id) == GRIB_SUCCESS) {
159
+ sprintf(vname, "id%ld", id);
160
+ } else {
161
+ printf("%s\n", vname);
162
+ rb_raise(rb_eRuntimeError, "cannot get variable name");
163
+ }
164
+ }
165
+ long ni, nj, ltype_id;
166
+ char gtype[MAX_VALUE_LENGTH];
167
+ len = MAX_VALUE_LENGTH;
168
+ if (grib_get_long(handle, "Ni", &ni) != GRIB_SUCCESS ||
169
+ grib_get_long(handle, "Nj", &nj) != GRIB_SUCCESS ||
170
+ grib_get_string(handle, "typeOfGrid", gtype, &len) != GRIB_SUCCESS ||
171
+ (grib_get_long(handle, "indicatorOfTypeOfLevel", &ltype_id) != GRIB_SUCCESS && grib_get_long(handle, "typeOfFirstFixedSurface", &ltype_id) != GRIB_SUCCESS)) {
172
+ rb_raise(rb_eRuntimeError, "connot identify grid type");
173
+ }
174
+ var_list *last = NULL;
175
+ var_list *var = pvar[0];
176
+ if (var) {
177
+ while (var) {
178
+ if (strcmp(var->vname, vname)==0 && var->ni == ni && var->nj == nj && strcmp(var->gtype,gtype)==0 && var->ltype_id==ltype_id) {
179
+ push_msg(var->ary, handle);
180
+ return;
181
+ }
182
+ last = var;
183
+ var = var->next;
184
+ }
185
+ }
186
+ var_list *var_new = var_list_alloc(file);
187
+ if (var_new == NULL)
188
+ rb_raise(rb_eRuntimeError, "cannot allocate memory");
189
+ var_new->ni = ni;
190
+ var_new->nj = nj;
191
+ var_new->ltype_id = ltype_id;
192
+ strcpy(var_new->vname, vname);
193
+ strcpy(var_new->gtype, gtype);
194
+ len = MAX_VALUE_LENGTH;
195
+ check_error(grib_get_string(handle, "typeOfLevel", vname, &len));
196
+ strcpy(var_new->ltype, vname);
197
+ push_msg(var_new->ary, handle);
198
+ if (last)
199
+ last->next = var_new;
200
+ else
201
+ pvar[0] = var_new;
202
+ }
203
+
204
+
205
+
206
+
10
207
  VALUE cGrib;
208
+ VALUE cVar;
11
209
  VALUE cMessage;
12
210
 
13
211
  typedef struct {
14
212
  FILE *file;
15
213
  char *fname;
16
- grib_handle **handles;
17
- int n;
214
+ var_list *var;
18
215
  } rg_file;
19
-
216
+ typedef struct {
217
+ VALUE file;
218
+ var_list *var_list;
219
+ } rg_var;
20
220
  typedef struct {
21
221
  VALUE file;
22
222
  grib_handle *handle;
23
223
  } rg_message;
24
224
 
25
- static void
26
- check_error(int code)
27
- {
28
- if (code)
29
- rb_raise(rb_eRuntimeError, grib_get_error_message(code));
30
- };
31
-
32
225
 
33
226
  static void
34
227
  message_free(rg_message *message)
35
228
  {
36
- if (message) {
37
- free(message);
38
- }
229
+ if (message) free(message);
39
230
  }
40
231
  static void
41
232
  message_mark(rg_message *message)
42
233
  {
43
- if (message && message->file != Qnil)
44
- rb_gc_mark(message->file);
234
+ if (message && message->file != Qnil) rb_gc_mark(message->file);
45
235
  }
46
236
  static VALUE
47
237
  message_alloc(VALUE klass)
48
238
  {
49
239
  rg_message *message = ALLOC(rg_message);
50
240
  message->file = Qnil;
51
- message->handle = NULL;
52
241
  return Data_Wrap_Struct(klass, message_mark, message_free, message);
53
242
  }
54
-
243
+ static void
244
+ var_free(rg_var *var)
245
+ {
246
+ if (var) free(var);
247
+ }
248
+ static void
249
+ var_mark(rg_var *var)
250
+ {
251
+ if (var && var->file != Qnil) rb_gc_mark(var->file);
252
+ }
253
+ static VALUE
254
+ var_alloc(VALUE klass)
255
+ {
256
+ rg_var *var = ALLOC(rg_var);
257
+ var->file = Qnil;
258
+ return Data_Wrap_Struct(klass, var_mark, var_free, var);
259
+ }
55
260
  static void
56
261
  file_close(rg_file *gfile)
57
262
  {
58
- int i;
59
263
  if (gfile) {
60
- if (gfile->handles) {
61
- for (i=0; i<gfile->n; i++)
62
- if (gfile->handles[i]) grib_handle_delete(gfile->handles[i]);
63
- free(gfile->handles);
64
- gfile->handles = NULL;
264
+ if (gfile->var) {
265
+ var_list_free(gfile->var);
266
+ gfile->var = NULL;
65
267
  }
66
- gfile->n = 0;
67
268
  if (gfile->file) {
68
269
  fclose(gfile->file);
69
270
  gfile->file = NULL;
@@ -88,23 +289,10 @@ file_alloc(VALUE klass)
88
289
  rg_file *gfile = ALLOC(rg_file);
89
290
  gfile->file = NULL;
90
291
  gfile->fname = NULL;
91
- gfile->handles = NULL;
92
- gfile->n = 0;
292
+ gfile->var = NULL;
93
293
  return Data_Wrap_Struct(klass, 0, file_free, gfile);
94
294
  }
95
295
 
96
- /*
97
- NumRu::Grib.open(filename [, mode]) -> NumRu::Grib::File
98
- */
99
- /*
100
- static VALUE
101
- rg_open(int argc, VALUE *argv, VALUE self)
102
- {
103
- VALUE rgfile = file_alloc(self);
104
- return rg_file_initialize(argc, argv, rgfile);
105
- }
106
- */
107
-
108
296
  /*
109
297
  NumRu::Grib.multi=(flag) -> True/False
110
298
  */
@@ -145,29 +333,71 @@ rg_file_initialize(int argc, VALUE *argv, VALUE self)
145
333
  gfile->fname = ALLOC_N(char, strlen(fname)+1);
146
334
  strcpy(gfile->fname, fname);
147
335
 
148
- int n = 0;
149
336
  int error;
150
337
  grib_handle *handle;
338
+ var_list *var = NULL;
151
339
  while ((handle = grib_handle_new_from_file(0, file, &error))) {
152
340
  check_error(error);
153
341
  if (handle == NULL)
154
342
  rb_raise(rb_eRuntimeError, "unable to create handle in %s", fname);
155
- grib_handle_delete(handle);
156
- n++;
343
+ push_msg_var(&var, handle, self);
157
344
  }
158
- rewind(file);
159
- grib_handle **handles = ALLOC_N(grib_handle*, n);
345
+ gfile->var = var;
346
+ var_list *var2;
347
+ const char *vname;
348
+ char buf[MAX_VALUE_LENGTH];
349
+ int first_ltype, first_gtype;
160
350
  int i;
161
- for (i=0; i<n; i++) handles[i] = NULL;
162
- for (i=0; i<n; i++) {
163
- handle = grib_handle_new_from_file(0, file, &error);
164
- check_error(error);
165
- if (handle == NULL)
166
- rb_raise(rb_eRuntimeError, "unable to create handle in %s", fname);
167
- handles[i] = handle;
351
+ while (var) {
352
+ vname = var->vname;
353
+ var2 = var->next;
354
+ i = 0;
355
+ first_ltype = 1;
356
+ first_gtype = 1;
357
+ while (var2) {
358
+ if (strcmp(var2->vname, vname) == 0) {
359
+ if (var->ltype_id != var2->ltype_id) {
360
+ if (first_ltype) {
361
+ if (strcmp(var->ltype,"isobaricInhPa") != 0 && strcmp(var->ltype,"pl") !=0) {
362
+ if (strcmp(var->ltype, "unknown")==0)
363
+ sprintf(buf, "%s_level%ld", var->vname, var->ltype_id);
364
+ else
365
+ sprintf(buf, "%s_%s", var->vname, var->ltype);
366
+ strcpy(var->vname, buf);
367
+ }
368
+ first_ltype = 0;
369
+ }
370
+ if (strcmp(var2->ltype,"isobaricInhPa") != 0 && strcmp(var2->ltype,"pl") != 0) {
371
+ if (strcmp(var2->ltype, "unknown")==0)
372
+ sprintf(buf, "%s_level%ld", var2->vname, var2->ltype_id);
373
+ else
374
+ sprintf(buf, "%s_%s", var2->vname, var2->ltype);
375
+ strcpy(var2->vname, buf);
376
+ }
377
+ } else if (strcmp(var->gtype, var2->gtype) != 0) {
378
+ if (first_gtype) {
379
+ sprintf(buf, "%s_%s", var->vname, var->gtype);
380
+ strcpy(var->vname, buf);
381
+ first_gtype = 0;
382
+ }
383
+ sprintf(buf, "%s_%s", var2->vname, var2->gtype);
384
+ strcpy(var2->vname, buf);
385
+ } else {
386
+ if (i==0) {
387
+ sprintf(buf, "%s_%d", var->vname, i);
388
+ strcpy(var->vname, buf);
389
+ i += 1;
390
+ }
391
+ sprintf(buf, "%s_%d", var2->vname, i);
392
+ strcpy(var2->vname, buf);
393
+ i += 1;
394
+ }
395
+ }
396
+ var2 = var2->next;
397
+ }
398
+ var = var->next;
168
399
  }
169
- gfile->n = n;
170
- gfile->handles = handles;
400
+
171
401
  return self;
172
402
  }
173
403
  /*
@@ -183,36 +413,104 @@ rg_file_close(VALUE self)
183
413
  }
184
414
 
185
415
  /*
186
- NumRu::Grib#get_messages() -> Array
416
+ NumRu::Grib#path() -> String
187
417
  */
188
418
  static VALUE
189
- rg_file_get_messages(VALUE self)
419
+ rg_file_path(VALUE self)
190
420
  {
191
421
  rg_file *gfile;
192
422
  Data_Get_Struct(self, rg_file, gfile);
193
- VALUE ary = rb_ary_new2(gfile->n);
194
- rg_message *message;
195
- VALUE rmessage;
196
- int i;
197
- for (i=0; i<gfile->n; i++) {
198
- rmessage = message_alloc(cMessage);
199
- Data_Get_Struct(rmessage, rg_message, message);
200
- message->file = self;
201
- message->handle = gfile->handles[i];
202
- rb_ary_store(ary, i, rmessage);
423
+ return rb_str_new2(gfile->fname);
424
+ }
425
+
426
+ /*
427
+ NumRu::Grib#var_names() -> Array
428
+ */
429
+ static VALUE
430
+ rg_file_var_names(VALUE self)
431
+ {
432
+ rg_file *gfile;
433
+ Data_Get_Struct(self, rg_file, gfile);
434
+ VALUE ary = rb_ary_new();
435
+ var_list *var = gfile->var;
436
+ while (var) {
437
+ rb_ary_push(ary, rb_str_new2(var->vname));
438
+ var = var->next;
203
439
  }
204
440
  return ary;
205
441
  }
206
442
 
443
+ static VALUE id_init;
207
444
  /*
208
- NumRu::Grib#path() -> String
445
+ NumRu::Grib#var(String) -> NumRu::GribVar
209
446
  */
210
447
  static VALUE
211
- rg_file_path(VALUE self)
448
+ rg_file_var(VALUE self, VALUE rvname)
212
449
  {
450
+ char *vname = StringValueCStr(rvname);
213
451
  rg_file *gfile;
214
452
  Data_Get_Struct(self, rg_file, gfile);
215
- return rb_str_new2(gfile->fname);
453
+ var_list *var_list = gfile->var;
454
+ while (var_list) {
455
+ if (strcmp(var_list->vname, vname) == 0) {
456
+ VALUE rvar = var_alloc(cVar);
457
+ rg_var *var;
458
+ Data_Get_Struct(rvar, rg_var, var);
459
+ var->file = self;
460
+ var->var_list = var_list;
461
+ rb_funcall(rvar, id_init, 0);
462
+ return rvar;
463
+ }
464
+ var_list = var_list->next;
465
+ }
466
+ rb_raise(rb_eArgError, "cannot find variable: %s", vname);
467
+ }
468
+
469
+ /*
470
+ NumRu::GribVar#file() -> NumRu::Grib
471
+ */
472
+ static VALUE
473
+ rg_var_file(VALUE self)
474
+ {
475
+ rg_var *var;
476
+ Data_Get_Struct(self, rg_var, var);
477
+ return var->file;
478
+ }
479
+
480
+ /*
481
+ NumRu::GribVar#name() -> String
482
+ */
483
+ static VALUE
484
+ rg_var_name(VALUE self)
485
+ {
486
+ rg_var *var;
487
+ Data_Get_Struct(self, rg_var, var);
488
+ return rb_str_new2(var->var_list->vname);
489
+ }
490
+
491
+ /*
492
+ NumRu::GribVar#get_messages() -> Array
493
+ */
494
+ static VALUE
495
+ rg_var_get_messages(VALUE self)
496
+ {
497
+ rg_var *var;
498
+ Data_Get_Struct(self, rg_var, var);
499
+ var_list *var_list = var->var_list;
500
+ size_t len = var_list->ary->len;
501
+ VALUE ary = rb_ary_new2(len);
502
+ rg_message *message;
503
+ VALUE rmessage;
504
+ int i;
505
+ for (i=0; i<len; i++) {
506
+ rmessage = message_alloc(cMessage);
507
+ Data_Get_Struct(rmessage, rg_message, message);
508
+ message->file = self;
509
+ message->handle = get_msg(var_list->ary, i);
510
+ rb_ary_store(ary, i, rmessage);
511
+ }
512
+ return ary;
513
+
216
514
  }
217
515
 
218
516
  /*
@@ -396,8 +694,11 @@ void Init_grib()
396
694
  {
397
695
  rb_require("narray");
398
696
 
697
+ id_init = rb_intern("init");
698
+
399
699
  VALUE mNumRu = rb_define_module("NumRu");
400
700
  cGrib = rb_define_class_under(mNumRu, "Grib", rb_cObject);
701
+ cVar = rb_define_class_under(mNumRu, "GribVar", rb_cObject);
401
702
  cMessage = rb_define_class_under(mNumRu, "GribMessage", rb_cObject);
402
703
 
403
704
  grib_multi_support_on(0);
@@ -408,8 +709,15 @@ void Init_grib()
408
709
  rb_define_alloc_func(cGrib, file_alloc);
409
710
  rb_define_method(cGrib, "initialize", rg_file_initialize, -1);
410
711
  rb_define_method(cGrib, "close", rg_file_close, 0);
411
- rb_define_method(cGrib, "get_messages", rg_file_get_messages, 0);
412
712
  rb_define_method(cGrib, "path", rg_file_path, 0);
713
+ rb_define_method(cGrib, "var_names", rg_file_var_names, 0);
714
+ rb_define_method(cGrib, "var", rg_file_var, 1);
715
+
716
+ rb_define_alloc_func(cVar, var_alloc);
717
+ rb_define_method(cVar, "file", rg_var_file, 0);
718
+ rb_define_method(cVar, "name", rg_var_name, 0);
719
+ rb_define_method(cVar, "get_messages", rg_var_get_messages, 0);
720
+
413
721
 
414
722
  rb_define_alloc_func(cMessage, message_alloc);
415
723
  rb_define_method(cMessage, "initialize", rg_message_initialize, 1);