1 // Copyright 2011 Juri Glass, Mathias Runge, Nadim El Sayed
2 // DAI-Labor, TU-Berlin
3 //
4 // This file is part of libSML.
5 //
6 // libSML is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // libSML is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with libSML. If not, see <http://www.gnu.org/licenses/>.
18
19
20 #include <sml/sml_time.h>
21 #include <sml/sml_shared.h>
22 #include <sml/sml_number.h>
23 #include <stdio.h>
24
sml_time_init()25 sml_time *sml_time_init() {
26 sml_time *t = (sml_time *) malloc(sizeof(sml_time));
27 *t = ( sml_time ) {
28 .tag = NULL,
29 .data.sec_index = NULL
30 };
31 return t;
32 }
33
sml_time_parse(sml_buffer * buf)34 sml_time *sml_time_parse(sml_buffer *buf) {
35 if (sml_buf_optional_is_skipped(buf)) {
36 return 0;
37 }
38
39 sml_time *tme = sml_time_init();
40
41 if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
42 buf->error = 1;
43 goto error;
44 }
45
46 if (sml_buf_get_next_length(buf) != 2) {
47 buf->error = 1;
48 goto error;
49 }
50
51 tme->tag = sml_u8_parse(buf);
52 if (sml_buf_has_errors(buf)) goto error;
53
54 int type = sml_buf_get_next_type(buf);
55 switch (type) {
56 case SML_TYPE_UNSIGNED:
57 tme->data.timestamp = sml_u32_parse(buf);
58 if (sml_buf_has_errors(buf)) goto error;
59 break;
60 case SML_TYPE_LIST:
61 // Some meters (e.g. FROETEC Multiflex ZG22) giving not one uint32
62 // as timestamp, but a list of 3 values.
63 // Ignoring these values, so that parsing does not fail.
64 sml_buf_get_next_length(buf); // should we check the length here?
65 u32 *t1 = sml_u32_parse(buf);
66 if (sml_buf_has_errors(buf)) goto error;
67 i16 *t2 = sml_i16_parse(buf);
68 if (sml_buf_has_errors(buf)) goto error;
69 i16 *t3 = sml_i16_parse(buf);
70 if (sml_buf_has_errors(buf)) goto error;
71 fprintf(stderr,
72 "libsml: error: sml_time as list[3]: ignoring value[0]=%u value[1]=%d value[2]=%d\n",
73 *t1, *t2, *t3);
74 break;
75 default:
76 goto error;
77 }
78
79 return tme;
80
81 error:
82 sml_time_free(tme);
83 return 0;
84 }
85
sml_time_write(sml_time * t,sml_buffer * buf)86 void sml_time_write(sml_time *t, sml_buffer *buf) {
87 if (t == 0) {
88 sml_buf_optional_write(buf);
89 return;
90 }
91
92 sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 2);
93 sml_u8_write(t->tag, buf);
94 sml_u32_write(t->data.timestamp, buf);
95 }
96
sml_time_free(sml_time * tme)97 void sml_time_free(sml_time *tme) {
98 if (tme) {
99 sml_number_free(tme->tag);
100 sml_number_free(tme->data.timestamp);
101 free(tme);
102 }
103 }
104
105