1 /*
2 * Copyright 2005-2018 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_data_secondary_bitmap
19 IMPLEMENTS = init
20 IMPLEMENTS = pack_double
21 IMPLEMENTS = value_count
22 MEMBERS=const char* number_of_values
23 END_CLASS_DEF
24 */
25
26 /* START_CLASS_IMP */
27
28 /*
29
30 Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
31 Instead edit values between START_CLASS_DEF and END_CLASS_DEF
32 or edit "accessor.class" and rerun ./make_class.pl
33
34 */
35
36 static int pack_double(grib_accessor*, const double* val,size_t *len);
37 static int value_count(grib_accessor*,long*);
38 static void init(grib_accessor*,const long, grib_arguments* );
39 static void init_class(grib_accessor_class*);
40
41 typedef struct grib_accessor_data_g2secondary_bitmap {
42 grib_accessor att;
43 /* Members defined in gen */
44 /* Members defined in data_secondary_bitmap */
45 const char* primary_bitmap;
46 const char* secondary_bitmap;
47 const char* missing_value;
48 const char* expand_by;
49 /* Members defined in data_g2secondary_bitmap */
50 const char* number_of_values;
51 } grib_accessor_data_g2secondary_bitmap;
52
53 extern grib_accessor_class* grib_accessor_class_data_secondary_bitmap;
54
55 static grib_accessor_class _grib_accessor_class_data_g2secondary_bitmap = {
56 &grib_accessor_class_data_secondary_bitmap, /* super */
57 "data_g2secondary_bitmap", /* name */
58 sizeof(grib_accessor_data_g2secondary_bitmap), /* size */
59 0, /* inited */
60 &init_class, /* init_class */
61 &init, /* init */
62 0, /* post_init */
63 0, /* free mem */
64 0, /* describes himself */
65 0, /* get length of section */
66 0, /* get length of string */
67 &value_count, /* get number of values */
68 0, /* get number of bytes */
69 0, /* get offset to bytes */
70 0, /* get native type */
71 0, /* get sub_section */
72 0, /* grib_pack procedures long */
73 0, /* grib_pack procedures long */
74 0, /* grib_pack procedures long */
75 0, /* grib_unpack procedures long */
76 &pack_double, /* grib_pack procedures double */
77 0, /* grib_unpack procedures double */
78 0, /* grib_pack procedures string */
79 0, /* grib_unpack procedures string */
80 0, /* grib_pack procedures bytes */
81 0, /* grib_unpack procedures bytes */
82 0, /* pack_expression */
83 0, /* notify_change */
84 0, /* update_size */
85 0, /* preferred_size */
86 0, /* resize */
87 0, /* nearest_smaller_value */
88 0, /* next accessor */
89 0, /* compare vs. another accessor */
90 0, /* unpack only ith value */
91 0, /* unpack a subarray */
92 0, /* clear */
93 };
94
95
96 grib_accessor_class* grib_accessor_class_data_g2secondary_bitmap = &_grib_accessor_class_data_g2secondary_bitmap;
97
98
init_class(grib_accessor_class * c)99 static void init_class(grib_accessor_class* c)
100 {
101 c->dump = (*(c->super))->dump;
102 c->next_offset = (*(c->super))->next_offset;
103 c->string_length = (*(c->super))->string_length;
104 c->byte_count = (*(c->super))->byte_count;
105 c->byte_offset = (*(c->super))->byte_offset;
106 c->get_native_type = (*(c->super))->get_native_type;
107 c->sub_section = (*(c->super))->sub_section;
108 c->pack_missing = (*(c->super))->pack_missing;
109 c->is_missing = (*(c->super))->is_missing;
110 c->pack_long = (*(c->super))->pack_long;
111 c->unpack_long = (*(c->super))->unpack_long;
112 c->unpack_double = (*(c->super))->unpack_double;
113 c->pack_string = (*(c->super))->pack_string;
114 c->unpack_string = (*(c->super))->unpack_string;
115 c->pack_bytes = (*(c->super))->pack_bytes;
116 c->unpack_bytes = (*(c->super))->unpack_bytes;
117 c->pack_expression = (*(c->super))->pack_expression;
118 c->notify_change = (*(c->super))->notify_change;
119 c->update_size = (*(c->super))->update_size;
120 c->preferred_size = (*(c->super))->preferred_size;
121 c->resize = (*(c->super))->resize;
122 c->nearest_smaller_value = (*(c->super))->nearest_smaller_value;
123 c->next = (*(c->super))->next;
124 c->compare = (*(c->super))->compare;
125 c->unpack_double_element = (*(c->super))->unpack_double_element;
126 c->unpack_double_subarray = (*(c->super))->unpack_double_subarray;
127 c->clear = (*(c->super))->clear;
128 }
129
130 /* END_CLASS_IMP */
131
init(grib_accessor * a,const long v,grib_arguments * args)132 static void init(grib_accessor* a,const long v, grib_arguments* args)
133 {
134 grib_accessor_data_g2secondary_bitmap *self =(grib_accessor_data_g2secondary_bitmap*)a;
135 self->number_of_values = grib_arguments_get_name(a->parent->h,args,4);
136 }
137
value_count(grib_accessor * a,long * len)138 static int value_count(grib_accessor* a,long* len)
139 {
140 grib_accessor_data_g2secondary_bitmap *self =(grib_accessor_data_g2secondary_bitmap*)a;
141 *len = 0;
142
143 return grib_get_long_internal(a->parent->h,self->number_of_values,len);
144 }
145
pack_double(grib_accessor * a,const double * val,size_t * len)146 static int pack_double(grib_accessor* a, const double* val, size_t *len)
147 {
148 grib_accessor_data_g2secondary_bitmap* self = (grib_accessor_data_g2secondary_bitmap*)a;
149
150 int err = 0;
151
152 long primary_len = 0;
153 long secondary_len = 0;
154 double* primary_bitmap = NULL;
155 double* secondary_bitmap = NULL;
156 long i = 0;
157 long j = 0;
158 long on = 0;
159 long k;
160 long m;
161 double missing_value = 0;
162 double present_value = 0;
163 long expand_by =0;
164
165 if (*len ==0) return GRIB_NO_VALUES;
166
167 if((err = grib_get_long(a->parent->h,self->expand_by,&expand_by)) != GRIB_SUCCESS)
168 return err;
169
170 if((err = grib_get_double_internal(a->parent->h,self->missing_value,&missing_value)) != GRIB_SUCCESS)
171 return err;
172
173 Assert(expand_by);
174
175 if(*len % expand_by)
176 {
177 /*TODO: issue warning */
178 return GRIB_ENCODING_ERROR;
179 }
180
181 primary_len = *len / expand_by;
182 primary_bitmap= (double*)grib_context_malloc_clear(a->parent->h->context,primary_len*sizeof(double));
183 if(!primary_bitmap) return GRIB_OUT_OF_MEMORY;
184
185 secondary_len = *len ;
186 secondary_bitmap= (double*)grib_context_malloc_clear(a->parent->h->context,secondary_len*sizeof(double));
187 if(!secondary_bitmap) {
188 grib_context_free(a->parent->h->context,primary_bitmap);
189 return GRIB_OUT_OF_MEMORY;
190 }
191
192 if(missing_value == 0)
193 present_value = 1;
194 else
195 present_value = 0;
196
197 k = 0;
198 m = 0;
199 for(i=0; i<*len ; i += expand_by)
200 {
201 int cnt = 0;
202 for(j = 0; j < expand_by; j++)
203 if(val[i+j] == missing_value)
204 cnt++;
205
206 if(cnt == expand_by) /* all expand_by values are missing */
207 primary_bitmap[k++] = missing_value;
208 else {
209 primary_bitmap[k++] = present_value;
210 for(j = 0; j < expand_by; j++)
211 secondary_bitmap[m++] = val[i+j];
212 on++;
213 }
214 }
215
216 *len = k;
217
218 Assert(k == primary_len);
219
220 err = grib_set_double_array_internal(a->parent->h,self->primary_bitmap,primary_bitmap,k);
221 if(err == GRIB_SUCCESS)
222 err = grib_set_double_array_internal(a->parent->h,self->secondary_bitmap,secondary_bitmap,m);
223
224 grib_context_free(a->parent->h->context,primary_bitmap);
225 grib_context_free(a->parent->h->context,secondary_bitmap);
226
227 if(err == GRIB_SUCCESS)
228 err = grib_set_long_internal(a->parent->h,self->number_of_values,*len * expand_by);
229
230 return err;
231 }
232