Coverage Report

Created: 2024-02-25 07:20

/src/libvsbsdl/libfdata/libfdata_segments_array.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The segments array functions
3
 *
4
 * Copyright (C) 2010-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 "libfdata_libcdata.h"
27
#include "libfdata_libcerror.h"
28
#include "libfdata_libcnotify.h"
29
#include "libfdata_mapped_range.h"
30
#include "libfdata_range.h"
31
#include "libfdata_segments_array.h"
32
33
/* Retrieves a specific segment
34
 * Returns 1 if successful or -1 on error
35
 */
36
int libfdata_segments_array_get_segment_by_index(
37
     libcdata_array_t *segments_array,
38
     int segment_index,
39
     int *segment_file_index,
40
     off64_t *segment_offset,
41
     size64_t *segment_size,
42
     uint32_t *segment_flags,
43
     libcerror_error_t **error )
44
43.7k
{
45
43.7k
  libfdata_range_t *segment_data_range = NULL;
46
43.7k
  static char *function                = "libfdata_segments_array_get_segment_by_index";
47
48
43.7k
  if( libcdata_array_get_entry_by_index(
49
43.7k
       segments_array,
50
43.7k
       segment_index,
51
43.7k
       (intptr_t **) &segment_data_range,
52
43.7k
       error ) != 1 )
53
0
  {
54
0
    libcerror_error_set(
55
0
     error,
56
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
57
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
58
0
     "%s: unable to retrieve entry: %d from segments array.",
59
0
     function,
60
0
     segment_index );
61
62
0
    return( -1 );
63
0
  }
64
43.7k
  if( libfdata_range_get(
65
43.7k
       segment_data_range,
66
43.7k
       segment_file_index,
67
43.7k
       segment_offset,
68
43.7k
       segment_size,
69
43.7k
       segment_flags,
70
43.7k
       error ) != 1 )
71
0
  {
72
0
    libcerror_error_set(
73
0
     error,
74
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
75
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
76
0
     "%s: unable to retrieve segment: %d data range values.",
77
0
     function,
78
0
     segment_index );
79
80
0
    return( -1 );
81
0
  }
82
43.7k
  return( 1 );
83
43.7k
}
84
85
/* Sets the offset and size of a specific segment
86
 * Returns 1 if successful or -1 on error
87
 */
88
int libfdata_segments_array_set_segment_by_index(
89
     libcdata_array_t *segments_array,
90
     libcdata_array_t *mapped_ranges_array,
91
     size64_t *data_size,
92
     int segment_index,
93
     int segment_file_index,
94
     off64_t segment_offset,
95
     size64_t segment_size,
96
     uint32_t segment_flags,
97
     libcerror_error_t **error )
98
703k
{
99
703k
  libfdata_mapped_range_t *mapped_range = NULL;
100
703k
  libfdata_range_t *segment_data_range  = NULL;
101
703k
  static char *function                 = "libfdata_segments_array_set_segment_by_index";
102
703k
  off64_t previous_segment_offset       = 0;
103
703k
  size64_t previous_segment_size        = 0;
104
703k
  uint32_t previous_segment_flags       = 0;
105
703k
  int previous_segment_file_index       = 0;
106
107
703k
  if( data_size == NULL )
108
0
  {
109
0
    libcerror_error_set(
110
0
     error,
111
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
112
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
113
0
     "%s: invalid data size.",
114
0
     function );
115
116
0
    return( -1 );
117
0
  }
118
703k
  if( segment_file_index < 0 )
119
0
  {
120
0
    libcerror_error_set(
121
0
     error,
122
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
123
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
124
0
     "%s: invalid segment file index value out of bounds.",
125
0
     function );
126
127
0
    return( -1 );
128
0
  }
129
703k
  if( segment_offset < 0 )
130
0
  {
131
0
    libcerror_error_set(
132
0
     error,
133
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
134
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
135
0
     "%s: invalid segment offset value out of bounds.",
136
0
     function );
137
138
0
    return( -1 );
139
0
  }
140
703k
  if( libcdata_array_get_entry_by_index(
141
703k
       segments_array,
142
703k
       segment_index,
143
703k
       (intptr_t **) &segment_data_range,
144
703k
       error ) != 1 )
145
0
  {
146
0
    libcerror_error_set(
147
0
     error,
148
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
149
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
150
0
     "%s: unable to retrieve entry: %d from segments array.",
151
0
     function,
152
0
     segment_index );
153
154
0
    return( -1 );
155
0
  }
156
703k
  if( segment_data_range == NULL )
157
703k
  {
158
703k
    if( libfdata_range_initialize(
159
703k
         &segment_data_range,
160
703k
         error ) != 1 )
161
0
    {
162
0
      libcerror_error_set(
163
0
       error,
164
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
165
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
166
0
       "%s: unable to create segment data range.",
167
0
       function );
168
169
0
      return( -1 );
170
0
    }
171
703k
    if( libcdata_array_set_entry_by_index(
172
703k
         segments_array,
173
703k
         segment_index,
174
703k
         (intptr_t *) segment_data_range,
175
703k
         error ) != 1 )
176
0
    {
177
0
      libcerror_error_set(
178
0
       error,
179
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
180
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
181
0
       "%s: unable to set entry: %d to segments array.",
182
0
       function,
183
0
       segment_index );
184
185
0
      libfdata_range_free(
186
0
       &segment_data_range,
187
0
       NULL );
188
189
0
      return( -1 );
190
0
    }
191
703k
  }
192
0
  else
193
0
  {
194
0
    if( libfdata_range_get(
195
0
         segment_data_range,
196
0
         &previous_segment_file_index,
197
0
         &previous_segment_offset,
198
0
         &previous_segment_size,
199
0
         &previous_segment_flags,
200
0
         error ) != 1 )
201
0
    {
202
0
      libcerror_error_set(
203
0
       error,
204
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
205
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
206
0
       "%s: unable to retrieve segment: %d data range values.",
207
0
       function,
208
0
       segment_index );
209
210
0
      return( -1 );
211
0
    }
212
0
    *data_size -= previous_segment_size;
213
0
  }
214
703k
  if( libfdata_range_set(
215
703k
       segment_data_range,
216
703k
       segment_file_index,
217
703k
       segment_offset,
218
703k
       segment_size,
219
703k
       segment_flags,
220
703k
       error ) != 1 )
221
0
  {
222
0
    libcerror_error_set(
223
0
     error,
224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
225
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
226
0
     "%s: unable to set segment data range values.",
227
0
     function );
228
229
0
    return( -1 );
230
0
  }
231
  /* Make sure there is a mapped range entry for every segment
232
   */
233
703k
  if( libcdata_array_get_entry_by_index(
234
703k
       mapped_ranges_array,
235
703k
       segment_index,
236
703k
       (intptr_t **) &mapped_range,
237
703k
       error ) != 1 )
238
0
  {
239
0
    libcerror_error_set(
240
0
     error,
241
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
242
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
243
0
     "%s: unable to retrieve entry: %d from mapped ranges array.",
244
0
     function,
245
0
     segment_index );
246
247
0
    return( -1 );
248
0
  }
249
703k
  if( mapped_range == NULL )
250
703k
  {
251
703k
    if( libfdata_mapped_range_initialize(
252
703k
         &mapped_range,
253
703k
         error ) != 1 )
254
0
    {
255
0
      libcerror_error_set(
256
0
       error,
257
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
258
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
259
0
       "%s: unable to create mapped range.",
260
0
       function );
261
262
0
      return( -1 );
263
0
    }
264
703k
    if( libcdata_array_set_entry_by_index(
265
703k
         mapped_ranges_array,
266
703k
         segment_index,
267
703k
         (intptr_t *) mapped_range,
268
703k
         error ) != 1 )
269
0
    {
270
0
      libcerror_error_set(
271
0
       error,
272
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
273
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
274
0
       "%s: unable to set entry: %d in mapped ranges array.",
275
0
       function,
276
0
       segment_index );
277
278
0
      libfdata_mapped_range_free(
279
0
       &mapped_range,
280
0
       NULL );
281
282
0
      return( -1 );
283
0
    }
284
703k
  }
285
703k
  *data_size += segment_size;
286
287
703k
  return( 1 );
288
703k
}
289
290
/* Prepends a segment
291
 * Returns 1 if successful or -1 on error
292
 */
293
int libfdata_segments_array_prepend_segment(
294
     libcdata_array_t *segments_array,
295
     libcdata_array_t *mapped_ranges_array,
296
     size64_t *data_size,
297
     int segment_file_index,
298
     off64_t segment_offset,
299
     size64_t segment_size,
300
     uint32_t segment_flags,
301
     libcerror_error_t **error )
302
0
{
303
0
  libfdata_mapped_range_t *mapped_range = NULL;
304
0
  libfdata_range_t *segment_data_range  = NULL;
305
0
  static char *function                 = "libfdata_segments_array_prepend_segment";
306
0
  int mapped_range_index                = -1;
307
308
0
  if( data_size == NULL )
309
0
  {
310
0
    libcerror_error_set(
311
0
     error,
312
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
313
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
314
0
     "%s: invalid data size.",
315
0
     function );
316
317
0
    return( -1 );
318
0
  }
319
0
  if( segment_file_index < 0 )
320
0
  {
321
0
    libcerror_error_set(
322
0
     error,
323
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
324
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
325
0
     "%s: invalid segment file index value out of bounds.",
326
0
     function );
327
328
0
    return( -1 );
329
0
  }
330
0
  if( segment_offset < 0 )
331
0
  {
332
0
    libcerror_error_set(
333
0
     error,
334
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
335
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
336
0
     "%s: invalid segment offset value out of bounds.",
337
0
     function );
338
339
0
    return( -1 );
340
0
  }
341
0
  if( segment_size > (size64_t) INT64_MAX )
342
0
  {
343
0
    libcerror_error_set(
344
0
     error,
345
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
346
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
347
0
     "%s: invalid segment size value out of bounds.",
348
0
     function );
349
350
0
    return( -1 );
351
0
  }
352
0
  if( libfdata_mapped_range_initialize(
353
0
       &mapped_range,
354
0
       error ) != 1 )
355
0
  {
356
0
    libcerror_error_set(
357
0
     error,
358
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
359
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
360
0
     "%s: unable to create mapped range.",
361
0
     function );
362
363
0
    goto on_error;
364
0
  }
365
0
  if( libfdata_mapped_range_set(
366
0
       mapped_range,
367
0
       (off64_t) *data_size,
368
0
       segment_size,
369
0
       error ) != 1 )
370
0
  {
371
0
    libcerror_error_set(
372
0
     error,
373
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
374
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
375
0
     "%s: unable to set mapped range values.",
376
0
     function );
377
378
0
    goto on_error;
379
0
  }
380
0
  if( libcdata_array_append_entry(
381
0
       mapped_ranges_array,
382
0
       &mapped_range_index,
383
0
       (intptr_t *) mapped_range,
384
0
       error ) != 1 )
385
0
  {
386
0
    libcerror_error_set(
387
0
     error,
388
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
389
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
390
0
     "%s: unable to append mapped range to array.",
391
0
     function );
392
393
0
    goto on_error;
394
0
  }
395
0
  if( libfdata_range_initialize(
396
0
       &segment_data_range,
397
0
       error ) != 1 )
398
0
  {
399
0
    libcerror_error_set(
400
0
     error,
401
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
402
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
403
0
     "%s: unable to create segment data range.",
404
0
     function );
405
406
0
    goto on_error;
407
0
  }
408
0
  if( libfdata_range_set(
409
0
       segment_data_range,
410
0
       segment_file_index,
411
0
       segment_offset,
412
0
       segment_size,
413
0
       segment_flags,
414
0
       error ) != 1 )
415
0
  {
416
0
    libcerror_error_set(
417
0
     error,
418
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
419
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
420
0
     "%s: unable to set segment data range values.",
421
0
     function );
422
423
0
    goto on_error;
424
0
  }
425
0
  if( libcdata_array_prepend_entry(
426
0
       segments_array,
427
0
       (intptr_t *) segment_data_range,
428
0
       error ) != 1 )
429
0
  {
430
0
    libcerror_error_set(
431
0
     error,
432
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
433
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
434
0
     "%s: unable to prepend data range to segments array.",
435
0
     function );
436
437
0
    goto on_error;
438
0
  }
439
0
  *data_size += segment_size;
440
441
0
  return( 1 );
442
443
0
on_error:
444
0
  if( segment_data_range != NULL )
445
0
  {
446
0
    libfdata_range_free(
447
0
     &segment_data_range,
448
0
     NULL );
449
0
  }
450
0
  if( mapped_range_index != -1 )
451
0
  {
452
0
    libcdata_array_set_entry_by_index(
453
0
     mapped_ranges_array,
454
0
     mapped_range_index,
455
0
     NULL,
456
0
     NULL );
457
0
  }
458
0
  if( mapped_range != NULL )
459
0
  {
460
0
    libfdata_mapped_range_free(
461
0
     &mapped_range,
462
0
     NULL );
463
0
  }
464
0
  return( -1 );
465
0
}
466
467
/* Appends a segment
468
 * Returns 1 if successful or -1 on error
469
 */
470
int libfdata_segments_array_append_segment(
471
     libcdata_array_t *segments_array,
472
     libcdata_array_t *mapped_ranges_array,
473
     size64_t *data_size,
474
     int *segment_index,
475
     int segment_file_index,
476
     off64_t segment_offset,
477
     size64_t segment_size,
478
     uint32_t segment_flags,
479
     libcerror_error_t **error )
480
2.39M
{
481
2.39M
  libfdata_mapped_range_t *mapped_range = NULL;
482
2.39M
  libfdata_range_t *segment_data_range  = NULL;
483
2.39M
  static char *function                 = "libfdata_segments_array_append_segment";
484
2.39M
  int mapped_range_index                = -1;
485
486
2.39M
  if( data_size == NULL )
487
0
  {
488
0
    libcerror_error_set(
489
0
     error,
490
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
491
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
492
0
     "%s: invalid data size.",
493
0
     function );
494
495
0
    return( -1 );
496
0
  }
497
2.39M
  if( segment_file_index < 0 )
498
0
  {
499
0
    libcerror_error_set(
500
0
     error,
501
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
502
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
503
0
     "%s: invalid segment file index value out of bounds.",
504
0
     function );
505
506
0
    return( -1 );
507
0
  }
508
2.39M
  if( segment_offset < 0 )
509
356
  {
510
356
    libcerror_error_set(
511
356
     error,
512
356
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
513
356
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
514
356
     "%s: invalid segment offset value out of bounds.",
515
356
     function );
516
517
356
    return( -1 );
518
356
  }
519
2.39M
  if( libfdata_mapped_range_initialize(
520
2.39M
       &mapped_range,
521
2.39M
       error ) != 1 )
522
0
  {
523
0
    libcerror_error_set(
524
0
     error,
525
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
526
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
527
0
     "%s: unable to create mapped range.",
528
0
     function );
529
530
0
    goto on_error;
531
0
  }
532
2.39M
  if( libfdata_mapped_range_set(
533
2.39M
       mapped_range,
534
2.39M
       (off64_t) *data_size,
535
2.39M
       segment_size,
536
2.39M
       error ) != 1 )
537
1.16k
  {
538
1.16k
    libcerror_error_set(
539
1.16k
     error,
540
1.16k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
541
1.16k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
542
1.16k
     "%s: unable to set mapped range values.",
543
1.16k
     function );
544
545
1.16k
    goto on_error;
546
1.16k
  }
547
2.39M
  if( libcdata_array_append_entry(
548
2.39M
       mapped_ranges_array,
549
2.39M
       &mapped_range_index,
550
2.39M
       (intptr_t *) mapped_range,
551
2.39M
       error ) != 1 )
552
0
  {
553
0
    libcerror_error_set(
554
0
     error,
555
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
556
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
557
0
     "%s: unable to append mapped range to array.",
558
0
     function );
559
560
0
    goto on_error;
561
0
  }
562
2.39M
  if( libfdata_range_initialize(
563
2.39M
       &segment_data_range,
564
2.39M
       error ) != 1 )
565
0
  {
566
0
    libcerror_error_set(
567
0
     error,
568
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
569
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
570
0
     "%s: unable to create segment data range.",
571
0
     function );
572
573
0
    goto on_error;
574
0
  }
575
2.39M
  if( libfdata_range_set(
576
2.39M
       segment_data_range,
577
2.39M
       segment_file_index,
578
2.39M
       segment_offset,
579
2.39M
       segment_size,
580
2.39M
       segment_flags,
581
2.39M
       error ) != 1 )
582
0
  {
583
0
    libcerror_error_set(
584
0
     error,
585
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
586
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
587
0
     "%s: unable to set segment data range values.",
588
0
     function );
589
590
0
    goto on_error;
591
0
  }
592
2.39M
  if( libcdata_array_append_entry(
593
2.39M
       segments_array,
594
2.39M
       segment_index,
595
2.39M
       (intptr_t *) segment_data_range,
596
2.39M
       error ) != 1 )
597
0
  {
598
0
    libcerror_error_set(
599
0
     error,
600
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
601
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
602
0
     "%s: unable to append data range to segments array.",
603
0
     function );
604
605
0
    goto on_error;
606
0
  }
607
#if defined( HAVE_DEBUG_OUTPUT )
608
  if( libcnotify_verbose != 0 )
609
  {
610
    libcnotify_printf(
611
     "%s: segment: %03d\tfile index: %03d offset: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
612
     function,
613
     *segment_index,
614
     segment_file_index,
615
     segment_offset,
616
     segment_offset + segment_size,
617
     segment_size );
618
619
    libcnotify_printf(
620
     "%s: segment: %03d\tmapped range: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
621
     function,
622
     *segment_index,
623
     *data_size,
624
     *data_size + segment_size,
625
     segment_size );
626
627
    libcnotify_printf(
628
     "\n" );
629
  }
630
#endif
631
2.39M
  *data_size += segment_size;
632
633
2.39M
  return( 1 );
634
635
1.16k
on_error:
636
1.16k
  if( segment_data_range != NULL )
637
0
  {
638
0
    libfdata_range_free(
639
0
     &segment_data_range,
640
0
     NULL );
641
0
  }
642
1.16k
  if( mapped_range_index != -1 )
643
0
  {
644
0
    libcdata_array_set_entry_by_index(
645
0
     mapped_ranges_array,
646
0
     mapped_range_index,
647
0
     NULL,
648
0
     NULL );
649
0
  }
650
1.16k
  if( mapped_range != NULL )
651
1.16k
  {
652
1.16k
    libfdata_mapped_range_free(
653
1.16k
     &mapped_range,
654
1.16k
     NULL );
655
1.16k
  }
656
1.16k
  return( -1 );
657
2.39M
}
658
659
/* Calculates the mapped ranges from the segments
660
 * Returns 1 if successful or -1 on error
661
 */
662
int libfdata_segments_array_calculate_mapped_ranges(
663
     libcdata_array_t *segments_array,
664
     libcdata_array_t *mapped_ranges_array,
665
     libcerror_error_t **error )
666
22
{
667
22
  libfdata_mapped_range_t *mapped_range = NULL;
668
22
  libfdata_range_t *segment_data_range  = NULL;
669
22
  static char *function                 = "libfdata_segments_array_calculate_mapped_ranges";
670
22
  off64_t mapped_offset                 = 0;
671
22
  off64_t segment_offset                = 0;
672
22
  size64_t segment_size                 = 0;
673
22
  uint32_t segment_flags                = 0;
674
22
  int number_of_segments                = 0;
675
22
  int segment_file_index                = 0;
676
22
  int segment_index                     = 0;
677
678
22
  if( libcdata_array_get_number_of_entries(
679
22
       segments_array,
680
22
       &number_of_segments,
681
22
       error ) != 1 )
682
0
  {
683
0
    libcerror_error_set(
684
0
     error,
685
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
686
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
687
0
     "%s: unable to retrieve number of entries from segments array.",
688
0
     function );
689
690
0
    return( -1 );
691
0
  }
692
22
  for( segment_index = 0;
693
44
       segment_index < number_of_segments;
694
22
       segment_index++ )
695
22
  {
696
22
    if( libcdata_array_get_entry_by_index(
697
22
         segments_array,
698
22
         segment_index,
699
22
         (intptr_t **) &segment_data_range,
700
22
         error ) != 1 )
701
0
    {
702
0
      libcerror_error_set(
703
0
       error,
704
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
705
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
706
0
       "%s: unable to retrieve entry: %d from segments array.",
707
0
       function,
708
0
       segment_index );
709
710
0
      return( -1 );
711
0
    }
712
22
    if( libcdata_array_get_entry_by_index(
713
22
         mapped_ranges_array,
714
22
         segment_index,
715
22
         (intptr_t **) &mapped_range,
716
22
         error ) != 1 )
717
0
    {
718
0
      libcerror_error_set(
719
0
       error,
720
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
721
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
722
0
       "%s: unable to retrieve entry: %d from mapped ranges array.",
723
0
       function,
724
0
       segment_index );
725
726
0
      return( -1 );
727
0
    }
728
22
    if( libfdata_range_get(
729
22
         segment_data_range,
730
22
         &segment_file_index,
731
22
         &segment_offset,
732
22
         &segment_size,
733
22
         &segment_flags,
734
22
         error ) != 1 )
735
0
    {
736
0
      libcerror_error_set(
737
0
       error,
738
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
739
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
740
0
       "%s: unable to retrieve segment: %d data range values.",
741
0
       function,
742
0
       segment_index );
743
744
0
      return( -1 );
745
0
    }
746
#if defined( HAVE_DEBUG_OUTPUT )
747
    if( libcnotify_verbose != 0 )
748
    {
749
      libcnotify_printf(
750
       "%s: segment: %03d\tfile index: %03d offset: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
751
       function,
752
       segment_index,
753
       segment_file_index,
754
       segment_offset,
755
       segment_offset + segment_size,
756
       segment_size );
757
758
      libcnotify_printf(
759
       "%s: segment: %03d\tmapped range: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
760
       function,
761
       segment_index,
762
       mapped_offset,
763
       mapped_offset + segment_size,
764
       segment_size );
765
    }
766
#endif
767
22
    if( libfdata_mapped_range_set(
768
22
         mapped_range,
769
22
         mapped_offset,
770
22
         segment_size,
771
22
         error ) != 1 )
772
0
    {
773
0
      libcerror_error_set(
774
0
       error,
775
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
776
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
777
0
       "%s: unable to set mapped range: %d values.",
778
0
       function,
779
0
       segment_index );
780
781
0
      return( -1 );
782
0
    }
783
22
    mapped_offset += (off64_t) segment_size;
784
22
  }
785
#if defined( HAVE_DEBUG_OUTPUT )
786
  if( libcnotify_verbose != 0 )
787
  {
788
    libcnotify_printf(
789
     "\n" );
790
  }
791
#endif
792
22
  return( 1 );
793
22
}
794
795
/* Retrieves the segment data range for a specific offset
796
 * Returns 1 if successful or -1 on error
797
 */
798
int libfdata_segments_array_get_data_range_at_offset(
799
     libcdata_array_t *segments_array,
800
     off64_t value_offset,
801
     off64_t *segment_data_offset,
802
     libfdata_range_t **segment_data_range,
803
     libcerror_error_t **error )
804
474k
{
805
474k
  static char *function  = "libfdata_segments_array_get_data_range_at_offset";
806
474k
  size64_t segment_size  = 0;
807
474k
  int number_of_segments = 0;
808
474k
  int segment_index      = 0;
809
810
474k
  if( segment_data_offset == NULL )
811
0
  {
812
0
    libcerror_error_set(
813
0
     error,
814
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
815
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
816
0
     "%s: invalid segment data offset.",
817
0
     function );
818
819
0
    return( -1 );
820
0
  }
821
474k
  if( segment_data_range == NULL )
822
0
  {
823
0
    libcerror_error_set(
824
0
     error,
825
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
826
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
827
0
     "%s: invalid segment data range.",
828
0
     function );
829
830
0
    return( -1 );
831
0
  }
832
474k
  if( libcdata_array_get_number_of_entries(
833
474k
       segments_array,
834
474k
       &number_of_segments,
835
474k
       error ) != 1 )
836
0
  {
837
0
    libcerror_error_set(
838
0
     error,
839
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
840
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
841
0
     "%s: unable to retrieve number of segments.",
842
0
     function );
843
844
0
    return( -1 );
845
0
  }
846
474k
  if( number_of_segments <= 0 )
847
0
  {
848
0
    libcerror_error_set(
849
0
     error,
850
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
851
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
852
0
     "%s: invalid number of segments value out of bounds.",
853
0
     function );
854
855
0
    return( -1 );
856
0
  }
857
474k
  for( segment_index = 0;
858
1.11M
       segment_index < number_of_segments;
859
642k
       segment_index++ )
860
1.11M
  {
861
1.11M
    if( libcdata_array_get_entry_by_index(
862
1.11M
         segments_array,
863
1.11M
         segment_index,
864
1.11M
         (intptr_t **) segment_data_range,
865
1.11M
         error ) != 1 )
866
0
    {
867
0
      libcerror_error_set(
868
0
       error,
869
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
870
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
871
0
       "%s: unable to retrieve segment data range: %d from array.",
872
0
       function,
873
0
       segment_index );
874
875
0
      return( -1 );
876
0
    }
877
1.11M
    if( libfdata_range_get_size(
878
1.11M
         *segment_data_range,
879
1.11M
         &segment_size,
880
1.11M
         error ) != 1 )
881
0
    {
882
0
      libcerror_error_set(
883
0
       error,
884
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
885
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
886
0
       "%s: unable to retrieve size from segment data range: %d.",
887
0
       function,
888
0
       segment_index );
889
890
0
      return( -1 );
891
0
    }
892
/* TODO what about compressed data ranges */
893
1.11M
    if( (size64_t) value_offset < segment_size )
894
474k
    {
895
474k
      *segment_data_offset = value_offset;
896
897
474k
      break;
898
474k
    }
899
642k
    value_offset -= segment_size;
900
642k
  }
901
474k
  if( segment_index >= number_of_segments )
902
23
  {
903
23
    libcerror_error_set(
904
23
     error,
905
23
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
906
23
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
907
23
     "%s: invalid segment index value out of bounds.",
908
23
     function );
909
910
23
    return( -1 );
911
23
  }
912
474k
  return( 1 );
913
474k
}
914