1 /*
2 * Balanced tree node functions
3 *
4 * Copyright (C) 2006-2020, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <memory.h>
24 #include <types.h>
25
26 #include "libcdata_array.h"
27 #include "libcdata_btree_node.h"
28 #include "libcdata_btree_values_list.h"
29 #include "libcdata_definitions.h"
30 #include "libcdata_libcerror.h"
31 #include "libcdata_list.h"
32 #include "libcdata_list_element.h"
33 #include "libcdata_tree_node.h"
34 #include "libcdata_types.h"
35
36 /* Retrieves the sub node for the specific value
37 *
38 * Uses the value_compare_function to determine the similarity of the entries
39 * The value_compare_function should return LIBCDATA_COMPARE_LESS,
40 * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error
41 *
42 * If value_compare_function is NULL the pointer of the value is used to check for a match
43 *
44 * Returns 1 if successful, 0 if the value does not exist or -1 on error
45 * If there was no possible sub match values_list_element is set to NULL
46 * it there is a possible sub match values_list_element is set but 0 is returned
47 * If the node is a leaf node sub_node is not set to NULL
48 */
libcdata_btree_node_get_sub_node_by_value(libcdata_tree_node_t * node,intptr_t * value,int (* value_compare_function)(intptr_t * first_value,intptr_t * second_value,libcerror_error_t ** error),libcdata_tree_node_t ** sub_node,libcdata_list_element_t ** values_list_element,libcerror_error_t ** error)49 int libcdata_btree_node_get_sub_node_by_value(
50 libcdata_tree_node_t *node,
51 intptr_t *value,
52 int (*value_compare_function)(
53 intptr_t *first_value,
54 intptr_t *second_value,
55 libcerror_error_t **error ),
56 libcdata_tree_node_t **sub_node,
57 libcdata_list_element_t **values_list_element,
58 libcerror_error_t **error )
59 {
60 libcdata_list_t *values_list = NULL;
61 libcdata_list_element_t *safe_values_list_element = NULL;
62 libcdata_tree_node_t *safe_sub_node = NULL;
63 intptr_t *values_list_value = NULL;
64 static char *function = "libcdata_btree_node_get_sub_node_by_value";
65 int number_of_sub_nodes = 0;
66 int number_of_values_list_elements = 0;
67 int result = 0;
68 int sub_node_index = 0;
69 int values_list_element_index = 0;
70
71 if( node == NULL )
72 {
73 libcerror_error_set(
74 error,
75 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
76 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
77 "%s: invalid node.",
78 function );
79
80 return( -1 );
81 }
82 if( value == NULL )
83 {
84 libcerror_error_set(
85 error,
86 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
87 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
88 "%s: invalid value.",
89 function );
90
91 return( -1 );
92 }
93 if( sub_node == NULL )
94 {
95 libcerror_error_set(
96 error,
97 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
98 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
99 "%s: invalid sub node.",
100 function );
101
102 return( -1 );
103 }
104 if( values_list_element == NULL )
105 {
106 libcerror_error_set(
107 error,
108 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
109 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
110 "%s: invalid values list element.",
111 function );
112
113 return( -1 );
114 }
115 *sub_node = NULL;
116 *values_list_element = NULL;
117
118 if( libcdata_tree_node_get_value(
119 node,
120 (intptr_t **) &values_list,
121 error ) != 1 )
122 {
123 libcerror_error_set(
124 error,
125 LIBCERROR_ERROR_DOMAIN_RUNTIME,
126 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
127 "%s: unable to retrieve values list.",
128 function );
129
130 return( -1 );
131 }
132 if( values_list != NULL )
133 {
134 if( libcdata_list_get_number_of_elements(
135 values_list,
136 &number_of_values_list_elements,
137 error ) != 1 )
138 {
139 libcerror_error_set(
140 error,
141 LIBCERROR_ERROR_DOMAIN_RUNTIME,
142 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
143 "%s: unable to retrieve number of values list elements.",
144 function );
145
146 return( -1 );
147 }
148 }
149 if( libcdata_tree_node_get_number_of_sub_nodes(
150 node,
151 &number_of_sub_nodes,
152 error ) != 1 )
153 {
154 libcerror_error_set(
155 error,
156 LIBCERROR_ERROR_DOMAIN_RUNTIME,
157 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
158 "%s: unable to retrieve number of sub nodes.",
159 function );
160
161 return( -1 );
162 }
163 if( ( number_of_sub_nodes != 0 )
164 && ( ( number_of_values_list_elements + 1 ) != number_of_sub_nodes ) )
165 {
166 libcerror_error_set(
167 error,
168 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
169 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
170 "%s: invalid number of values list elements value out of bounds.",
171 function );
172
173 return( -1 );
174 }
175 if( number_of_values_list_elements == 0 )
176 {
177 return( 0 );
178 }
179 if( libcdata_list_get_first_element(
180 values_list,
181 &safe_values_list_element,
182 error ) != 1 )
183 {
184 libcerror_error_set(
185 error,
186 LIBCERROR_ERROR_DOMAIN_RUNTIME,
187 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
188 "%s: unable to retrieve first values list element.",
189 function );
190
191 return( -1 );
192 }
193 if( number_of_sub_nodes != 0 )
194 {
195 if( libcdata_tree_node_get_sub_node_by_index(
196 node,
197 0,
198 &safe_sub_node,
199 error ) != 1 )
200 {
201 libcerror_error_set(
202 error,
203 LIBCERROR_ERROR_DOMAIN_RUNTIME,
204 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
205 "%s: unable to retrieve sub node: 0.",
206 function );
207
208 return( -1 );
209 }
210 }
211 for( values_list_element_index = 0;
212 values_list_element_index < number_of_values_list_elements;
213 values_list_element_index++ )
214 {
215 if( libcdata_list_element_get_value(
216 safe_values_list_element,
217 &values_list_value,
218 error ) != 1 )
219 {
220 libcerror_error_set(
221 error,
222 LIBCERROR_ERROR_DOMAIN_RUNTIME,
223 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
224 "%s: unable to retrieve value from values list element: %d.",
225 function,
226 values_list_element_index );
227
228 return( -1 );
229 }
230 if( values_list_value == NULL )
231 {
232 libcerror_error_set(
233 error,
234 LIBCERROR_ERROR_DOMAIN_RUNTIME,
235 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
236 "%s: invalid values list element: %d - missing value.",
237 function,
238 values_list_element_index );
239
240 return( -1 );
241 }
242 if( value_compare_function != NULL )
243 {
244 result = value_compare_function(
245 value,
246 values_list_value,
247 error );
248 }
249 else if( value == values_list_value )
250 {
251 result = LIBCDATA_COMPARE_EQUAL;
252 }
253 else
254 {
255 result = LIBCDATA_COMPARE_GREATER;
256 }
257 if( result == -1 )
258 {
259 libcerror_error_set(
260 error,
261 LIBCERROR_ERROR_DOMAIN_RUNTIME,
262 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
263 "%s: unable to compare value with values list value: %d.",
264 function,
265 values_list_element_index );
266
267 return( -1 );
268 }
269 else if( result == LIBCDATA_COMPARE_EQUAL )
270 {
271 *sub_node = safe_sub_node;
272 *values_list_element = safe_values_list_element;
273
274 return( 1 );
275 }
276 else if( result == LIBCDATA_COMPARE_LESS )
277 {
278 break;
279 }
280 else if( result != LIBCDATA_COMPARE_GREATER )
281 {
282 libcerror_error_set(
283 error,
284 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
285 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
286 "%s: unsupported value compare function return value: %d.",
287 function,
288 result );
289
290 return( -1 );
291 }
292 if( libcdata_list_element_get_next_element(
293 safe_values_list_element,
294 &safe_values_list_element,
295 error ) != 1 )
296 {
297 libcerror_error_set(
298 error,
299 LIBCERROR_ERROR_DOMAIN_RUNTIME,
300 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
301 "%s: unable to retrieve next element from values list element: %d.",
302 function,
303 values_list_element_index );
304
305 return( -1 );
306 }
307 if( number_of_sub_nodes != 0 )
308 {
309 if( libcdata_tree_node_get_next_node(
310 safe_sub_node,
311 &safe_sub_node,
312 error ) != 1 )
313 {
314 libcerror_error_set(
315 error,
316 LIBCERROR_ERROR_DOMAIN_RUNTIME,
317 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
318 "%s: unable to retrieve next node from sub node: %d.",
319 function,
320 sub_node_index );
321
322 return( -1 );
323 }
324 sub_node_index++;
325 }
326 }
327 *sub_node = safe_sub_node;
328 *values_list_element = safe_values_list_element;
329
330 return( 0 );
331 }
332
333 /* Retrieves the upper node for the specific value
334 *
335 * Uses the value_compare_function to determine the similarity of the entries
336 * The value_compare_function should return LIBCDATA_COMPARE_LESS,
337 * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error
338 *
339 * Returns 1 if successful, 0 if the value does not exist or -1 on error
340 */
libcdata_btree_node_get_upper_node_by_value(libcdata_tree_node_t * node,intptr_t * value,int (* value_compare_function)(intptr_t * first_value,intptr_t * second_value,libcerror_error_t ** error),libcdata_tree_node_t ** upper_node,libcdata_list_element_t ** values_list_element,libcerror_error_t ** error)341 int libcdata_btree_node_get_upper_node_by_value(
342 libcdata_tree_node_t *node,
343 intptr_t *value,
344 int (*value_compare_function)(
345 intptr_t *first_value,
346 intptr_t *second_value,
347 libcerror_error_t **error ),
348 libcdata_tree_node_t **upper_node,
349 libcdata_list_element_t **values_list_element,
350 libcerror_error_t **error )
351 {
352 libcdata_list_element_t *sub_values_list_element = NULL;
353 libcdata_tree_node_t *sub_node = NULL;
354 static char *function = "libcdata_btree_node_get_upper_node_by_value";
355 int result = 0;
356
357 if( node == NULL )
358 {
359 libcerror_error_set(
360 error,
361 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
362 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
363 "%s: invalid node.",
364 function );
365
366 return( -1 );
367 }
368 if( value == NULL )
369 {
370 libcerror_error_set(
371 error,
372 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
373 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
374 "%s: invalid value.",
375 function );
376
377 return( -1 );
378 }
379 if( value_compare_function == NULL )
380 {
381 libcerror_error_set(
382 error,
383 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
384 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
385 "%s: invalid value compare function.",
386 function );
387
388 return( -1 );
389 }
390 if( upper_node == NULL )
391 {
392 libcerror_error_set(
393 error,
394 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
395 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
396 "%s: invalid upper node.",
397 function );
398
399 return( -1 );
400 }
401 if( values_list_element == NULL )
402 {
403 libcerror_error_set(
404 error,
405 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
406 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
407 "%s: invalid values list element.",
408 function );
409
410 return( -1 );
411 }
412 *upper_node = NULL;
413 *values_list_element = NULL;
414
415 result = libcdata_btree_node_get_sub_node_by_value(
416 node,
417 value,
418 value_compare_function,
419 &sub_node,
420 &sub_values_list_element,
421 error );
422
423 if( result == -1 )
424 {
425 libcerror_error_set(
426 error,
427 LIBCERROR_ERROR_DOMAIN_RUNTIME,
428 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
429 "%s: unable to retrieve sub node by value.",
430 function );
431
432 return( -1 );
433 }
434 else if( sub_node != NULL )
435 {
436 result = libcdata_btree_node_get_upper_node_by_value(
437 sub_node,
438 value,
439 value_compare_function,
440 upper_node,
441 values_list_element,
442 error );
443
444 if( result == -1 )
445 {
446 libcerror_error_set(
447 error,
448 LIBCERROR_ERROR_DOMAIN_RUNTIME,
449 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
450 "%s: unable to retrieve upper node in sub node.",
451 function );
452
453 return( -1 );
454 }
455 }
456 else if( result != 0 )
457 {
458 *values_list_element = sub_values_list_element;
459 }
460 if( *upper_node == NULL )
461 {
462 *upper_node = node;
463 }
464 return( result );
465 }
466
467 /* Appends a value into a tree node
468 * Returns 1 if successful or -1 on error
469 */
libcdata_btree_node_append_value(libcdata_tree_node_t * node,intptr_t * value,libcerror_error_t ** error)470 int libcdata_btree_node_append_value(
471 libcdata_tree_node_t *node,
472 intptr_t *value,
473 libcerror_error_t **error )
474 {
475 libcdata_list_t *values_list = NULL;
476 static char *function = "libcdata_btree_node_append_value";
477
478 if( libcdata_tree_node_get_value(
479 node,
480 (intptr_t **) &values_list,
481 error ) != 1 )
482 {
483 libcerror_error_set(
484 error,
485 LIBCERROR_ERROR_DOMAIN_RUNTIME,
486 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
487 "%s: unable to retrieve values list.",
488 function );
489
490 return( -1 );
491 }
492 if( values_list == NULL )
493 {
494 if( libcdata_list_initialize(
495 &values_list,
496 error ) != 1 )
497 {
498 libcerror_error_set(
499 error,
500 LIBCERROR_ERROR_DOMAIN_RUNTIME,
501 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
502 "%s: unable to create values list.",
503 function );
504
505 return( -1 );
506 }
507 if( libcdata_tree_node_set_value(
508 node,
509 (intptr_t *) values_list,
510 error ) != 1 )
511 {
512 libcerror_error_set(
513 error,
514 LIBCERROR_ERROR_DOMAIN_RUNTIME,
515 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
516 "%s: unable to set values list.",
517 function );
518
519 libcdata_list_free(
520 &values_list,
521 NULL,
522 NULL );
523
524 return( -1 );
525 }
526 }
527 if( libcdata_list_append_value(
528 values_list,
529 value,
530 error ) != 1 )
531 {
532 libcerror_error_set(
533 error,
534 LIBCERROR_ERROR_DOMAIN_RUNTIME,
535 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
536 "%s: unable to append value to values list.",
537 function );
538
539 return( -1 );
540 }
541 return( 1 );
542 }
543
544 /* Inserts a value into a tree node
545 * The tree node must be the most upper node (leaf)
546 *
547 * Uses the value_compare_function to determine the order of the entries
548 * The value_compare_function should return LIBCDATA_COMPARE_LESS,
549 * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error
550 *
551 * Returns 1 if successful, 0 if the value already exists or -1 on error
552 */
libcdata_btree_node_insert_value(libcdata_tree_node_t * node,intptr_t * value,int (* value_compare_function)(intptr_t * first_value,intptr_t * second_value,libcerror_error_t ** error),libcerror_error_t ** error)553 int libcdata_btree_node_insert_value(
554 libcdata_tree_node_t *node,
555 intptr_t *value,
556 int (*value_compare_function)(
557 intptr_t *first_value,
558 intptr_t *second_value,
559 libcerror_error_t **error ),
560 libcerror_error_t **error )
561 {
562 libcdata_list_t *values_list = NULL;
563 static char *function = "libcdata_btree_node_insert_value";
564 int number_of_sub_nodes = 0;
565 int result = 0;
566
567 if( libcdata_tree_node_get_number_of_sub_nodes(
568 node,
569 &number_of_sub_nodes,
570 error ) != 1 )
571 {
572 libcerror_error_set(
573 error,
574 LIBCERROR_ERROR_DOMAIN_RUNTIME,
575 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
576 "%s: unable to retrieve number of sub nodes.",
577 function );
578
579 return( -1 );
580 }
581 if( number_of_sub_nodes != 0 )
582 {
583 libcerror_error_set(
584 error,
585 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
586 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
587 "%s: cannot insert value in node with sub nodes.",
588 function );
589
590 return( -1 );
591 }
592 if( libcdata_tree_node_get_value(
593 node,
594 (intptr_t **) &values_list,
595 error ) != 1 )
596 {
597 libcerror_error_set(
598 error,
599 LIBCERROR_ERROR_DOMAIN_RUNTIME,
600 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
601 "%s: unable to retrieve values list.",
602 function );
603
604 return( -1 );
605 }
606 if( values_list == NULL )
607 {
608 if( libcdata_list_initialize(
609 &values_list,
610 error ) != 1 )
611 {
612 libcerror_error_set(
613 error,
614 LIBCERROR_ERROR_DOMAIN_RUNTIME,
615 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
616 "%s: unable to create values list.",
617 function );
618
619 return( -1 );
620 }
621 if( libcdata_tree_node_set_value(
622 node,
623 (intptr_t *) values_list,
624 error ) != 1 )
625 {
626 libcerror_error_set(
627 error,
628 LIBCERROR_ERROR_DOMAIN_RUNTIME,
629 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
630 "%s: unable to set values list.",
631 function );
632
633 libcdata_list_free(
634 &values_list,
635 NULL,
636 NULL );
637
638 return( -1 );
639 }
640 }
641 result = libcdata_list_insert_value(
642 values_list,
643 value,
644 value_compare_function,
645 LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES,
646 error );
647
648 if( result == -1 )
649 {
650 libcerror_error_set(
651 error,
652 LIBCERROR_ERROR_DOMAIN_RUNTIME,
653 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
654 "%s: unable to insert value in values list.",
655 function );
656
657 return( -1 );
658 }
659 return( result );
660 }
661
662 /* Replaces a value in the tree node
663 * The tree node must be the most upper node (leaf) in the first call
664 * Returns 1 if successful or -1 on error
665 */
libcdata_btree_node_replace_value(libcdata_tree_node_t * node,intptr_t * value,intptr_t * replacement_value,libcerror_error_t ** error)666 int libcdata_btree_node_replace_value(
667 libcdata_tree_node_t *node,
668 intptr_t *value,
669 intptr_t *replacement_value,
670 libcerror_error_t **error )
671 {
672 libcdata_list_element_t *values_list_element = NULL;
673 libcdata_tree_node_t *parent_node = NULL;
674 libcdata_tree_node_t *sub_node = NULL;
675 static char *function = "libcdata_btree_node_replace_value";
676 int result = 0;
677
678 if( value == NULL )
679 {
680 libcerror_error_set(
681 error,
682 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
683 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
684 "%s: invalid value.",
685 function );
686
687 return( -1 );
688 }
689 if( replacement_value == NULL )
690 {
691 libcerror_error_set(
692 error,
693 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
694 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
695 "%s: invalid replacement value.",
696 function );
697
698 return( -1 );
699 }
700 result = libcdata_btree_node_get_sub_node_by_value(
701 node,
702 value,
703 NULL,
704 &sub_node,
705 &values_list_element,
706 error );
707
708 if( result == -1 )
709 {
710 libcerror_error_set(
711 error,
712 LIBCERROR_ERROR_DOMAIN_RUNTIME,
713 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
714 "%s: unable to retrieve sub node by value.",
715 function );
716
717 return( -1 );
718 }
719 else if( result != 0 )
720 {
721 if( libcdata_list_element_set_value(
722 values_list_element,
723 replacement_value,
724 error ) != 1 )
725 {
726 libcerror_error_set(
727 error,
728 LIBCERROR_ERROR_DOMAIN_RUNTIME,
729 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
730 "%s: unable to set value in values list element.",
731 function );
732
733 return( -1 );
734 }
735 }
736 if( libcdata_tree_node_get_parent_node(
737 node,
738 &parent_node,
739 error ) != 1 )
740 {
741 libcerror_error_set(
742 error,
743 LIBCERROR_ERROR_DOMAIN_RUNTIME,
744 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
745 "%s: unable to retrieve parent node.",
746 function );
747
748 return( -1 );
749 }
750 if( parent_node != NULL )
751 {
752 if( libcdata_btree_node_replace_value(
753 parent_node,
754 value,
755 replacement_value,
756 error ) != 1 )
757 {
758 libcerror_error_set(
759 error,
760 LIBCERROR_ERROR_DOMAIN_RUNTIME,
761 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
762 "%s: unable to replace value in parent node.",
763 function );
764
765 return( -1 );
766 }
767 }
768 return( 1 );
769 }
770
771 /* Flattens a tree node and its sub node
772 * Returns 1 if successful or -1 on error
773 */
libcdata_btree_node_flatten_node(libcdata_tree_node_t ** node,libcerror_error_t ** error)774 int libcdata_btree_node_flatten_node(
775 libcdata_tree_node_t **node,
776 libcerror_error_t **error )
777 {
778 libcdata_tree_node_t *sub_node = NULL;
779 static char *function = "libcdata_btree_node_flatten_node";
780
781 if( node == NULL )
782 {
783 libcerror_error_set(
784 error,
785 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
786 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
787 "%s: invalid node.",
788 function );
789
790 return( -1 );
791 }
792 if( libcdata_tree_node_get_first_sub_node(
793 *node,
794 &sub_node,
795 error ) != 1 )
796 {
797 libcerror_error_set(
798 error,
799 LIBCERROR_ERROR_DOMAIN_RUNTIME,
800 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
801 "%s: unable to retrieve first sub node.",
802 function );
803
804 return( -1 );
805 }
806 if( libcdata_tree_node_remove_node(
807 *node,
808 sub_node,
809 error ) != 1 )
810 {
811 libcerror_error_set(
812 error,
813 LIBCERROR_ERROR_DOMAIN_RUNTIME,
814 LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
815 "%s: unable to remove sub node from node.",
816 function );
817
818 return( -1 );
819 }
820 if( libcdata_tree_node_replace_node(
821 *node,
822 sub_node,
823 error ) != 1 )
824 {
825 libcerror_error_set(
826 error,
827 LIBCERROR_ERROR_DOMAIN_RUNTIME,
828 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
829 "%s: unable to replace node with sub node.",
830 function );
831
832 libcdata_tree_node_append_node(
833 *node,
834 sub_node,
835 NULL );
836
837 return( -1 );
838 }
839 if( libcdata_tree_node_free(
840 node,
841 (int (*)(intptr_t **, libcerror_error_t **)) &libcdata_btree_values_list_free,
842 error ) != 1 )
843 {
844 libcerror_error_set(
845 error,
846 LIBCERROR_ERROR_DOMAIN_RUNTIME,
847 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
848 "%s: unable to free node.",
849 function );
850
851 return( -1 );
852 }
853 *node = sub_node;
854
855 return( 1 );
856 }
857
858 /* Removes a sub node from the B-tree node
859 * Returns 1 if successful or -1 on error
860 */
libcdata_btree_node_remove_sub_node(libcdata_tree_node_t * node,libcdata_tree_node_t ** sub_node,libcerror_error_t ** error)861 int libcdata_btree_node_remove_sub_node(
862 libcdata_tree_node_t *node,
863 libcdata_tree_node_t **sub_node,
864 libcerror_error_t **error )
865 {
866 static char *function = "libcdata_btree_node_remove_sub_node";
867
868 if( node == NULL )
869 {
870 libcerror_error_set(
871 error,
872 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
873 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
874 "%s: invalid node.",
875 function );
876
877 return( -1 );
878 }
879 if( sub_node == NULL )
880 {
881 libcerror_error_set(
882 error,
883 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
884 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
885 "%s: invalid sub node.",
886 function );
887
888 return( -1 );
889 }
890 if( libcdata_tree_node_remove_node(
891 node,
892 *sub_node,
893 error ) != 1 )
894 {
895 libcerror_error_set(
896 error,
897 LIBCERROR_ERROR_DOMAIN_RUNTIME,
898 LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
899 "%s: unable to remove sub node from node.",
900 function );
901
902 return( -1 );
903 }
904 if( libcdata_tree_node_free(
905 sub_node,
906 (int (*)(intptr_t **, libcerror_error_t **)) &libcdata_btree_values_list_free,
907 error ) != 1 )
908 {
909 libcerror_error_set(
910 error,
911 LIBCERROR_ERROR_DOMAIN_RUNTIME,
912 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
913 "%s: unable to free sub node.",
914 function );
915
916 return( -1 );
917 }
918 return( 1 );
919 }
920
921 /* Removes a value from the tree node
922 * The tree node must be the most upper node (leaf) in the first call
923 * Returns 1 if successful, 0 if no such value or -1 on error
924 */
libcdata_btree_node_remove_value(libcdata_tree_node_t * node,intptr_t * value,intptr_t * replacement_value,libcerror_error_t ** error)925 int libcdata_btree_node_remove_value(
926 libcdata_tree_node_t *node,
927 intptr_t *value,
928 intptr_t *replacement_value,
929 libcerror_error_t **error )
930 {
931 libcdata_list_t *sub_node_values_list = NULL;
932 libcdata_list_t *values_list = NULL;
933 libcdata_list_element_t *values_list_element = NULL;
934 libcdata_tree_node_t *parent_node = NULL;
935 libcdata_tree_node_t *sub_node = NULL;
936 static char *function = "libcdata_btree_node_remove_value";
937 int number_of_sub_nodes = 0;
938 int number_of_values_list_elements = 0;
939 int result = 0;
940 int sub_node_number_of_sub_nodes = 0;
941 int sub_node_number_of_values_list_elements = 0;
942
943 if( value == NULL )
944 {
945 libcerror_error_set(
946 error,
947 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
948 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
949 "%s: invalid value.",
950 function );
951
952 return( -1 );
953 }
954 result = libcdata_btree_node_get_sub_node_by_value(
955 node,
956 value,
957 NULL,
958 &sub_node,
959 &values_list_element,
960 error );
961
962 if( result == -1 )
963 {
964 libcerror_error_set(
965 error,
966 LIBCERROR_ERROR_DOMAIN_RUNTIME,
967 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
968 "%s: unable to retrieve sub node by value.",
969 function );
970
971 return( -1 );
972 }
973 if( libcdata_tree_node_get_value(
974 node,
975 (intptr_t **) &values_list,
976 error ) != 1 )
977 {
978 libcerror_error_set(
979 error,
980 LIBCERROR_ERROR_DOMAIN_RUNTIME,
981 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
982 "%s: unable to retrieve values list.",
983 function );
984
985 return( -1 );
986 }
987 if( libcdata_list_get_number_of_elements(
988 values_list,
989 &number_of_values_list_elements,
990 error ) != 1 )
991 {
992 libcerror_error_set(
993 error,
994 LIBCERROR_ERROR_DOMAIN_RUNTIME,
995 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
996 "%s: unable to retrieve number of values list elements.",
997 function );
998
999 return( -1 );
1000 }
1001 if( libcdata_tree_node_get_number_of_sub_nodes(
1002 node,
1003 &number_of_sub_nodes,
1004 error ) != 1 )
1005 {
1006 libcerror_error_set(
1007 error,
1008 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1009 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1010 "%s: unable to retrieve number of sub nodes.",
1011 function );
1012
1013 return( -1 );
1014 }
1015 if( sub_node != NULL )
1016 {
1017 if( libcdata_tree_node_get_value(
1018 sub_node,
1019 (intptr_t **) &sub_node_values_list,
1020 error ) != 1 )
1021 {
1022 libcerror_error_set(
1023 error,
1024 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1025 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1026 "%s: unable to retrieve sub node values list.",
1027 function );
1028
1029 return( -1 );
1030 }
1031 if( libcdata_list_get_number_of_elements(
1032 sub_node_values_list,
1033 &sub_node_number_of_values_list_elements,
1034 error ) != 1 )
1035 {
1036 libcerror_error_set(
1037 error,
1038 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1039 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1040 "%s: unable to retrieve sub node number of values list elements.",
1041 function );
1042
1043 return( -1 );
1044 }
1045 if( libcdata_tree_node_get_number_of_sub_nodes(
1046 sub_node,
1047 &sub_node_number_of_sub_nodes,
1048 error ) != 1 )
1049 {
1050 libcerror_error_set(
1051 error,
1052 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1053 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1054 "%s: unable to retrieve number of sub nodes.",
1055 function );
1056
1057 return( -1 );
1058 }
1059 /* If the sub node is empty remove it
1060 */
1061 if( ( sub_node_number_of_sub_nodes == 0 )
1062 && ( sub_node_number_of_values_list_elements == 0 ) )
1063 {
1064 if( libcdata_btree_node_remove_sub_node(
1065 node,
1066 &sub_node,
1067 error ) != 1 )
1068 {
1069 libcerror_error_set(
1070 error,
1071 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1072 LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
1073 "%s: unable to remove remaining sub node from node.",
1074 function );
1075
1076 return( -1 );
1077 }
1078 if( libcdata_tree_node_get_number_of_sub_nodes(
1079 node,
1080 &number_of_sub_nodes,
1081 error ) != 1 )
1082 {
1083 libcerror_error_set(
1084 error,
1085 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1086 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1087 "%s: unable to retrieve number of sub nodes.",
1088 function );
1089
1090 return( -1 );
1091 }
1092 if( values_list_element == NULL )
1093 {
1094 if( libcdata_list_get_last_element(
1095 values_list,
1096 &values_list_element,
1097 error ) != 1 )
1098 {
1099 libcerror_error_set(
1100 error,
1101 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1102 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1103 "%s: unable to retrieve last values list element.",
1104 function );
1105
1106 return( -1 );
1107 }
1108 if( libcdata_list_element_get_value(
1109 values_list_element,
1110 &replacement_value,
1111 error ) != 1 )
1112 {
1113 libcerror_error_set(
1114 error,
1115 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1116 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1117 "%s: unable to retrieve value from last values list element.",
1118 function );
1119
1120 return( -1 );
1121 }
1122 }
1123 if( values_list_element != NULL )
1124 {
1125 if( libcdata_btree_values_list_remove_element(
1126 values_list,
1127 &values_list_element,
1128 error ) != 1 )
1129 {
1130 libcerror_error_set(
1131 error,
1132 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1133 LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
1134 "%s: unable to remove element from values list.",
1135 function );
1136
1137 return( -1 );
1138 }
1139 if( libcdata_list_get_number_of_elements(
1140 values_list,
1141 &number_of_values_list_elements,
1142 error ) != 1 )
1143 {
1144 libcerror_error_set(
1145 error,
1146 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1147 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1148 "%s: unable to retrieve number of values list elements.",
1149 function );
1150
1151 return( -1 );
1152 }
1153 }
1154 }
1155 }
1156 if( number_of_sub_nodes != 0 )
1157 {
1158 if( ( number_of_values_list_elements + 1 ) != number_of_sub_nodes )
1159 {
1160 libcerror_error_set(
1161 error,
1162 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1163 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1164 "%s: invalid number of values list elements value out of bounds.",
1165 function );
1166
1167 return( -1 );
1168 }
1169 /* If one sub node remains flatten the node
1170 */
1171 if( number_of_sub_nodes == 1 )
1172 {
1173 if( libcdata_btree_node_flatten_node(
1174 &node,
1175 error ) != 1 )
1176 {
1177 libcerror_error_set(
1178 error,
1179 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1180 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1181 "%s: unable to flatten node.",
1182 function );
1183
1184 return( -1 );
1185 }
1186 if( libcdata_tree_node_get_value(
1187 node,
1188 (intptr_t **) &values_list,
1189 error ) != 1 )
1190 {
1191 libcerror_error_set(
1192 error,
1193 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1194 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1195 "%s: unable to retrieve values list.",
1196 function );
1197
1198 return( -1 );
1199 }
1200 }
1201 /* If the sub node contains more than one values list elements
1202 * use the replacement value determined in the sub node
1203 */
1204 else if( values_list_element != NULL )
1205 {
1206 if( replacement_value == NULL )
1207 {
1208 libcerror_error_set(
1209 error,
1210 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1211 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1212 "%s: invalid replacement value.",
1213 function );
1214
1215 return( -1 );
1216 }
1217 if( libcdata_list_element_set_value(
1218 values_list_element,
1219 replacement_value,
1220 error ) != 1 )
1221 {
1222 libcerror_error_set(
1223 error,
1224 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1225 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1226 "%s: unable to set value in values list element.",
1227 function );
1228
1229 return( -1 );
1230 }
1231 }
1232 }
1233 /* In a leaf node remove the values list element from the list
1234 */
1235 else if( values_list_element != NULL )
1236 {
1237 if( libcdata_btree_values_list_replace_element_with_previous(
1238 values_list,
1239 &values_list_element,
1240 &replacement_value,
1241 error ) != 1 )
1242 {
1243 libcerror_error_set(
1244 error,
1245 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1246 LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
1247 "%s: unable to replace values list element with previous.",
1248 function );
1249
1250 return( -1 );
1251 }
1252 }
1253 if( libcdata_tree_node_get_parent_node(
1254 node,
1255 &parent_node,
1256 error ) != 1 )
1257 {
1258 libcerror_error_set(
1259 error,
1260 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1261 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1262 "%s: unable to retrieve parent node.",
1263 function );
1264
1265 return( -1 );
1266 }
1267 if( parent_node != NULL )
1268 {
1269 if( libcdata_btree_node_remove_value(
1270 parent_node,
1271 value,
1272 replacement_value,
1273 error ) == -1 )
1274 {
1275 libcerror_error_set(
1276 error,
1277 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1278 LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
1279 "%s: unable to remove value from parent node.",
1280 function );
1281
1282 return( -1 );
1283 }
1284 }
1285 return( result );
1286 }
1287
1288 /* Splits the node
1289 * Returns 1 if successful or -1 on error
1290 */
libcdata_btree_node_split(libcdata_tree_node_t * node,libcerror_error_t ** error)1291 int libcdata_btree_node_split(
1292 libcdata_tree_node_t *node,
1293 libcerror_error_t **error )
1294 {
1295 libcdata_list_t *split_values_list = NULL;
1296 libcdata_list_t *values_list = NULL;
1297 libcdata_list_element_t *values_list_element = NULL;
1298 libcdata_tree_node_t *sub_node = NULL;
1299 intptr_t *values_list_value = NULL;
1300 static char *function = "libcdata_btree_node_split";
1301 int number_of_split_values_list_elements = 0;
1302 int number_of_sub_nodes = 0;
1303 int number_of_values_list_elements = 0;
1304 int split_values_list_element_index = 0;
1305 int sub_node_index = 0;
1306 int values_list_element_index = 0;
1307
1308 if( node == NULL )
1309 {
1310 libcerror_error_set(
1311 error,
1312 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1313 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1314 "%s: invalid node.",
1315 function );
1316
1317 return( -1 );
1318 }
1319 if( libcdata_tree_node_get_number_of_sub_nodes(
1320 node,
1321 &number_of_sub_nodes,
1322 error ) != 1 )
1323 {
1324 libcerror_error_set(
1325 error,
1326 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1327 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1328 "%s: unable to retrieve number of sub nodes.",
1329 function );
1330
1331 goto on_error;
1332 }
1333 if( number_of_sub_nodes != 0 )
1334 {
1335 libcerror_error_set(
1336 error,
1337 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1338 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1339 "%s: cannot split node with sub nodes.",
1340 function );
1341
1342 goto on_error;
1343 }
1344 if( libcdata_tree_node_get_value(
1345 node,
1346 (intptr_t **) &values_list,
1347 error ) != 1 )
1348 {
1349 libcerror_error_set(
1350 error,
1351 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1352 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1353 "%s: unable to retrieve values list.",
1354 function );
1355
1356 goto on_error;
1357 }
1358 /* Split to have about 25 values per sub node
1359 */
1360 number_of_split_values_list_elements = 25;
1361
1362 if( libcdata_list_initialize(
1363 &split_values_list,
1364 error ) != 1 )
1365 {
1366 libcerror_error_set(
1367 error,
1368 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1369 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1370 "%s: unable to create split values list.",
1371 function );
1372
1373 goto on_error;
1374 }
1375 if( libcdata_tree_node_set_value(
1376 node,
1377 (intptr_t *) split_values_list,
1378 error ) != 1 )
1379 {
1380 libcerror_error_set(
1381 error,
1382 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1383 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1384 "%s: unable to set split values list.",
1385 function );
1386
1387 goto on_error;
1388 }
1389 if( libcdata_list_get_number_of_elements(
1390 values_list,
1391 &number_of_values_list_elements,
1392 error ) != 1 )
1393 {
1394 libcerror_error_set(
1395 error,
1396 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1397 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1398 "%s: unable to retrieve number of values list elements.",
1399 function );
1400
1401 goto on_error;
1402 }
1403 if( libcdata_list_get_first_element(
1404 values_list,
1405 &values_list_element,
1406 error ) != 1 )
1407 {
1408 libcerror_error_set(
1409 error,
1410 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1411 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1412 "%s: unable to retrieve first values list element.",
1413 function );
1414
1415 goto on_error;
1416 }
1417 for( values_list_element_index = 0;
1418 values_list_element_index < number_of_values_list_elements;
1419 values_list_element_index++ )
1420 {
1421 if( libcdata_list_element_get_value(
1422 values_list_element,
1423 &values_list_value,
1424 error ) != 1 )
1425 {
1426 libcerror_error_set(
1427 error,
1428 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1429 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1430 "%s: unable to retrieve value from values list element: %d.",
1431 function,
1432 values_list_element_index );
1433
1434 goto on_error;
1435 }
1436 if( values_list_value == NULL )
1437 {
1438 libcerror_error_set(
1439 error,
1440 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1441 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1442 "%s: invalid values list element: %d - missing value.",
1443 function,
1444 values_list_element_index );
1445
1446 goto on_error;
1447 }
1448 if( sub_node == NULL )
1449 {
1450 if( libcdata_tree_node_initialize(
1451 &sub_node,
1452 error ) != 1 )
1453 {
1454 libcerror_error_set(
1455 error,
1456 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1457 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1458 "%s: unable to create sub node: %d.",
1459 function,
1460 sub_node_index );
1461
1462 goto on_error;
1463 }
1464 }
1465 if( libcdata_btree_node_append_value(
1466 sub_node,
1467 values_list_value,
1468 error ) != 1 )
1469 {
1470 libcerror_error_set(
1471 error,
1472 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1473 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1474 "%s: unable to append value: %d to sub node: %d.",
1475 function,
1476 values_list_element_index,
1477 sub_node_index );
1478
1479 goto on_error;
1480 }
1481 if( values_list_element_index >= split_values_list_element_index )
1482 {
1483 if( ( values_list_element_index + 1 ) < number_of_values_list_elements )
1484 {
1485 if( libcdata_list_append_value(
1486 split_values_list,
1487 values_list_value,
1488 error ) != 1 )
1489 {
1490 libcerror_error_set(
1491 error,
1492 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1493 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1494 "%s: unable to append value: %d to sub nodes values list.",
1495 function,
1496 values_list_element_index );
1497
1498 goto on_error;
1499 }
1500 }
1501 split_values_list_element_index += number_of_split_values_list_elements;
1502
1503 if( libcdata_tree_node_append_node(
1504 node,
1505 sub_node,
1506 error ) != 1 )
1507 {
1508 libcerror_error_set(
1509 error,
1510 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1511 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1512 "%s: unable to append sub node: %d to node.",
1513 function,
1514 sub_node_index );
1515
1516 goto on_error;
1517 }
1518 sub_node = NULL;
1519
1520 sub_node_index++;
1521 }
1522 if( libcdata_list_element_get_next_element(
1523 values_list_element,
1524 &values_list_element,
1525 error ) != 1 )
1526 {
1527 libcerror_error_set(
1528 error,
1529 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1530 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1531 "%s: unable to retrieve next element from values list element: %d.",
1532 function,
1533 values_list_element_index );
1534
1535 goto on_error;
1536 }
1537 }
1538 if( sub_node != NULL )
1539 {
1540 if( libcdata_tree_node_append_node(
1541 node,
1542 sub_node,
1543 error ) != 1 )
1544 {
1545 libcerror_error_set(
1546 error,
1547 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1548 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1549 "%s: unable to append sub node: %d to node.",
1550 function,
1551 sub_node_index );
1552
1553 goto on_error;
1554 }
1555 sub_node = NULL;
1556
1557 sub_node_index++;
1558 }
1559 split_values_list = NULL;
1560
1561 if( libcdata_list_free(
1562 &values_list,
1563 NULL,
1564 error ) != 1 )
1565 {
1566 libcerror_error_set(
1567 error,
1568 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1569 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1570 "%s: unable to free values list.",
1571 function );
1572
1573 goto on_error;
1574 }
1575 return( 1 );
1576
1577 on_error:
1578 if( sub_node != NULL )
1579 {
1580 libcdata_tree_node_remove_node(
1581 node,
1582 sub_node,
1583 NULL );
1584 libcdata_tree_node_free(
1585 &sub_node,
1586 NULL,
1587 NULL );
1588 }
1589 if( split_values_list != NULL )
1590 {
1591 libcdata_tree_node_empty(
1592 node,
1593 NULL,
1594 NULL );
1595 libcdata_tree_node_set_value(
1596 node,
1597 (intptr_t *) values_list,
1598 NULL );
1599 libcdata_list_free(
1600 &split_values_list,
1601 NULL,
1602 NULL );
1603 }
1604 return( -1 );
1605 }
1606
1607
1608