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  *   Jean Baptiste Filippi - 01.11.2005                                                           *
13  *   Enrico Fucile
14  *                                                                         *
15  ***************************************************************************/
16 #include "grib_api_internal.h"
17 /*
18    This is used by make_class.pl
19 
20    START_CLASS_DEF
21    CLASS      = accessor
22    IMPLEMENTS = unpack_long;pack_long; clear
23    IMPLEMENTS = unpack_double;pack_double;unpack_double_element
24    IMPLEMENTS = unpack_string;pack_string
25    IMPLEMENTS = unpack_string_array;pack_string_array
26    IMPLEMENTS = unpack_bytes;pack_bytes
27    IMPLEMENTS = unpack_double_subarray
28    IMPLEMENTS = init;dump;destroy;string_length
29    IMPLEMENTS = get_native_type;sub_section
30    IMPLEMENTS = next_offset;value_count;byte_offset;byte_count
31    IMPLEMENTS = notify_change;pack_expression
32    IMPLEMENTS  = update_size; next; preferred_size
33    IMPLEMENTS = compare;is_missing;make_clone
34    END_CLASS_DEF
35 
36  */
37 
38 /* START_CLASS_IMP */
39 
40 /*
41 
42 Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
43 Instead edit values between START_CLASS_DEF and END_CLASS_DEF
44 or edit "accessor.class" and rerun ./make_class.pl
45 
46 */
47 
48 static grib_section* sub_section(grib_accessor* a);
49 static int get_native_type(grib_accessor*);
50 static int is_missing(grib_accessor*);
51 static int pack_bytes(grib_accessor*, const unsigned char*, size_t* len);
52 static int pack_double(grib_accessor*, const double* val, size_t* len);
53 static int pack_long(grib_accessor*, const long* val, size_t* len);
54 static int pack_string(grib_accessor*, const char*, size_t* len);
55 static int pack_string_array(grib_accessor*, const char**, size_t* len);
56 static int pack_expression(grib_accessor*, grib_expression*);
57 static int unpack_bytes(grib_accessor*, unsigned char*, size_t* len);
58 static int unpack_double(grib_accessor*, double* val, size_t* len);
59 static int unpack_long(grib_accessor*, long* val, size_t* len);
60 static int unpack_string(grib_accessor*, char*, size_t* len);
61 static int unpack_string_array(grib_accessor*, char**, size_t* len);
62 static size_t string_length(grib_accessor*);
63 static long byte_count(grib_accessor*);
64 static long byte_offset(grib_accessor*);
65 static long next_offset(grib_accessor*);
66 static int value_count(grib_accessor*, long*);
67 static void destroy(grib_context*, grib_accessor*);
68 static void dump(grib_accessor*, grib_dumper*);
69 static void init(grib_accessor*, const long, grib_arguments*);
70 static void init_class(grib_accessor_class*);
71 static int notify_change(grib_accessor*, grib_accessor*);
72 static void update_size(grib_accessor*, size_t);
73 static size_t preferred_size(grib_accessor*, int);
74 static grib_accessor* next(grib_accessor*, int);
75 static int compare(grib_accessor*, grib_accessor*);
76 static int unpack_double_element(grib_accessor*, size_t i, double* val);
77 static int unpack_double_subarray(grib_accessor*, double* val, size_t start, size_t len);
78 static int clear(grib_accessor*);
79 static grib_accessor* make_clone(grib_accessor*, grib_section*, int*);
80 
81 typedef struct grib_accessor_gen
82 {
83     grib_accessor att;
84     /* Members defined in gen */
85 } grib_accessor_gen;
86 
87 
88 static grib_accessor_class _grib_accessor_class_gen = {
89     0,                         /* super                     */
90     "gen",                     /* name                      */
91     sizeof(grib_accessor_gen), /* size                      */
92     0,                         /* inited */
93     &init_class,               /* init_class */
94     &init,                     /* init                      */
95     0,                         /* post_init                      */
96     &destroy,                  /* free mem                       */
97     &dump,                     /* describes himself         */
98     &next_offset,              /* get length of section     */
99     &string_length,            /* get length of string      */
100     &value_count,              /* get number of values      */
101     &byte_count,               /* get number of bytes      */
102     &byte_offset,              /* get offset to bytes           */
103     &get_native_type,          /* get native type               */
104     &sub_section,              /* get sub_section                */
105     0,                         /* grib_pack procedures long      */
106     &is_missing,               /* grib_pack procedures long      */
107     &pack_long,                /* grib_pack procedures long      */
108     &unpack_long,              /* grib_unpack procedures long    */
109     &pack_double,              /* grib_pack procedures double    */
110     &unpack_double,            /* grib_unpack procedures double  */
111     &pack_string,              /* grib_pack procedures string    */
112     &unpack_string,            /* grib_unpack procedures string  */
113     &pack_string_array,        /* grib_pack array procedures string    */
114     &unpack_string_array,      /* grib_unpack array procedures string  */
115     &pack_bytes,               /* grib_pack procedures bytes     */
116     &unpack_bytes,             /* grib_unpack procedures bytes   */
117     &pack_expression,          /* pack_expression */
118     &notify_change,            /* notify_change   */
119     &update_size,              /* update_size   */
120     &preferred_size,           /* preferred_size   */
121     0,                         /* resize   */
122     0,                         /* nearest_smaller_value */
123     &next,                     /* next accessor    */
124     &compare,                  /* compare vs. another accessor   */
125     &unpack_double_element,    /* unpack only ith value          */
126     &unpack_double_subarray,   /* unpack a subarray         */
127     &clear,                    /* clear          */
128     &make_clone,               /* clone accessor          */
129 };
130 
131 
132 grib_accessor_class* grib_accessor_class_gen = &_grib_accessor_class_gen;
133 
134 
init_class(grib_accessor_class * c)135 static void init_class(grib_accessor_class* c)
136 {
137 }
138 
139 /* END_CLASS_IMP */
140 
init(grib_accessor * a,const long len,grib_arguments * param)141 static void init(grib_accessor* a, const long len, grib_arguments* param)
142 {
143     grib_action* act = (grib_action*)(a->creator);
144     if (a->flags & GRIB_ACCESSOR_FLAG_TRANSIENT) {
145         a->length = 0;
146         if (!a->vvalue)
147             a->vvalue = (grib_virtual_value*)grib_context_malloc_clear(a->context, sizeof(grib_virtual_value));
148         a->vvalue->type   = grib_accessor_get_native_type(a);
149         a->vvalue->length = len;
150         if (act->default_value != NULL) {
151             const char* p = 0;
152             size_t s_len  = 1;
153             long l;
154             int ret = 0;
155             double d;
156             char tmp[1024];
157             grib_expression* expression = grib_arguments_get_expression(grib_handle_of_accessor(a), act->default_value, 0);
158             int type                    = grib_expression_native_type(grib_handle_of_accessor(a), expression);
159             switch (type) {
160                 case GRIB_TYPE_DOUBLE:
161                     grib_expression_evaluate_double(grib_handle_of_accessor(a), expression, &d);
162                     grib_pack_double(a, &d, &s_len);
163                     break;
164 
165                 case GRIB_TYPE_LONG:
166                     grib_expression_evaluate_long(grib_handle_of_accessor(a), expression, &l);
167                     grib_pack_long(a, &l, &s_len);
168                     break;
169 
170                 default:
171                     s_len = sizeof(tmp);
172                     p     = grib_expression_evaluate_string(grib_handle_of_accessor(a), expression, tmp, &s_len, &ret);
173                     if (ret != GRIB_SUCCESS) {
174                         grib_context_log(a->context, GRIB_LOG_ERROR, "Unable to evaluate %s as string", a->name);
175                         Assert(0);
176                     }
177                     s_len = strlen(p) + 1;
178                     grib_pack_string(a, p, &s_len);
179                     break;
180             }
181         }
182     }
183     else {
184         a->length = len;
185     }
186 }
187 
dump(grib_accessor * a,grib_dumper * dumper)188 static void dump(grib_accessor* a, grib_dumper* dumper)
189 {
190     int type = grib_accessor_get_native_type(a);
191 
192     switch (type) {
193         case GRIB_TYPE_STRING:
194             grib_dump_string(dumper, a, NULL);
195             break;
196         case GRIB_TYPE_DOUBLE:
197             grib_dump_double(dumper, a, NULL);
198             break;
199         case GRIB_TYPE_LONG:
200             grib_dump_long(dumper, a, NULL);
201             break;
202         default:
203             grib_dump_bytes(dumper, a, NULL);
204     }
205 }
206 
next_offset(grib_accessor * a)207 static long next_offset(grib_accessor* a)
208 {
209     return a->offset + a->length;
210 }
211 
value_count(grib_accessor * a,long * count)212 static int value_count(grib_accessor* a, long* count)
213 {
214     *count = 1;
215     return 0;
216 }
217 
string_length(grib_accessor * a)218 static size_t string_length(grib_accessor* a)
219 {
220     return 1024;
221 }
222 
byte_count(grib_accessor * a)223 static long byte_count(grib_accessor* a)
224 {
225     return a->length;
226 }
227 
get_native_type(grib_accessor * a)228 static int get_native_type(grib_accessor* a)
229 {
230     grib_context_log(a->context, GRIB_LOG_ERROR,
231                      "Accessor %s [%s] must implement 'get_native_type'", a->name, a->cclass->name);
232     return GRIB_TYPE_UNDEFINED;
233 }
234 
byte_offset(grib_accessor * a)235 static long byte_offset(grib_accessor* a)
236 {
237     return a->offset;
238 }
239 
unpack_bytes(grib_accessor * a,unsigned char * val,size_t * len)240 static int unpack_bytes(grib_accessor* a, unsigned char* val, size_t* len)
241 {
242     unsigned char* buf = grib_handle_of_accessor(a)->buffer->data;
243     long length        = grib_byte_count(a);
244     long offset        = grib_byte_offset(a);
245 
246     if (*len < length) {
247         grib_context_log(a->context, GRIB_LOG_ERROR, "Wrong size for %s it is %d bytes long\n", a->name, length);
248         *len = length;
249         return GRIB_ARRAY_TOO_SMALL;
250     }
251 
252     memcpy(val, buf + offset, length);
253     *len = length;
254 
255     return GRIB_SUCCESS;
256 }
257 
clear(grib_accessor * a)258 static int clear(grib_accessor* a)
259 {
260     unsigned char* buf = grib_handle_of_accessor(a)->buffer->data;
261     long length        = grib_byte_count(a);
262     long offset        = grib_byte_offset(a);
263 
264     memset(buf + offset, 0, length);
265 
266     return GRIB_SUCCESS;
267 }
268 
unpack_long(grib_accessor * a,long * v,size_t * len)269 static int unpack_long(grib_accessor* a, long* v, size_t* len)
270 {
271     int type = GRIB_TYPE_UNDEFINED;
272     if (a->cclass->unpack_double && a->cclass->unpack_double != &unpack_double) {
273         double val = 0.0;
274         size_t l   = 1;
275         grib_unpack_double(a, &val, &l);
276         if (val == GRIB_MISSING_DOUBLE)
277             *v = GRIB_MISSING_LONG;
278         else
279             *v = (long)val;
280         grib_context_log(a->context, GRIB_LOG_DEBUG, "Casting double %s to long", a->name);
281         return GRIB_SUCCESS;
282     }
283 
284     if (a->cclass->unpack_string && a->cclass->unpack_string != &unpack_string) {
285         char val[1024];
286         size_t l   = sizeof(val);
287         char* last = NULL;
288         grib_unpack_string(a, val, &l);
289 
290         *v = strtol(val, &last, 10);
291 
292         if (*last == 0) {
293             grib_context_log(a->context, GRIB_LOG_DEBUG, "Casting string %s to long", a->name);
294             return GRIB_SUCCESS;
295         }
296     }
297 
298     grib_context_log(a->context, GRIB_LOG_ERROR, "Cannot unpack %s as long", a->name);
299     if (grib_get_native_type(grib_handle_of_accessor(a), a->name, &type) == GRIB_SUCCESS) {
300         grib_context_log(a->context, GRIB_LOG_ERROR, "Hint: Try unpacking as %s", grib_get_type_name(type));
301     }
302     return GRIB_NOT_IMPLEMENTED;
303 }
304 
unpack_double(grib_accessor * a,double * v,size_t * len)305 static int unpack_double(grib_accessor* a, double* v, size_t* len)
306 {
307     int type = GRIB_TYPE_UNDEFINED;
308     if (a->cclass->unpack_long && a->cclass->unpack_long != &unpack_long) {
309         long val = 0;
310         size_t l = 1;
311         grib_unpack_long(a, &val, &l);
312         *v = val;
313         grib_context_log(a->context, GRIB_LOG_DEBUG, "Casting long %s to double", a->name);
314         return GRIB_SUCCESS;
315     }
316 
317     if (a->cclass->unpack_string && a->cclass->unpack_string != &unpack_string) {
318         char val[1024];
319         size_t l   = sizeof(val);
320         char* last = NULL;
321         grib_unpack_string(a, val, &l);
322 
323         *v = strtod(val, &last);
324 
325         if (*last == 0) {
326             grib_context_log(a->context, GRIB_LOG_DEBUG, "Casting string %s to long", a->name);
327             return GRIB_SUCCESS;
328         }
329     }
330 
331     grib_context_log(a->context, GRIB_LOG_ERROR, "Cannot unpack %s as double", a->name);
332     if (grib_get_native_type(grib_handle_of_accessor(a), a->name, &type) == GRIB_SUCCESS) {
333         grib_context_log(a->context, GRIB_LOG_ERROR, "Hint: Try unpacking as %s", grib_get_type_name(type));
334     }
335 
336     return GRIB_NOT_IMPLEMENTED;
337 }
338 
unpack_string(grib_accessor * a,char * v,size_t * len)339 static int unpack_string(grib_accessor* a, char* v, size_t* len)
340 {
341     if (a->cclass->unpack_double && a->cclass->unpack_double != &unpack_double) {
342         double val = 0.0;
343         size_t l   = 1;
344         grib_unpack_double(a, &val, &l);
345         sprintf(v, "%g", val);
346         *len = strlen(v);
347         grib_context_log(a->context, GRIB_LOG_DEBUG, "Casting double %s to string", a->name);
348         return GRIB_SUCCESS;
349     }
350 
351     if (a->cclass->unpack_long && a->cclass->unpack_long != &unpack_long) {
352         long val = 0;
353         size_t l = 1;
354         grib_unpack_long(a, &val, &l);
355         sprintf(v, "%ld", val);
356         *len = strlen(v);
357         grib_context_log(a->context, GRIB_LOG_DEBUG, "Casting long %s to string  \n", a->name);
358         return GRIB_SUCCESS;
359     }
360 
361     return GRIB_NOT_IMPLEMENTED;
362 }
363 
unpack_string_array(grib_accessor * a,char ** v,size_t * len)364 static int unpack_string_array(grib_accessor* a, char** v, size_t* len)
365 {
366     int err       = 0;
367     size_t length = 0;
368 
369     err = _grib_get_string_length(a, &length);
370     if (err)
371         return err;
372     v[0] = (char*)grib_context_malloc_clear(a->context, length);
373     grib_unpack_string(a, v[0], &length);
374     *len = 1;
375 
376     return GRIB_SUCCESS;
377 }
378 
pack_expression(grib_accessor * a,grib_expression * e)379 static int pack_expression(grib_accessor* a, grib_expression* e)
380 {
381     size_t len        = 1;
382     long lval         = 0;
383     double dval       = 0;
384     const char* cval  = NULL;
385     int ret           = 0;
386     grib_handle* hand = grib_handle_of_accessor(a);
387 
388     switch (grib_accessor_get_native_type(a)) {
389         case GRIB_TYPE_LONG: {
390             len = 1;
391             ret = grib_expression_evaluate_long(hand, e, &lval);
392             if (ret != GRIB_SUCCESS) {
393                 grib_context_log(a->context, GRIB_LOG_ERROR, "Unable to set %s as long (from %s)",
394                                  a->name, e->cclass->name);
395                 return ret;
396             }
397             /*if (hand->context->debug)
398                 printf("ECCODES DEBUG grib_accessor_class_gen::pack_expression %s %ld\n", a->name,lval);*/
399             return grib_pack_long(a, &lval, &len);
400         }
401 
402         case GRIB_TYPE_DOUBLE: {
403             len = 1;
404             ret = grib_expression_evaluate_double(hand, e, &dval);
405             if (ret != GRIB_SUCCESS) {
406                 grib_context_log(a->context, GRIB_LOG_ERROR, "unable to set %s as double (from %s)",
407                                  a->name, e->cclass->name);
408                 return ret;
409             }
410             /*if (hand->context->debug)
411                 printf("ECCODES DEBUG grib_accessor_class_gen::pack_expression %s %g\n", a->name, dval);*/
412             return grib_pack_double(a, &dval, &len);
413         }
414 
415         case GRIB_TYPE_STRING: {
416             char tmp[1024];
417             len  = sizeof(tmp);
418             cval = grib_expression_evaluate_string(hand, e, tmp, &len, &ret);
419             if (ret != GRIB_SUCCESS) {
420                 grib_context_log(a->context, GRIB_LOG_ERROR, "unable to set %s as string (from %s)",
421                                  a->name, e->cclass->name);
422                 return ret;
423             }
424             len = strlen(cval);
425             /*if (hand->context->debug)
426                 printf("ECCODES DEBUG grib_accessor_class_gen::pack_expression %s %s\n", a->name, cval);*/
427             return grib_pack_string(a, cval, &len);
428         }
429     }
430 
431     return GRIB_NOT_IMPLEMENTED;
432 }
433 
pack_long(grib_accessor * a,const long * v,size_t * len)434 static int pack_long(grib_accessor* a, const long* v, size_t* len)
435 {
436     grib_context* c = a->context;
437     if (a->cclass->pack_double && a->cclass->pack_double != &pack_double) {
438         int i = 0, ret = 0;
439         double* val = (double*)grib_context_malloc(c, *len * (sizeof(double)));
440         if (!val) {
441             grib_context_log(c, GRIB_LOG_ERROR,
442                              "Unable to allocate %d bytes\n", (int)(*len * (sizeof(double))));
443             return GRIB_OUT_OF_MEMORY;
444         }
445         for (i = 0; i < *len; i++)
446             val[i] = (long)v[i];
447         ret = grib_pack_double(a, val, len);
448         grib_context_free(c, val);
449         return ret;
450     }
451     grib_context_log(c, GRIB_LOG_ERROR, "Should not grib_pack %s as long", a->name);
452     Assert(0);
453     return GRIB_NOT_IMPLEMENTED;
454 }
455 
pack_double_array_as_long(grib_accessor * a,const double * v,size_t * len)456 static int pack_double_array_as_long(grib_accessor* a, const double* v, size_t* len)
457 {
458     grib_context* c = a->context;
459     int ret         = GRIB_SUCCESS;
460     size_t i        = 0;
461     size_t numBytes = *len * (sizeof(long));
462     long* lValues   = (long*)grib_context_malloc(c, numBytes);
463     if (!lValues) {
464         grib_context_log(c, GRIB_LOG_ERROR, "Unable to allocate %ld bytes\n", numBytes);
465         return GRIB_OUT_OF_MEMORY;
466     }
467     for (i = 0; i < *len; i++)
468         lValues[i] = (long)v[i]; /* convert from double to long */
469     ret = grib_pack_long(a, lValues, len);
470     grib_context_free(c, lValues);
471     return ret;
472 }
473 
pack_double(grib_accessor * a,const double * v,size_t * len)474 static int pack_double(grib_accessor* a, const double* v, size_t* len)
475 {
476     int do_pack_as_long = 0;
477     grib_context* c     = a->context;
478     if (a->cclass->pack_long && a->cclass->pack_long != &pack_long) {
479         do_pack_as_long = 1;
480     }
481     else {
482         /* ECC-648: Special case of codetable */
483         if (strcmp(a->cclass->name, "codetable") == 0) {
484             do_pack_as_long = 1;
485         }
486     }
487     if (do_pack_as_long) {
488         return pack_double_array_as_long(a, v, len);
489     }
490     grib_context_log(c, GRIB_LOG_ERROR, "Should not grib_pack %s as double", a->name);
491     return GRIB_NOT_IMPLEMENTED;
492 }
493 
pack_string_array(grib_accessor * a,const char ** v,size_t * len)494 static int pack_string_array(grib_accessor* a, const char** v, size_t* len)
495 {
496     long i;
497     int err           = 0;
498     size_t length     = 0;
499     grib_accessor* as = 0;
500 
501     as = a;
502     i  = (long)*len - 1;
503     while (as && i >= 0) {
504         length = strlen(v[i]);
505         err    = grib_pack_string(as, v[i], &length);
506         if (err)
507             return err;
508         --i;
509         as = as->same;
510     }
511     return GRIB_SUCCESS;
512 }
513 
pack_string(grib_accessor * a,const char * v,size_t * len)514 static int pack_string(grib_accessor* a, const char* v, size_t* len)
515 {
516     if (a->cclass->pack_double && a->cclass->pack_double != &pack_double) {
517         size_t l   = 1;
518         double val = atof(v);
519         return grib_pack_double(a, &val, &l);
520     }
521 
522     if (a->cclass->pack_long && a->cclass->pack_long != &pack_long) {
523         size_t l = 1;
524         long val = atof(v);
525         return grib_pack_long(a, &val, &l);
526     }
527 
528     grib_context_log(a->context, GRIB_LOG_ERROR,
529                      "Should not grib_pack %s as string", a->name);
530     return GRIB_NOT_IMPLEMENTED;
531 }
532 
pack_bytes(grib_accessor * a,const unsigned char * val,size_t * len)533 static int pack_bytes(grib_accessor* a, const unsigned char* val, size_t* len)
534 {
535     const size_t length = *len;
536     if (length != a->length) {
537         grib_context_log(a->context, GRIB_LOG_ERROR,
538                          "pack_bytes: Wrong size (%lu) for %s. It is %lu bytes long",
539                          length, a->name, a->length);
540         return GRIB_BUFFER_TOO_SMALL;
541     }
542     grib_buffer_replace(a, val, length, 1, 1);
543     return GRIB_SUCCESS;
544 }
545 
destroy(grib_context * ct,grib_accessor * a)546 static void destroy(grib_context* ct, grib_accessor* a)
547 {
548     grib_dependency_remove_observed(a);
549     grib_dependency_remove_observer(a);
550     if (a->vvalue != NULL) {
551         grib_context_free(ct, a->vvalue);
552         a->vvalue = NULL;
553     }
554     /*grib_context_log(ct,GRIB_LOG_DEBUG,"address=%p",a);*/
555 }
556 
sub_section(grib_accessor * a)557 static grib_section* sub_section(grib_accessor* a)
558 {
559     return NULL;
560 }
561 
notify_change(grib_accessor * self,grib_accessor * observed)562 static int notify_change(grib_accessor* self, grib_accessor* observed)
563 {
564     /* Default behaviour is to notify creator */
565     return grib_action_notify_change(self->creator, self, observed);
566 }
567 
update_size(grib_accessor * a,size_t s)568 static void update_size(grib_accessor* a, size_t s)
569 {
570     grib_context_log(a->context, GRIB_LOG_ERROR,
571                      "Accessor %s [%s] must implement 'update_size'", a->name, a->cclass->name);
572     Assert(0 == 1);
573 }
574 
next(grib_accessor * a,int mod)575 static grib_accessor* next(grib_accessor* a, int mod)
576 {
577     grib_accessor* next = NULL;
578     if (a->next) {
579         next = a->next;
580     }
581     else {
582         if (a->parent->owner)
583             next = a->parent->owner->cclass->next(a->parent->owner, 0);
584     }
585     return next;
586 }
587 
compare(grib_accessor * a,grib_accessor * b)588 static int compare(grib_accessor* a, grib_accessor* b)
589 {
590     return GRIB_NOT_IMPLEMENTED;
591 }
592 
593 /* Redefined in all padding */
594 
preferred_size(grib_accessor * a,int from_handle)595 static size_t preferred_size(grib_accessor* a, int from_handle)
596 {
597     return a->length;
598 }
599 
is_missing(grib_accessor * a)600 static int is_missing(grib_accessor* a)
601 {
602     int i              = 0;
603     int is_missing     = 1;
604     unsigned char ones = 0xff;
605     unsigned char* v   = NULL;
606 
607     if (a->flags & GRIB_ACCESSOR_FLAG_TRANSIENT) {
608         if (a->vvalue == NULL) {
609             grib_context_log(a->context, GRIB_LOG_ERROR, "%s internal error (flags=0x%X)", a->name, a->flags);
610             Assert(!"grib_accessor_class_gen::is_missing(): a->vvalue == NULL");
611             return 0;
612         }
613         return a->vvalue->missing;
614     }
615     Assert(a->length >= 0);
616 
617     v = grib_handle_of_accessor(a)->buffer->data + a->offset;
618 
619     for (i = 0; i < a->length; i++) {
620         if (*v != ones) {
621             is_missing = 0;
622             break;
623         }
624         v++;
625     }
626 
627     return is_missing;
628 }
629 
unpack_double_element(grib_accessor * a,size_t i,double * val)630 static int unpack_double_element(grib_accessor* a, size_t i, double* val)
631 {
632     return GRIB_NOT_IMPLEMENTED;
633 }
634 
unpack_double_subarray(grib_accessor * a,double * val,size_t start,size_t len)635 static int unpack_double_subarray(grib_accessor* a, double* val, size_t start, size_t len)
636 {
637     return GRIB_NOT_IMPLEMENTED;
638 }
639 
make_clone(grib_accessor * a,grib_section * s,int * err)640 static grib_accessor* make_clone(grib_accessor* a, grib_section* s, int* err)
641 {
642     *err = GRIB_NOT_IMPLEMENTED;
643     return NULL;
644 }
645