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