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_tree.h>
21 #include <sml/sml_value.h>
22 #include <stdio.h>
23 
24 // sml_tree_path;
25 
sml_tree_path_init()26 sml_tree_path *sml_tree_path_init() {
27 	sml_tree_path *tree_path = (sml_tree_path *) malloc(sizeof(sml_tree_path));
28 	*tree_path = ( sml_tree_path ) {
29 		.path_entries_len = 0,
30 		.path_entries = NULL
31 	};
32 
33 	return tree_path;
34 }
35 
sml_tree_path_parse(sml_buffer * buf)36 sml_tree_path *sml_tree_path_parse(sml_buffer *buf) {
37 	if (sml_buf_optional_is_skipped(buf)) {
38 		return 0;
39 	}
40 
41 	sml_tree_path *tree_path = sml_tree_path_init();
42 
43 	if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
44 		buf->error = 1;
45 		return 0;
46 	}
47 
48 	octet_string *s;
49 	int elems;
50 	for (elems = sml_buf_get_next_length(buf); elems > 0; elems--) {
51 		s = sml_octet_string_parse(buf);
52 		if (sml_buf_has_errors(buf)) goto error;
53 		if (s) {
54 			sml_tree_path_add_path_entry(tree_path, s);
55 		}
56 	}
57 
58 	return tree_path;
59 
60 error:
61 	buf->error = 1;
62 	sml_tree_path_free(tree_path);
63 	return 0;
64 }
65 
sml_tree_path_add_path_entry(sml_tree_path * tree_path,octet_string * entry)66 void sml_tree_path_add_path_entry(sml_tree_path *tree_path, octet_string *entry) {
67 	tree_path->path_entries_len++;
68 	tree_path->path_entries = (octet_string **) realloc(tree_path->path_entries,
69 		sizeof(octet_string *) * tree_path->path_entries_len);
70 
71 	tree_path->path_entries[tree_path->path_entries_len - 1] = entry;
72 }
73 
sml_tree_path_write(sml_tree_path * tree_path,sml_buffer * buf)74 void sml_tree_path_write(sml_tree_path *tree_path, sml_buffer *buf) {
75 	if (tree_path == 0) {
76 		sml_buf_optional_write(buf);
77 		return;
78 	}
79 
80 	if (tree_path->path_entries && tree_path->path_entries_len > 0) {
81 		sml_buf_set_type_and_length(buf, SML_TYPE_LIST, tree_path->path_entries_len);
82 
83 		int i;
84 		for (i = 0; i < tree_path->path_entries_len; i++) {
85 			sml_octet_string_write(tree_path->path_entries[i], buf);
86 		}
87 	}
88 }
89 
sml_tree_path_free(sml_tree_path * tree_path)90 void sml_tree_path_free(sml_tree_path *tree_path) {
91 	if (tree_path) {
92 		if (tree_path->path_entries && tree_path->path_entries_len > 0) {
93 			int i;
94 			for (i = 0; i < tree_path->path_entries_len; i++) {
95 				sml_octet_string_free(tree_path->path_entries[i]);
96 			}
97 
98 			free(tree_path->path_entries);
99 		}
100 
101 		free(tree_path);
102 	}
103 }
104 
105 
106 // sml_tree;
107 
sml_tree_init()108 sml_tree *sml_tree_init() {
109 	sml_tree *tree = (sml_tree *) malloc(sizeof(sml_tree));
110 	*tree = ( sml_tree ) {
111 		.parameter_name = NULL,
112 		.parameter_value = NULL,
113 		.child_list = NULL,
114 		.child_list_len = 0
115 	};
116 
117 	return tree;
118 }
119 
sml_tree_parse(sml_buffer * buf)120 sml_tree *sml_tree_parse(sml_buffer *buf) {
121 	if (sml_buf_optional_is_skipped(buf)) {
122 		return 0;
123 	}
124 
125 	sml_tree *tree = sml_tree_init();
126 
127 	if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
128 		buf->error = 1;
129 		goto error;
130 	}
131 
132 	if (sml_buf_get_next_length(buf) != 3) {
133 		buf->error = 1;
134 		goto error;
135 	}
136 
137 	tree->parameter_name = sml_octet_string_parse(buf);
138 	if (sml_buf_has_errors(buf)) goto error;
139 
140 	tree->parameter_value = sml_proc_par_value_parse(buf);
141 	if (sml_buf_has_errors(buf)) goto error;
142 
143 	if (!sml_buf_optional_is_skipped(buf)) {
144 		if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
145 			buf->error = 1;
146 			goto error;
147 		}
148 
149 		sml_tree *c;
150 		int elems;
151 		for (elems = sml_buf_get_next_length(buf); elems > 0; elems--) {
152 			c = sml_tree_parse(buf);
153 			if (sml_buf_has_errors(buf)) goto error;
154 			if (c) {
155 				sml_tree_add_tree(tree, c);
156 			}
157 		}
158 	}
159 
160 	return tree;
161 
162 error:
163 	sml_tree_free(tree);
164 	return 0;
165 }
166 
sml_tree_add_tree(sml_tree * base_tree,sml_tree * tree)167 void sml_tree_add_tree(sml_tree *base_tree, sml_tree *tree) {
168 	base_tree->child_list_len++;
169 	base_tree->child_list = (sml_tree **) realloc(base_tree->child_list,
170 		sizeof(sml_tree *) * base_tree->child_list_len);
171 	base_tree->child_list[base_tree->child_list_len - 1] = tree;
172 }
173 
sml_tree_free(sml_tree * tree)174 void sml_tree_free(sml_tree *tree) {
175 	if (tree) {
176 		sml_octet_string_free(tree->parameter_name);
177 		sml_proc_par_value_free(tree->parameter_value);
178 		int i;
179 		for (i = 0; i < tree->child_list_len; i++) {
180 			sml_tree_free(tree->child_list[i]);
181 		}
182 
183 		free(tree->child_list);
184 		free(tree);
185 	}
186 }
187 
sml_tree_write(sml_tree * tree,sml_buffer * buf)188 void sml_tree_write(sml_tree *tree, sml_buffer *buf) {
189 	if (tree == 0) {
190 		sml_buf_optional_write(buf);
191 		return;
192 	}
193 
194 	sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 3);
195 
196 	sml_octet_string_write(tree->parameter_name, buf);
197 	sml_proc_par_value_write(tree->parameter_value, buf);
198 
199 	if (tree->child_list && tree->child_list_len > 0) {
200 		sml_buf_set_type_and_length(buf, SML_TYPE_LIST, tree->child_list_len);
201 
202 		int i;
203 		for (i = 0; i < tree->child_list_len; i++) {
204 			sml_tree_write(tree->child_list[i], buf);
205 		}
206 	}
207 	else {
208 		sml_buf_optional_write(buf);
209 	}
210 }
211 
212 
213 // sml_proc_par_value;
214 
sml_proc_par_value_init()215 sml_proc_par_value *sml_proc_par_value_init() {
216 	sml_proc_par_value *value = (sml_proc_par_value *) malloc(sizeof(sml_proc_par_value));
217 	*value = ( sml_proc_par_value ) {
218 		.tag = NULL,
219 		.data.value = NULL
220 	};
221 	return value;
222 }
223 
sml_proc_par_value_parse(sml_buffer * buf)224 sml_proc_par_value *sml_proc_par_value_parse(sml_buffer *buf) {
225 	if (sml_buf_optional_is_skipped(buf)) {
226 		return 0;
227 	}
228 
229 	sml_proc_par_value *ppv = sml_proc_par_value_init();
230 
231 	if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
232 		buf->error = 1;
233 		goto error;
234 	}
235 
236 	if (sml_buf_get_next_length(buf) != 2) {
237 		buf->error = 1;
238 		goto error;
239 	}
240 
241 	ppv->tag = sml_u8_parse(buf);
242 	if (sml_buf_has_errors(buf)) goto error;
243 
244 	switch (*(ppv->tag)) {
245 		case SML_PROC_PAR_VALUE_TAG_VALUE:
246 			ppv->data.value = sml_value_parse(buf);
247 			break;
248 		case SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY:
249 			ppv->data.period_entry = sml_period_entry_parse(buf);
250 			break;
251 		case SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY:
252 			ppv->data.tupel_entry = sml_tupel_entry_parse(buf);
253 			break;
254 		case SML_PROC_PAR_VALUE_TAG_TIME:
255 			ppv->data.time = sml_time_parse(buf);
256 			break;
257 		default:
258 			buf->error = 1;
259 			goto error;
260 	}
261 
262 	return ppv;
263 
264 error:
265 	sml_proc_par_value_free(ppv);
266 	return 0;
267 }
268 
sml_proc_par_value_write(sml_proc_par_value * value,sml_buffer * buf)269 void sml_proc_par_value_write(sml_proc_par_value *value, sml_buffer *buf) {
270 	if (value == 0) {
271 		sml_buf_optional_write(buf);
272 		return;
273 	}
274 
275 	sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 2);
276 	sml_u8_write(value->tag, buf);
277 
278 	switch (*(value->tag)) {
279 		case SML_PROC_PAR_VALUE_TAG_VALUE:
280 			sml_value_write(value->data.value, buf);
281 			break;
282 		case SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY:
283 			sml_period_entry_write(value->data.period_entry, buf);
284 			break;
285 		case SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY:
286 			sml_tupel_entry_write(value->data.tupel_entry, buf);
287 			break;
288 		case SML_PROC_PAR_VALUE_TAG_TIME:
289 			sml_time_write(value->data.time, buf);
290 			break;
291 		default:
292 			fprintf(stderr,"libsml: error: unknown tag in %s\n", __FUNCTION__);
293 	}
294 }
295 
sml_proc_par_value_free(sml_proc_par_value * ppv)296 void sml_proc_par_value_free(sml_proc_par_value *ppv) {
297 	if (ppv) {
298 		if (ppv->tag) {
299 			switch (*(ppv->tag)) {
300 				case SML_PROC_PAR_VALUE_TAG_VALUE:
301 					sml_value_free(ppv->data.value);
302 					break;
303 				case SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY:
304 					sml_period_entry_free(ppv->data.period_entry);
305 					break;
306 				case SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY:
307 					sml_tupel_entry_free(ppv->data.tupel_entry);
308 					break;
309 				case SML_PROC_PAR_VALUE_TAG_TIME:
310 					sml_time_free(ppv->data.time);
311 					break;
312 				default:
313 					if (ppv->data.value) {
314 						free(ppv->data.value);
315 					}
316 			}
317 			sml_number_free(ppv->tag);
318 		}
319 		else {
320 			// Without the tag, there might be a memory leak.
321 			if (ppv->data.value) {
322 				free(ppv->data.value);
323 			}
324 		}
325 
326 		free(ppv);
327 	}
328 }
329 
330 
331 // sml_tuple_entry;
332 
sml_tupel_entry_init()333 sml_tupel_entry *sml_tupel_entry_init() {
334 	sml_tupel_entry *tupel = (sml_tupel_entry *) malloc(sizeof(sml_tupel_entry));
335 	*tupel = ( sml_tupel_entry ) {
336 		.server_id = NULL,
337 		.sec_index = NULL,
338 		.status = NULL,
339 		.unit_pA = NULL,
340 		.scaler_pA = NULL,
341 		.value_pA = NULL,
342 		.unit_R1 = NULL,
343 		.scaler_R1 = NULL,
344 		.value_R1 = NULL,
345 		.unit_R4 = NULL,
346 		.scaler_R4 = NULL,
347 		.value_R4 = NULL,
348 		.signature_pA_R1_R4 = NULL,
349 		.unit_mA = NULL,
350 		.scaler_mA = NULL,
351 		.value_mA = NULL,
352 		.unit_R2 = NULL,
353 		.scaler_R2 = NULL,
354 		.value_R2 = NULL,
355 		.unit_R3 = NULL,
356 		.scaler_R3 = NULL,
357 		.value_R3 = NULL,
358 		.signature_mA_R2_R3 = NULL
359 	};
360 
361 	return tupel;
362 }
363 
sml_tupel_entry_parse(sml_buffer * buf)364 sml_tupel_entry *sml_tupel_entry_parse(sml_buffer *buf) {
365 	if (sml_buf_optional_is_skipped(buf)) {
366 		return 0;
367 	}
368 
369 	sml_tupel_entry *tupel = sml_tupel_entry_init();
370 
371 	if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
372 		buf->error = 1;
373 		goto error;
374 	}
375 
376 	if (sml_buf_get_next_length(buf) != 23) {
377 		buf->error = 1;
378 		goto error;
379 	}
380 
381 	tupel->server_id = sml_octet_string_parse(buf);
382 	if (sml_buf_has_errors(buf)) goto error;
383 	tupel->sec_index = sml_time_parse(buf);
384 	if (sml_buf_has_errors(buf)) goto error;
385 	tupel->status = sml_u64_parse(buf);
386 	if (sml_buf_has_errors(buf)) goto error;
387 
388 	tupel->unit_pA = sml_unit_parse(buf);
389 	if (sml_buf_has_errors(buf)) goto error;
390 	tupel->scaler_pA = sml_i8_parse(buf);
391 	if (sml_buf_has_errors(buf)) goto error;
392 	tupel->value_pA = sml_i64_parse(buf);
393 	if (sml_buf_has_errors(buf)) goto error;
394 
395 	tupel->unit_R1 = sml_unit_parse(buf);
396 	if (sml_buf_has_errors(buf)) goto error;
397 	tupel->scaler_R1 = sml_i8_parse(buf);
398 	if (sml_buf_has_errors(buf)) goto error;
399 	tupel->value_R1 = sml_i64_parse(buf);
400 	if (sml_buf_has_errors(buf)) goto error;
401 
402 	tupel->unit_R4 = sml_unit_parse(buf);
403 	if (sml_buf_has_errors(buf)) goto error;
404 	tupel->scaler_R4 = sml_i8_parse(buf);
405 	if (sml_buf_has_errors(buf)) goto error;
406 	tupel->value_R4 = sml_i64_parse(buf);
407 	if (sml_buf_has_errors(buf)) goto error;
408 
409 	tupel->signature_pA_R1_R4 = sml_octet_string_parse(buf);
410 	if (sml_buf_has_errors(buf)) goto error;
411 
412 	tupel->unit_mA = sml_unit_parse(buf);
413 	if (sml_buf_has_errors(buf)) goto error;
414 	tupel->scaler_mA = sml_i8_parse(buf);
415 	if (sml_buf_has_errors(buf)) goto error;
416 	tupel->value_mA = sml_i64_parse(buf);
417 	if (sml_buf_has_errors(buf)) goto error;
418 
419 	tupel->unit_R2 = sml_unit_parse(buf);
420 	if (sml_buf_has_errors(buf)) goto error;
421 	tupel->scaler_R2 = sml_i8_parse(buf);
422 	if (sml_buf_has_errors(buf)) goto error;
423 	tupel->value_R2 = sml_i64_parse(buf);
424 	if (sml_buf_has_errors(buf)) goto error;
425 
426 	tupel->unit_R3 = sml_unit_parse(buf);
427 	if (sml_buf_has_errors(buf)) goto error;
428 	tupel->scaler_R3 = sml_i8_parse(buf);
429 	if (sml_buf_has_errors(buf)) goto error;
430 	tupel->value_R3 = sml_i64_parse(buf);
431 	if (sml_buf_has_errors(buf)) goto error;
432 
433 	tupel->signature_mA_R2_R3 = sml_octet_string_parse(buf);
434 	if (sml_buf_has_errors(buf)) goto error;
435 
436 	return tupel;
437 
438 error:
439 	sml_tupel_entry_free(tupel);
440 	return 0;
441 }
442 
sml_tupel_entry_write(sml_tupel_entry * tupel,sml_buffer * buf)443 void sml_tupel_entry_write(sml_tupel_entry *tupel, sml_buffer *buf) {
444 	if (tupel == 0) {
445 		sml_buf_optional_write(buf);
446 		return;
447 	}
448 
449 	sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 23);
450 
451 	sml_octet_string_write(tupel->server_id, buf);
452 	sml_time_write(tupel->sec_index, buf);
453 	sml_u64_write(tupel->status, buf);
454 
455 	sml_unit_write(tupel->unit_pA, buf);
456 	sml_i8_write(tupel->scaler_pA, buf);
457 	sml_i64_write(tupel->value_pA, buf);
458 
459 	sml_unit_write(tupel->unit_R1, buf);
460 	sml_i8_write(tupel->scaler_R1, buf);
461 	sml_i64_write(tupel->value_R1, buf);
462 
463 	sml_unit_write(tupel->unit_R4, buf);
464 	sml_i8_write(tupel->scaler_R4, buf);
465 	sml_i64_write(tupel->value_R4, buf);
466 
467 	sml_octet_string_write(tupel->signature_pA_R1_R4, buf);
468 
469 	sml_unit_write(tupel->unit_mA, buf);
470 	sml_i8_write(tupel->scaler_mA, buf);
471 	sml_i64_write(tupel->value_mA, buf);
472 
473 	sml_unit_write(tupel->unit_R2, buf);
474 	sml_i8_write(tupel->scaler_R2, buf);
475 	sml_i64_write(tupel->value_R2, buf);
476 
477 	sml_unit_write(tupel->unit_R3, buf);
478 	sml_i8_write(tupel->scaler_R3, buf);
479 	sml_i64_write(tupel->value_R3, buf);
480 
481 	sml_octet_string_write(tupel->signature_mA_R2_R3, buf);
482 }
483 
sml_tupel_entry_free(sml_tupel_entry * tupel)484 void sml_tupel_entry_free(sml_tupel_entry *tupel) {
485 	if (tupel) {
486 		sml_octet_string_free(tupel->server_id);
487 		sml_time_free(tupel->sec_index);
488 		sml_number_free(tupel->status);
489 
490 		sml_unit_free(tupel->unit_pA);
491 		sml_number_free(tupel->scaler_pA);
492 		sml_number_free(tupel->value_pA);
493 
494 		sml_unit_free(tupel->unit_R1);
495 		sml_number_free(tupel->scaler_R1);
496 		sml_number_free(tupel->value_R1);
497 
498 		sml_unit_free(tupel->unit_R4);
499 		sml_number_free(tupel->scaler_R4);
500 		sml_number_free(tupel->value_R4);
501 
502 		sml_octet_string_free(tupel->signature_pA_R1_R4);
503 
504 		sml_unit_free(tupel->unit_mA);
505 		sml_number_free(tupel->scaler_mA);
506 		sml_number_free(tupel->value_mA);
507 
508 		sml_unit_free(tupel->unit_R2);
509 		sml_number_free(tupel->scaler_R2);
510 		sml_number_free(tupel->value_R2);
511 
512 		sml_unit_free(tupel->unit_R3);
513 		sml_number_free(tupel->scaler_R3);
514 		sml_number_free(tupel->value_R3);
515 
516 		sml_octet_string_free(tupel->signature_mA_R2_R3);
517 
518 		free(tupel);
519 	}
520 }
521 
522 
523 
524 // sml_period_entry;
525 
sml_period_entry_init()526 sml_period_entry *sml_period_entry_init() {
527 	sml_period_entry *period = (sml_period_entry *) malloc(sizeof(sml_period_entry));
528 	*period = ( sml_period_entry ) {
529 		.obj_name = NULL,
530 		.unit = NULL,
531 		.scaler = NULL,
532 		.value = NULL,
533 		.value_signature = NULL
534 	};
535 
536 	return period;
537 }
538 
sml_period_entry_parse_(sml_buffer * buf)539 static void * sml_period_entry_parse_(sml_buffer *buf) {
540 	if (sml_buf_optional_is_skipped(buf)) {
541 		return 0;
542 	}
543 
544 	sml_period_entry *period = sml_period_entry_init();
545 
546 	if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
547 		buf->error = 1;
548 		goto error;
549 	}
550 
551 	if (sml_buf_get_next_length(buf) != 5) {
552 		buf->error = 1;
553 		goto error;
554 	}
555 
556 	period->obj_name = sml_octet_string_parse(buf);
557 	if (sml_buf_has_errors(buf)) goto error;
558 
559 	period->unit = sml_unit_parse(buf);
560 	if (sml_buf_has_errors(buf)) goto error;
561 
562 	period->scaler = sml_i8_parse(buf);
563 	if (sml_buf_has_errors(buf)) goto error;
564 
565 	period->value = sml_value_parse(buf);
566 	if (sml_buf_has_errors(buf)) goto error;
567 
568 	period->value_signature = sml_octet_string_parse(buf);
569 	if (sml_buf_has_errors(buf)) goto error;
570 
571 	return period;
572 
573 error:
574 	sml_period_entry_free(period);
575 	return 0;
576 }
577 
sml_period_entry_parse(sml_buffer * buf)578 sml_period_entry * sml_period_entry_parse( sml_buffer * buf ) {
579 	return sml_period_entry_parse_( buf );
580 }
581 
sml_period_entry_write(sml_period_entry * period,sml_buffer * buf)582 void sml_period_entry_write(sml_period_entry *period, sml_buffer *buf) {
583 	if (period == 0) {
584 		sml_buf_optional_write(buf);
585 		return;
586 	}
587 
588 	sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 5);
589 
590 	sml_octet_string_write(period->obj_name, buf);
591 	sml_unit_write(period->unit, buf);
592 	sml_i8_write(period->scaler, buf);
593 	sml_value_write(period->value, buf);
594 	sml_octet_string_write(period->value_signature, buf);
595 }
596 
sml_period_entry_free_(void * p)597 static void sml_period_entry_free_( void * p ) {
598 	sml_period_entry * period = p;
599 
600 	if (period) {
601 		sml_octet_string_free(period->obj_name);
602 		sml_unit_free(period->unit);
603 		sml_number_free(period->scaler);
604 		sml_value_free(period->value);
605 		sml_octet_string_free(period->value_signature);
606 
607 		free(period);
608 	}
609 }
610 
sml_period_entry_free(sml_period_entry * period)611 void sml_period_entry_free( sml_period_entry * period ) {
612 	sml_period_entry_free_( period );
613 }
614