1 /*
2 * (C) Copyright 2005- 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
13 /*
14 This is used by make_class.pl
15
16 START_CLASS_DEF
17 CLASS = accessor
18 SUPER = grib_accessor_class_gen
19 IMPLEMENTS = init
20 IMPLEMENTS = unpack_double;unpack_double_element
21 IMPLEMENTS = pack_double
22 IMPLEMENTS = value_count
23 IMPLEMENTS = dump;get_native_type
24 MEMBERS=const char* coded_values
25 MEMBERS=const char* bitmap
26 MEMBERS=const char* missing_value
27 MEMBERS=const char* number_of_data_points
28 MEMBERS=const char* number_of_values
29 MEMBERS=const char* binary_scale_factor
30 END_CLASS_DEF
31 */
32
33 /* START_CLASS_IMP */
34
35 /*
36
37 Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
38 Instead edit values between START_CLASS_DEF and END_CLASS_DEF
39 or edit "accessor.class" and rerun ./make_class.pl
40
41 */
42
43 static int get_native_type(grib_accessor*);
44 static int pack_double(grib_accessor*, const double* val, size_t* len);
45 static int unpack_double(grib_accessor*, double* val, size_t* len);
46 static int value_count(grib_accessor*, long*);
47 static void dump(grib_accessor*, grib_dumper*);
48 static void init(grib_accessor*, const long, grib_arguments*);
49 static void init_class(grib_accessor_class*);
50 static int unpack_double_element(grib_accessor*, size_t i, double* val);
51
52 typedef struct grib_accessor_data_apply_bitmap
53 {
54 grib_accessor att;
55 /* Members defined in gen */
56 /* Members defined in data_apply_bitmap */
57 const char* coded_values;
58 const char* bitmap;
59 const char* missing_value;
60 const char* number_of_data_points;
61 const char* number_of_values;
62 const char* binary_scale_factor;
63 } grib_accessor_data_apply_bitmap;
64
65 extern grib_accessor_class* grib_accessor_class_gen;
66
67 static grib_accessor_class _grib_accessor_class_data_apply_bitmap = {
68 &grib_accessor_class_gen, /* super */
69 "data_apply_bitmap", /* name */
70 sizeof(grib_accessor_data_apply_bitmap), /* size */
71 0, /* inited */
72 &init_class, /* init_class */
73 &init, /* init */
74 0, /* post_init */
75 0, /* free mem */
76 &dump, /* describes himself */
77 0, /* get length of section */
78 0, /* get length of string */
79 &value_count, /* get number of values */
80 0, /* get number of bytes */
81 0, /* get offset to bytes */
82 &get_native_type, /* get native type */
83 0, /* get sub_section */
84 0, /* grib_pack procedures long */
85 0, /* grib_pack procedures long */
86 0, /* grib_pack procedures long */
87 0, /* grib_unpack procedures long */
88 &pack_double, /* grib_pack procedures double */
89 &unpack_double, /* grib_unpack procedures double */
90 0, /* grib_pack procedures string */
91 0, /* grib_unpack procedures string */
92 0, /* grib_pack array procedures string */
93 0, /* grib_unpack array procedures string */
94 0, /* grib_pack procedures bytes */
95 0, /* grib_unpack procedures bytes */
96 0, /* pack_expression */
97 0, /* notify_change */
98 0, /* update_size */
99 0, /* preferred_size */
100 0, /* resize */
101 0, /* nearest_smaller_value */
102 0, /* next accessor */
103 0, /* compare vs. another accessor */
104 &unpack_double_element, /* unpack only ith value */
105 0, /* unpack a subarray */
106 0, /* clear */
107 0, /* clone accessor */
108 };
109
110
111 grib_accessor_class* grib_accessor_class_data_apply_bitmap = &_grib_accessor_class_data_apply_bitmap;
112
113
init_class(grib_accessor_class * c)114 static void init_class(grib_accessor_class* c)
115 {
116 c->next_offset = (*(c->super))->next_offset;
117 c->string_length = (*(c->super))->string_length;
118 c->byte_count = (*(c->super))->byte_count;
119 c->byte_offset = (*(c->super))->byte_offset;
120 c->sub_section = (*(c->super))->sub_section;
121 c->pack_missing = (*(c->super))->pack_missing;
122 c->is_missing = (*(c->super))->is_missing;
123 c->pack_long = (*(c->super))->pack_long;
124 c->unpack_long = (*(c->super))->unpack_long;
125 c->pack_string = (*(c->super))->pack_string;
126 c->unpack_string = (*(c->super))->unpack_string;
127 c->pack_string_array = (*(c->super))->pack_string_array;
128 c->unpack_string_array = (*(c->super))->unpack_string_array;
129 c->pack_bytes = (*(c->super))->pack_bytes;
130 c->unpack_bytes = (*(c->super))->unpack_bytes;
131 c->pack_expression = (*(c->super))->pack_expression;
132 c->notify_change = (*(c->super))->notify_change;
133 c->update_size = (*(c->super))->update_size;
134 c->preferred_size = (*(c->super))->preferred_size;
135 c->resize = (*(c->super))->resize;
136 c->nearest_smaller_value = (*(c->super))->nearest_smaller_value;
137 c->next = (*(c->super))->next;
138 c->compare = (*(c->super))->compare;
139 c->unpack_double_subarray = (*(c->super))->unpack_double_subarray;
140 c->clear = (*(c->super))->clear;
141 c->make_clone = (*(c->super))->make_clone;
142 }
143
144 /* END_CLASS_IMP */
145
init(grib_accessor * a,const long v,grib_arguments * args)146 static void init(grib_accessor* a, const long v, grib_arguments* args)
147 {
148 int n = 0;
149 grib_accessor_data_apply_bitmap* self = (grib_accessor_data_apply_bitmap*)a;
150
151 self->coded_values = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
152 self->bitmap = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
153 self->missing_value = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
154 self->binary_scale_factor = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
155 self->number_of_data_points = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
156 self->number_of_values = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
157
158 a->length = 0;
159 }
dump(grib_accessor * a,grib_dumper * dumper)160 static void dump(grib_accessor* a, grib_dumper* dumper)
161 {
162 grib_dump_values(dumper, a);
163 }
164
value_count(grib_accessor * a,long * count)165 static int value_count(grib_accessor* a, long* count)
166 {
167 grib_accessor_data_apply_bitmap* self = (grib_accessor_data_apply_bitmap*)a;
168 size_t len = 0;
169 int ret = 0;
170
171 if (grib_find_accessor(grib_handle_of_accessor(a), self->bitmap))
172 ret = grib_get_size(grib_handle_of_accessor(a), self->bitmap, &len);
173 else
174 ret = grib_get_size(grib_handle_of_accessor(a), self->coded_values, &len);
175
176 *count = len;
177
178 return ret;
179 }
180
unpack_double(grib_accessor * a,double * val,size_t * len)181 static int unpack_double(grib_accessor* a, double* val, size_t* len)
182 {
183 grib_accessor_data_apply_bitmap* self = (grib_accessor_data_apply_bitmap*)a;
184
185 size_t i = 0;
186 size_t j = 0;
187 size_t n_vals = 0;
188 long nn = 0;
189 int err = 0;
190 size_t coded_n_vals = 0;
191 double* coded_vals = NULL;
192 double missing_value = 0;
193
194 err = grib_value_count(a, &nn);
195 n_vals = nn;
196 if (err)
197 return err;
198
199 if (!grib_find_accessor(grib_handle_of_accessor(a), self->bitmap))
200 return grib_get_double_array(grib_handle_of_accessor(a), self->coded_values, val, len);
201
202 if ((err = grib_get_size(grib_handle_of_accessor(a), self->coded_values, &coded_n_vals)) != GRIB_SUCCESS)
203 return err;
204
205 if ((err = grib_get_double_internal(grib_handle_of_accessor(a), self->missing_value, &missing_value)) != GRIB_SUCCESS)
206 return err;
207
208 if (*len < n_vals) {
209 *len = n_vals;
210 return GRIB_ARRAY_TOO_SMALL;
211 }
212
213 if (coded_n_vals == 0) {
214 for (i = 0; i < n_vals; i++)
215 val[i] = missing_value;
216
217 *len = n_vals;
218 return GRIB_SUCCESS;
219 }
220
221 if ((err = grib_get_double_array_internal(grib_handle_of_accessor(a), self->bitmap, val, &n_vals)) != GRIB_SUCCESS)
222 return err;
223
224 coded_vals = (double*)grib_context_malloc(a->context, coded_n_vals * sizeof(double));
225 if (coded_vals == NULL)
226 return GRIB_OUT_OF_MEMORY;
227
228 if ((err = grib_get_double_array(grib_handle_of_accessor(a), self->coded_values, coded_vals, &coded_n_vals)) != GRIB_SUCCESS) {
229 grib_context_free(a->context, coded_vals);
230 return err;
231 }
232
233 grib_context_log(a->context, GRIB_LOG_DEBUG,
234 "grib_accessor_class_data_apply_bitmap: unpack_double : creating %s, %d values",
235 a->name, n_vals);
236
237 for (i = 0; i < n_vals; i++) {
238 if (val[i] == 0) {
239 val[i] = missing_value;
240 }
241 else {
242 val[i] = coded_vals[j++];
243 if (j > coded_n_vals) {
244 grib_context_free(a->context, coded_vals);
245 grib_context_log(a->context, GRIB_LOG_ERROR,
246 "grib_accessor_class_data_apply_bitmap [%s]:"
247 " unpack_double : number of coded values does not match bitmap %ld %ld",
248 a->name, coded_n_vals, n_vals);
249
250 return GRIB_ARRAY_TOO_SMALL;
251 }
252 }
253 }
254
255 *len = n_vals;
256
257 grib_context_free(a->context, coded_vals);
258 return err;
259 }
260
unpack_double_element(grib_accessor * a,size_t idx,double * val)261 static int unpack_double_element(grib_accessor* a, size_t idx, double* val)
262 {
263 grib_accessor_data_apply_bitmap* self = (grib_accessor_data_apply_bitmap*)a;
264 int err = 0, i = 0;
265 size_t cidx = 0;
266 double missing_value = 0;
267 double* bvals = NULL;
268 size_t n_vals = 0;
269 long nn = 0;
270
271 err = grib_value_count(a, &nn);
272 n_vals = nn;
273 if (err)
274 return err;
275
276 if (!grib_find_accessor(grib_handle_of_accessor(a), self->bitmap))
277 return grib_get_double_element_internal(grib_handle_of_accessor(a), self->coded_values, idx, val);
278
279 if ((err = grib_get_double_internal(grib_handle_of_accessor(a), self->missing_value, &missing_value)) != GRIB_SUCCESS)
280 return err;
281
282 if ((err = grib_get_double_element_internal(grib_handle_of_accessor(a), self->bitmap, idx, val)) != GRIB_SUCCESS)
283 return err;
284
285 if (*val == 0) {
286 *val = missing_value;
287 return GRIB_SUCCESS;
288 }
289
290 bvals = (double*)grib_context_malloc(a->context, n_vals * sizeof(double));
291 if (bvals == NULL)
292 return GRIB_OUT_OF_MEMORY;
293
294 if ((err = grib_get_double_array_internal(grib_handle_of_accessor(a), self->bitmap, bvals, &n_vals)) != GRIB_SUCCESS)
295 return err;
296
297 cidx = 0;
298 for (i = 0; i < idx; i++) {
299 cidx += bvals[i];
300 }
301
302 grib_context_free(a->context, bvals);
303
304 return grib_get_double_element_internal(grib_handle_of_accessor(a), self->coded_values, cidx, val);
305 }
306
pack_double(grib_accessor * a,const double * val,size_t * len)307 static int pack_double(grib_accessor* a, const double* val, size_t* len)
308 {
309 grib_accessor_data_apply_bitmap* self = (grib_accessor_data_apply_bitmap*)a;
310 int err = 0;
311 size_t bmaplen = *len;
312 long coded_n_vals = 0;
313 double* coded_vals = NULL;
314 long i = 0;
315 long j = 0;
316 double missing_value = 0;
317
318 if (*len == 0)
319 return GRIB_NO_VALUES;
320
321 if (!grib_find_accessor(grib_handle_of_accessor(a), self->bitmap)) {
322 err = grib_set_double_array_internal(grib_handle_of_accessor(a), self->coded_values, val, *len);
323 /*printf("SETTING TOTAL number_of_data_points %s %ld\n",self->number_of_data_points,*len);*/
324 if (self->number_of_data_points)
325 grib_set_long_internal(grib_handle_of_accessor(a), self->number_of_data_points, *len);
326 return err;
327 }
328
329 if ((err = grib_get_double_internal(grib_handle_of_accessor(a), self->missing_value, &missing_value)) != GRIB_SUCCESS)
330 return err;
331
332 if ((err = grib_set_double_array_internal(grib_handle_of_accessor(a), self->bitmap, val, bmaplen)) != GRIB_SUCCESS)
333 return err;
334
335 coded_n_vals = *len;
336
337 if (coded_n_vals < 1) {
338 err = grib_set_double_array_internal(grib_handle_of_accessor(a), self->coded_values, NULL, 0);
339 return err;
340 }
341
342 coded_vals = (double*)grib_context_malloc_clear(a->context, coded_n_vals * sizeof(double));
343 if (!coded_vals)
344 return GRIB_OUT_OF_MEMORY;
345
346 for (i = 0; i < *len; i++) {
347 if (val[i] != missing_value) {
348 coded_vals[j++] = val[i];
349 }
350 }
351
352 err = grib_set_double_array_internal(grib_handle_of_accessor(a), self->coded_values, coded_vals, j);
353 if (j == 0) {
354 if (self->number_of_values)
355 err = grib_set_long_internal(grib_handle_of_accessor(a), self->number_of_values, 0);
356 if (self->binary_scale_factor)
357 err = grib_set_long_internal(grib_handle_of_accessor(a), self->binary_scale_factor, 0);
358 }
359
360 grib_context_free(a->context, coded_vals);
361
362 return err;
363 }
364
get_native_type(grib_accessor * a)365 static int get_native_type(grib_accessor* a)
366 {
367 /* grib_accessor_data_apply_bitmap* self = (grib_accessor_data_apply_bitmap*)a;
368 return grib_accessor_get_native_type(grib_find_accessor(grib_handle_of_accessor(a),self->coded_values));*/
369
370 return GRIB_TYPE_DOUBLE;
371 }
372