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 /******************************
12 * Enrico Fucile
13 *****************************/
14
15 #include "grib_api_internal.h"
16
17 /*
18 This is used by make_class.pl
19
20 START_CLASS_DEF
21 CLASS = accessor
22 SUPER = grib_accessor_class_gen
23 IMPLEMENTS = init
24 IMPLEMENTS = unpack_double
25 IMPLEMENTS = pack_double
26 IMPLEMENTS = value_count
27 MEMBERS=const char* missing_value
28 MEMBERS=const char* number_of_values
29 MEMBERS=const char* number_of_points
30 MEMBERS=const char* latitude_of_first_point
31 MEMBERS=const char* ni
32
33 END_CLASS_DEF
34 */
35
36 /* START_CLASS_IMP */
37
38 /*
39
40 Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
41 Instead edit values between START_CLASS_DEF and END_CLASS_DEF
42 or edit "accessor.class" and rerun ./make_class.pl
43
44 */
45
46 static int pack_double(grib_accessor*, const double* val, size_t* len);
47 static int unpack_double(grib_accessor*, double* val, size_t* len);
48 static int value_count(grib_accessor*, long*);
49 static void init(grib_accessor*, const long, grib_arguments*);
50 static void init_class(grib_accessor_class*);
51
52 typedef struct grib_accessor_gds_not_present_bitmap
53 {
54 grib_accessor att;
55 /* Members defined in gen */
56 /* Members defined in gds_not_present_bitmap */
57 const char* missing_value;
58 const char* number_of_values;
59 const char* number_of_points;
60 const char* latitude_of_first_point;
61 const char* ni;
62 } grib_accessor_gds_not_present_bitmap;
63
64 extern grib_accessor_class* grib_accessor_class_gen;
65
66 static grib_accessor_class _grib_accessor_class_gds_not_present_bitmap = {
67 &grib_accessor_class_gen, /* super */
68 "gds_not_present_bitmap", /* name */
69 sizeof(grib_accessor_gds_not_present_bitmap), /* size */
70 0, /* inited */
71 &init_class, /* init_class */
72 &init, /* init */
73 0, /* post_init */
74 0, /* free mem */
75 0, /* describes himself */
76 0, /* get length of section */
77 0, /* get length of string */
78 &value_count, /* get number of values */
79 0, /* get number of bytes */
80 0, /* get offset to bytes */
81 0, /* get native type */
82 0, /* get sub_section */
83 0, /* grib_pack procedures long */
84 0, /* grib_pack procedures long */
85 0, /* grib_pack procedures long */
86 0, /* grib_unpack procedures long */
87 &pack_double, /* grib_pack procedures double */
88 &unpack_double, /* grib_unpack procedures double */
89 0, /* grib_pack procedures string */
90 0, /* grib_unpack procedures string */
91 0, /* grib_pack array procedures string */
92 0, /* grib_unpack array procedures string */
93 0, /* grib_pack procedures bytes */
94 0, /* grib_unpack procedures bytes */
95 0, /* pack_expression */
96 0, /* notify_change */
97 0, /* update_size */
98 0, /* preferred_size */
99 0, /* resize */
100 0, /* nearest_smaller_value */
101 0, /* next accessor */
102 0, /* compare vs. another accessor */
103 0, /* unpack only ith value */
104 0, /* unpack a subarray */
105 0, /* clear */
106 0, /* clone accessor */
107 };
108
109
110 grib_accessor_class* grib_accessor_class_gds_not_present_bitmap = &_grib_accessor_class_gds_not_present_bitmap;
111
112
init_class(grib_accessor_class * c)113 static void init_class(grib_accessor_class* c)
114 {
115 c->dump = (*(c->super))->dump;
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->get_native_type = (*(c->super))->get_native_type;
121 c->sub_section = (*(c->super))->sub_section;
122 c->pack_missing = (*(c->super))->pack_missing;
123 c->is_missing = (*(c->super))->is_missing;
124 c->pack_long = (*(c->super))->pack_long;
125 c->unpack_long = (*(c->super))->unpack_long;
126 c->pack_string = (*(c->super))->pack_string;
127 c->unpack_string = (*(c->super))->unpack_string;
128 c->pack_string_array = (*(c->super))->pack_string_array;
129 c->unpack_string_array = (*(c->super))->unpack_string_array;
130 c->pack_bytes = (*(c->super))->pack_bytes;
131 c->unpack_bytes = (*(c->super))->unpack_bytes;
132 c->pack_expression = (*(c->super))->pack_expression;
133 c->notify_change = (*(c->super))->notify_change;
134 c->update_size = (*(c->super))->update_size;
135 c->preferred_size = (*(c->super))->preferred_size;
136 c->resize = (*(c->super))->resize;
137 c->nearest_smaller_value = (*(c->super))->nearest_smaller_value;
138 c->next = (*(c->super))->next;
139 c->compare = (*(c->super))->compare;
140 c->unpack_double_element = (*(c->super))->unpack_double_element;
141 c->unpack_double_subarray = (*(c->super))->unpack_double_subarray;
142 c->clear = (*(c->super))->clear;
143 c->make_clone = (*(c->super))->make_clone;
144 }
145
146 /* END_CLASS_IMP */
147
init(grib_accessor * a,const long v,grib_arguments * args)148 static void init(grib_accessor* a, const long v, grib_arguments* args)
149 {
150 int n = 0;
151 grib_accessor_gds_not_present_bitmap* self = (grib_accessor_gds_not_present_bitmap*)a;
152
153 self->missing_value = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
154 self->number_of_values = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
155 self->number_of_points = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
156 self->latitude_of_first_point = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
157 self->ni = grib_arguments_get_name(grib_handle_of_accessor(a), args, n++);
158 a->length = 0;
159 }
160
value_count(grib_accessor * a,long * number_of_points)161 static int value_count(grib_accessor* a, long* number_of_points)
162 {
163 grib_accessor_gds_not_present_bitmap* self = (grib_accessor_gds_not_present_bitmap*)a;
164 *number_of_points = 0;
165 return grib_get_long_internal(grib_handle_of_accessor(a), self->number_of_points, number_of_points);
166 }
167
unpack_double(grib_accessor * a,double * val,size_t * len)168 static int unpack_double(grib_accessor* a, double* val, size_t* len)
169 {
170 grib_accessor_gds_not_present_bitmap* self = (grib_accessor_gds_not_present_bitmap*)a;
171
172 long number_of_points = 0, number_of_values = 0, ni = 0;
173 long latitude_of_first_point = 0;
174 size_t i = 0;
175 size_t n_vals = 0;
176 long nn = 0;
177 long missing_value;
178
179 int err = 0;
180 double* coded_vals = NULL;
181 err = grib_value_count(a, &nn);
182 n_vals = nn;
183 if (err)
184 return err;
185
186 if ((err = grib_get_long(grib_handle_of_accessor(a), self->number_of_points, &number_of_points)) != GRIB_SUCCESS)
187 return err;
188
189 if ((err = grib_get_long(grib_handle_of_accessor(a), self->number_of_values, &number_of_values)) != GRIB_SUCCESS)
190 return err;
191
192 if ((err = grib_get_long(grib_handle_of_accessor(a), self->latitude_of_first_point, &latitude_of_first_point)) != GRIB_SUCCESS)
193 return err;
194
195 if ((err = grib_get_long(grib_handle_of_accessor(a), self->missing_value, &missing_value)) != GRIB_SUCCESS)
196 return err;
197
198 if ((err = grib_get_long(grib_handle_of_accessor(a), self->ni, &ni)) != GRIB_SUCCESS)
199 return err;
200
201 if (*len < number_of_points) {
202 *len = n_vals;
203 return GRIB_ARRAY_TOO_SMALL;
204 }
205
206 if (number_of_values > 0) {
207 coded_vals = (double*)grib_context_malloc(a->context, number_of_values * sizeof(double));
208
209 if (coded_vals == NULL)
210 return GRIB_OUT_OF_MEMORY;
211 }
212
213 if (latitude_of_first_point == 0) {
214 for (i = 0; i < number_of_values; i++)
215 val[i] = 1;
216 for (i = number_of_values; i < number_of_points; i++)
217 val[i] = 0;
218 }
219 else {
220 for (i = 0; i < ni - 1; i++)
221 val[i] = 0;
222 for (i = ni - 1; i < number_of_points; i++)
223 val[i] = 1;
224 }
225
226 *len = number_of_points;
227
228 grib_context_free(a->context, coded_vals);
229 return err;
230 }
231
232 #if 0
233
234 static void grib_set_bit_on( unsigned char* p, long *bitp){
235 unsigned char o = 1;
236 p += (*bitp >> 3);
237 o <<= 7-((*bitp)%8);
238 *p |= o;
239 (*bitp)+=1;
240 }
241
242 static int pack_double(grib_accessor* a, const double* val,size_t *len){
243 grib_accessor_gds_not_present_bitmap* self = (grib_accessor_gds_not_present_bitmap*)a;
244
245 size_t tlen;
246
247 unsigned char* buf = NULL;
248 long i;
249 int err = 0;
250 long pos = 0;
251 long bmaplen = 0;
252 const int bit_padding = 16;
253 double miss_values = 0;
254 tlen = ((*len+bit_padding-1)/bit_padding*bit_padding)/8;
255
256 if((err = grib_get_double_internal(grib_handle_of_accessor(a), self->missing_value, &miss_values)) != GRIB_SUCCESS)
257 {
258 grib_context_log(a->context, GRIB_LOG_ERROR, "grib_accessor_class_bitmap : pack_double : Cannot unpack %s err=%d ",self->missing_value,err);
259 return err;
260 }
261
262 buf = grib_context_malloc_clear(a->context,tlen);
263 if(!buf) return GRIB_OUT_OF_MEMORY;
264 pos=0;
265 for(i=0;i<*len;i++)
266 {
267 if (val[i] == miss_values)
268 pos++;
269 else{
270 bmaplen++;
271 grib_set_bit_on(buf, &pos);
272 }
273 }
274
275 if((err = grib_set_long_internal(grib_handle_of_accessor(a), self->unusedBits,tlen*8 - *len )) != GRIB_SUCCESS) {
276 grib_context_log(a->context, GRIB_LOG_ERROR, "grib_accessor_class_bitmap : pack_double : Cannot pack %s err=%d ",self->unusedBits,err);
277 grib_context_free(a->context,buf);
278 return err;
279 }
280
281
282 grib_buffer_replace(a, buf, tlen,1,1);
283
284 grib_context_free(a->context,buf);
285
286 return GRIB_SUCCESS;
287 }
288
289 #else
290
pack_double(grib_accessor * a,const double * val,size_t * len)291 static int pack_double(grib_accessor* a, const double* val, size_t* len)
292 {
293 return GRIB_NOT_IMPLEMENTED;
294 }
295
296 #endif
297