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