Coverage Report

Created: 2024-02-25 07:20

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