Coverage Report

Created: 2024-02-25 07:20

/src/libmsiecf/libcdata/libcdata_range_list.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Range list
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_definitions.h"
27
#include "libcdata_libcerror.h"
28
#include "libcdata_libcthreads.h"
29
#include "libcdata_list_element.h"
30
#include "libcdata_range_list.h"
31
#include "libcdata_range_list_value.h"
32
#include "libcdata_types.h"
33
#include "libcdata_unused.h"
34
35
/* Creates a range list
36
 * Make sure the value range_list is referencing, is set to NULL
37
 * Returns 1 if successful or -1 on error
38
 */
39
int libcdata_range_list_initialize(
40
     libcdata_range_list_t **range_list,
41
     libcerror_error_t **error )
42
24.5M
{
43
24.5M
  libcdata_internal_range_list_t *internal_range_list = NULL;
44
24.5M
  static char *function                               = "libcdata_range_list_initialize";
45
46
24.5M
  if( range_list == NULL )
47
0
  {
48
0
    libcerror_error_set(
49
0
     error,
50
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
51
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
52
0
     "%s: invalid range list.",
53
0
     function );
54
55
0
    return( -1 );
56
0
  }
57
24.5M
  if( *range_list != NULL )
58
0
  {
59
0
    libcerror_error_set(
60
0
     error,
61
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
62
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
63
0
     "%s: invalid range list value already set.",
64
0
     function );
65
66
0
    return( -1 );
67
0
  }
68
24.5M
  internal_range_list = memory_allocate_structure(
69
24.5M
                         libcdata_internal_range_list_t );
70
71
24.5M
  if( internal_range_list == NULL )
72
0
  {
73
0
    libcerror_error_set(
74
0
     error,
75
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
76
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
77
0
     "%s: unable to create range list.",
78
0
     function );
79
80
0
    goto on_error;
81
0
  }
82
24.5M
  if( memory_set(
83
24.5M
       internal_range_list,
84
24.5M
       0,
85
24.5M
       sizeof( libcdata_internal_range_list_t ) ) == NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
90
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
91
0
     "%s: unable to clear range list.",
92
0
     function );
93
94
0
    memory_free(
95
0
     internal_range_list );
96
97
0
    return( -1 );
98
0
  }
99
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
100
  if( libcthreads_read_write_lock_initialize(
101
       &( internal_range_list->read_write_lock ),
102
       error ) != 1 )
103
  {
104
    libcerror_error_set(
105
     error,
106
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
107
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
108
     "%s: unable to initialize read/write lock.",
109
     function );
110
111
    goto on_error;
112
  }
113
#endif
114
24.5M
  *range_list = (libcdata_range_list_t *) internal_range_list;
115
116
24.5M
  return( 1 );
117
118
0
on_error:
119
0
  if( internal_range_list != NULL )
120
0
  {
121
0
    memory_free(
122
0
     internal_range_list );
123
0
  }
124
0
  return( -1 );
125
24.5M
}
126
127
/* Frees a range list including the elements
128
 * Uses the value_free_function to free the element value
129
 * Returns 1 if successful or -1 on error
130
 */
131
int libcdata_range_list_free(
132
     libcdata_range_list_t **range_list,
133
     int (*value_free_function)(
134
            intptr_t **value,
135
            libcerror_error_t **error ),
136
     libcerror_error_t **error )
137
24.5M
{
138
24.5M
  libcdata_internal_range_list_t *internal_range_list = NULL;
139
24.5M
  static char *function                               = "libcdata_range_list_free";
140
24.5M
  int result                                          = 1;
141
142
24.5M
  if( range_list == NULL )
143
0
  {
144
0
    libcerror_error_set(
145
0
     error,
146
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
147
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
148
0
     "%s: invalid range list.",
149
0
     function );
150
151
0
    return( -1 );
152
0
  }
153
24.5M
  if( *range_list != NULL )
154
24.5M
  {
155
24.5M
    internal_range_list = (libcdata_internal_range_list_t *) *range_list;
156
24.5M
    *range_list         = NULL;
157
158
24.5M
    if( libcdata_range_list_empty(
159
24.5M
         (libcdata_range_list_t *) internal_range_list,
160
24.5M
         value_free_function,
161
24.5M
         error ) != 1 )
162
0
    {
163
0
      libcerror_error_set(
164
0
       error,
165
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
166
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
167
0
       "%s: unable to empty range list.",
168
0
       function );
169
170
0
      result = -1;
171
0
    }
172
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
173
    if( libcthreads_read_write_lock_free(
174
         &( internal_range_list->read_write_lock ),
175
         error ) != 1 )
176
    {
177
      libcerror_error_set(
178
       error,
179
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
180
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
181
       "%s: unable to free read/write lock.",
182
       function );
183
184
      result = -1;
185
    }
186
#endif
187
24.5M
    memory_free(
188
24.5M
     internal_range_list );
189
24.5M
  }
190
24.5M
  return( result );
191
24.5M
}
192
193
/* Frees a range list element
194
 * Uses the value_free_function to free the element value
195
 * Returns 1 if successful or -1 on error
196
 */
197
int libcdata_internal_range_list_free_element(
198
     libcdata_internal_range_list_t *internal_range_list,
199
     libcdata_list_element_t **range_list_element,
200
     int (*value_free_function)(
201
            intptr_t **value,
202
            libcerror_error_t **error ),
203
     libcerror_error_t **error )
204
24.4M
{
205
24.4M
  libcdata_range_list_value_t *range_list_value = NULL;
206
24.4M
  static char *function                         = "libcdata_internal_range_list_free_element";
207
24.4M
  int result                                    = 1;
208
209
24.4M
  if( internal_range_list == NULL )
210
0
  {
211
0
    libcerror_error_set(
212
0
     error,
213
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
214
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
215
0
     "%s: invalid range list.",
216
0
     function );
217
218
0
    return( -1 );
219
0
  }
220
24.4M
  if( range_list_element == NULL )
221
0
  {
222
0
    libcerror_error_set(
223
0
     error,
224
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
225
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
226
0
     "%s: invalid range list element.",
227
0
     function );
228
229
0
    return( -1 );
230
0
  }
231
24.4M
  if( *range_list_element != NULL )
232
24.4M
  {
233
24.4M
    if( libcdata_list_element_get_value(
234
24.4M
         *range_list_element,
235
24.4M
         (intptr_t **) &range_list_value,
236
24.4M
         error ) != 1 )
237
0
    {
238
0
      libcerror_error_set(
239
0
       error,
240
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
241
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
242
0
       "%s: unable to retrieve value from range list element.",
243
0
       function );
244
245
0
      return( -1 );
246
0
    }
247
24.4M
    if( libcdata_range_list_value_free(
248
24.4M
         &range_list_value,
249
24.4M
         value_free_function,
250
24.4M
         error ) != 1 )
251
0
    {
252
0
      libcerror_error_set(
253
0
       error,
254
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
255
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
256
0
       "%s: unable to free range list value.",
257
0
       function );
258
259
0
      result = -1;
260
0
    }
261
24.4M
    if( libcdata_list_element_free(
262
24.4M
         range_list_element,
263
24.4M
         NULL,
264
24.4M
         error ) != 1 )
265
0
    {
266
0
      libcerror_error_set(
267
0
       error,
268
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
269
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
270
0
       "%s: unable to free list element.",
271
0
       function );
272
273
0
      result = -1;
274
0
    }
275
24.4M
  }
276
24.4M
  return( result );
277
24.4M
}
278
279
/* Empties a range list and frees the elements
280
 * Uses the value_free_function to free the element value
281
 * Returns 1 if successful or -1 on error
282
 */
283
int libcdata_range_list_empty(
284
     libcdata_range_list_t *range_list,
285
     int (*value_free_function)(
286
            intptr_t **value,
287
            libcerror_error_t **error ),
288
     libcerror_error_t **error )
289
24.5M
{
290
24.5M
  libcdata_internal_range_list_t *internal_range_list = NULL;
291
24.5M
  libcdata_list_element_t *list_element               = NULL;
292
24.5M
  libcdata_list_element_t *next_element               = NULL;
293
24.5M
  static char *function                               = "libcdata_range_list_empty";
294
24.5M
  int element_index                                   = 0;
295
24.5M
  int number_of_elements                              = 0;
296
24.5M
  int result                                          = 1;
297
298
24.5M
  if( range_list == NULL )
299
0
  {
300
0
    libcerror_error_set(
301
0
     error,
302
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
303
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
304
0
     "%s: invalid range list.",
305
0
     function );
306
307
0
    return( -1 );
308
0
  }
309
24.5M
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
310
311
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
312
  if( libcthreads_read_write_lock_grab_for_write(
313
       internal_range_list->read_write_lock,
314
       error ) != 1 )
315
  {
316
    libcerror_error_set(
317
     error,
318
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
319
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
320
     "%s: unable to grab read/write lock for writing.",
321
     function );
322
323
    return( -1 );
324
  }
325
#endif
326
24.5M
  if( internal_range_list->number_of_elements > 0 )
327
52.4k
  {
328
52.4k
    number_of_elements = internal_range_list->number_of_elements;
329
52.4k
    list_element       = internal_range_list->first_element;
330
331
52.4k
    for( element_index = 0;
332
24.5M
         element_index < number_of_elements;
333
24.4M
         element_index++ )
334
24.4M
    {
335
24.4M
      if( libcdata_list_element_get_next_element(
336
24.4M
           list_element,
337
24.4M
           &next_element,
338
24.4M
           error ) != 1 )
339
0
      {
340
0
        libcerror_error_set(
341
0
         error,
342
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
343
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
344
0
         "%s: unable to retrieve next element from list element: %d.",
345
0
         function,
346
0
         element_index );
347
348
0
        result = -1;
349
350
0
        break;
351
0
      }
352
24.4M
      internal_range_list->first_element = next_element;
353
354
24.4M
      if( internal_range_list->last_element == list_element )
355
52.4k
      {
356
52.4k
        internal_range_list->last_element = next_element;
357
52.4k
      }
358
24.4M
      internal_range_list->number_of_elements -= 1;
359
360
24.4M
      if( next_element != NULL )
361
24.3M
      {
362
24.3M
        if( libcdata_list_element_set_previous_element(
363
24.3M
             next_element,
364
24.3M
             NULL,
365
24.3M
             error ) != 1 )
366
0
        {
367
0
          libcerror_error_set(
368
0
           error,
369
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
370
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
371
0
           "%s: unable to set previous element of list element: %d.",
372
0
           function,
373
0
           element_index + 1 );
374
375
0
          result = -1;
376
0
        }
377
24.3M
      }
378
24.4M
      if( libcdata_list_element_set_next_element(
379
24.4M
           list_element,
380
24.4M
           NULL,
381
24.4M
           error ) != 1 )
382
0
      {
383
0
        libcerror_error_set(
384
0
         error,
385
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
386
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
387
0
         "%s: unable to set next element of list element: %d.",
388
0
         function,
389
0
         element_index );
390
391
0
        result = -1;
392
0
      }
393
24.4M
      if( libcdata_internal_range_list_free_element(
394
24.4M
           internal_range_list,
395
24.4M
           &list_element,
396
24.4M
           value_free_function,
397
24.4M
           error ) != 1 )
398
0
      {
399
0
        libcerror_error_set(
400
0
         error,
401
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
402
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
403
0
         "%s: unable to free range list element: %d.",
404
0
         function,
405
0
         element_index );
406
407
0
        result = -1;
408
0
      }
409
24.4M
      list_element = next_element;
410
24.4M
    }
411
52.4k
    internal_range_list->current_element       = NULL;
412
52.4k
    internal_range_list->current_element_index = 0;
413
52.4k
  }
414
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
415
  if( libcthreads_read_write_lock_release_for_write(
416
       internal_range_list->read_write_lock,
417
       error ) != 1 )
418
  {
419
    libcerror_error_set(
420
     error,
421
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
422
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
423
     "%s: unable to release read/write lock for writing.",
424
     function );
425
426
    result = -1;
427
  }
428
#endif
429
24.5M
  return( result );
430
24.5M
}
431
432
/* Clones the range list
433
 *
434
 * The values are cloned using the value_clone_function
435
 * On error the values are freed using the value_free_function
436
 *
437
 * Returns 1 if successful or -1 on error
438
 */
439
int libcdata_range_list_clone(
440
     libcdata_range_list_t **destination_range_list,
441
     libcdata_range_list_t *source_range_list,
442
     int (*value_free_function)(
443
            intptr_t **value,
444
            libcerror_error_t **error ),
445
     int (*value_clone_function)(
446
            intptr_t **destination,
447
            intptr_t *source,
448
            libcerror_error_t **error ),
449
     libcerror_error_t **error )
450
0
{
451
0
  libcdata_internal_list_element_t *internal_source_list_element  = NULL;
452
0
  libcdata_internal_range_list_t *internal_destination_range_list = NULL;
453
0
  libcdata_internal_range_list_t *internal_source_range_list      = NULL;
454
0
  libcdata_range_list_value_t *destination_range_list_value       = NULL;
455
0
  static char *function                                           = "libcdata_range_list_clone";
456
0
  int element_index                                               = 0;
457
458
0
  if( destination_range_list == NULL )
459
0
  {
460
0
    libcerror_error_set(
461
0
     error,
462
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
463
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
464
0
     "%s: invalid destination range list.",
465
0
     function );
466
467
0
    return( -1 );
468
0
  }
469
0
  if( *destination_range_list != NULL )
470
0
  {
471
0
    libcerror_error_set(
472
0
     error,
473
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
474
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
475
0
     "%s: invalid destination range list value already set.",
476
0
     function );
477
478
0
    return( -1 );
479
0
  }
480
0
  if( source_range_list == NULL )
481
0
  {
482
0
    *destination_range_list = NULL;
483
484
0
    return( 1 );
485
0
  }
486
0
  internal_source_range_list = (libcdata_internal_range_list_t *) source_range_list;
487
488
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
489
  if( libcthreads_read_write_lock_grab_for_read(
490
       internal_source_range_list->read_write_lock,
491
       error ) != 1 )
492
  {
493
    libcerror_error_set(
494
     error,
495
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
496
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
497
     "%s: unable to grab read/write lock for reading.",
498
     function );
499
500
    return( -1 );
501
  }
502
#endif
503
0
  if( libcdata_range_list_initialize(
504
0
       (libcdata_range_list_t **) &internal_destination_range_list,
505
0
       error ) != 1 )
506
0
  {
507
0
    libcerror_error_set(
508
0
     error,
509
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
510
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
511
0
     "%s: unable to create destination range list.",
512
0
     function );
513
514
0
    goto on_error;
515
0
  }
516
0
  if( internal_destination_range_list == NULL )
517
0
  {
518
0
    libcerror_error_set(
519
0
     error,
520
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
521
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
522
0
     "%s: missing destination range list.",
523
0
     function );
524
525
0
    goto on_error;
526
0
  }
527
0
  if( internal_source_range_list->first_element != NULL )
528
0
  {
529
0
    internal_source_list_element = (libcdata_internal_list_element_t *) internal_source_range_list->first_element;
530
531
0
    for( element_index = 0;
532
0
         element_index < internal_source_range_list->number_of_elements;
533
0
         element_index++ )
534
0
    {
535
0
      if( internal_source_list_element == NULL )
536
0
      {
537
0
        libcerror_error_set(
538
0
         error,
539
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
540
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
541
0
         "%s: missing source list element: %d.",
542
0
         function,
543
0
         element_index );
544
545
0
        goto on_error;
546
0
      }
547
0
      if( libcdata_range_list_value_clone(
548
0
           &destination_range_list_value,
549
0
           (libcdata_range_list_value_t *) internal_source_list_element->value,
550
0
           value_free_function,
551
0
           value_clone_function,
552
0
           error ) != 1 )
553
0
      {
554
0
        libcerror_error_set(
555
0
         error,
556
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
557
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
558
0
         "%s: unable to create destination range list value: %d.",
559
0
         function,
560
0
         element_index );
561
562
0
        goto on_error;
563
0
      }
564
0
      if( libcdata_internal_range_list_append_value(
565
0
           internal_destination_range_list,
566
0
           destination_range_list_value,
567
0
           error ) != 1 )
568
0
      {
569
0
        libcerror_error_set(
570
0
         error,
571
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
572
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
573
0
         "%s: unable to append value: %d to destination range list.",
574
0
         function,
575
0
         element_index );
576
577
0
        goto on_error;
578
0
      }
579
0
      destination_range_list_value = NULL;
580
581
0
      internal_source_list_element = (libcdata_internal_list_element_t *) internal_source_list_element->next_element;
582
0
    }
583
0
  }
584
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
585
  if( libcthreads_read_write_lock_release_for_read(
586
       internal_source_range_list->read_write_lock,
587
       error ) != 1 )
588
  {
589
    libcerror_error_set(
590
     error,
591
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
592
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
593
     "%s: unable to release read/write lock for reading.",
594
     function );
595
596
    libcdata_range_list_free(
597
     (libcdata_range_list_t **) &internal_destination_range_list,
598
     value_free_function,
599
     NULL );
600
601
    return( -1 );
602
  }
603
#endif
604
0
  *destination_range_list = (libcdata_range_list_t *) internal_destination_range_list;
605
606
0
  return( 1 );
607
608
0
on_error:
609
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
610
  libcthreads_read_write_lock_release_for_read(
611
   internal_source_range_list->read_write_lock,
612
   NULL );
613
#endif
614
0
  if( destination_range_list_value != NULL )
615
0
  {
616
0
    libcdata_range_list_value_free(
617
0
     &destination_range_list_value,
618
0
     value_free_function,
619
0
     NULL );
620
0
  }
621
0
  if( internal_destination_range_list != NULL )
622
0
  {
623
0
    libcdata_range_list_free(
624
0
     (libcdata_range_list_t **) &internal_destination_range_list,
625
0
     value_free_function,
626
0
     NULL );
627
0
  }
628
0
  return( -1 );
629
0
}
630
631
/* Retrieves the number of elements in the range list
632
 * Returns 1 if successful or -1 on error
633
 */
634
int libcdata_range_list_get_number_of_elements(
635
     libcdata_range_list_t *range_list,
636
     int *number_of_elements,
637
     libcerror_error_t **error )
638
0
{
639
0
  libcdata_internal_range_list_t *internal_range_list = NULL;
640
0
  static char *function                               = "libcdata_range_list_get_number_of_elements";
641
642
0
  if( range_list == NULL )
643
0
  {
644
0
    libcerror_error_set(
645
0
     error,
646
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
647
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
648
0
     "%s: invalid range list.",
649
0
     function );
650
651
0
    return( -1 );
652
0
  }
653
0
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
654
655
0
  if( number_of_elements == NULL )
656
0
  {
657
0
    libcerror_error_set(
658
0
     error,
659
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
660
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
661
0
     "%s: invalid number of elements.",
662
0
     function );
663
664
0
    return( -1 );
665
0
  }
666
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
667
  if( libcthreads_read_write_lock_grab_for_read(
668
       internal_range_list->read_write_lock,
669
       error ) != 1 )
670
  {
671
    libcerror_error_set(
672
     error,
673
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
674
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
675
     "%s: unable to grab read/write lock for reading.",
676
     function );
677
678
    return( -1 );
679
  }
680
#endif
681
0
  *number_of_elements = internal_range_list->number_of_elements;
682
683
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
684
  if( libcthreads_read_write_lock_release_for_read(
685
       internal_range_list->read_write_lock,
686
       error ) != 1 )
687
  {
688
    libcerror_error_set(
689
     error,
690
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
691
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
692
     "%s: unable to release read/write lock for reading.",
693
     function );
694
695
    return( -1 );
696
  }
697
#endif
698
0
  return( 1 );
699
0
}
700
701
/* Retrieves the first elements in the range list
702
 * Returns 1 if successful or -1 on error
703
 */
704
int libcdata_range_list_get_first_element(
705
     libcdata_range_list_t *range_list,
706
     libcdata_list_element_t **element,
707
     libcerror_error_t **error )
708
0
{
709
0
  libcdata_internal_range_list_t *internal_range_list = NULL;
710
0
  static char *function                               = "libcdata_range_list_get_first_element";
711
712
0
  if( range_list == NULL )
713
0
  {
714
0
    libcerror_error_set(
715
0
     error,
716
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
717
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
718
0
     "%s: invalid range list.",
719
0
     function );
720
721
0
    return( -1 );
722
0
  }
723
0
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
724
725
0
  if( element == NULL )
726
0
  {
727
0
    libcerror_error_set(
728
0
     error,
729
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
730
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
731
0
     "%s: invalid element.",
732
0
     function );
733
734
0
    return( -1 );
735
0
  }
736
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
737
  if( libcthreads_read_write_lock_grab_for_read(
738
       internal_range_list->read_write_lock,
739
       error ) != 1 )
740
  {
741
    libcerror_error_set(
742
     error,
743
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
744
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
745
     "%s: unable to grab read/write lock for reading.",
746
     function );
747
748
    return( -1 );
749
  }
750
#endif
751
0
  *element = internal_range_list->first_element;
752
753
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
754
  if( libcthreads_read_write_lock_release_for_read(
755
       internal_range_list->read_write_lock,
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 release read/write lock for reading.",
763
     function );
764
765
    return( -1 );
766
  }
767
#endif
768
0
  return( 1 );
769
0
}
770
771
/* Sets the first element in the range list
772
 * Returns 1 if successful or -1 on error
773
 */
774
int libcdata_internal_range_list_set_first_element(
775
     libcdata_internal_range_list_t *internal_range_list,
776
     libcdata_list_element_t *element,
777
     libcerror_error_t **error )
778
0
{
779
0
  libcdata_list_element_t *backup_first_element = NULL;
780
0
  libcdata_list_element_t *backup_next_element  = NULL;
781
0
  static char *function                         = "libcdata_internal_range_list_set_first_element";
782
783
0
  if( internal_range_list == NULL )
784
0
  {
785
0
    libcerror_error_set(
786
0
     error,
787
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
788
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
789
0
     "%s: invalid range list.",
790
0
     function );
791
792
0
    return( -1 );
793
0
  }
794
0
  if( element != NULL )
795
0
  {
796
0
    if( libcdata_list_element_get_next_element(
797
0
         element,
798
0
         &backup_next_element,
799
0
         error ) != 1 )
800
0
    {
801
0
      libcerror_error_set(
802
0
       error,
803
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
804
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
805
0
       "%s: unable to retrieve next element of element.",
806
0
       function );
807
808
0
      return( -1 );
809
0
    }
810
0
  }
811
0
  backup_first_element = internal_range_list->first_element;
812
813
0
  if( element != NULL )
814
0
  {
815
0
    if( libcdata_list_element_set_next_element(
816
0
         element,
817
0
         internal_range_list->first_element,
818
0
         error ) != 1 )
819
0
    {
820
0
      libcerror_error_set(
821
0
       error,
822
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
823
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
824
0
       "%s: unable to set next element of element.",
825
0
       function );
826
827
0
      goto on_error;
828
0
    }
829
0
  }
830
0
  if( internal_range_list->first_element != NULL )
831
0
  {
832
0
    if( libcdata_list_element_set_previous_element(
833
0
         internal_range_list->first_element,
834
0
         element,
835
0
         error ) != 1 )
836
0
    {
837
0
      libcerror_error_set(
838
0
       error,
839
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
840
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
841
0
       "%s: unable to set previous element of first element.",
842
0
       function );
843
844
0
      goto on_error;
845
0
    }
846
0
  }
847
0
  internal_range_list->first_element = element;
848
849
0
  return( 1 );
850
851
0
on_error:
852
0
  if( element != NULL )
853
0
  {
854
0
    libcdata_list_element_set_next_element(
855
0
     element,
856
0
     backup_next_element,
857
0
     NULL );
858
0
  }
859
0
  if( backup_first_element != NULL )
860
0
  {
861
0
    libcdata_list_element_set_next_element(
862
0
     backup_first_element,
863
0
     NULL,
864
0
     NULL );
865
0
  }
866
0
  internal_range_list->first_element = backup_first_element;
867
868
0
  return( -1 );
869
0
}
870
871
/* Retrieves the last elements in the range list
872
 * Returns 1 if successful or -1 on error
873
 */
874
int libcdata_range_list_get_last_element(
875
     libcdata_range_list_t *range_list,
876
     libcdata_list_element_t **element,
877
     libcerror_error_t **error )
878
0
{
879
0
  libcdata_internal_range_list_t *internal_range_list = NULL;
880
0
  static char *function                               = "libcdata_range_list_get_last_element";
881
882
0
  if( range_list == NULL )
883
0
  {
884
0
    libcerror_error_set(
885
0
     error,
886
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
887
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
888
0
     "%s: invalid range list.",
889
0
     function );
890
891
0
    return( -1 );
892
0
  }
893
0
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
894
895
0
  if( element == NULL )
896
0
  {
897
0
    libcerror_error_set(
898
0
     error,
899
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
900
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
901
0
     "%s: invalid element.",
902
0
     function );
903
904
0
    return( -1 );
905
0
  }
906
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
907
  if( libcthreads_read_write_lock_grab_for_read(
908
       internal_range_list->read_write_lock,
909
       error ) != 1 )
910
  {
911
    libcerror_error_set(
912
     error,
913
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
914
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
915
     "%s: unable to grab read/write lock for reading.",
916
     function );
917
918
    return( -1 );
919
  }
920
#endif
921
0
  *element = internal_range_list->last_element;
922
923
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
924
  if( libcthreads_read_write_lock_release_for_read(
925
       internal_range_list->read_write_lock,
926
       error ) != 1 )
927
  {
928
    libcerror_error_set(
929
     error,
930
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
931
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
932
     "%s: unable to release read/write lock for reading.",
933
     function );
934
935
    return( -1 );
936
  }
937
#endif
938
0
  return( 1 );
939
0
}
940
941
/* Sets the last element in the list
942
 * Returns 1 if successful or -1 on error
943
 */
944
int libcdata_internal_range_list_set_last_element(
945
     libcdata_internal_range_list_t *internal_range_list,
946
     libcdata_list_element_t *element,
947
     libcerror_error_t **error )
948
24.4M
{
949
24.4M
  libcdata_list_element_t *backup_last_element     = NULL;
950
24.4M
  libcdata_list_element_t *backup_previous_element = NULL;
951
24.4M
  static char *function                            = "libcdata_internal_range_list_set_last_element";
952
953
24.4M
  if( internal_range_list == NULL )
954
0
  {
955
0
    libcerror_error_set(
956
0
     error,
957
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
958
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
959
0
     "%s: invalid range list.",
960
0
     function );
961
962
0
    return( -1 );
963
0
  }
964
24.4M
  if( element != NULL )
965
24.4M
  {
966
24.4M
    if( libcdata_list_element_get_previous_element(
967
24.4M
         element,
968
24.4M
         &backup_previous_element,
969
24.4M
         error ) != 1 )
970
0
    {
971
0
      libcerror_error_set(
972
0
       error,
973
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
974
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
975
0
       "%s: unable to retrieve previous element of element.",
976
0
       function );
977
978
0
      return( -1 );
979
0
    }
980
24.4M
  }
981
24.4M
  backup_last_element = internal_range_list->last_element;
982
983
24.4M
  if( element != NULL )
984
24.4M
  {
985
24.4M
    if( libcdata_list_element_set_previous_element(
986
24.4M
         element,
987
24.4M
         internal_range_list->last_element,
988
24.4M
         error ) != 1 )
989
0
    {
990
0
      libcerror_error_set(
991
0
       error,
992
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
993
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
994
0
       "%s: unable to set previous element of element.",
995
0
       function );
996
997
0
      goto on_error;
998
0
    }
999
24.4M
  }
1000
24.4M
  if( internal_range_list->last_element != NULL )
1001
24.3M
  {
1002
24.3M
    if( libcdata_list_element_set_next_element(
1003
24.3M
         internal_range_list->last_element,
1004
24.3M
         element,
1005
24.3M
         error ) != 1 )
1006
0
    {
1007
0
      libcerror_error_set(
1008
0
       error,
1009
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1010
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1011
0
       "%s: unable to set next element of last element.",
1012
0
       function );
1013
1014
0
      goto on_error;
1015
0
    }
1016
24.3M
  }
1017
24.4M
  internal_range_list->last_element = element;
1018
1019
24.4M
  return( 1 );
1020
1021
0
on_error:
1022
0
  if( element != NULL )
1023
0
  {
1024
0
    libcdata_list_element_set_previous_element(
1025
0
     element,
1026
0
     backup_previous_element,
1027
0
     NULL );
1028
0
  }
1029
0
  if( backup_last_element != NULL )
1030
0
  {
1031
0
    libcdata_list_element_set_next_element(
1032
0
     backup_last_element,
1033
0
     NULL,
1034
0
     NULL );
1035
0
  }
1036
0
  internal_range_list->last_element = backup_last_element;
1037
1038
0
  return( -1 );
1039
24.4M
}
1040
1041
/* Append a list element to the list
1042
 * Returns 1 if successful or -1 on error
1043
 */
1044
int libcdata_internal_range_list_append_element(
1045
     libcdata_internal_range_list_t *internal_range_list,
1046
     libcdata_list_element_t *element,
1047
     libcerror_error_t **error )
1048
50.9k
{
1049
50.9k
  static char *function = "libcdata_internal_range_list_append_element";
1050
1051
50.9k
  if( internal_range_list == NULL )
1052
0
  {
1053
0
    libcerror_error_set(
1054
0
     error,
1055
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1056
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1057
0
     "%s: invalid range list.",
1058
0
     function );
1059
1060
0
    return( -1 );
1061
0
  }
1062
50.9k
  if( element == NULL )
1063
0
  {
1064
0
    libcerror_error_set(
1065
0
     error,
1066
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1067
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1068
0
     "%s: invalid list element.",
1069
0
     function );
1070
1071
0
    return( -1 );
1072
0
  }
1073
50.9k
  if( internal_range_list->first_element == NULL )
1074
48.2k
  {
1075
48.2k
    internal_range_list->first_element = element;
1076
48.2k
  }
1077
50.9k
  if( libcdata_internal_range_list_set_last_element(
1078
50.9k
       internal_range_list,
1079
50.9k
       element,
1080
50.9k
       error ) != 1 )
1081
0
  {
1082
0
    libcerror_error_set(
1083
0
     error,
1084
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1085
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1086
0
     "%s: unable to set last element.",
1087
0
     function );
1088
1089
0
    return( -1 );
1090
0
  }
1091
50.9k
  internal_range_list->number_of_elements += 1;
1092
1093
50.9k
  return( 1 );
1094
50.9k
}
1095
1096
/* Append a value to the list
1097
 * Creates a new list element
1098
 * Returns 1 if successful or -1 on error
1099
 */
1100
int libcdata_internal_range_list_append_value(
1101
     libcdata_internal_range_list_t *internal_range_list,
1102
     libcdata_range_list_value_t *value,
1103
     libcerror_error_t **error )
1104
50.9k
{
1105
50.9k
  libcdata_list_element_t *list_element = NULL;
1106
50.9k
  static char *function                 = "libcdata_internal_range_list_append_value";
1107
1108
50.9k
  if( libcdata_list_element_initialize(
1109
50.9k
       &list_element,
1110
50.9k
       error ) != 1 )
1111
0
  {
1112
0
    libcerror_error_set(
1113
0
     error,
1114
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1115
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1116
0
     "%s: unable to create list element.",
1117
0
     function );
1118
1119
0
    goto on_error;
1120
0
  }
1121
50.9k
  if( libcdata_list_element_set_value(
1122
50.9k
       list_element,
1123
50.9k
       (intptr_t *) value,
1124
50.9k
       error ) != 1 )
1125
0
  {
1126
0
    libcerror_error_set(
1127
0
     error,
1128
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1129
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1130
0
     "%s: unable to set value of list element.",
1131
0
     function );
1132
1133
0
    goto on_error;
1134
0
  }
1135
50.9k
  if( libcdata_internal_range_list_append_element(
1136
50.9k
       internal_range_list,
1137
50.9k
       list_element,
1138
50.9k
       error ) != 1 )
1139
0
  {
1140
0
    libcerror_error_set(
1141
0
     error,
1142
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1143
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1144
0
     "%s: unable to append element to range list.",
1145
0
     function );
1146
1147
0
    goto on_error;
1148
0
  }
1149
50.9k
  return( 1 );
1150
1151
0
on_error:
1152
0
  if( list_element != NULL )
1153
0
  {
1154
0
    libcdata_list_element_free(
1155
0
     &list_element,
1156
0
     NULL,
1157
0
     NULL );
1158
0
  }
1159
0
  return( -1 );
1160
50.9k
}
1161
1162
/* Removes an element from the range list
1163
 * Returns 1 if successful, or -1 on error
1164
 */
1165
int libcdata_internal_range_list_remove_element(
1166
     libcdata_internal_range_list_t *internal_range_list,
1167
     libcdata_list_element_t *range_list_element,
1168
     libcerror_error_t **error )
1169
2.71k
{
1170
2.71k
  libcdata_list_element_t *next_element     = NULL;
1171
2.71k
  libcdata_list_element_t *previous_element = NULL;
1172
2.71k
  static char *function                     = "libcdata_internal_range_list_remove_element";
1173
1174
2.71k
  if( internal_range_list == NULL )
1175
0
  {
1176
0
    libcerror_error_set(
1177
0
     error,
1178
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1179
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1180
0
     "%s: invalid range list.",
1181
0
     function );
1182
1183
0
    return( -1 );
1184
0
  }
1185
2.71k
  if( libcdata_list_element_get_elements(
1186
2.71k
       range_list_element,
1187
2.71k
       &previous_element,
1188
2.71k
       &next_element,
1189
2.71k
       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 previous and next element from range list element.",
1196
0
     function );
1197
1198
0
    return( -1 );
1199
0
  }
1200
2.71k
  if( range_list_element == internal_range_list->first_element )
1201
0
  {
1202
0
    internal_range_list->first_element = next_element;
1203
0
  }
1204
2.71k
  if( range_list_element == internal_range_list->last_element )
1205
751
  {
1206
751
    internal_range_list->last_element = previous_element;
1207
751
  }
1208
2.71k
  if( next_element != NULL )
1209
1.96k
  {
1210
1.96k
    if( libcdata_list_element_set_previous_element(
1211
1.96k
         next_element,
1212
1.96k
         previous_element,
1213
1.96k
         error ) != 1 )
1214
0
    {
1215
0
      libcerror_error_set(
1216
0
       error,
1217
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1218
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1219
0
       "%s: unable to set previous element of next element.",
1220
0
       function );
1221
1222
0
      return( -1 );
1223
0
    }
1224
1.96k
  }
1225
2.71k
  if( previous_element != NULL )
1226
2.71k
  {
1227
2.71k
    if( libcdata_list_element_set_next_element(
1228
2.71k
         previous_element,
1229
2.71k
         next_element,
1230
2.71k
         error ) != 1 )
1231
0
    {
1232
0
      libcerror_error_set(
1233
0
       error,
1234
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1235
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1236
0
       "%s: unable to set next element of previous element.",
1237
0
       function );
1238
1239
0
      return( -1 );
1240
0
    }
1241
2.71k
  }
1242
2.71k
  if( libcdata_list_element_set_elements(
1243
2.71k
       range_list_element,
1244
2.71k
       NULL,
1245
2.71k
       NULL,
1246
2.71k
       error ) != 1 )
1247
0
  {
1248
0
    libcerror_error_set(
1249
0
     error,
1250
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1251
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1252
0
     "%s: unable to set previous and next element of range list element.",
1253
0
     function );
1254
1255
0
    return( -1 );
1256
0
  }
1257
2.71k
  internal_range_list->current_element       = NULL;
1258
2.71k
  internal_range_list->current_element_index = 0;
1259
1260
2.71k
  internal_range_list->number_of_elements -= 1;
1261
1262
2.71k
  return( 1 );
1263
2.71k
}
1264
1265
/* Removes an element from the range list and frees the element
1266
 * Returns 1 if successful, or -1 on error
1267
 */
1268
int libcdata_internal_range_list_remove_range_value(
1269
     libcdata_internal_range_list_t *internal_range_list,
1270
     libcdata_list_element_t **range_list_element,
1271
     int (*value_free_function)(
1272
            intptr_t **value,
1273
            libcerror_error_t **error ),
1274
     libcerror_error_t **error )
1275
0
{
1276
0
  libcdata_range_list_value_t *range_list_value = NULL;
1277
0
  static char *function                         = "libcdata_internal_range_list_remove_range_value";
1278
0
  int result                                    = 1;
1279
1280
0
  if( internal_range_list == NULL )
1281
0
  {
1282
0
    libcerror_error_set(
1283
0
     error,
1284
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1285
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1286
0
     "%s: invalid range list.",
1287
0
     function );
1288
1289
0
    return( -1 );
1290
0
  }
1291
0
  if( range_list_element == NULL )
1292
0
  {
1293
0
    libcerror_error_set(
1294
0
     error,
1295
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1296
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1297
0
     "%s: invalid range list element.",
1298
0
     function );
1299
1300
0
    return( -1 );
1301
0
  }
1302
0
  if( libcdata_internal_range_list_remove_element(
1303
0
       internal_range_list,
1304
0
       *range_list_element,
1305
0
       error ) != 1 )
1306
0
  {
1307
0
    libcerror_error_set(
1308
0
     error,
1309
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1310
0
     LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
1311
0
     "%s: unable to remove range list element.",
1312
0
     function );
1313
1314
0
    return( -1 );
1315
0
  }
1316
0
  if( libcdata_list_element_get_value(
1317
0
       *range_list_element,
1318
0
       (intptr_t **) &range_list_value,
1319
0
       error ) != 1 )
1320
0
  {
1321
0
    libcerror_error_set(
1322
0
     error,
1323
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1324
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1325
0
     "%s: unable to retrieve range list value from range list element.",
1326
0
     function );
1327
1328
0
    return( -1 );
1329
0
  }
1330
0
  if( libcdata_list_element_free(
1331
0
       range_list_element,
1332
0
       NULL,
1333
0
       error ) != 1 )
1334
0
  {
1335
0
    libcerror_error_set(
1336
0
     error,
1337
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1338
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1339
0
     "%s: unable to free range list element.",
1340
0
     function );
1341
1342
0
    result = -1;
1343
0
  }
1344
0
  if( libcdata_range_list_value_free(
1345
0
       &range_list_value,
1346
0
       value_free_function,
1347
0
       error ) != 1 )
1348
0
  {
1349
0
    libcerror_error_set(
1350
0
     error,
1351
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1352
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1353
0
     "%s: unable to free range list value.",
1354
0
     function );
1355
1356
0
    result = -1;
1357
0
  }
1358
0
  return( result );
1359
0
}
1360
1361
/* Retrieves the element which the range should be inserted before or merged within
1362
 *
1363
 * On return element will be set to NULL if the range should be inserted at the end of the list.
1364
 *
1365
 * Returns 1 if successful or -1 on error
1366
 */
1367
int libcdata_internal_range_list_insert_range_find_element(
1368
     libcdata_internal_range_list_t *internal_range_list,
1369
     uint64_t range_start,
1370
     uint64_t range_end LIBCDATA_ATTRIBUTE_UNUSED,
1371
     int *element_index,
1372
     libcdata_list_element_t **element,
1373
     libcerror_error_t **error )
1374
24.4M
{
1375
24.4M
  libcdata_list_element_t *current_element      = NULL;
1376
24.4M
  libcdata_list_element_t *previous_element     = NULL;
1377
24.4M
  libcdata_range_list_value_t *range_list_value = NULL;
1378
24.4M
  static char *function                         = "libcdata_internal_range_list_insert_range_find_element";
1379
24.4M
  int current_element_index                     = 0;
1380
24.4M
  int last_element_index                        = 0;
1381
1382
24.4M
  LIBCDATA_UNREFERENCED_PARAMETER( range_end )
1383
1384
24.4M
  if( internal_range_list == NULL )
1385
0
  {
1386
0
    libcerror_error_set(
1387
0
     error,
1388
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1389
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1390
0
     "%s: invalid range list.",
1391
0
     function );
1392
1393
0
    return( -1 );
1394
0
  }
1395
24.4M
  if( element == NULL )
1396
0
  {
1397
0
    libcerror_error_set(
1398
0
     error,
1399
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1400
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1401
0
     "%s: invalid element.",
1402
0
     function );
1403
1404
0
    return( -1 );
1405
0
  }
1406
24.4M
  if( element_index == NULL )
1407
0
  {
1408
0
    libcerror_error_set(
1409
0
     error,
1410
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1411
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1412
0
     "%s: invalid element index.",
1413
0
     function );
1414
1415
0
    return( -1 );
1416
0
  }
1417
24.4M
  current_element       = internal_range_list->last_element;
1418
24.4M
  current_element_index = internal_range_list->number_of_elements;
1419
1420
24.4M
  if( internal_range_list->number_of_elements > 0 )
1421
24.4M
  {
1422
    /* Check the last element first, most often the list will be filled linear
1423
     */
1424
24.4M
    current_element_index--;
1425
1426
24.4M
    if( libcdata_list_element_get_value(
1427
24.4M
         current_element,
1428
24.4M
         (intptr_t **) &range_list_value,
1429
24.4M
         error ) != 1 )
1430
0
    {
1431
0
      libcerror_error_set(
1432
0
       error,
1433
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1434
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1435
0
       "%s: unable to retrieve value from list element: %d.",
1436
0
       function,
1437
0
       current_element_index );
1438
1439
0
      return( -1 );
1440
0
    }
1441
24.4M
    if( range_list_value == NULL )
1442
0
    {
1443
0
      libcerror_error_set(
1444
0
       error,
1445
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1446
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1447
0
       "%s: missing range list value element: %d.",
1448
0
       function,
1449
0
       current_element_index );
1450
1451
0
      return( -1 );
1452
0
    }
1453
24.4M
    if( range_start > range_list_value->end )
1454
24.3M
    {
1455
24.3M
      current_element = NULL;
1456
1457
24.3M
      current_element_index++;
1458
24.3M
    }
1459
53.2k
    else if( internal_range_list->number_of_elements > 1 )
1460
44.2k
    {
1461
44.2k
      last_element_index = current_element_index;
1462
1463
44.2k
      if( ( current_element_index != internal_range_list->current_element_index )
1464
44.2k
       && ( internal_range_list->current_element != NULL ) )
1465
5.30k
      {
1466
        /* Check the current element
1467
         */
1468
5.30k
        current_element       = internal_range_list->current_element;
1469
5.30k
        current_element_index = internal_range_list->current_element_index;
1470
1471
5.30k
        if( libcdata_list_element_get_value(
1472
5.30k
             current_element,
1473
5.30k
             (intptr_t **) &range_list_value,
1474
5.30k
             error ) != 1 )
1475
0
        {
1476
0
          libcerror_error_set(
1477
0
           error,
1478
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1479
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1480
0
           "%s: unable to retrieve value from list element: %d.",
1481
0
           function,
1482
0
           current_element_index );
1483
1484
0
          return( -1 );
1485
0
        }
1486
5.30k
        if( range_list_value == NULL )
1487
0
        {
1488
0
          libcerror_error_set(
1489
0
           error,
1490
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1491
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1492
0
           "%s: missing range list value element: %d.",
1493
0
           function,
1494
0
           current_element_index );
1495
1496
0
          return( -1 );
1497
0
        }
1498
5.30k
      }
1499
44.2k
      if( range_start > range_list_value->end )
1500
1.23k
      {
1501
3.24k
        while( current_element_index < last_element_index )
1502
3.24k
        {
1503
3.24k
          if( libcdata_list_element_get_next_element(
1504
3.24k
               current_element,
1505
3.24k
               &current_element,
1506
3.24k
               error ) != 1 )
1507
0
          {
1508
0
            libcerror_error_set(
1509
0
             error,
1510
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1511
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1512
0
             "%s: unable to retrieve next element from list element: %d.",
1513
0
             function,
1514
0
             current_element_index );
1515
1516
0
            return( -1 );
1517
0
          }
1518
3.24k
          current_element_index++;
1519
1520
3.24k
          if( libcdata_list_element_get_value(
1521
3.24k
               current_element,
1522
3.24k
               (intptr_t **) &range_list_value,
1523
3.24k
               error ) != 1 )
1524
0
          {
1525
0
            libcerror_error_set(
1526
0
             error,
1527
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1528
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1529
0
             "%s: unable to retrieve value from list element: %d.",
1530
0
             function,
1531
0
             current_element_index );
1532
1533
0
            return( -1 );
1534
0
          }
1535
3.24k
          if( range_list_value == NULL )
1536
0
          {
1537
0
            libcerror_error_set(
1538
0
             error,
1539
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1540
0
             LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1541
0
             "%s: missing range list value element: %d.",
1542
0
             function,
1543
0
             current_element_index );
1544
1545
0
            return( -1 );
1546
0
          }
1547
3.24k
          if( range_start <= range_list_value->end )
1548
1.23k
          {
1549
1.23k
            break;
1550
1.23k
          }
1551
3.24k
        }
1552
1.23k
      }
1553
43.0k
      else
1554
43.0k
      {
1555
107k
        while( current_element_index > 0 )
1556
104k
        {
1557
104k
          previous_element = current_element;
1558
1559
104k
          if( libcdata_list_element_get_previous_element(
1560
104k
               current_element,
1561
104k
               &current_element,
1562
104k
               error ) != 1 )
1563
0
          {
1564
0
            libcerror_error_set(
1565
0
             error,
1566
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1567
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1568
0
             "%s: unable to retrieve previous element from list element: %d.",
1569
0
             function,
1570
0
             current_element_index );
1571
1572
0
            return( -1 );
1573
0
          }
1574
104k
          current_element_index--;
1575
1576
104k
          if( libcdata_list_element_get_value(
1577
104k
               current_element,
1578
104k
               (intptr_t **) &range_list_value,
1579
104k
               error ) != 1 )
1580
0
          {
1581
0
            libcerror_error_set(
1582
0
             error,
1583
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1584
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1585
0
             "%s: unable to retrieve value from list element: %d.",
1586
0
             function,
1587
0
             current_element_index );
1588
1589
0
            return( -1 );
1590
0
          }
1591
104k
          if( range_list_value == NULL )
1592
0
          {
1593
0
            libcerror_error_set(
1594
0
             error,
1595
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1596
0
             LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1597
0
             "%s: missing range list value element: %d.",
1598
0
             function,
1599
0
             current_element_index );
1600
1601
0
            return( -1 );
1602
0
          }
1603
104k
          if( range_start > range_list_value->end )
1604
39.6k
          {
1605
39.6k
            current_element = previous_element;
1606
1607
39.6k
            current_element_index++;
1608
1609
39.6k
            break;
1610
39.6k
          }
1611
104k
        }
1612
43.0k
      }
1613
44.2k
    }
1614
24.4M
  }
1615
24.4M
  if( current_element != NULL )
1616
53.2k
  {
1617
53.2k
    internal_range_list->current_element       = current_element;
1618
53.2k
    internal_range_list->current_element_index = current_element_index;
1619
53.2k
  }
1620
24.4M
  *element       = current_element;
1621
24.4M
  *element_index = current_element_index;
1622
1623
24.4M
  return( 1 );
1624
24.4M
}
1625
1626
/* Checks if the range overlaps with the value of the range list element
1627
 * Returns 1 if the range overlaps, 0 if not or -1 on error
1628
 */
1629
int libcdata_internal_range_list_check_range_overlap(
1630
     libcdata_internal_range_list_t *internal_range_list,
1631
     libcdata_list_element_t *range_list_element,
1632
     uint64_t range_start,
1633
     uint64_t range_end,
1634
     libcerror_error_t **error )
1635
24.4M
{
1636
24.4M
  libcdata_range_list_value_t *range_list_value = NULL;
1637
24.4M
  static char *function                         = "libcdata_internal_range_list_check_range_overlap";
1638
24.4M
  int result                                    = 0;
1639
1640
24.4M
  if( internal_range_list == NULL )
1641
0
  {
1642
0
    libcerror_error_set(
1643
0
     error,
1644
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1645
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1646
0
     "%s: invalid range list.",
1647
0
     function );
1648
1649
0
    return( -1 );
1650
0
  }
1651
24.4M
  if( range_list_element != NULL )
1652
63.4k
  {
1653
63.4k
    if( libcdata_list_element_get_value(
1654
63.4k
         range_list_element,
1655
63.4k
         (intptr_t **) &range_list_value,
1656
63.4k
         error ) != 1 )
1657
0
    {
1658
0
      libcerror_error_set(
1659
0
       error,
1660
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1661
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1662
0
       "%s: unable to retrieve value from range list element.",
1663
0
       function );
1664
1665
0
      return( -1 );
1666
0
    }
1667
63.4k
    result = libcdata_range_list_value_check_range_overlap(
1668
63.4k
              range_list_value,
1669
63.4k
              range_start,
1670
63.4k
              range_end,
1671
63.4k
              error );
1672
1673
63.4k
    if( result == -1 )
1674
0
    {
1675
0
      libcerror_error_set(
1676
0
       error,
1677
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1678
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1679
0
       "%s: unable to determine if range overlaps with range list value.",
1680
0
       function );
1681
1682
0
      return( -1 );
1683
0
    }
1684
63.4k
  }
1685
24.4M
  return( result );
1686
24.4M
}
1687
1688
/* Inserts the range before the range list element
1689
 * If range_list_element is NULL the element is inserted before or as the first element in the list
1690
 * Returns 1 if successful, or -1 on error
1691
 */
1692
int libcdata_internal_range_list_insert_range_before_element(
1693
     libcdata_internal_range_list_t *internal_range_list,
1694
     libcdata_list_element_t *range_list_element,
1695
     uint64_t range_start,
1696
     uint64_t range_end,
1697
     intptr_t *value,
1698
     libcdata_list_element_t **new_range_list_element,
1699
     libcerror_error_t **error )
1700
24.4M
{
1701
24.4M
  libcdata_list_element_t *backup_first_element     = NULL;
1702
24.4M
  libcdata_list_element_t *backup_last_element      = NULL;
1703
24.4M
  libcdata_list_element_t *new_element              = NULL;
1704
24.4M
  libcdata_list_element_t *previous_element         = NULL;
1705
24.4M
  libcdata_range_list_value_t *new_range_list_value = NULL;
1706
24.4M
  static char *function                             = "libcdata_internal_range_list_insert_range_before_element";
1707
1708
24.4M
  if( internal_range_list == NULL )
1709
0
  {
1710
0
    libcerror_error_set(
1711
0
     error,
1712
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1713
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1714
0
     "%s: invalid range list.",
1715
0
     function );
1716
1717
0
    return( -1 );
1718
0
  }
1719
24.4M
  if( new_range_list_element == NULL )
1720
0
  {
1721
0
    libcerror_error_set(
1722
0
     error,
1723
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1724
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1725
0
     "%s: invalid new range list element.",
1726
0
     function );
1727
1728
0
    return( -1 );
1729
0
  }
1730
24.4M
  if( range_list_element != NULL )
1731
4.95k
  {
1732
4.95k
    if( libcdata_list_element_get_previous_element(
1733
4.95k
         range_list_element,
1734
4.95k
         &previous_element,
1735
4.95k
         error ) != 1 )
1736
0
    {
1737
0
      libcerror_error_set(
1738
0
       error,
1739
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1740
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1741
0
       "%s: unable to retrieve previous element from range list element.",
1742
0
       function );
1743
1744
0
      return( -1 );
1745
0
    }
1746
4.95k
  }
1747
24.4M
  if( libcdata_range_list_value_initialize(
1748
24.4M
       &new_range_list_value,
1749
24.4M
       error ) != 1 )
1750
0
  {
1751
0
    libcerror_error_set(
1752
0
     error,
1753
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1754
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1755
0
     "%s: unable to create range list value.",
1756
0
     function );
1757
1758
0
    goto on_error;
1759
0
  }
1760
24.4M
  backup_first_element = internal_range_list->first_element;
1761
24.4M
  backup_last_element  = internal_range_list->last_element;
1762
1763
24.4M
  if( new_range_list_value == NULL )
1764
0
  {
1765
0
    libcerror_error_set(
1766
0
     error,
1767
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1768
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1769
0
     "%s: missing range list value.",
1770
0
     function );
1771
1772
0
    goto on_error;
1773
0
  }
1774
24.4M
  new_range_list_value->start = range_start;
1775
24.4M
  new_range_list_value->size  = range_end - range_start;
1776
24.4M
  new_range_list_value->end   = range_end;
1777
24.4M
  new_range_list_value->value = value;
1778
1779
24.4M
  if( libcdata_list_element_initialize(
1780
24.4M
       &new_element,
1781
24.4M
       error ) != 1 )
1782
0
  {
1783
0
    libcerror_error_set(
1784
0
     error,
1785
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1786
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1787
0
     "%s: unable to create list element.",
1788
0
     function );
1789
1790
0
    goto on_error;
1791
0
  }
1792
24.4M
  if( libcdata_list_element_set_value(
1793
24.4M
       new_element,
1794
24.4M
       (intptr_t *) new_range_list_value,
1795
24.4M
       error ) != 1 )
1796
0
  {
1797
0
    libcerror_error_set(
1798
0
     error,
1799
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1800
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1801
0
     "%s: unable to set value in list element.",
1802
0
     function );
1803
1804
0
    goto on_error;
1805
0
  }
1806
24.4M
  if( internal_range_list->number_of_elements == 0 )
1807
4.16k
  {
1808
4.16k
    internal_range_list->first_element = new_element;
1809
4.16k
    internal_range_list->last_element  = new_element;
1810
4.16k
  }
1811
24.3M
  else if( range_list_element == NULL )
1812
24.3M
  {
1813
24.3M
    if( libcdata_internal_range_list_set_last_element(
1814
24.3M
         internal_range_list,
1815
24.3M
         new_element,
1816
24.3M
         error ) != 1 )
1817
0
    {
1818
0
      libcerror_error_set(
1819
0
       error,
1820
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1821
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1822
0
       "%s: unable to set last element.",
1823
0
       function );
1824
1825
0
      goto on_error;
1826
0
    }
1827
24.3M
  }
1828
4.95k
  else
1829
4.95k
  {
1830
4.95k
    if( libcdata_list_element_set_elements(
1831
4.95k
         new_element,
1832
4.95k
         previous_element,
1833
4.95k
         range_list_element,
1834
4.95k
         error ) != 1 )
1835
0
    {
1836
0
      libcerror_error_set(
1837
0
       error,
1838
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1839
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1840
0
       "%s: unable to set previous and next element of element.",
1841
0
       function );
1842
1843
0
      goto on_error;
1844
0
    }
1845
4.95k
    if( internal_range_list->first_element == range_list_element )
1846
1.65k
    {
1847
1.65k
      internal_range_list->first_element = new_element;
1848
1.65k
    }
1849
3.29k
    else
1850
3.29k
    {
1851
3.29k
      if( libcdata_list_element_set_next_element(
1852
3.29k
           previous_element,
1853
3.29k
           new_element,
1854
3.29k
           error ) != 1 )
1855
0
      {
1856
0
        libcerror_error_set(
1857
0
         error,
1858
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1859
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1860
0
         "%s: unable to set next element of previous element.",
1861
0
         function );
1862
1863
0
        goto on_error;
1864
0
      }
1865
3.29k
    }
1866
4.95k
    if( libcdata_list_element_set_previous_element(
1867
4.95k
         range_list_element,
1868
4.95k
         new_element,
1869
4.95k
         error ) != 1 )
1870
0
    {
1871
0
      libcerror_error_set(
1872
0
       error,
1873
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1874
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1875
0
       "%s: unable to set previous element of range list element.",
1876
0
       function );
1877
1878
0
      goto on_error;
1879
0
    }
1880
4.95k
  }
1881
24.4M
  internal_range_list->current_element       = NULL;
1882
24.4M
  internal_range_list->current_element_index = 0;
1883
1884
24.4M
  internal_range_list->number_of_elements += 1;
1885
1886
24.4M
  *new_range_list_element = new_element;
1887
1888
24.4M
  return( 1 );
1889
1890
0
on_error:
1891
0
  if( new_element != NULL )
1892
0
  {
1893
0
    libcdata_list_element_set_elements(
1894
0
     new_element,
1895
0
     NULL,
1896
0
     NULL,
1897
0
     NULL );
1898
1899
0
    libcdata_list_element_free(
1900
0
     &new_element,
1901
0
     NULL,
1902
0
     NULL );
1903
0
  }
1904
0
  if( new_range_list_value != NULL )
1905
0
  {
1906
0
    libcdata_range_list_value_free(
1907
0
     &new_range_list_value,
1908
0
     NULL,
1909
0
     NULL );
1910
0
  }
1911
0
  if( previous_element != NULL )
1912
0
  {
1913
0
    libcdata_list_element_set_next_element(
1914
0
     previous_element,
1915
0
     range_list_element,
1916
0
     NULL );
1917
0
  }
1918
0
  if( range_list_element != NULL )
1919
0
  {
1920
0
    libcdata_list_element_set_previous_element(
1921
0
     range_list_element,
1922
0
     previous_element,
1923
0
     NULL );
1924
0
  }
1925
0
  internal_range_list->first_element = backup_first_element;
1926
0
  internal_range_list->last_element  = backup_last_element;
1927
1928
0
  return( -1 );
1929
24.4M
}
1930
1931
/* Inserts the element in the range list after the range list element
1932
 * If range_list_element is NULL the element is inserted as the first element in the list
1933
 * Returns 1 if successful, or -1 on error
1934
 */
1935
int libcdata_internal_range_list_insert_element_after_element(
1936
     libcdata_internal_range_list_t *internal_range_list,
1937
     libcdata_list_element_t *range_list_element,
1938
     libcdata_list_element_t *element,
1939
     libcerror_error_t **error )
1940
0
{
1941
0
  libcdata_list_element_t *next_element     = NULL;
1942
0
  libcdata_list_element_t *previous_element = NULL;
1943
0
  static char *function                     = "libcdata_internal_range_list_insert_element_after_element";
1944
1945
0
  if( internal_range_list == NULL )
1946
0
  {
1947
0
    libcerror_error_set(
1948
0
     error,
1949
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1950
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1951
0
     "%s: invalid range list.",
1952
0
     function );
1953
1954
0
    return( -1 );
1955
0
  }
1956
0
  if( libcdata_list_element_get_elements(
1957
0
       element,
1958
0
       &previous_element,
1959
0
       &next_element,
1960
0
       error ) != 1 )
1961
0
  {
1962
0
    libcerror_error_set(
1963
0
     error,
1964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1965
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1966
0
     "%s: unable to retrieve previous and next element from list element.",
1967
0
     function );
1968
1969
0
    return( -1 );
1970
0
  }
1971
0
  if( ( previous_element != NULL )
1972
0
   || ( next_element != NULL ) )
1973
0
  {
1974
0
    libcerror_error_set(
1975
0
     error,
1976
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1977
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1978
0
     "%s: list element already part of a list.",
1979
0
     function );
1980
1981
0
    return( -1 );
1982
0
  }
1983
0
  if( internal_range_list->number_of_elements == 0 )
1984
0
  {
1985
0
    if( internal_range_list->first_element != NULL )
1986
0
    {
1987
0
      libcerror_error_set(
1988
0
       error,
1989
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1990
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1991
0
       "%s: invalid range list - first element already set.",
1992
0
       function );
1993
1994
0
      return( -1 );
1995
0
    }
1996
0
    if( internal_range_list->last_element != NULL )
1997
0
    {
1998
0
      libcerror_error_set(
1999
0
       error,
2000
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2001
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2002
0
       "%s: invalid range list - last element already set.",
2003
0
       function );
2004
2005
0
      return( -1 );
2006
0
    }
2007
0
    internal_range_list->first_element = element;
2008
0
    internal_range_list->last_element  = element;
2009
0
  }
2010
0
  else
2011
0
  {
2012
0
    if( internal_range_list->first_element == NULL )
2013
0
    {
2014
0
      libcerror_error_set(
2015
0
       error,
2016
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2017
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2018
0
       "%s: invalid range list - missing first element.",
2019
0
       function );
2020
2021
0
      return( -1 );
2022
0
    }
2023
0
    if( internal_range_list->last_element == NULL )
2024
0
    {
2025
0
      libcerror_error_set(
2026
0
       error,
2027
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2028
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2029
0
       "%s: invalid range list - missing last element.",
2030
0
       function );
2031
2032
0
      return( -1 );
2033
0
    }
2034
0
    if( range_list_element == NULL )
2035
0
    {
2036
0
      if( libcdata_internal_range_list_set_first_element(
2037
0
           internal_range_list,
2038
0
           element,
2039
0
           error ) != 1 )
2040
0
      {
2041
0
        libcerror_error_set(
2042
0
         error,
2043
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2044
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2045
0
         "%s: unable to set first element.",
2046
0
         function );
2047
2048
0
        return( -1 );
2049
0
      }
2050
0
    }
2051
0
    else
2052
0
    {
2053
0
      if( libcdata_list_element_get_next_element(
2054
0
           range_list_element,
2055
0
           &next_element,
2056
0
           error ) != 1 )
2057
0
      {
2058
0
        libcerror_error_set(
2059
0
         error,
2060
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2061
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2062
0
         "%s: unable to retrieve next element from range list element.",
2063
0
         function );
2064
2065
0
        return( -1 );
2066
0
      }
2067
0
      if( libcdata_list_element_set_elements(
2068
0
           element,
2069
0
           range_list_element,
2070
0
           next_element,
2071
0
           error ) != 1 )
2072
0
      {
2073
0
        libcerror_error_set(
2074
0
         error,
2075
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2076
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2077
0
         "%s: unable to set previous and next element of list element.",
2078
0
         function );
2079
2080
0
        return( -1 );
2081
0
      }
2082
0
      if( range_list_element == internal_range_list->last_element )
2083
0
      {
2084
0
        internal_range_list->last_element = element;
2085
0
      }
2086
0
      else if( next_element == NULL )
2087
0
      {
2088
0
        libcerror_error_set(
2089
0
         error,
2090
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2091
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2092
0
         "%s: invalid range list element - missing next element.",
2093
0
         function );
2094
2095
0
        return( -1 );
2096
0
      }
2097
0
      else
2098
0
      {
2099
0
        if( libcdata_list_element_set_previous_element(
2100
0
             next_element,
2101
0
             element,
2102
0
             error ) != 1 )
2103
0
        {
2104
0
          libcerror_error_set(
2105
0
           error,
2106
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2107
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2108
0
           "%s: unable to set previous element of next element.",
2109
0
           function );
2110
2111
0
          return( -1 );
2112
0
        }
2113
0
      }
2114
0
      if( libcdata_list_element_set_next_element(
2115
0
           range_list_element,
2116
0
           element,
2117
0
           error ) != 1 )
2118
0
      {
2119
0
        libcerror_error_set(
2120
0
         error,
2121
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2122
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2123
0
         "%s: unable to set next element of range list element.",
2124
0
         function );
2125
2126
0
        return( -1 );
2127
0
      }
2128
0
    }
2129
0
  }
2130
0
  internal_range_list->number_of_elements += 1;
2131
2132
0
  return( 1 );
2133
0
}
2134
2135
/* Inserts the range list value in the range list after the range list element
2136
 * If range_list_element is NULL the value is inserted before the first element in the list
2137
 * Returns 1 if successful, or -1 on error
2138
 */
2139
int libcdata_internal_range_list_insert_value_after_element(
2140
     libcdata_internal_range_list_t *internal_range_list,
2141
     libcdata_list_element_t *range_list_element,
2142
     libcdata_range_list_value_t *value,
2143
     libcerror_error_t **error )
2144
0
{
2145
0
  libcdata_list_element_t *list_element = NULL;
2146
0
  static char *function                 = "libcdata_internal_range_list_insert_value_after_element";
2147
2148
0
  if( internal_range_list == NULL )
2149
0
  {
2150
0
    libcerror_error_set(
2151
0
     error,
2152
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2153
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2154
0
     "%s: invalid range list.",
2155
0
     function );
2156
2157
0
    return( -1 );
2158
0
  }
2159
0
  if( libcdata_list_element_initialize(
2160
0
       &list_element,
2161
0
       error ) != 1 )
2162
0
  {
2163
0
    libcerror_error_set(
2164
0
     error,
2165
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2166
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2167
0
     "%s: unable to create list element.",
2168
0
     function );
2169
2170
0
    goto on_error;
2171
0
  }
2172
0
  if( libcdata_list_element_set_value(
2173
0
       list_element,
2174
0
       (intptr_t *) value,
2175
0
       error ) != 1 )
2176
0
  {
2177
0
    libcerror_error_set(
2178
0
     error,
2179
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2180
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2181
0
     "%s: unable to set value in list element.",
2182
0
     function );
2183
2184
0
    goto on_error;
2185
0
  }
2186
0
  if( libcdata_internal_range_list_insert_element_after_element(
2187
0
       internal_range_list,
2188
0
       range_list_element,
2189
0
       list_element,
2190
0
       error ) != 1 )
2191
0
  {
2192
0
    libcerror_error_set(
2193
0
     error,
2194
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2195
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2196
0
     "%s: unable to insert element after range list element.",
2197
0
     function );
2198
2199
0
    goto on_error;
2200
0
  }
2201
0
  list_element = NULL;
2202
2203
0
  return( 1 );
2204
2205
0
on_error:
2206
0
  if( list_element != NULL )
2207
0
  {
2208
0
    libcdata_list_element_free(
2209
0
     &list_element,
2210
0
     NULL,
2211
0
     NULL );
2212
0
  }
2213
0
  return( -1 );
2214
0
}
2215
2216
/* Merges the range into the range list element
2217
 * Returns 1 if successful, or -1 on error
2218
 */
2219
int libcdata_internal_range_list_merge_range(
2220
     libcdata_internal_range_list_t *internal_range_list,
2221
     libcdata_list_element_t *range_list_element,
2222
     uint64_t range_start,
2223
     uint64_t range_end,
2224
     intptr_t *value,
2225
     int (*value_merge_function)(
2226
            intptr_t *destination_value,
2227
            intptr_t *source_value,
2228
            libcerror_error_t **error ),
2229
     libcerror_error_t **error )
2230
50.9k
{
2231
50.9k
  libcdata_range_list_value_t *range_list_value = NULL;
2232
50.9k
  static char *function                         = "libcdata_internal_range_list_merge_range";
2233
2234
50.9k
  if( internal_range_list == NULL )
2235
0
  {
2236
0
    libcerror_error_set(
2237
0
     error,
2238
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2239
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2240
0
     "%s: invalid range list.",
2241
0
     function );
2242
2243
0
    return( -1 );
2244
0
  }
2245
50.9k
  if( libcdata_list_element_get_value(
2246
50.9k
       range_list_element,
2247
50.9k
       (intptr_t **) &range_list_value,
2248
50.9k
       error ) != 1 )
2249
0
  {
2250
0
    libcerror_error_set(
2251
0
     error,
2252
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2253
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2254
0
     "%s: unable to retrieve value from range list element.",
2255
0
     function );
2256
2257
0
    return( -1 );
2258
0
  }
2259
50.9k
  if( range_list_value == NULL )
2260
0
  {
2261
0
    libcerror_error_set(
2262
0
     error,
2263
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2264
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2265
0
     "%s: missing range list value.",
2266
0
     function );
2267
2268
0
    return( -1 );
2269
0
  }
2270
50.9k
  if( range_list_value->value != NULL )
2271
0
  {
2272
0
    if( value_merge_function == NULL )
2273
0
    {
2274
0
      libcerror_error_set(
2275
0
       error,
2276
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2277
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2278
0
       "%s: invalid value merge function.",
2279
0
       function );
2280
2281
0
      return( -1 );
2282
0
    }
2283
0
  }
2284
50.9k
  if( range_list_value->value == NULL )
2285
50.9k
  {
2286
50.9k
    range_list_value->value = value;
2287
50.9k
  }
2288
0
  else
2289
0
  {
2290
0
    if( value_merge_function(
2291
0
         range_list_value->value,
2292
0
         value,
2293
0
         error ) != 1 )
2294
0
    {
2295
0
      libcerror_error_set(
2296
0
       error,
2297
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2298
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2299
0
       "%s: unable to merge value.",
2300
0
       function );
2301
2302
0
      return( -1 );
2303
0
    }
2304
0
  }
2305
50.9k
  if( range_start < range_list_value->start )
2306
3.28k
  {
2307
3.28k
    range_list_value->size += range_list_value->start - range_start;
2308
3.28k
    range_list_value->start = range_start;
2309
3.28k
  }
2310
50.9k
  if( range_end > range_list_value->end )
2311
42.8k
  {
2312
42.8k
    range_list_value->size += range_end - range_list_value->end;
2313
42.8k
    range_list_value->end   = range_end;
2314
42.8k
  }
2315
50.9k
  return( 1 );
2316
50.9k
}
2317
2318
/* Merges successive overlapping ranges
2319
 * Returns 1 if successful, or -1 on error
2320
 */
2321
int libcdata_internal_range_list_merge_overlapping_ranges(
2322
     libcdata_internal_range_list_t *internal_range_list,
2323
     libcdata_list_element_t *range_list_element,
2324
     int (*value_merge_function)(
2325
            intptr_t *destination_value,
2326
            intptr_t *source_value,
2327
            libcerror_error_t **error ),
2328
     libcdata_range_list_t *backup_range_list,
2329
     libcerror_error_t **error )
2330
48.2k
{
2331
48.2k
  libcdata_list_element_t *list_element              = NULL;
2332
48.2k
  libcdata_list_element_t *next_element              = NULL;
2333
48.2k
  libcdata_range_list_value_t *next_range_list_value = NULL;
2334
48.2k
  static char *function                              = "libcdata_internal_range_list_merge_overlapping_ranges";
2335
48.2k
  int result                                         = 0;
2336
2337
48.2k
  if( internal_range_list == NULL )
2338
0
  {
2339
0
    libcerror_error_set(
2340
0
     error,
2341
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2342
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2343
0
     "%s: invalid range list.",
2344
0
     function );
2345
2346
0
    return( -1 );
2347
0
  }
2348
48.2k
  if( libcdata_list_element_get_next_element(
2349
48.2k
       range_list_element,
2350
48.2k
       &next_element,
2351
48.2k
       error ) != 1 )
2352
0
  {
2353
0
    libcerror_error_set(
2354
0
     error,
2355
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2356
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2357
0
     "%s: unable to retrieve next element from range list element.",
2358
0
     function );
2359
2360
0
    return( -1 );
2361
0
  }
2362
50.9k
  while( next_element != NULL )
2363
10.2k
  {
2364
10.2k
    list_element = next_element;
2365
2366
10.2k
    if( libcdata_list_element_get_next_element(
2367
10.2k
         list_element,
2368
10.2k
         &next_element,
2369
10.2k
         error ) != 1 )
2370
0
    {
2371
0
      libcerror_error_set(
2372
0
       error,
2373
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2374
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2375
0
       "%s: unable to retrieve next element.",
2376
0
       function );
2377
2378
0
      return( -1 );
2379
0
    }
2380
10.2k
    if( libcdata_list_element_get_value(
2381
10.2k
         list_element,
2382
10.2k
         (intptr_t **) &next_range_list_value,
2383
10.2k
         error ) != 1 )
2384
0
    {
2385
0
      libcerror_error_set(
2386
0
       error,
2387
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2388
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2389
0
       "%s: unable to retrieve value from next element.",
2390
0
       function );
2391
2392
0
      return( -1 );
2393
0
    }
2394
10.2k
    if( next_range_list_value == NULL )
2395
0
    {
2396
0
      libcerror_error_set(
2397
0
       error,
2398
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2399
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2400
0
       "%s: missing next range list value.",
2401
0
       function );
2402
2403
0
      return( -1 );
2404
0
    }
2405
10.2k
    result = libcdata_internal_range_list_check_range_overlap(
2406
10.2k
              internal_range_list,
2407
10.2k
              range_list_element,
2408
10.2k
              next_range_list_value->start,
2409
10.2k
              next_range_list_value->end,
2410
10.2k
              error );
2411
2412
10.2k
    if( result == -1 )
2413
0
    {
2414
0
      libcerror_error_set(
2415
0
       error,
2416
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2417
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2418
0
       "%s: unable to determine if next range overlaps with range list element.",
2419
0
       function );
2420
2421
0
      return( -1 );
2422
0
    }
2423
10.2k
    else if( result == 0 )
2424
7.51k
    {
2425
7.51k
      break;
2426
7.51k
    }
2427
2.71k
    if( libcdata_internal_range_list_append_value(
2428
2.71k
         (libcdata_internal_range_list_t *) backup_range_list,
2429
2.71k
         next_range_list_value,
2430
2.71k
         error ) != 1 )
2431
0
    {
2432
0
      libcerror_error_set(
2433
0
       error,
2434
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2435
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2436
0
       "%s: unable to append value to backup range list.",
2437
0
       function );
2438
2439
0
      return( -1 );
2440
0
    }
2441
2.71k
    if( libcdata_internal_range_list_remove_element(
2442
2.71k
         internal_range_list,
2443
2.71k
         list_element,
2444
2.71k
         error ) != 1 )
2445
0
    {
2446
0
      libcerror_error_set(
2447
0
       error,
2448
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2449
0
       LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
2450
0
       "%s: unable to remove list element.",
2451
0
       function );
2452
2453
0
      return( -1 );
2454
0
    }
2455
2.71k
    if( libcdata_list_element_free(
2456
2.71k
         &list_element,
2457
2.71k
         NULL,
2458
2.71k
         error ) != 1 )
2459
0
    {
2460
0
      libcerror_error_set(
2461
0
       error,
2462
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2463
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2464
0
       "%s: unable to free list element.",
2465
0
       function );
2466
2467
0
      return( -1 );
2468
0
    }
2469
2.71k
    if( libcdata_internal_range_list_merge_range(
2470
2.71k
         internal_range_list,
2471
2.71k
         range_list_element,
2472
2.71k
         next_range_list_value->start,
2473
2.71k
         next_range_list_value->end,
2474
2.71k
         next_range_list_value->value,
2475
2.71k
         value_merge_function,
2476
2.71k
         error ) != 1 )
2477
0
    {
2478
0
      libcerror_error_set(
2479
0
       error,
2480
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2481
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2482
0
       "%s: unable to merge next range with range list element.",
2483
0
       function );
2484
2485
0
      return( -1 );
2486
0
    }
2487
2.71k
  }
2488
48.2k
  return( 1 );
2489
48.2k
}
2490
2491
/* Inserts a range by merging the range into the range list element and successive overlapping ranges
2492
 * Returns 1 if successful or -1 on error
2493
 */
2494
int libcdata_internal_range_list_insert_range_merge(
2495
     libcdata_internal_range_list_t *internal_range_list,
2496
     libcdata_list_element_t *range_list_element,
2497
     uint64_t range_start,
2498
     uint64_t range_end,
2499
     intptr_t *value,
2500
     int (*value_merge_function)(
2501
            intptr_t *destination_value,
2502
            intptr_t *source_value,
2503
            libcerror_error_t **error ),
2504
     libcdata_range_list_t *backup_range_list,
2505
     libcerror_error_t **error )
2506
48.2k
{
2507
48.2k
  libcdata_range_list_value_t *backup_range_list_value = NULL;
2508
48.2k
  libcdata_range_list_value_t *range_list_value        = NULL;
2509
48.2k
  static char *function                                = "libcdata_internal_range_list_insert_range_merge";
2510
2511
48.2k
  if( internal_range_list == NULL )
2512
0
  {
2513
0
    libcerror_error_set(
2514
0
     error,
2515
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2516
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2517
0
     "%s: invalid range list.",
2518
0
     function );
2519
2520
0
    return( -1 );
2521
0
  }
2522
48.2k
  if( libcdata_list_element_get_value(
2523
48.2k
       range_list_element,
2524
48.2k
       (intptr_t **) &range_list_value,
2525
48.2k
       error ) != 1 )
2526
0
  {
2527
0
    libcerror_error_set(
2528
0
     error,
2529
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2530
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2531
0
     "%s: unable to retrieve value from range list element.",
2532
0
     function );
2533
2534
0
    goto on_error;
2535
0
  }
2536
48.2k
  if( libcdata_range_list_value_initialize(
2537
48.2k
       &backup_range_list_value,
2538
48.2k
       error ) != 1 )
2539
0
  {
2540
0
    libcerror_error_set(
2541
0
     error,
2542
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2543
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2544
0
     "%s: unable to create backup range list value.",
2545
0
     function );
2546
2547
0
    goto on_error;
2548
0
  }
2549
48.2k
  backup_range_list_value->start = range_list_value->start;
2550
48.2k
  backup_range_list_value->end   = range_list_value->end;
2551
48.2k
  backup_range_list_value->size  = range_list_value->size;
2552
2553
48.2k
  if( libcdata_internal_range_list_append_value(
2554
48.2k
       (libcdata_internal_range_list_t *) backup_range_list,
2555
48.2k
       backup_range_list_value,
2556
48.2k
       error ) != 1 )
2557
0
  {
2558
0
    libcerror_error_set(
2559
0
     error,
2560
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2561
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2562
0
     "%s: unable to append value to backup range list.",
2563
0
     function );
2564
2565
0
    goto on_error;
2566
0
  }
2567
48.2k
  backup_range_list_value = NULL;
2568
2569
48.2k
  if( libcdata_internal_range_list_merge_range(
2570
48.2k
       internal_range_list,
2571
48.2k
       range_list_element,
2572
48.2k
       range_start,
2573
48.2k
       range_end,
2574
48.2k
       value,
2575
48.2k
       value_merge_function,
2576
48.2k
       error ) != 1 )
2577
0
  {
2578
0
    libcerror_error_set(
2579
0
     error,
2580
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2581
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2582
0
     "%s: unable to merge range with range list element.",
2583
0
     function );
2584
2585
0
    goto on_error;
2586
0
  }
2587
48.2k
  if( libcdata_internal_range_list_merge_overlapping_ranges(
2588
48.2k
       internal_range_list,
2589
48.2k
       range_list_element,
2590
48.2k
       value_merge_function,
2591
48.2k
       backup_range_list,
2592
48.2k
       error ) != 1 )
2593
0
  {
2594
0
    libcerror_error_set(
2595
0
     error,
2596
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2597
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2598
0
     "%s: unable to merge range list element with overlapping ranges.",
2599
0
     function );
2600
2601
0
    goto on_error;
2602
0
  }
2603
48.2k
  return( 1 );
2604
2605
0
on_error:
2606
0
  if( backup_range_list_value != NULL )
2607
0
  {
2608
0
    libcdata_range_list_value_free(
2609
0
     &backup_range_list_value,
2610
0
     NULL,
2611
0
     NULL );
2612
0
  }
2613
0
  return( -1 );
2614
48.2k
}
2615
2616
/* Reverts a previously merge of the range list element and successive overlapping ranges
2617
 * Returns 1 if successful or -1 on error
2618
 */
2619
int libcdata_internal_range_list_insert_range_revert_merge(
2620
     libcdata_internal_range_list_t *internal_range_list,
2621
     libcdata_list_element_t *range_list_element,
2622
     libcdata_range_list_t *backup_range_list,
2623
     libcerror_error_t **error )
2624
0
{
2625
0
  libcdata_internal_range_list_t *internal_backup_range_list = NULL;
2626
0
  libcdata_list_element_t *backup_range_list_element         = NULL;
2627
0
  libcdata_range_list_value_t *backup_range_list_value       = NULL;
2628
0
  libcdata_range_list_value_t *range_list_value              = NULL;
2629
0
  static char *function                                      = "libcdata_internal_range_list_insert_range_revert_merge";
2630
2631
0
  if( internal_range_list == NULL )
2632
0
  {
2633
0
    libcerror_error_set(
2634
0
     error,
2635
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2636
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2637
0
     "%s: invalid range list.",
2638
0
     function );
2639
2640
0
    return( -1 );
2641
0
  }
2642
0
  if( backup_range_list == NULL )
2643
0
  {
2644
0
    libcerror_error_set(
2645
0
     error,
2646
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2647
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2648
0
     "%s: invalid backup range list.",
2649
0
     function );
2650
2651
0
    return( -1 );
2652
0
  }
2653
0
  internal_backup_range_list = (libcdata_internal_range_list_t *) backup_range_list;
2654
2655
0
  if( internal_backup_range_list->first_element == NULL )
2656
0
  {
2657
0
    return( 1 );
2658
0
  }
2659
0
  if( libcdata_list_element_get_value(
2660
0
       internal_backup_range_list->first_element,
2661
0
       (intptr_t **) &backup_range_list_value,
2662
0
       error ) != 1 )
2663
0
  {
2664
0
    libcerror_error_set(
2665
0
     error,
2666
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2667
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2668
0
     "%s: unable to retrieve value from first backup range list element.",
2669
0
     function );
2670
2671
0
    return( -1 );
2672
0
  }
2673
0
  if( libcdata_list_element_get_value(
2674
0
       range_list_element,
2675
0
       (intptr_t **) &range_list_value,
2676
0
       error ) != 1 )
2677
0
  {
2678
0
    libcerror_error_set(
2679
0
     error,
2680
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2681
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2682
0
     "%s: unable to retrieve value from range list element.",
2683
0
     function );
2684
2685
0
    return( -1 );
2686
0
  }
2687
0
  range_list_value->start = backup_range_list_value->start;
2688
0
  range_list_value->end   = backup_range_list_value->end;
2689
0
  range_list_value->size  = backup_range_list_value->size;
2690
2691
0
  while( internal_backup_range_list->first_element != NULL )
2692
0
  {
2693
0
    if( libcdata_list_element_get_next_element(
2694
0
         internal_backup_range_list->first_element,
2695
0
         &backup_range_list_element,
2696
0
         error ) != 1 )
2697
0
    {
2698
0
      libcerror_error_set(
2699
0
       error,
2700
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2701
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2702
0
       "%s: unable to retrieve next element from first backup range list element.",
2703
0
       function );
2704
2705
0
      return( -1 );
2706
0
    }
2707
0
    if( backup_range_list_element == NULL )
2708
0
    {
2709
0
      break;
2710
0
    }
2711
0
    if( libcdata_internal_range_list_remove_element(
2712
0
         internal_backup_range_list,
2713
0
         backup_range_list_element,
2714
0
         error ) != 1 )
2715
0
    {
2716
0
      libcerror_error_set(
2717
0
       error,
2718
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2719
0
       LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
2720
0
       "%s: unable to remove backup range list element.",
2721
0
       function );
2722
2723
0
      return( -1 );
2724
0
    }
2725
0
    if( libcdata_internal_range_list_insert_element_after_element(
2726
0
         internal_range_list,
2727
0
         range_list_element,
2728
0
         backup_range_list_element,
2729
0
         error ) != 1 )
2730
0
    {
2731
0
      libcerror_error_set(
2732
0
       error,
2733
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2734
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2735
0
       "%s: unable to insert element after range list element.",
2736
0
       function );
2737
2738
0
      return( -1 );
2739
0
    }
2740
0
    backup_range_list_element = NULL;
2741
0
  }
2742
0
  return( 1 );
2743
0
}
2744
2745
/* Inserts a range
2746
 *
2747
 * The values are merged using the value_merge_function.
2748
 * If the source value is NULL the merge function is not called.
2749
 *
2750
 * After a merge and on error the values are freed using
2751
 * the value_free_function
2752
 *
2753
 * Returns 1 if successful, 0 if the range was merged or -1 on error
2754
 */
2755
int libcdata_range_list_insert_range(
2756
     libcdata_range_list_t *range_list,
2757
     uint64_t range_start,
2758
     uint64_t range_size,
2759
     intptr_t *value,
2760
     int (*value_free_function)(
2761
            intptr_t **value,
2762
            libcerror_error_t **error ),
2763
     int (*value_merge_function)(
2764
            intptr_t *destination_value,
2765
            intptr_t *source_value,
2766
            libcerror_error_t **error ),
2767
     libcerror_error_t **error )
2768
24.4M
{
2769
24.4M
  libcdata_internal_range_list_t *internal_range_list = NULL;
2770
24.4M
  libcdata_list_element_t *list_element               = NULL;
2771
24.4M
  libcdata_list_element_t *new_element                = NULL;
2772
24.4M
  libcdata_range_list_t *backup_range_list            = NULL;
2773
24.4M
  static char *function                               = "libcdata_range_list_insert_range";
2774
24.4M
  uint64_t range_end                                  = 0;
2775
24.4M
  int element_index                                   = 0;
2776
24.4M
  int result                                          = 1;
2777
2778
24.4M
  if( range_list == NULL )
2779
0
  {
2780
0
    libcerror_error_set(
2781
0
     error,
2782
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2783
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2784
0
     "%s: invalid range list.",
2785
0
     function );
2786
2787
0
    return( -1 );
2788
0
  }
2789
24.4M
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
2790
2791
24.4M
  if( range_start > (uint64_t) INT64_MAX )
2792
0
  {
2793
0
    libcerror_error_set(
2794
0
     error,
2795
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2796
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2797
0
     "%s: invalid range start value exceeds maximum.",
2798
0
     function );
2799
2800
0
    return( -1 );
2801
0
  }
2802
24.4M
  if( range_size > (uint64_t) INT64_MAX )
2803
0
  {
2804
0
    libcerror_error_set(
2805
0
     error,
2806
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2807
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2808
0
     "%s: invalid range size value exceeds maximum.",
2809
0
     function );
2810
2811
0
    return( -1 );
2812
0
  }
2813
24.4M
  range_end = range_start + range_size;
2814
2815
24.4M
  if( range_end < range_start )
2816
0
  {
2817
0
    libcerror_error_set(
2818
0
     error,
2819
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2820
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2821
0
     "%s: invalid range end value out of bounds.",
2822
0
     function );
2823
2824
0
    return( -1 );
2825
0
  }
2826
24.4M
  if( libcdata_range_list_initialize(
2827
24.4M
       &backup_range_list,
2828
24.4M
       error ) != 1 )
2829
0
  {
2830
0
    libcerror_error_set(
2831
0
     error,
2832
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2833
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2834
0
     "%s: unable to create backup range list.",
2835
0
     function );
2836
2837
0
    return( -1 );
2838
0
  }
2839
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
2840
  if( libcthreads_read_write_lock_grab_for_write(
2841
       internal_range_list->read_write_lock,
2842
       error ) != 1 )
2843
  {
2844
    libcerror_error_set(
2845
     error,
2846
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2847
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2848
     "%s: unable to grab read/write lock for writing.",
2849
     function );
2850
2851
    libcdata_range_list_free(
2852
     &backup_range_list,
2853
     NULL,
2854
     NULL );
2855
2856
    return( -1 );
2857
  }
2858
#endif
2859
24.4M
  if( libcdata_internal_range_list_insert_range_find_element(
2860
24.4M
       internal_range_list,
2861
24.4M
       range_start,
2862
24.4M
       range_end,
2863
24.4M
       &element_index,
2864
24.4M
       &list_element,
2865
24.4M
       error ) != 1 )
2866
0
  {
2867
0
    libcerror_error_set(
2868
0
     error,
2869
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2870
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2871
0
     "%s: unable to find element in list.",
2872
0
     function );
2873
2874
0
    result = -1;
2875
0
  }
2876
24.4M
  if( result == 1 )
2877
24.4M
  {
2878
24.4M
    result = libcdata_internal_range_list_check_range_overlap(
2879
24.4M
              internal_range_list,
2880
24.4M
              list_element,
2881
24.4M
              range_start,
2882
24.4M
              range_end,
2883
24.4M
              error );
2884
2885
24.4M
    if( result == -1 )
2886
0
    {
2887
0
      libcerror_error_set(
2888
0
       error,
2889
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2890
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2891
0
       "%s: unable to determine if range overlaps with range list element: %d.",
2892
0
       function,
2893
0
       element_index );
2894
2895
0
      result = -1;
2896
0
    }
2897
24.4M
  }
2898
24.4M
  if( result == 0 )
2899
24.4M
  {
2900
24.4M
    result = 1;
2901
2902
24.4M
    if( libcdata_internal_range_list_insert_range_before_element(
2903
24.4M
         internal_range_list,
2904
24.4M
         list_element,
2905
24.4M
         range_start,
2906
24.4M
         range_end,
2907
24.4M
         value,
2908
24.4M
         &new_element,
2909
24.4M
         error ) != 1 )
2910
0
    {
2911
0
      libcerror_error_set(
2912
0
       error,
2913
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2914
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2915
0
       "%s: unable to insert range before range list element.",
2916
0
       function );
2917
2918
0
      result = -1;
2919
0
    }
2920
24.4M
  }
2921
48.2k
  else if( result != -1 )
2922
48.2k
  {
2923
48.2k
    result = 0;
2924
2925
48.2k
    if( libcdata_internal_range_list_insert_range_merge(
2926
48.2k
         internal_range_list,
2927
48.2k
         list_element,
2928
48.2k
         range_start,
2929
48.2k
         range_end,
2930
48.2k
         value,
2931
48.2k
         value_merge_function,
2932
48.2k
         backup_range_list,
2933
48.2k
         error ) != 1 )
2934
0
    {
2935
0
      libcerror_error_set(
2936
0
       error,
2937
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2938
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2939
0
       "%s: unable to merge range with list element: %d.",
2940
0
       function,
2941
0
       element_index );
2942
2943
0
      result = -1;
2944
0
    }
2945
48.2k
  }
2946
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
2947
  if( libcthreads_read_write_lock_release_for_write(
2948
       internal_range_list->read_write_lock,
2949
       error ) != 1 )
2950
  {
2951
    libcerror_error_set(
2952
     error,
2953
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2954
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2955
     "%s: unable to release read/write lock for writing.",
2956
     function );
2957
2958
    goto on_error;
2959
  }
2960
#endif
2961
24.4M
  libcdata_range_list_free(
2962
24.4M
   &backup_range_list,
2963
24.4M
   value_free_function,
2964
24.4M
   NULL );
2965
2966
24.4M
  return( result );
2967
2968
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
2969
on_error:
2970
  if( result == 0 )
2971
  {
2972
    libcdata_internal_range_list_insert_range_revert_merge(
2973
     internal_range_list,
2974
     list_element,
2975
     backup_range_list,
2976
     NULL );
2977
  }
2978
  else if( result == 1 )
2979
  {
2980
    libcdata_internal_range_list_remove_range_value(
2981
     internal_range_list,
2982
     &new_element,
2983
     NULL,
2984
     NULL );
2985
  }
2986
  libcdata_range_list_free(
2987
   &backup_range_list,
2988
   NULL,
2989
   NULL );
2990
2991
  return( -1 );
2992
#endif
2993
24.4M
}
2994
2995
/* Inserts a range list
2996
 *
2997
 * The values are merged using the value_merge_function.
2998
 * If the source value is NULL the merge function is not called.
2999
 *
3000
 * After a merge and on error the values are freed using
3001
 * the value_free_function
3002
 *
3003
 * The values in the source_range_list are not affected.
3004
 *
3005
 * Returns 1 if successful, or -1 on error
3006
 */
3007
int libcdata_range_list_insert_range_list(
3008
     libcdata_range_list_t *range_list,
3009
     libcdata_range_list_t *source_range_list,
3010
     int (*value_free_function)(
3011
            intptr_t **value,
3012
            libcerror_error_t **error ),
3013
     int (*value_merge_function)(
3014
            intptr_t *destination_value,
3015
            intptr_t *source_value,
3016
            libcerror_error_t **error ),
3017
     libcerror_error_t **error )
3018
0
{
3019
0
  libcdata_list_element_t *source_list_element         = NULL;
3020
0
  libcdata_range_list_value_t *source_range_list_value = NULL;
3021
0
  static char *function                                = "libcdata_range_list_insert_range_list";
3022
0
  int element_index                                    = 0;
3023
0
  int number_of_elements                               = 0;
3024
0
  int result                                           = 0;
3025
3026
0
  if( range_list == NULL )
3027
0
  {
3028
0
    libcerror_error_set(
3029
0
     error,
3030
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3031
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3032
0
     "%s: invalid range list.",
3033
0
     function );
3034
3035
0
    return( -1 );
3036
0
  }
3037
0
  if( source_range_list == NULL )
3038
0
  {
3039
0
    libcerror_error_set(
3040
0
     error,
3041
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3042
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3043
0
     "%s: invalid source range list.",
3044
0
     function );
3045
3046
0
    return( -1 );
3047
0
  }
3048
0
  if( libcdata_range_list_get_number_of_elements(
3049
0
       source_range_list,
3050
0
       &number_of_elements,
3051
0
       error ) != 1 )
3052
0
  {
3053
0
    libcerror_error_set(
3054
0
     error,
3055
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3056
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3057
0
     "%s: unable to retrieve number of source list elements.",
3058
0
     function );
3059
3060
0
    return( -1 );
3061
0
  }
3062
0
  if( libcdata_range_list_get_first_element(
3063
0
       source_range_list,
3064
0
       &source_list_element,
3065
0
       error ) != 1 )
3066
0
  {
3067
0
    libcerror_error_set(
3068
0
     error,
3069
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3070
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3071
0
     "%s: unable to retrieve first element from source list.",
3072
0
     function );
3073
3074
0
    return( -1 );
3075
0
  }
3076
0
  for( element_index = 0;
3077
0
       element_index < number_of_elements;
3078
0
       element_index++ )
3079
0
  {
3080
0
    if( libcdata_list_element_get_value(
3081
0
         source_list_element,
3082
0
         (intptr_t **) &source_range_list_value,
3083
0
         error ) != 1 )
3084
0
    {
3085
0
      libcerror_error_set(
3086
0
       error,
3087
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3088
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3089
0
       "%s: unable to retrieve value from source list element: %d.",
3090
0
       function,
3091
0
       element_index );
3092
3093
0
      return( -1 );
3094
0
    }
3095
0
    result = libcdata_range_list_insert_range(
3096
0
              range_list,
3097
0
              source_range_list_value->start,
3098
0
              source_range_list_value->size,
3099
0
              source_range_list_value->value,
3100
0
              value_free_function,
3101
0
              value_merge_function,
3102
0
              error );
3103
3104
0
    if( result == -1 )
3105
0
    {
3106
0
      libcerror_error_set(
3107
0
       error,
3108
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3109
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3110
0
       "%s: unable to insert source range list value: %d to range list.",
3111
0
       function,
3112
0
       element_index );
3113
3114
0
      return( -1 );
3115
0
    }
3116
0
    if( libcdata_list_element_get_next_element(
3117
0
         source_list_element,
3118
0
         &source_list_element,
3119
0
         error ) != 1 )
3120
0
    {
3121
0
      libcerror_error_set(
3122
0
       error,
3123
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3124
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3125
0
       "%s: unable to retrieve next element from source list element: %d.",
3126
0
       function,
3127
0
       element_index );
3128
3129
0
      return( -1 );
3130
0
    }
3131
0
  }
3132
0
  return( 1 );
3133
0
}
3134
3135
/* Shrinks a range
3136
 *
3137
 * A range that either overlaps the start or the end of the range list element
3138
 * is removed by shrining the range of the range list element.
3139
 *
3140
 * Returns 1 if successful, or -1 on error
3141
 */
3142
int libcdata_internal_range_list_remove_shrink_range(
3143
     libcdata_internal_range_list_t *internal_range_list,
3144
     libcdata_list_element_t *range_list_element,
3145
     libcdata_range_list_value_t *range_list_value,
3146
     uint64_t range_start,
3147
     uint64_t range_end,
3148
     int (*value_free_function)(
3149
            intptr_t **value,
3150
            libcerror_error_t **error ),
3151
     int (*value_split_function)(
3152
            intptr_t **destination_value,
3153
            intptr_t *source_value,
3154
            uint64_t split_range_offset,
3155
            libcerror_error_t **error ),
3156
     libcerror_error_t **error )
3157
0
{
3158
0
  intptr_t *split_value = NULL;
3159
0
  static char *function = "libcdata_internal_range_list_remove_shrink_range";
3160
0
  uint64_t split_offset = 0;
3161
3162
0
  if( internal_range_list == NULL )
3163
0
  {
3164
0
    libcerror_error_set(
3165
0
     error,
3166
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3167
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3168
0
     "%s: invalid range list.",
3169
0
     function );
3170
3171
0
    return( -1 );
3172
0
  }
3173
0
  if( range_list_element == NULL )
3174
0
  {
3175
0
    libcerror_error_set(
3176
0
     error,
3177
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3178
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3179
0
     "%s: invalid range list element.",
3180
0
     function );
3181
3182
0
    return( -1 );
3183
0
  }
3184
0
  if( range_list_value == NULL )
3185
0
  {
3186
0
    libcerror_error_set(
3187
0
     error,
3188
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3189
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3190
0
     "%s: invalid range list value.",
3191
0
     function );
3192
3193
0
    return( -1 );
3194
0
  }
3195
0
  if( ( range_start > range_list_value->start )
3196
0
   && ( range_end < range_list_value->end ) )
3197
0
  {
3198
0
    libcerror_error_set(
3199
0
     error,
3200
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3201
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3202
0
     "%s: invalid range value out of bounds.",
3203
0
     function );
3204
3205
0
    return( -1 );
3206
0
  }
3207
0
  if( range_list_value->value != NULL )
3208
0
  {
3209
0
    if( value_free_function == NULL )
3210
0
    {
3211
0
      libcerror_error_set(
3212
0
       error,
3213
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3214
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3215
0
       "%s: invalid value free function.",
3216
0
       function );
3217
3218
0
      return( -1 );
3219
0
    }
3220
0
    if( value_split_function == NULL )
3221
0
    {
3222
0
      libcerror_error_set(
3223
0
       error,
3224
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3225
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3226
0
       "%s: invalid value split function.",
3227
0
       function );
3228
3229
0
      return( -1 );
3230
0
    }
3231
0
  }
3232
0
  if( range_start <= range_list_value->start )
3233
0
  {
3234
0
    split_offset = range_end;
3235
0
  }
3236
0
  else
3237
0
  {
3238
0
    split_offset = range_start;
3239
0
  }
3240
0
  if( range_list_value->value != NULL )
3241
0
  {
3242
0
    if( value_split_function(
3243
0
         &split_value,
3244
0
         range_list_value->value,
3245
0
         split_offset,
3246
0
         error ) != 1 )
3247
0
    {
3248
0
      libcerror_error_set(
3249
0
       error,
3250
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3251
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3252
0
       "%s: unable to split value range offset: %" PRIu64 ".",
3253
0
       function,
3254
0
       split_offset );
3255
3256
0
      goto on_error;
3257
0
    }
3258
0
    if( value_free_function(
3259
0
         &( range_list_value->value ),
3260
0
         error ) != 1 )
3261
0
    {
3262
0
      libcerror_error_set(
3263
0
       error,
3264
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3265
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3266
0
       "%s: unable to free value.",
3267
0
       function );
3268
3269
0
      range_list_value->value = split_value;
3270
3271
0
      goto on_error;
3272
0
    }
3273
0
    range_list_value->value = split_value;
3274
0
  }
3275
0
  if( split_offset > range_list_value->start )
3276
0
  {
3277
0
    range_list_value->start = split_offset;
3278
0
    range_list_value->size  = range_list_value->end - split_offset;
3279
0
  }
3280
0
  else
3281
0
  {
3282
0
    range_list_value->end  = split_offset;
3283
0
    range_list_value->size = split_offset - range_list_value->start;
3284
0
  }
3285
0
  return( 1 );
3286
3287
0
on_error:
3288
0
  return( -1 );
3289
0
}
3290
3291
/* Splits a range
3292
 *
3293
 * A range that either overlaps a part of the range list element
3294
 * is removed by splitting the range of the range list element.
3295
 *
3296
 * Returns 1 if successful, or -1 on error
3297
 */
3298
int libcdata_internal_range_list_remove_split_range(
3299
     libcdata_internal_range_list_t *internal_range_list,
3300
     libcdata_list_element_t *range_list_element,
3301
     libcdata_range_list_value_t *range_list_value,
3302
     uint64_t range_start,
3303
     uint64_t range_end,
3304
     int (*value_free_function)(
3305
            intptr_t **value,
3306
            libcerror_error_t **error ),
3307
     int (*value_split_function)(
3308
            intptr_t **destination_value,
3309
            intptr_t *source_value,
3310
            uint64_t split_range_offset,
3311
            libcerror_error_t **error ),
3312
     libcerror_error_t **error )
3313
0
{
3314
0
  libcdata_range_list_value_t *split_range_list_value = NULL;
3315
0
  static char *function                               = "libcdata_internal_range_list_remove_split_range";
3316
0
  uint64_t split_offset                               = 0;
3317
3318
0
  if( internal_range_list == NULL )
3319
0
  {
3320
0
    libcerror_error_set(
3321
0
     error,
3322
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3323
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3324
0
     "%s: invalid range list.",
3325
0
     function );
3326
3327
0
    return( -1 );
3328
0
  }
3329
0
  if( range_list_element == NULL )
3330
0
  {
3331
0
    libcerror_error_set(
3332
0
     error,
3333
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3334
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3335
0
     "%s: invalid range list element.",
3336
0
     function );
3337
3338
0
    return( -1 );
3339
0
  }
3340
0
  if( range_list_value == NULL )
3341
0
  {
3342
0
    libcerror_error_set(
3343
0
     error,
3344
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3345
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3346
0
     "%s: invalid range list value.",
3347
0
     function );
3348
3349
0
    return( -1 );
3350
0
  }
3351
0
  if( ( range_start <= range_list_value->start )
3352
0
   || ( range_end >= range_list_value->end ) )
3353
0
  {
3354
0
    libcerror_error_set(
3355
0
     error,
3356
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3357
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3358
0
     "%s: invalid range value out of bounds.",
3359
0
     function );
3360
3361
0
    return( -1 );
3362
0
  }
3363
0
  if( range_list_value->value != NULL )
3364
0
  {
3365
0
    if( value_free_function == NULL )
3366
0
    {
3367
0
      libcerror_error_set(
3368
0
       error,
3369
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3370
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3371
0
       "%s: invalid value free function.",
3372
0
       function );
3373
3374
0
      return( -1 );
3375
0
    }
3376
0
    if( value_split_function == NULL )
3377
0
    {
3378
0
      libcerror_error_set(
3379
0
       error,
3380
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3381
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3382
0
       "%s: invalid value split function.",
3383
0
       function );
3384
3385
0
      return( -1 );
3386
0
    }
3387
0
  }
3388
0
  split_offset = range_end;
3389
3390
0
  if( libcdata_range_list_value_initialize(
3391
0
       &split_range_list_value,
3392
0
       error ) != 1 )
3393
0
  {
3394
0
    libcerror_error_set(
3395
0
     error,
3396
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3397
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3398
0
     "%s: unable to create range list value.",
3399
0
     function );
3400
3401
0
    goto on_error;
3402
0
  }
3403
0
  if( split_range_list_value == NULL )
3404
0
  {
3405
0
    libcerror_error_set(
3406
0
     error,
3407
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3408
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3409
0
     "%s: missing range list value.",
3410
0
     function );
3411
3412
0
    goto on_error;
3413
0
  }
3414
0
  if( range_list_value->value != NULL )
3415
0
  {
3416
0
    if( value_split_function(
3417
0
         &( split_range_list_value->value ),
3418
0
         range_list_value->value,
3419
0
         split_offset,
3420
0
         error ) != 1 )
3421
0
    {
3422
0
      libcerror_error_set(
3423
0
       error,
3424
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3425
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3426
0
       "%s: unable to split value at range offset: %" PRIu64 ".",
3427
0
       function,
3428
0
       split_offset );
3429
3430
0
      goto on_error;
3431
0
    }
3432
0
  }
3433
0
  split_range_list_value->start = split_offset;
3434
0
  split_range_list_value->size  = range_list_value->end - split_offset;
3435
0
  split_range_list_value->end   = range_list_value->end;
3436
3437
0
  range_list_value->size = split_offset - range_list_value->start;
3438
0
  range_list_value->end  = split_offset;
3439
3440
0
  if( libcdata_internal_range_list_insert_value_after_element(
3441
0
       internal_range_list,
3442
0
       range_list_element,
3443
0
       split_range_list_value,
3444
0
       error ) != 1 )
3445
0
  {
3446
0
    libcerror_error_set(
3447
0
     error,
3448
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3449
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3450
0
     "%s: unable to insert range list value after range list element.",
3451
0
     function );
3452
3453
0
    goto on_error;
3454
0
  }
3455
0
  split_range_list_value = NULL;
3456
3457
0
  if( libcdata_internal_range_list_remove_shrink_range(
3458
0
       internal_range_list,
3459
0
       range_list_element,
3460
0
       range_list_value,
3461
0
       range_start,
3462
0
       range_end,
3463
0
       value_free_function,
3464
0
       value_split_function,
3465
0
       error ) != 1 )
3466
0
  {
3467
0
    libcerror_error_set(
3468
0
     error,
3469
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3470
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3471
0
     "%s: unable to shrink range.",
3472
0
     function );
3473
3474
0
    goto on_error;
3475
0
  }
3476
0
  return( 1 );
3477
3478
0
on_error:
3479
0
  if( split_range_list_value != NULL )
3480
0
  {
3481
0
    libcdata_range_list_value_free(
3482
0
     &split_range_list_value,
3483
0
     value_free_function,
3484
0
     NULL );
3485
0
  }
3486
0
  return( -1 );
3487
0
}
3488
3489
/* Removes a range
3490
 *
3491
 * The values are split using the value_merge_function.
3492
 * If the source value is NULL the split function is not called.
3493
 * On return destination_value of the value_merge_function
3494
 * should contain data greater equal to the split_range_offset.
3495
 *
3496
 * After a split and on error the values are freed using
3497
 * the value_free_function
3498
 *
3499
 * Returns 1 if successful, or -1 on error
3500
 */
3501
int libcdata_range_list_remove_range(
3502
     libcdata_range_list_t *range_list,
3503
     uint64_t range_start,
3504
     uint64_t range_size,
3505
     int (*value_free_function)(
3506
            intptr_t **value,
3507
            libcerror_error_t **error ),
3508
     int (*value_split_function)(
3509
            intptr_t **destination_value,
3510
            intptr_t *source_value,
3511
            uint64_t split_range_offset,
3512
            libcerror_error_t **error ),
3513
     libcerror_error_t **error )
3514
0
{
3515
0
  libcdata_internal_range_list_t *internal_range_list = NULL;
3516
0
  libcdata_list_element_t *list_element               = NULL;
3517
0
  libcdata_range_list_value_t *range_list_value       = NULL;
3518
0
  static char *function                               = "libcdata_range_list_remove_range";
3519
0
  uint64_t next_range_start                           = 0;
3520
0
  uint64_t range_end                                  = 0;
3521
0
  int result                                          = 1;
3522
3523
0
  if( range_list == NULL )
3524
0
  {
3525
0
    libcerror_error_set(
3526
0
     error,
3527
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3528
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3529
0
     "%s: invalid range list.",
3530
0
     function );
3531
3532
0
    return( -1 );
3533
0
  }
3534
0
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
3535
3536
0
  if( range_start > (uint64_t) INT64_MAX )
3537
0
  {
3538
0
    libcerror_error_set(
3539
0
     error,
3540
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3541
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3542
0
     "%s: invalid range start value exceeds maximum.",
3543
0
     function );
3544
3545
0
    return( -1 );
3546
0
  }
3547
0
  if( range_size > (uint64_t) INT64_MAX )
3548
0
  {
3549
0
    libcerror_error_set(
3550
0
     error,
3551
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3552
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3553
0
     "%s: invalid range size value exceeds maximum.",
3554
0
     function );
3555
3556
0
    return( -1 );
3557
0
  }
3558
0
  range_end = range_start + range_size;
3559
3560
0
  if( range_end < range_start )
3561
0
  {
3562
0
    libcerror_error_set(
3563
0
     error,
3564
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3565
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3566
0
     "%s: invalid range end value out of bounds.",
3567
0
     function );
3568
3569
0
    return( -1 );
3570
0
  }
3571
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
3572
  if( libcthreads_read_write_lock_grab_for_write(
3573
       internal_range_list->read_write_lock,
3574
       error ) != 1 )
3575
  {
3576
    libcerror_error_set(
3577
     error,
3578
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3579
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3580
     "%s: unable to grab read/write lock for writing.",
3581
     function );
3582
3583
    return( -1 );
3584
  }
3585
#endif
3586
0
  while( range_start < range_end )
3587
0
  {
3588
0
    result = libcdata_internal_range_list_get_element_at_offset(
3589
0
              internal_range_list,
3590
0
              range_start,
3591
0
              &list_element,
3592
0
              error );
3593
3594
0
    if( result == -1 )
3595
0
    {
3596
0
      libcerror_error_set(
3597
0
       error,
3598
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3599
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3600
0
       "%s: unable to retrieve list element for range offset: %" PRIu64 ".",
3601
0
       function,
3602
0
       range_start );
3603
3604
0
      goto on_error;
3605
0
    }
3606
0
    else if( result == 0 )
3607
0
    {
3608
      /* The specified range is not defined in the range list
3609
       */
3610
0
      if( list_element == NULL )
3611
0
      {
3612
0
        break;
3613
0
      }
3614
0
    }
3615
0
    if( libcdata_list_element_get_value(
3616
0
         list_element,
3617
0
         (intptr_t **) &range_list_value,
3618
0
         error ) != 1 )
3619
0
    {
3620
0
      libcerror_error_set(
3621
0
       error,
3622
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3623
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3624
0
       "%s: unable to retrieve value from list element for range offset: %" PRIu64 ".",
3625
0
       function,
3626
0
       range_start );
3627
3628
0
      goto on_error;
3629
0
    }
3630
0
    if( range_list_value == NULL )
3631
0
    {
3632
0
      libcerror_error_set(
3633
0
       error,
3634
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3635
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3636
0
       "%s: missing range list value element for range offset: %" PRIu64 ".",
3637
0
       function,
3638
0
       range_start );
3639
3640
0
      goto on_error;
3641
0
    }
3642
0
    if( result == 0 )
3643
0
    {
3644
      /* The specified range is not defined in the range list
3645
       */
3646
0
      if( range_list_value->start >= range_end )
3647
0
      {
3648
0
        break;
3649
0
      }
3650
0
      range_start = range_list_value->start;
3651
0
    }
3652
0
    next_range_start = range_list_value->end;
3653
3654
0
    if( ( range_start <= range_list_value->start )
3655
0
     && ( range_end >= range_list_value->end ) )
3656
0
    {
3657
0
      if( libcdata_internal_range_list_remove_range_value(
3658
0
           internal_range_list,
3659
0
           &list_element,
3660
0
           value_free_function,
3661
0
           error ) != 1 )
3662
0
      {
3663
0
        libcerror_error_set(
3664
0
         error,
3665
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3666
0
         LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
3667
0
         "%s: unable to remove range value.",
3668
0
         function );
3669
3670
0
        goto on_error;
3671
0
      }
3672
0
    }
3673
0
    else if( ( range_start > range_list_value->start )
3674
0
          && ( range_end < range_list_value->end ) )
3675
0
    {
3676
0
      if( libcdata_internal_range_list_remove_split_range(
3677
0
           internal_range_list,
3678
0
           list_element,
3679
0
           range_list_value,
3680
0
           range_start,
3681
0
           range_end,
3682
0
           value_free_function,
3683
0
           value_split_function,
3684
0
           error ) != 1 )
3685
0
      {
3686
0
        libcerror_error_set(
3687
0
         error,
3688
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3689
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3690
0
         "%s: unable to split range.",
3691
0
         function );
3692
3693
0
        goto on_error;
3694
0
      }
3695
0
    }
3696
0
    else
3697
0
    {
3698
0
      if( libcdata_internal_range_list_remove_shrink_range(
3699
0
           internal_range_list,
3700
0
           list_element,
3701
0
           range_list_value,
3702
0
           range_start,
3703
0
           range_end,
3704
0
           value_free_function,
3705
0
           value_split_function,
3706
0
           error ) != 1 )
3707
0
      {
3708
0
        libcerror_error_set(
3709
0
         error,
3710
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3711
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3712
0
         "%s: unable to shrink range.",
3713
0
         function );
3714
3715
0
        goto on_error;
3716
0
      }
3717
0
    }
3718
0
    range_start = next_range_start;
3719
0
  }
3720
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
3721
  if( libcthreads_read_write_lock_release_for_write(
3722
       internal_range_list->read_write_lock,
3723
       error ) != 1 )
3724
  {
3725
    libcerror_error_set(
3726
     error,
3727
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3728
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3729
     "%s: unable to release read/write lock for writing.",
3730
     function );
3731
3732
    return( -1 );
3733
  }
3734
#endif
3735
0
  return( result );
3736
3737
0
on_error:
3738
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
3739
  libcthreads_read_write_lock_release_for_write(
3740
   internal_range_list->read_write_lock,
3741
   NULL );
3742
#endif
3743
0
  return( -1 );
3744
0
}
3745
3746
/* Retrieves a specific element from the range list
3747
 * Returns 1 if successful or -1 on error
3748
 */
3749
int libcdata_internal_range_list_get_element_by_index(
3750
     libcdata_internal_range_list_t *internal_range_list,
3751
     int element_index,
3752
     libcdata_list_element_t **element,
3753
     libcerror_error_t **error )
3754
0
{
3755
0
  libcdata_list_element_t *current_element = NULL;
3756
0
  static char *function                    = "libcdata_internal_range_list_get_element_by_index";
3757
0
  int current_element_index                = 0;
3758
3759
0
  if( internal_range_list == NULL )
3760
0
  {
3761
0
    libcerror_error_set(
3762
0
     error,
3763
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3764
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3765
0
     "%s: invalid range list.",
3766
0
     function );
3767
3768
0
    return( -1 );
3769
0
  }
3770
0
  if( ( element_index < 0 )
3771
0
   || ( element_index >= internal_range_list->number_of_elements ) )
3772
0
  {
3773
0
    libcerror_error_set(
3774
0
     error,
3775
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3776
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3777
0
     "%s: invalid element index value out of bounds.",
3778
0
     function );
3779
3780
0
    return( -1 );
3781
0
  }
3782
0
  if( element == NULL )
3783
0
  {
3784
0
    libcerror_error_set(
3785
0
     error,
3786
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3787
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3788
0
     "%s: invalid element.",
3789
0
     function );
3790
3791
0
    return( -1 );
3792
0
  }
3793
0
  current_element       = internal_range_list->current_element;
3794
0
  current_element_index = internal_range_list->current_element_index;
3795
3796
0
  if( ( current_element != NULL )
3797
0
   && ( current_element_index != element_index ) )
3798
0
  {
3799
0
    if( element_index < current_element_index )
3800
0
    {
3801
0
      if( ( current_element_index - element_index ) < ( internal_range_list->number_of_elements / 2 ) )
3802
0
      {
3803
0
        while( current_element_index > element_index )
3804
0
        {
3805
0
          if( libcdata_list_element_get_previous_element(
3806
0
               current_element,
3807
0
               &current_element,
3808
0
               error ) != 1 )
3809
0
          {
3810
0
            libcerror_error_set(
3811
0
             error,
3812
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3813
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3814
0
             "%s: unable to retrieve previous element from list element: %d.",
3815
0
             function,
3816
0
             current_element_index );
3817
3818
0
            return( -1 );
3819
0
          }
3820
0
          current_element_index--;
3821
0
        }
3822
0
      }
3823
0
    }
3824
0
    else
3825
0
    {
3826
0
      if( ( element_index - current_element_index ) < ( internal_range_list->number_of_elements / 2 ) )
3827
0
      {
3828
0
        while( current_element_index < element_index )
3829
0
        {
3830
0
          if( libcdata_list_element_get_next_element(
3831
0
               current_element,
3832
0
               &current_element,
3833
0
               error ) != 1 )
3834
0
          {
3835
0
            libcerror_error_set(
3836
0
             error,
3837
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3838
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3839
0
             "%s: unable to retrieve next element from list element: %d.",
3840
0
             function,
3841
0
             current_element_index );
3842
3843
0
            return( -1 );
3844
0
          }
3845
0
          current_element_index++;
3846
0
        }
3847
0
      }
3848
0
    }
3849
0
  }
3850
0
  if( ( current_element == NULL )
3851
0
   || ( current_element_index != element_index ) )
3852
0
  {
3853
0
    if( element_index < ( internal_range_list->number_of_elements / 2 ) )
3854
0
    {
3855
0
      current_element = internal_range_list->first_element;
3856
3857
0
      for( current_element_index = 0;
3858
0
           current_element_index < element_index;
3859
0
           current_element_index++ )
3860
0
      {
3861
0
        if( libcdata_list_element_get_next_element(
3862
0
             current_element,
3863
0
             &current_element,
3864
0
             error ) != 1 )
3865
0
        {
3866
0
          libcerror_error_set(
3867
0
           error,
3868
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
3869
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3870
0
           "%s: unable to retrieve next element from list element: %d.",
3871
0
           function,
3872
0
           current_element_index );
3873
3874
0
          return( -1 );
3875
0
        }
3876
0
      }
3877
0
    }
3878
0
    else
3879
0
    {
3880
0
      current_element = internal_range_list->last_element;
3881
3882
0
      for( current_element_index = ( internal_range_list->number_of_elements - 1 );
3883
0
           current_element_index > element_index;
3884
0
           current_element_index-- )
3885
0
      {
3886
0
        if( libcdata_list_element_get_previous_element(
3887
0
             current_element,
3888
0
             &current_element,
3889
0
             error ) != 1 )
3890
0
        {
3891
0
          libcerror_error_set(
3892
0
           error,
3893
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
3894
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3895
0
           "%s: unable to retrieve previous element from list element: %d.",
3896
0
           function,
3897
0
           current_element_index );
3898
3899
0
          return( -1 );
3900
0
        }
3901
0
      }
3902
0
    }
3903
0
  }
3904
0
  if( current_element != NULL )
3905
0
  {
3906
0
    internal_range_list->current_element       = current_element;
3907
0
    internal_range_list->current_element_index = current_element_index;
3908
0
  }
3909
0
  *element = current_element;
3910
3911
0
  return( 1 );
3912
0
}
3913
3914
/* Retrieves the element that contains the range offset
3915
 * If the function returns element can be set to contain the element
3916
 * containing the next range list value.
3917
 * Returns 1 if successful, 0 if not found or -1 on error
3918
 */
3919
int libcdata_internal_range_list_get_element_at_offset(
3920
     libcdata_internal_range_list_t *internal_range_list,
3921
     uint64_t range_offset,
3922
     libcdata_list_element_t **element,
3923
     libcerror_error_t **error )
3924
196k
{
3925
196k
  libcdata_list_element_t *range_list_element   = NULL;
3926
196k
  libcdata_range_list_value_t *range_list_value = NULL;
3927
196k
  static char *function                         = "libcdata_internal_range_list_get_element_at_offset";
3928
196k
  int element_index                             = 0;
3929
3930
196k
  if( internal_range_list == NULL )
3931
0
  {
3932
0
    libcerror_error_set(
3933
0
     error,
3934
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3935
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3936
0
     "%s: invalid range list.",
3937
0
     function );
3938
3939
0
    return( -1 );
3940
0
  }
3941
196k
  if( range_offset > (uint64_t) INT64_MAX )
3942
0
  {
3943
0
    libcerror_error_set(
3944
0
     error,
3945
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3946
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3947
0
     "%s: invalid range offset value exceeds maximum.",
3948
0
     function );
3949
3950
0
    return( -1 );
3951
0
  }
3952
196k
  if( element == NULL )
3953
0
  {
3954
0
    libcerror_error_set(
3955
0
     error,
3956
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3957
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3958
0
     "%s: invalid element.",
3959
0
     function );
3960
3961
0
    return( -1 );
3962
0
  }
3963
/* TODO add optimization using current element */
3964
196k
  range_list_element = internal_range_list->first_element;
3965
3966
196k
  for( element_index = 0;
3967
24.6M
       element_index < internal_range_list->number_of_elements;
3968
24.4M
       element_index++ )
3969
24.6M
  {
3970
24.6M
    if( libcdata_list_element_get_value(
3971
24.6M
         range_list_element,
3972
24.6M
         (intptr_t **) &range_list_value,
3973
24.6M
         error ) != 1 )
3974
0
    {
3975
0
      libcerror_error_set(
3976
0
       error,
3977
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3978
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3979
0
       "%s: unable to retrieve value from list element: %d.",
3980
0
       function,
3981
0
       element_index );
3982
3983
0
      return( -1 );
3984
0
    }
3985
24.6M
    if( range_list_value == NULL )
3986
0
    {
3987
0
      libcerror_error_set(
3988
0
       error,
3989
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3990
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3991
0
       "%s: missing range list value element: %d.",
3992
0
       function,
3993
0
       element_index );
3994
3995
0
      return( -1 );
3996
0
    }
3997
24.6M
    if( range_offset < range_list_value->start )
3998
79.0k
    {
3999
79.0k
      break;
4000
79.0k
    }
4001
24.5M
    if( ( range_offset >= range_list_value->start )
4002
24.5M
     && ( range_offset < range_list_value->end ) )
4003
75.8k
    {
4004
75.8k
      *element = range_list_element;
4005
4006
75.8k
      return( 1 );
4007
75.8k
    }
4008
24.4M
    if( libcdata_list_element_get_next_element(
4009
24.4M
         range_list_element,
4010
24.4M
         &range_list_element,
4011
24.4M
         error ) != 1 )
4012
0
    {
4013
0
      libcerror_error_set(
4014
0
       error,
4015
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4016
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4017
0
       "%s: unable to retrieve next element from list element: %d.",
4018
0
       function,
4019
0
       element_index );
4020
4021
0
      return( -1 );
4022
0
    }
4023
24.4M
  }
4024
120k
  *element = NULL;
4025
4026
120k
  return( 0 );
4027
196k
}
4028
4029
/* Retrieves a specific value from the range list
4030
 * Returns 1 if successful or -1 on error
4031
 */
4032
int libcdata_internal_range_list_get_value_by_index(
4033
     libcdata_internal_range_list_t *internal_range_list,
4034
     int element_index,
4035
     libcdata_range_list_value_t **range_list_value,
4036
     libcerror_error_t **error )
4037
0
{
4038
0
  libcdata_list_element_t *list_element = NULL;
4039
0
  static char *function                 = "libcdata_internal_range_list_get_value_by_index";
4040
4041
0
  if( range_list_value == NULL )
4042
0
  {
4043
0
    libcerror_error_set(
4044
0
     error,
4045
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4046
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4047
0
     "%s: invalid range list value.",
4048
0
     function );
4049
4050
0
    return( -1 );
4051
0
  }
4052
0
  if( libcdata_internal_range_list_get_element_by_index(
4053
0
       internal_range_list,
4054
0
       element_index,
4055
0
       &list_element,
4056
0
       error ) != 1 )
4057
0
  {
4058
0
    libcerror_error_set(
4059
0
     error,
4060
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4061
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4062
0
     "%s: unable to retrieve list element: %d.",
4063
0
     function,
4064
0
     element_index );
4065
4066
0
    return( -1 );
4067
0
  }
4068
0
  if( libcdata_list_element_get_value(
4069
0
       list_element,
4070
0
       (intptr_t **) range_list_value,
4071
0
       error ) != 1 )
4072
0
  {
4073
0
    libcerror_error_set(
4074
0
     error,
4075
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4076
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4077
0
     "%s: unable to retrieve value from list element: %d.",
4078
0
     function,
4079
0
     element_index );
4080
4081
0
    return( -1 );
4082
0
  }
4083
0
  if( range_list_value == NULL )
4084
0
  {
4085
0
    libcerror_error_set(
4086
0
     error,
4087
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4088
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4089
0
     "%s: missing range list value: %d .",
4090
0
     function,
4091
0
     element_index );
4092
4093
0
    return( -1 );
4094
0
  }
4095
0
  return( 1 );
4096
0
}
4097
4098
/* Retrieves the value that contains the range offset
4099
 * Returns 1 if successful, 0 if no value was found or -1 on error
4100
 */
4101
int libcdata_internal_range_list_get_value_at_offset(
4102
     libcdata_internal_range_list_t *internal_range_list,
4103
     uint64_t range_offset,
4104
     libcdata_range_list_value_t **range_list_value,
4105
     libcerror_error_t **error )
4106
196k
{
4107
196k
  libcdata_list_element_t *list_element = NULL;
4108
196k
  static char *function                 = "libcdata_internal_range_list_get_value_at_offset";
4109
196k
  int result                            = 0;
4110
4111
196k
  if( range_list_value == NULL )
4112
0
  {
4113
0
    libcerror_error_set(
4114
0
     error,
4115
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4116
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4117
0
     "%s: invalid range list value.",
4118
0
     function );
4119
4120
0
    return( -1 );
4121
0
  }
4122
196k
  result = libcdata_internal_range_list_get_element_at_offset(
4123
196k
            internal_range_list,
4124
196k
            range_offset,
4125
196k
            &list_element,
4126
196k
            error );
4127
4128
196k
  if( result == -1 )
4129
0
  {
4130
0
    libcerror_error_set(
4131
0
     error,
4132
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4133
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4134
0
     "%s: unable to retrieve list element for range offset: %" PRIu64 ".",
4135
0
     function,
4136
0
     range_offset );
4137
4138
0
    return( -1 );
4139
0
  }
4140
196k
  else if( result != 0 )
4141
75.8k
  {
4142
75.8k
    if( libcdata_list_element_get_value(
4143
75.8k
         list_element,
4144
75.8k
         (intptr_t **) range_list_value,
4145
75.8k
         error ) != 1 )
4146
0
    {
4147
0
      libcerror_error_set(
4148
0
       error,
4149
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4150
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4151
0
       "%s: unable to retrieve value from list element for range offset: %" PRIu64 ".",
4152
0
       function,
4153
0
       range_offset );
4154
4155
0
      return( -1 );
4156
0
    }
4157
75.8k
    if( *range_list_value == NULL )
4158
0
    {
4159
0
      libcerror_error_set(
4160
0
       error,
4161
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4162
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4163
0
       "%s: missing range list value for range offset: %" PRIu64 ".",
4164
0
       function,
4165
0
       range_offset );
4166
4167
0
      return( -1 );
4168
0
    }
4169
75.8k
  }
4170
196k
  return( result );
4171
196k
}
4172
4173
/* Retrieves a specific range
4174
 * Returns 1 if successful or -1 on error
4175
 */
4176
int libcdata_range_list_get_range_by_index(
4177
     libcdata_range_list_t *range_list,
4178
     int element_index,
4179
     uint64_t *range_start,
4180
     uint64_t *range_size,
4181
     intptr_t **value,
4182
     libcerror_error_t **error )
4183
0
{
4184
0
  libcdata_internal_range_list_t *internal_range_list = NULL;
4185
0
  libcdata_range_list_value_t *range_list_value       = NULL;
4186
0
  static char *function                               = "libcdata_range_list_get_range_by_index";
4187
4188
0
  if( range_list == NULL )
4189
0
  {
4190
0
    libcerror_error_set(
4191
0
     error,
4192
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4193
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4194
0
     "%s: invalid range list.",
4195
0
     function );
4196
4197
0
    return( -1 );
4198
0
  }
4199
0
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
4200
4201
0
  if( range_start == NULL )
4202
0
  {
4203
0
    libcerror_error_set(
4204
0
     error,
4205
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4206
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4207
0
     "%s: invalid range start.",
4208
0
     function );
4209
4210
0
    return( -1 );
4211
0
  }
4212
0
  if( range_size == NULL )
4213
0
  {
4214
0
    libcerror_error_set(
4215
0
     error,
4216
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4217
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4218
0
     "%s: invalid range size.",
4219
0
     function );
4220
4221
0
    return( -1 );
4222
0
  }
4223
0
  if( value == NULL )
4224
0
  {
4225
0
    libcerror_error_set(
4226
0
     error,
4227
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4228
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4229
0
     "%s: invalid value.",
4230
0
     function );
4231
4232
0
    return( -1 );
4233
0
  }
4234
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4235
  if( libcthreads_read_write_lock_grab_for_read(
4236
       internal_range_list->read_write_lock,
4237
       error ) != 1 )
4238
  {
4239
    libcerror_error_set(
4240
     error,
4241
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4242
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4243
     "%s: unable to grab read/write lock for reading.",
4244
     function );
4245
4246
    return( -1 );
4247
  }
4248
#endif
4249
0
  if( libcdata_internal_range_list_get_value_by_index(
4250
0
       internal_range_list,
4251
0
       element_index,
4252
0
       &range_list_value,
4253
0
       error ) != 1 )
4254
0
  {
4255
0
    libcerror_error_set(
4256
0
     error,
4257
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4258
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4259
0
     "%s: unable to retrieve range list value: %d.",
4260
0
     function,
4261
0
     element_index );
4262
4263
0
    goto on_error;
4264
0
  }
4265
0
  if( range_list_value == NULL )
4266
0
  {
4267
0
    libcerror_error_set(
4268
0
     error,
4269
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4270
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4271
0
     "%s: missing range list value: %d.",
4272
0
     function,
4273
0
     element_index );
4274
4275
0
    goto on_error;
4276
0
  }
4277
0
  *range_start = range_list_value->start;
4278
0
  *range_size  = range_list_value->size;
4279
0
  *value       = range_list_value->value;
4280
4281
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4282
  if( libcthreads_read_write_lock_release_for_read(
4283
       internal_range_list->read_write_lock,
4284
       error ) != 1 )
4285
  {
4286
    libcerror_error_set(
4287
     error,
4288
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4289
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4290
     "%s: unable to release read/write lock for reading.",
4291
     function );
4292
4293
    return( -1 );
4294
  }
4295
#endif
4296
0
  return( 1 );
4297
4298
0
on_error:
4299
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4300
  libcthreads_read_write_lock_release_for_read(
4301
   internal_range_list->read_write_lock,
4302
   NULL );
4303
#endif
4304
0
  return( -1 );
4305
0
}
4306
4307
/* Retrieves a range for a specific range offset
4308
 * Returns 1 if successful, 0 if no range was found or -1 on error
4309
 */
4310
int libcdata_range_list_get_range_at_offset(
4311
     libcdata_range_list_t *range_list,
4312
     uint64_t range_offset,
4313
     uint64_t *range_start,
4314
     uint64_t *range_size,
4315
     intptr_t **value,
4316
     libcerror_error_t **error )
4317
196k
{
4318
196k
  libcdata_internal_range_list_t *internal_range_list = NULL;
4319
196k
  libcdata_range_list_value_t *range_list_value       = NULL;
4320
196k
  static char *function                               = "libcdata_range_list_get_range_at_offset";
4321
196k
  int result                                          = 0;
4322
4323
196k
  if( range_list == NULL )
4324
0
  {
4325
0
    libcerror_error_set(
4326
0
     error,
4327
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4328
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4329
0
     "%s: invalid range list.",
4330
0
     function );
4331
4332
0
    return( -1 );
4333
0
  }
4334
196k
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
4335
4336
196k
  if( range_start == NULL )
4337
0
  {
4338
0
    libcerror_error_set(
4339
0
     error,
4340
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4341
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4342
0
     "%s: invalid range start.",
4343
0
     function );
4344
4345
0
    return( -1 );
4346
0
  }
4347
196k
  if( range_size == NULL )
4348
0
  {
4349
0
    libcerror_error_set(
4350
0
     error,
4351
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4352
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4353
0
     "%s: invalid range size.",
4354
0
     function );
4355
4356
0
    return( -1 );
4357
0
  }
4358
196k
  if( value == NULL )
4359
0
  {
4360
0
    libcerror_error_set(
4361
0
     error,
4362
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4363
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4364
0
     "%s: invalid value.",
4365
0
     function );
4366
4367
0
    return( -1 );
4368
0
  }
4369
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4370
  if( libcthreads_read_write_lock_grab_for_read(
4371
       internal_range_list->read_write_lock,
4372
       error ) != 1 )
4373
  {
4374
    libcerror_error_set(
4375
     error,
4376
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4377
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4378
     "%s: unable to grab read/write lock for reading.",
4379
     function );
4380
4381
    return( -1 );
4382
  }
4383
#endif
4384
196k
  result = libcdata_internal_range_list_get_value_at_offset(
4385
196k
            internal_range_list,
4386
196k
            range_offset,
4387
196k
            &range_list_value,
4388
196k
            error );
4389
4390
196k
  if( result == -1 )
4391
0
  {
4392
0
    libcerror_error_set(
4393
0
     error,
4394
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4395
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4396
0
     "%s: unable to retrieve range list value for range offset: %" PRIu64 ".",
4397
0
     function,
4398
0
     range_offset );
4399
4400
0
    goto on_error;
4401
0
  }
4402
196k
  else if( result != 0 )
4403
75.8k
  {
4404
75.8k
    if( range_list_value == NULL )
4405
0
    {
4406
0
      libcerror_error_set(
4407
0
       error,
4408
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4409
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4410
0
       "%s: missing range list value for range offset: %" PRIu64 ".",
4411
0
       function,
4412
0
       range_offset );
4413
4414
0
      goto on_error;
4415
0
    }
4416
75.8k
    *range_start = range_list_value->start;
4417
75.8k
    *range_size  = range_list_value->size;
4418
75.8k
    *value       = range_list_value->value;
4419
75.8k
  }
4420
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4421
  if( libcthreads_read_write_lock_release_for_read(
4422
       internal_range_list->read_write_lock,
4423
       error ) != 1 )
4424
  {
4425
    libcerror_error_set(
4426
     error,
4427
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4428
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4429
     "%s: unable to release read/write lock for reading.",
4430
     function );
4431
4432
    return( -1 );
4433
  }
4434
#endif
4435
196k
  return( result );
4436
4437
0
on_error:
4438
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4439
  libcthreads_read_write_lock_release_for_read(
4440
   internal_range_list->read_write_lock,
4441
   NULL );
4442
#endif
4443
0
  return( -1 );
4444
196k
}
4445
4446
/* Determines if a certain range is present in the list
4447
 * This function does not check for partial overlapping ranges
4448
 * Returns 1 if a range is present, 0 if not or -1 on error
4449
 */
4450
int libcdata_range_list_range_is_present(
4451
     libcdata_range_list_t *range_list,
4452
     uint64_t range_start,
4453
     uint64_t range_size,
4454
     libcerror_error_t **error )
4455
30.6k
{
4456
30.6k
  libcdata_internal_range_list_t *internal_range_list = NULL;
4457
30.6k
  libcdata_list_element_t *list_element               = NULL;
4458
30.6k
  libcdata_range_list_value_t *range_list_value       = NULL;
4459
30.6k
  static char *function                               = "libcdata_range_list_range_is_present";
4460
30.6k
  uint64_t range_end                                  = 0;
4461
30.6k
  int element_index                                   = 0;
4462
30.6k
  int result                                          = 0;
4463
4464
30.6k
  if( range_list == NULL )
4465
0
  {
4466
0
    libcerror_error_set(
4467
0
     error,
4468
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4469
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4470
0
     "%s: invalid range list.",
4471
0
     function );
4472
4473
0
    return( -1 );
4474
0
  }
4475
30.6k
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
4476
4477
30.6k
  if( range_start > (uint64_t) INT64_MAX )
4478
0
  {
4479
0
    libcerror_error_set(
4480
0
     error,
4481
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4482
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4483
0
     "%s: invalid range start value exceeds maximum.",
4484
0
     function );
4485
4486
0
    return( -1 );
4487
0
  }
4488
30.6k
  if( range_size > (uint64_t) INT64_MAX )
4489
0
  {
4490
0
    libcerror_error_set(
4491
0
     error,
4492
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4493
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4494
0
     "%s: invalid size value exceeds maximum.",
4495
0
     function );
4496
4497
0
    return( -1 );
4498
0
  }
4499
30.6k
  range_end = range_start + range_size;
4500
4501
30.6k
  if( range_end < range_start )
4502
0
  {
4503
0
    libcerror_error_set(
4504
0
     error,
4505
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4506
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4507
0
     "%s: invalid range end value out of bounds.",
4508
0
     function );
4509
4510
0
    return( -1 );
4511
0
  }
4512
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4513
  if( libcthreads_read_write_lock_grab_for_read(
4514
       internal_range_list->read_write_lock,
4515
       error ) != 1 )
4516
  {
4517
    libcerror_error_set(
4518
     error,
4519
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4520
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4521
     "%s: unable to grab read/write lock for reading.",
4522
     function );
4523
4524
    return( -1 );
4525
  }
4526
#endif
4527
/* TODO add optimization using current element */
4528
30.6k
  list_element = internal_range_list->first_element;
4529
4530
30.6k
  for( element_index = 0;
4531
159k
       element_index < internal_range_list->number_of_elements;
4532
129k
       element_index++ )
4533
135k
  {
4534
135k
    if( libcdata_list_element_get_value(
4535
135k
         list_element,
4536
135k
         (intptr_t **) &range_list_value,
4537
135k
         error ) != 1 )
4538
0
    {
4539
0
      libcerror_error_set(
4540
0
       error,
4541
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4542
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4543
0
       "%s: unable to retrieve value from list element: %d.",
4544
0
       function,
4545
0
       element_index );
4546
4547
0
      goto on_error;
4548
0
    }
4549
135k
    if( range_end < range_list_value->start )
4550
4.93k
    {
4551
4.93k
      break;
4552
4.93k
    }
4553
130k
    if( ( range_start >= range_list_value->start )
4554
130k
     && ( range_end <= range_list_value->end ) )
4555
1.26k
    {
4556
1.26k
      result = 1;
4557
4558
1.26k
      break;
4559
1.26k
    }
4560
129k
    if( libcdata_list_element_get_next_element(
4561
129k
         list_element,
4562
129k
         &list_element,
4563
129k
         error ) != 1 )
4564
0
    {
4565
0
      libcerror_error_set(
4566
0
       error,
4567
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4568
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4569
0
       "%s: unable to retrieve next element from list element: %d.",
4570
0
       function,
4571
0
       element_index );
4572
4573
0
      goto on_error;
4574
0
    }
4575
129k
  }
4576
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4577
  if( libcthreads_read_write_lock_release_for_read(
4578
       internal_range_list->read_write_lock,
4579
       error ) != 1 )
4580
  {
4581
    libcerror_error_set(
4582
     error,
4583
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4584
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4585
     "%s: unable to release read/write lock for reading.",
4586
     function );
4587
4588
    return( -1 );
4589
  }
4590
#endif
4591
30.6k
  return( result );
4592
4593
0
on_error:
4594
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4595
  libcthreads_read_write_lock_release_for_read(
4596
   internal_range_list->read_write_lock,
4597
   NULL );
4598
#endif
4599
0
  return( -1 );
4600
30.6k
}
4601
4602
/* Determines if a certain range is present in the list
4603
 * This function does not check for partial overlapping ranges
4604
 * Returns 1 if a range is present, 0 if not or -1 on error
4605
 */
4606
int libcdata_range_list_range_has_overlapping_range(
4607
     libcdata_range_list_t *range_list,
4608
     uint64_t range_start,
4609
     uint64_t range_size,
4610
     libcerror_error_t **error )
4611
18.8k
{
4612
18.8k
  libcdata_internal_range_list_t *internal_range_list = NULL;
4613
18.8k
  libcdata_list_element_t *list_element               = NULL;
4614
18.8k
  libcdata_range_list_value_t *range_list_value       = NULL;
4615
18.8k
  static char *function                               = "libcdata_range_list_range_has_overlapping_range";
4616
18.8k
  uint64_t range_end                                  = 0;
4617
18.8k
  int element_index                                   = 0;
4618
18.8k
  int result                                          = 0;
4619
4620
18.8k
  if( range_list == NULL )
4621
0
  {
4622
0
    libcerror_error_set(
4623
0
     error,
4624
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4625
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4626
0
     "%s: invalid range list.",
4627
0
     function );
4628
4629
0
    return( -1 );
4630
0
  }
4631
18.8k
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
4632
4633
18.8k
  if( range_start > (uint64_t) INT64_MAX )
4634
0
  {
4635
0
    libcerror_error_set(
4636
0
     error,
4637
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4638
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4639
0
     "%s: invalid range start value exceeds maximum.",
4640
0
     function );
4641
4642
0
    return( -1 );
4643
0
  }
4644
18.8k
  if( range_size > (uint64_t) INT64_MAX )
4645
0
  {
4646
0
    libcerror_error_set(
4647
0
     error,
4648
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4649
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4650
0
     "%s: invalid size value exceeds maximum.",
4651
0
     function );
4652
4653
0
    return( -1 );
4654
0
  }
4655
18.8k
  range_end = range_start + range_size;
4656
4657
18.8k
  if( range_end < range_start )
4658
0
  {
4659
0
    libcerror_error_set(
4660
0
     error,
4661
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4662
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4663
0
     "%s: invalid range end value out of bounds.",
4664
0
     function );
4665
4666
0
    return( -1 );
4667
0
  }
4668
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4669
  if( libcthreads_read_write_lock_grab_for_read(
4670
       internal_range_list->read_write_lock,
4671
       error ) != 1 )
4672
  {
4673
    libcerror_error_set(
4674
     error,
4675
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4676
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4677
     "%s: unable to grab read/write lock for reading.",
4678
     function );
4679
4680
    return( -1 );
4681
  }
4682
#endif
4683
/* TODO add optimization using current element */
4684
18.8k
  list_element = internal_range_list->first_element;
4685
4686
18.8k
  for( element_index = 0;
4687
162k
       element_index < internal_range_list->number_of_elements;
4688
143k
       element_index++ )
4689
151k
  {
4690
151k
    if( libcdata_list_element_get_value(
4691
151k
         list_element,
4692
151k
         (intptr_t **) &range_list_value,
4693
151k
         error ) != 1 )
4694
0
    {
4695
0
      libcerror_error_set(
4696
0
       error,
4697
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4698
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4699
0
       "%s: unable to retrieve value from list element: %d.",
4700
0
       function,
4701
0
       element_index );
4702
4703
0
      goto on_error;
4704
0
    }
4705
151k
    if( range_end < range_list_value->start )
4706
7.57k
    {
4707
7.57k
      break;
4708
7.57k
    }
4709
144k
    if( ( range_start >= range_list_value->start )
4710
144k
     && ( range_start < range_list_value->end ) )
4711
55
    {
4712
55
      result = 1;
4713
4714
55
      break;
4715
55
    }
4716
144k
    if( ( range_end > range_list_value->start )
4717
144k
     && ( range_end <= range_list_value->end ) )
4718
34
    {
4719
34
      result = 1;
4720
4721
34
      break;
4722
34
    }
4723
143k
    if( libcdata_list_element_get_next_element(
4724
143k
         list_element,
4725
143k
         &list_element,
4726
143k
         error ) != 1 )
4727
0
    {
4728
0
      libcerror_error_set(
4729
0
       error,
4730
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4731
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4732
0
       "%s: unable to retrieve next element from list element: %d.",
4733
0
       function,
4734
0
       element_index );
4735
4736
0
      goto on_error;
4737
0
    }
4738
143k
  }
4739
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4740
  if( libcthreads_read_write_lock_release_for_read(
4741
       internal_range_list->read_write_lock,
4742
       error ) != 1 )
4743
  {
4744
    libcerror_error_set(
4745
     error,
4746
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4747
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4748
     "%s: unable to release read/write lock for reading.",
4749
     function );
4750
4751
    return( -1 );
4752
  }
4753
#endif
4754
18.8k
  return( result );
4755
4756
0
on_error:
4757
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4758
  libcthreads_read_write_lock_release_for_read(
4759
   internal_range_list->read_write_lock,
4760
   NULL );
4761
#endif
4762
0
  return( -1 );
4763
18.8k
}
4764
4765
/* Retrieves the range spanning the ranges in the range list
4766
 * Returns 1 if present, 0 if not present or -1 on error
4767
 */
4768
int libcdata_range_list_get_spanning_range(
4769
     libcdata_range_list_t *range_list,
4770
     uint64_t *range_start,
4771
     uint64_t *range_size,
4772
     libcerror_error_t **error )
4773
0
{
4774
0
  libcdata_internal_range_list_t *internal_range_list = NULL;
4775
0
  libcdata_range_list_value_t *range_list_value       = NULL;
4776
0
  static char *function                               = "libcdata_range_list_get_spanning_range";
4777
0
  int element_index                                   = 0;
4778
0
  int result                                          = 0;
4779
4780
0
  if( range_list == NULL )
4781
0
  {
4782
0
    libcerror_error_set(
4783
0
     error,
4784
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4785
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4786
0
     "%s: invalid range list.",
4787
0
     function );
4788
4789
0
    return( -1 );
4790
0
  }
4791
0
  internal_range_list = (libcdata_internal_range_list_t *) range_list;
4792
4793
0
  if( range_start == NULL )
4794
0
  {
4795
0
    libcerror_error_set(
4796
0
     error,
4797
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4798
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4799
0
     "%s: invalid range start.",
4800
0
     function );
4801
4802
0
    return( -1 );
4803
0
  }
4804
0
  if( range_size == NULL )
4805
0
  {
4806
0
    libcerror_error_set(
4807
0
     error,
4808
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4809
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4810
0
     "%s: invalid range size.",
4811
0
     function );
4812
4813
0
    return( -1 );
4814
0
  }
4815
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4816
  if( libcthreads_read_write_lock_grab_for_read(
4817
       internal_range_list->read_write_lock,
4818
       error ) != 1 )
4819
  {
4820
    libcerror_error_set(
4821
     error,
4822
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4823
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4824
     "%s: unable to grab read/write lock for reading.",
4825
     function );
4826
4827
    return( -1 );
4828
  }
4829
#endif
4830
0
  if( internal_range_list->number_of_elements > 0 )
4831
0
  {
4832
0
    if( libcdata_internal_range_list_get_value_by_index(
4833
0
         internal_range_list,
4834
0
         0,
4835
0
         &range_list_value,
4836
0
         error ) != 1 )
4837
0
    {
4838
0
      libcerror_error_set(
4839
0
       error,
4840
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4841
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4842
0
       "%s: unable to retrieve range list value: 0.",
4843
0
       function );
4844
4845
0
      goto on_error;
4846
0
    }
4847
0
    if( range_list_value == NULL )
4848
0
    {
4849
0
      libcerror_error_set(
4850
0
       error,
4851
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4852
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4853
0
       "%s: missing range list value: 0.",
4854
0
       function );
4855
4856
0
      goto on_error;
4857
0
    }
4858
0
    *range_start = range_list_value->start;
4859
4860
0
    if( internal_range_list->number_of_elements > 1 )
4861
0
    {
4862
0
      element_index = internal_range_list->number_of_elements - 1;
4863
4864
0
      if( libcdata_internal_range_list_get_value_by_index(
4865
0
           internal_range_list,
4866
0
           element_index,
4867
0
           &range_list_value,
4868
0
           error ) != 1 )
4869
0
      {
4870
0
        libcerror_error_set(
4871
0
         error,
4872
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4873
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4874
0
         "%s: unable to retrieve range list value: %d.",
4875
0
         function,
4876
0
         element_index );
4877
4878
0
        goto on_error;
4879
0
      }
4880
0
      if( range_list_value == NULL )
4881
0
      {
4882
0
        libcerror_error_set(
4883
0
         error,
4884
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4885
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4886
0
         "%s: missing range list value: %d.",
4887
0
         function,
4888
0
         element_index );
4889
4890
0
        goto on_error;
4891
0
      }
4892
0
    }
4893
0
    *range_size = range_list_value->end - *range_start;
4894
4895
0
    result = 1;
4896
0
  }
4897
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4898
  if( libcthreads_read_write_lock_release_for_read(
4899
       internal_range_list->read_write_lock,
4900
       error ) != 1 )
4901
  {
4902
    libcerror_error_set(
4903
     error,
4904
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4905
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4906
     "%s: unable to release read/write lock for reading.",
4907
     function );
4908
4909
    return( -1 );
4910
  }
4911
#endif
4912
0
  return( result );
4913
4914
0
on_error:
4915
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
4916
  libcthreads_read_write_lock_release_for_read(
4917
   internal_range_list->read_write_lock,
4918
   NULL );
4919
#endif
4920
0
  return( -1 );
4921
0
}
4922