Coverage Report

Created: 2024-02-25 07:20

/src/libvslvm/libfdata/libfdata_vector.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The vector 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_definitions.h"
27
#include "libfdata_libcdata.h"
28
#include "libfdata_libcerror.h"
29
#include "libfdata_libcnotify.h"
30
#include "libfdata_libfcache.h"
31
#include "libfdata_mapped_range.h"
32
#include "libfdata_range.h"
33
#include "libfdata_segments_array.h"
34
#include "libfdata_types.h"
35
#include "libfdata_unused.h"
36
#include "libfdata_vector.h"
37
38
/* Creates a vector
39
 * Make sure the value vector is referencing, is set to NULL
40
 *
41
 * If the flag LIBFDATA_DATA_HANDLE_FLAG_MANAGED is set the vector
42
 * takes over management of the data handle and the data handle is freed when
43
 * no longer needed
44
 *
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libfdata_vector_initialize(
48
     libfdata_vector_t **vector,
49
     size64_t element_data_size,
50
     intptr_t *data_handle,
51
     int (*free_data_handle)(
52
            intptr_t **data_handle,
53
            libcerror_error_t **error ),
54
     int (*clone_data_handle)(
55
            intptr_t **destination_data_handle,
56
            intptr_t *source_data_handle,
57
            libcerror_error_t **error ),
58
     int (*read_element_data)(
59
            intptr_t *data_handle,
60
            intptr_t *file_io_handle,
61
            libfdata_vector_t *vector,
62
            libfdata_cache_t *cache,
63
            int element_index,
64
            int element_data_file_index,
65
            off64_t element_data_offset,
66
            size64_t element_data_size,
67
            uint32_t element_data_flags,
68
            uint8_t read_flags,
69
            libcerror_error_t **error ),
70
     int (*write_element_data)(
71
            intptr_t *data_handle,
72
            intptr_t *file_io_handle,
73
            libfdata_vector_t *vector,
74
            libfdata_cache_t *cache,
75
            int element_index,
76
            int element_data_file_index,
77
            off64_t element_data_offset,
78
            size64_t element_data_size,
79
            uint32_t element_data_flags,
80
            uint8_t write_flags,
81
            libcerror_error_t **error ),
82
     uint8_t flags,
83
     libcerror_error_t **error )
84
41.2k
{
85
41.2k
  libfdata_internal_vector_t *internal_vector = NULL;
86
41.2k
  static char *function                       = "libfdata_vector_initialize";
87
88
41.2k
  if( vector == NULL )
89
0
  {
90
0
    libcerror_error_set(
91
0
     error,
92
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
93
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
94
0
     "%s: invalid vector.",
95
0
     function );
96
97
0
    return( -1 );
98
0
  }
99
41.2k
  if( *vector != NULL )
100
0
  {
101
0
    libcerror_error_set(
102
0
     error,
103
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
104
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
105
0
     "%s: invalid vector value already set.",
106
0
     function );
107
108
0
    return( -1 );
109
0
  }
110
41.2k
  if( element_data_size == 0 )
111
0
  {
112
0
    libcerror_error_set(
113
0
     error,
114
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
115
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
116
0
     "%s: invalid element data size value zero or less.",
117
0
     function );
118
119
0
    return( -1 );
120
0
  }
121
41.2k
  internal_vector = memory_allocate_structure(
122
41.2k
                     libfdata_internal_vector_t );
123
124
41.2k
  if( internal_vector == NULL )
125
0
  {
126
0
    libcerror_error_set(
127
0
     error,
128
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
129
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
130
0
     "%s: unable to create vector.",
131
0
     function );
132
133
0
    goto on_error;
134
0
  }
135
41.2k
  if( memory_set(
136
41.2k
       internal_vector,
137
41.2k
       0,
138
41.2k
       sizeof( libfdata_internal_vector_t ) ) == NULL )
139
0
  {
140
0
    libcerror_error_set(
141
0
     error,
142
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
143
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
144
0
     "%s: unable to clear vector.",
145
0
     function );
146
147
0
    memory_free(
148
0
     internal_vector );
149
150
0
    return( -1 );
151
0
  }
152
41.2k
  if( libcdata_array_initialize(
153
41.2k
       &( internal_vector->segments_array ),
154
41.2k
       0,
155
41.2k
       error ) != 1 )
156
0
  {
157
0
    libcerror_error_set(
158
0
     error,
159
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
160
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
161
0
     "%s: unable to create segments array.",
162
0
     function );
163
164
0
    goto on_error;
165
0
  }
166
41.2k
  if( libcdata_array_initialize(
167
41.2k
       &( internal_vector->mapped_ranges_array ),
168
41.2k
       0,
169
41.2k
       error ) != 1 )
170
0
  {
171
0
    libcerror_error_set(
172
0
     error,
173
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
174
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
175
0
     "%s: unable to create mapped ranges array.",
176
0
     function );
177
178
0
    goto on_error;
179
0
  }
180
41.2k
  if( libfcache_date_time_get_timestamp(
181
41.2k
       &( internal_vector->timestamp ),
182
41.2k
       error ) != 1 )
183
0
  {
184
0
    libcerror_error_set(
185
0
     error,
186
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
187
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
188
0
     "%s: unable to retrieve cache timestamp.",
189
0
     function );
190
191
0
    goto on_error;
192
0
  }
193
41.2k
  internal_vector->element_data_size  = element_data_size;
194
41.2k
  internal_vector->flags             |= flags;
195
41.2k
  internal_vector->data_handle        = data_handle;
196
41.2k
  internal_vector->free_data_handle   = free_data_handle;
197
41.2k
  internal_vector->clone_data_handle  = clone_data_handle;
198
41.2k
  internal_vector->read_element_data  = read_element_data;
199
41.2k
  internal_vector->write_element_data = write_element_data;
200
201
41.2k
  *vector = (libfdata_vector_t *) internal_vector;
202
203
41.2k
  return( 1 );
204
205
0
on_error:
206
0
  if( internal_vector != NULL )
207
0
  {
208
0
    if( internal_vector->mapped_ranges_array != NULL )
209
0
    {
210
0
      libcdata_array_free(
211
0
       &( internal_vector->mapped_ranges_array ),
212
0
       NULL,
213
0
       NULL );
214
0
    }
215
0
    if( internal_vector->segments_array != NULL )
216
0
    {
217
0
      libcdata_array_free(
218
0
       &( internal_vector->segments_array ),
219
0
       NULL,
220
0
       NULL );
221
0
    }
222
0
    memory_free(
223
0
     internal_vector );
224
0
  }
225
0
  return( -1 );
226
41.2k
}
227
228
/* Frees a vector
229
 * Returns 1 if successful or -1 on error
230
 */
231
int libfdata_vector_free(
232
     libfdata_vector_t **vector,
233
     libcerror_error_t **error )
234
46.0k
{
235
46.0k
  libfdata_internal_vector_t *internal_vector = NULL;
236
46.0k
  static char *function                       = "libfdata_vector_free";
237
46.0k
  int result                                  = 1;
238
239
46.0k
  if( vector == NULL )
240
0
  {
241
0
    libcerror_error_set(
242
0
     error,
243
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
244
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
245
0
     "%s: invalid vector.",
246
0
     function );
247
248
0
    return( -1 );
249
0
  }
250
46.0k
  if( *vector != NULL )
251
41.2k
  {
252
41.2k
    internal_vector = (libfdata_internal_vector_t *) *vector;
253
41.2k
    *vector         = NULL;
254
255
41.2k
    if( libcdata_array_free(
256
41.2k
         &( internal_vector->segments_array ),
257
41.2k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
258
41.2k
         error ) != 1 )
259
0
    {
260
0
      libcerror_error_set(
261
0
       error,
262
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
263
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
264
0
       "%s: unable to free the segments array.",
265
0
       function );
266
267
0
      result = -1;
268
0
    }
269
41.2k
    if( libcdata_array_free(
270
41.2k
         &( internal_vector->mapped_ranges_array ),
271
41.2k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
272
41.2k
         error ) != 1 )
273
0
    {
274
0
      libcerror_error_set(
275
0
       error,
276
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
277
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
278
0
       "%s: unable to free the mapped ranges array.",
279
0
       function );
280
281
0
      result = -1;
282
0
    }
283
41.2k
    if( ( internal_vector->flags & LIBFDATA_DATA_HANDLE_FLAG_MANAGED ) != 0 )
284
17.0k
    {
285
17.0k
      if( internal_vector->data_handle != NULL )
286
17.0k
      {
287
17.0k
        if( internal_vector->free_data_handle == NULL )
288
0
        {
289
0
          libcerror_error_set(
290
0
           error,
291
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
292
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
293
0
           "%s: invalid vector - missing free data handle function.",
294
0
           function );
295
296
0
          result = -1;
297
0
        }
298
17.0k
        else if( internal_vector->free_data_handle(
299
17.0k
                  &( internal_vector->data_handle ),
300
17.0k
                  error ) != 1 )
301
0
        {
302
0
          libcerror_error_set(
303
0
           error,
304
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
305
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
306
0
           "%s: unable to free data handle.",
307
0
           function );
308
309
0
          result = -1;
310
0
        }
311
17.0k
      }
312
17.0k
    }
313
41.2k
    memory_free(
314
41.2k
     internal_vector );
315
41.2k
  }
316
46.0k
  return( result );
317
46.0k
}
318
319
/* Clones (duplicates) the vector
320
 * Returns 1 if successful or -1 on error
321
 */
322
int libfdata_vector_clone(
323
     libfdata_vector_t **destination_vector,
324
     libfdata_vector_t *source_vector,
325
     libcerror_error_t **error )
326
0
{
327
0
  libfdata_internal_vector_t *internal_destination_vector = NULL;
328
0
  libfdata_internal_vector_t *internal_source_vector      = NULL;
329
0
  static char *function                                   = "libfdata_vector_clone";
330
331
0
  if( destination_vector == NULL )
332
0
  {
333
0
    libcerror_error_set(
334
0
     error,
335
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
336
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
337
0
     "%s: invalid destination vector.",
338
0
     function );
339
340
0
    return( -1 );
341
0
  }
342
0
  if( *destination_vector != NULL )
343
0
  {
344
0
    libcerror_error_set(
345
0
     error,
346
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
347
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
348
0
     "%s: invalid destination vector value already set.",
349
0
     function );
350
351
0
    return( -1 );
352
0
  }
353
0
  if( source_vector == NULL )
354
0
  {
355
0
    *destination_vector = source_vector;
356
357
0
    return( 1 );
358
0
  }
359
0
  internal_source_vector = (libfdata_internal_vector_t *) source_vector;
360
361
0
  internal_destination_vector = memory_allocate_structure(
362
0
                                 libfdata_internal_vector_t );
363
364
0
  if( internal_destination_vector == NULL )
365
0
  {
366
0
    libcerror_error_set(
367
0
     error,
368
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
369
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
370
0
     "%s: unable to create destination vector.",
371
0
     function );
372
373
0
    goto on_error;
374
0
  }
375
0
  if( memory_set(
376
0
       internal_destination_vector,
377
0
       0,
378
0
       sizeof( libfdata_internal_vector_t ) ) == NULL )
379
0
  {
380
0
    libcerror_error_set(
381
0
     error,
382
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
383
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
384
0
     "%s: unable to clear destination vector.",
385
0
     function );
386
387
0
    memory_free(
388
0
     internal_destination_vector );
389
390
0
    return( -1 );
391
0
  }
392
0
  if( internal_source_vector->data_handle != NULL )
393
0
  {
394
0
    if( internal_source_vector->free_data_handle == NULL )
395
0
    {
396
0
      libcerror_error_set(
397
0
       error,
398
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
399
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
400
0
       "%s: invalid source vector - missing free data handle function.",
401
0
       function );
402
403
0
      goto on_error;
404
0
    }
405
0
    if( internal_source_vector->clone_data_handle == NULL )
406
0
    {
407
0
      libcerror_error_set(
408
0
       error,
409
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
410
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
411
0
       "%s: invalid source vector - missing clone data handle function.",
412
0
       function );
413
414
0
      goto on_error;
415
0
    }
416
0
    if( internal_source_vector->clone_data_handle(
417
0
         &( internal_destination_vector->data_handle ),
418
0
         internal_source_vector->data_handle,
419
0
         error ) != 1 )
420
0
    {
421
0
      libcerror_error_set(
422
0
       error,
423
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
424
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
425
0
       "%s: unable to create destination data handle.",
426
0
       function );
427
428
0
      goto on_error;
429
0
    }
430
0
  }
431
0
  if( libcdata_array_clone(
432
0
       &( internal_destination_vector->segments_array ),
433
0
       internal_source_vector->segments_array,
434
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
435
0
       (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libfdata_range_clone,
436
0
       error ) != 1 )
437
0
  {
438
0
    libcerror_error_set(
439
0
     error,
440
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
441
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
442
0
     "%s: unable to create destination segments array.",
443
0
     function );
444
445
0
    goto on_error;
446
0
  }
447
0
  if( libcdata_array_clone(
448
0
       &( internal_destination_vector->mapped_ranges_array ),
449
0
       internal_source_vector->mapped_ranges_array,
450
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
451
0
       (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libfdata_mapped_range_clone,
452
0
       error ) != 1 )
453
0
  {
454
0
    libcerror_error_set(
455
0
     error,
456
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
457
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
458
0
     "%s: unable to create destination mapped ranges array.",
459
0
     function );
460
461
0
    goto on_error;
462
0
  }
463
0
  internal_destination_vector->element_data_size  = internal_source_vector->element_data_size;
464
0
  internal_destination_vector->timestamp          = internal_source_vector->timestamp;
465
0
  internal_destination_vector->flags              = internal_source_vector->flags | LIBFDATA_DATA_HANDLE_FLAG_MANAGED;
466
0
  internal_destination_vector->data_handle        = internal_source_vector->data_handle;
467
0
  internal_destination_vector->free_data_handle   = internal_source_vector->free_data_handle;
468
0
  internal_destination_vector->clone_data_handle  = internal_source_vector->clone_data_handle;
469
0
  internal_destination_vector->read_element_data  = internal_source_vector->read_element_data;
470
0
  internal_destination_vector->write_element_data = internal_source_vector->write_element_data;
471
472
0
  *destination_vector = (libfdata_vector_t *) internal_destination_vector;
473
474
0
  return( 1 );
475
476
0
on_error:
477
0
  if( internal_destination_vector != NULL )
478
0
  {
479
0
    if( internal_destination_vector->segments_array != NULL )
480
0
    {
481
0
      libcdata_array_free(
482
0
       &( internal_destination_vector->segments_array ),
483
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
484
0
       NULL );
485
0
    }
486
0
    if( ( internal_destination_vector->data_handle != NULL )
487
0
     && ( internal_source_vector->free_data_handle != NULL ) )
488
0
    {
489
0
      internal_source_vector->free_data_handle(
490
0
       &( internal_destination_vector->data_handle ),
491
0
       NULL );
492
0
    }
493
0
    memory_free(
494
0
     internal_destination_vector );
495
0
  }
496
0
  return( -1 );
497
0
}
498
499
/* Segment functions
500
 */
501
502
/* Empties the vector
503
 * Returns 1 if successful or -1 on error
504
 */
505
int libfdata_vector_empty(
506
     libfdata_vector_t *vector,
507
     libcerror_error_t **error )
508
0
{
509
0
  libfdata_internal_vector_t *internal_vector = NULL;
510
0
  static char *function                       = "libfdata_vector_empty";
511
512
0
  if( vector == NULL )
513
0
  {
514
0
    libcerror_error_set(
515
0
     error,
516
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
517
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
518
0
     "%s: invalid vector.",
519
0
     function );
520
521
0
    return( -1 );
522
0
  }
523
0
  internal_vector = (libfdata_internal_vector_t *) vector;
524
525
0
  if( libcdata_array_empty(
526
0
       internal_vector->segments_array,
527
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
528
0
       error ) != 1 )
529
0
  {
530
0
    libcerror_error_set(
531
0
     error,
532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
533
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
534
0
     "%s: unable to empty segments array.",
535
0
     function );
536
537
0
    return( -1 );
538
0
  }
539
0
  if( libcdata_array_empty(
540
0
       internal_vector->mapped_ranges_array,
541
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
542
0
       error ) != 1 )
543
0
  {
544
0
    libcerror_error_set(
545
0
     error,
546
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
547
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
548
0
     "%s: unable to empty mapped ranges array.",
549
0
     function );
550
551
0
    return( -1 );
552
0
  }
553
0
  internal_vector->size = 0;
554
555
0
  return( 1 );
556
0
}
557
558
/* Resizes the segments
559
 * Returns 1 if successful or -1 on error
560
 */
561
int libfdata_vector_resize(
562
     libfdata_vector_t *vector,
563
     int number_of_segments,
564
     libcerror_error_t **error )
565
0
{
566
0
  libfdata_internal_vector_t *internal_vector = NULL;
567
0
  static char *function                       = "libfdata_vector_resize";
568
569
0
  if( vector == NULL )
570
0
  {
571
0
    libcerror_error_set(
572
0
     error,
573
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
574
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
575
0
     "%s: invalid vector.",
576
0
     function );
577
578
0
    return( -1 );
579
0
  }
580
0
  internal_vector = (libfdata_internal_vector_t *) vector;
581
582
0
  if( libcdata_array_resize(
583
0
       internal_vector->segments_array,
584
0
       number_of_segments,
585
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
586
0
       error ) != 1 )
587
0
  {
588
0
    libcerror_error_set(
589
0
     error,
590
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
591
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
592
0
     "%s: unable to resize segments array.",
593
0
     function );
594
595
0
    return( -1 );
596
0
  }
597
0
  if( libcdata_array_resize(
598
0
       internal_vector->mapped_ranges_array,
599
0
       number_of_segments,
600
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
601
0
       error ) != 1 )
602
0
  {
603
0
    libcerror_error_set(
604
0
     error,
605
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
606
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
607
0
     "%s: unable to resize mapped ranges array.",
608
0
     function );
609
610
0
    return( -1 );
611
0
  }
612
0
  internal_vector->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
613
614
0
  return( 1 );
615
0
}
616
617
/* Retrieves the number of segments of the vector
618
 * Returns 1 if successful or -1 on error
619
 */
620
int libfdata_vector_get_number_of_segments(
621
     libfdata_vector_t *vector,
622
     int *number_of_segments,
623
     libcerror_error_t **error )
624
332
{
625
332
  libfdata_internal_vector_t *internal_vector = NULL;
626
332
  static char *function                       = "libfdata_vector_get_number_of_segments";
627
628
332
  if( vector == NULL )
629
0
  {
630
0
    libcerror_error_set(
631
0
     error,
632
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
633
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
634
0
     "%s: invalid vector.",
635
0
     function );
636
637
0
    return( -1 );
638
0
  }
639
332
  internal_vector = (libfdata_internal_vector_t *) vector;
640
641
332
  if( libcdata_array_get_number_of_entries(
642
332
       internal_vector->segments_array,
643
332
       number_of_segments,
644
332
       error ) != 1 )
645
0
  {
646
0
    libcerror_error_set(
647
0
     error,
648
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
649
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
650
0
     "%s: unable to retrieve number of entries from segments array.",
651
0
     function );
652
653
0
    return( -1 );
654
0
  }
655
332
  return( 1 );
656
332
}
657
658
/* Retrieves the offset and size of a specific segment
659
 * Returns 1 if successful or -1 on error
660
 */
661
int libfdata_vector_get_segment_by_index(
662
     libfdata_vector_t *vector,
663
     int segment_index,
664
     int *segment_file_index,
665
     off64_t *segment_offset,
666
     size64_t *segment_size,
667
     uint32_t *segment_flags,
668
     libcerror_error_t **error )
669
633
{
670
633
  libfdata_internal_vector_t *internal_vector = NULL;
671
633
  static char *function                       = "libfdata_vector_get_segment_by_index";
672
673
633
  if( vector == NULL )
674
0
  {
675
0
    libcerror_error_set(
676
0
     error,
677
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
678
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
679
0
     "%s: invalid vector.",
680
0
     function );
681
682
0
    return( -1 );
683
0
  }
684
633
  internal_vector = (libfdata_internal_vector_t *) vector;
685
686
633
  if( libfdata_segments_array_get_segment_by_index(
687
633
       internal_vector->segments_array,
688
633
       segment_index,
689
633
       segment_file_index,
690
633
       segment_offset,
691
633
       segment_size,
692
633
       segment_flags,
693
633
       error ) != 1 )
694
0
  {
695
0
    libcerror_error_set(
696
0
     error,
697
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
698
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
699
0
     "%s: unable to retrieve segment: %d.",
700
0
     function,
701
0
     segment_index );
702
703
0
    return( -1 );
704
0
  }
705
633
  return( 1 );
706
633
}
707
708
/* Sets the offset and size of a specific segment
709
 * Returns 1 if successful or -1 on error
710
 */
711
int libfdata_vector_set_segment_by_index(
712
     libfdata_vector_t *vector,
713
     int segment_index,
714
     int segment_file_index,
715
     off64_t segment_offset,
716
     size64_t segment_size,
717
     uint32_t segment_flags,
718
     libcerror_error_t **error )
719
0
{
720
0
  libfdata_internal_vector_t *internal_vector = NULL;
721
0
  static char *function                       = "libfdata_vector_set_segment_by_index";
722
723
0
  if( vector == NULL )
724
0
  {
725
0
    libcerror_error_set(
726
0
     error,
727
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
728
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
729
0
     "%s: invalid vector.",
730
0
     function );
731
732
0
    return( -1 );
733
0
  }
734
0
  internal_vector = (libfdata_internal_vector_t *) vector;
735
736
0
  if( libfdata_segments_array_set_segment_by_index(
737
0
       internal_vector->segments_array,
738
0
       internal_vector->mapped_ranges_array,
739
0
       &( internal_vector->size ),
740
0
       segment_index,
741
0
       segment_file_index,
742
0
       segment_offset,
743
0
       segment_size,
744
0
       segment_flags,
745
0
       error ) != 1 )
746
0
  {
747
0
    libcerror_error_set(
748
0
     error,
749
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
750
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
751
0
     "%s: unable to set segment: %d.",
752
0
     function,
753
0
     segment_index );
754
755
0
    return( -1 );
756
0
  }
757
0
  internal_vector->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
758
759
0
  return( 1 );
760
0
}
761
762
/* Prepends a segment
763
 * Returns 1 if successful or -1 on error
764
 */
765
int libfdata_vector_prepend_segment(
766
     libfdata_vector_t *vector,
767
     int segment_file_index,
768
     off64_t segment_offset,
769
     size64_t segment_size,
770
     uint32_t segment_flags,
771
     libcerror_error_t **error )
772
0
{
773
0
  libfdata_internal_vector_t *internal_vector = NULL;
774
0
  static char *function                       = "libfdata_vector_prepend_segment";
775
776
0
  if( vector == NULL )
777
0
  {
778
0
    libcerror_error_set(
779
0
     error,
780
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
781
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
782
0
     "%s: invalid vector.",
783
0
     function );
784
785
0
    return( -1 );
786
0
  }
787
0
  internal_vector = (libfdata_internal_vector_t *) vector;
788
789
0
  if( libfdata_segments_array_prepend_segment(
790
0
       internal_vector->segments_array,
791
0
       internal_vector->mapped_ranges_array,
792
0
       &( internal_vector->size ),
793
0
       segment_file_index,
794
0
       segment_offset,
795
0
       segment_size,
796
0
       segment_flags,
797
0
       error ) != 1 )
798
0
  {
799
0
    libcerror_error_set(
800
0
     error,
801
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
802
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
803
0
     "%s: unable to prepend segment.",
804
0
     function );
805
806
0
    return( -1 );
807
0
  }
808
0
  internal_vector->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
809
810
0
  return( 1 );
811
0
}
812
813
/* Appends a segment
814
 * Returns 1 if successful or -1 on error
815
 */
816
int libfdata_vector_append_segment(
817
     libfdata_vector_t *vector,
818
     int *segment_index,
819
     int segment_file_index,
820
     off64_t segment_offset,
821
     size64_t segment_size,
822
     uint32_t segment_flags,
823
     libcerror_error_t **error )
824
729k
{
825
729k
  libfdata_internal_vector_t *internal_vector = NULL;
826
729k
  static char *function                       = "libfdata_vector_append_segment";
827
828
729k
  if( vector == NULL )
829
0
  {
830
0
    libcerror_error_set(
831
0
     error,
832
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
833
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
834
0
     "%s: invalid vector.",
835
0
     function );
836
837
0
    return( -1 );
838
0
  }
839
729k
  internal_vector = (libfdata_internal_vector_t *) vector;
840
841
729k
  if( libfdata_segments_array_append_segment(
842
729k
       internal_vector->segments_array,
843
729k
       internal_vector->mapped_ranges_array,
844
729k
       &( internal_vector->size ),
845
729k
       segment_index,
846
729k
       segment_file_index,
847
729k
       segment_offset,
848
729k
       segment_size,
849
729k
       segment_flags,
850
729k
       error ) != 1 )
851
774
  {
852
774
    libcerror_error_set(
853
774
     error,
854
774
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
855
774
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
856
774
     "%s: unable to append segment.",
857
774
     function );
858
859
774
    return( -1 );
860
774
  }
861
728k
  return( 1 );
862
729k
}
863
864
/* Vector element functions
865
 */
866
867
/* Retrieves the element data size of the vector
868
 * Returns 1 if successful or -1 on error
869
 */
870
int libfdata_vector_get_element_data_size(
871
     libfdata_vector_t *vector,
872
     size64_t *element_data_size,
873
     libcerror_error_t **error )
874
0
{
875
0
  libfdata_internal_vector_t *internal_vector = NULL;
876
0
  static char *function                       = "libfdata_vector_get_element_data_size";
877
878
0
  if( vector == NULL )
879
0
  {
880
0
    libcerror_error_set(
881
0
     error,
882
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
883
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
884
0
     "%s: invalid vector.",
885
0
     function );
886
887
0
    return( -1 );
888
0
  }
889
0
  internal_vector = (libfdata_internal_vector_t *) vector;
890
891
0
  if( element_data_size == NULL )
892
0
  {
893
0
    libcerror_error_set(
894
0
     error,
895
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
896
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
897
0
     "%s: invalid element data size.",
898
0
     function );
899
900
0
    return( -1 );
901
0
  }
902
0
  *element_data_size = internal_vector->element_data_size;
903
904
0
  return( 1 );
905
0
}
906
907
/* Retrieves the number of elements of the vector
908
 * Returns 1 if successful or -1 on error
909
 */
910
int libfdata_vector_get_number_of_elements(
911
     libfdata_vector_t *vector,
912
     int *number_of_elements,
913
     libcerror_error_t **error )
914
1.87k
{
915
1.87k
  libfdata_internal_vector_t *internal_vector = NULL;
916
1.87k
  static char *function                       = "libfdata_vector_get_number_of_elements";
917
1.87k
  size64_t safe_number_of_elements            = 0;
918
919
1.87k
  if( vector == NULL )
920
0
  {
921
0
    libcerror_error_set(
922
0
     error,
923
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
924
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
925
0
     "%s: invalid vector.",
926
0
     function );
927
928
0
    return( -1 );
929
0
  }
930
1.87k
  internal_vector = (libfdata_internal_vector_t *) vector;
931
932
1.87k
  if( internal_vector->element_data_size == 0 )
933
0
  {
934
0
    libcerror_error_set(
935
0
     error,
936
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
937
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
938
0
     "%s: invalid vector - element data size value out of bounds.",
939
0
     function );
940
941
0
    return( -1 );
942
0
  }
943
1.87k
  if( number_of_elements == NULL )
944
0
  {
945
0
    libcerror_error_set(
946
0
     error,
947
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
948
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
949
0
     "%s: invalid number of elements.",
950
0
     function );
951
952
0
    return( -1 );
953
0
  }
954
1.87k
  safe_number_of_elements = internal_vector->size / internal_vector->element_data_size;
955
956
1.87k
  if( ( internal_vector->size % internal_vector->element_data_size ) != 0 )
957
0
  {
958
0
    safe_number_of_elements++;
959
0
  }
960
1.87k
  if( safe_number_of_elements > (size64_t) INT_MAX )
961
17
  {
962
17
    libcerror_error_set(
963
17
     error,
964
17
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
965
17
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
966
17
     "%s: number of elements value out of bounds.",
967
17
     function );
968
969
17
    return( -1 );
970
17
  }
971
1.86k
  *number_of_elements = (int) safe_number_of_elements;
972
973
1.86k
  return( 1 );
974
1.87k
}
975
976
/* Mapped range functions
977
 */
978
979
/* Retrieves the element index for a specific offset
980
 * Returns 1 if successful or -1 on error
981
 */
982
int libfdata_vector_get_element_index_at_offset(
983
     libfdata_vector_t *vector,
984
     off64_t element_value_offset,
985
     int *element_index,
986
     off64_t *element_data_offset,
987
     libcerror_error_t **error )
988
65.5k
{
989
65.5k
  libfdata_internal_vector_t *internal_vector = NULL;
990
65.5k
  libfdata_mapped_range_t *mapped_range       = NULL;
991
65.5k
  static char *function                       = "libfdata_vector_get_element_index_at_offset";
992
65.5k
  off64_t mapped_range_end_offset             = 0;
993
65.5k
  off64_t mapped_range_start_offset           = 0;
994
65.5k
  off64_t segment_data_offset                 = 0;
995
65.5k
  size64_t mapped_range_size                  = 0;
996
65.5k
  uint64_t calculated_element_index           = 0;
997
65.5k
  int initial_segment_index                   = 0;
998
65.5k
  int number_of_segments                      = 0;
999
65.5k
  int segment_index                           = 0;
1000
65.5k
  int result                                  = 0;
1001
1002
#if defined( HAVE_DEBUG_OUTPUT )
1003
  libfdata_range_t *segment_data_range        = NULL;
1004
  off64_t segment_offset                      = 0;
1005
  size64_t segment_size                       = 0;
1006
  uint32_t segment_flags                      = 0;
1007
  int segment_file_index                      = -1;
1008
#endif
1009
1010
65.5k
  if( vector == NULL )
1011
4
  {
1012
4
    libcerror_error_set(
1013
4
     error,
1014
4
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1015
4
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1016
4
     "%s: invalid vector.",
1017
4
     function );
1018
1019
4
    return( -1 );
1020
4
  }
1021
65.5k
  internal_vector = (libfdata_internal_vector_t *) vector;
1022
1023
65.5k
  if( internal_vector->element_data_size == 0 )
1024
0
  {
1025
0
    libcerror_error_set(
1026
0
     error,
1027
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1028
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1029
0
     "%s: invalid vector - element data size value out of bounds.",
1030
0
     function );
1031
1032
0
    return( -1 );
1033
0
  }
1034
65.5k
  if( internal_vector->size == 0 )
1035
3
  {
1036
3
    libcerror_error_set(
1037
3
     error,
1038
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1039
3
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1040
3
     "%s: invalid vector - size value out of bounds.",
1041
3
     function );
1042
1043
3
    return( -1 );
1044
3
  }
1045
65.5k
  if( element_value_offset < 0 )
1046
0
  {
1047
0
    libcerror_error_set(
1048
0
     error,
1049
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1050
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
1051
0
     "%s: invalid element value offset value less than zero.",
1052
0
     function );
1053
1054
0
    return( -1 );
1055
0
  }
1056
65.5k
  if( element_index == NULL )
1057
0
  {
1058
0
    libcerror_error_set(
1059
0
     error,
1060
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1061
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1062
0
     "%s: invalid element index.",
1063
0
     function );
1064
1065
0
    return( -1 );
1066
0
  }
1067
65.5k
  if( element_data_offset == NULL )
1068
0
  {
1069
0
    libcerror_error_set(
1070
0
     error,
1071
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1072
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1073
0
     "%s: invalid element data offset.",
1074
0
     function );
1075
1076
0
    return( -1 );
1077
0
  }
1078
65.5k
  if( ( internal_vector->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
1079
0
  {
1080
0
    if( libfdata_segments_array_calculate_mapped_ranges(
1081
0
         internal_vector->segments_array,
1082
0
         internal_vector->mapped_ranges_array,
1083
0
         error ) != 1 )
1084
0
    {
1085
0
      libcerror_error_set(
1086
0
       error,
1087
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1088
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1089
0
       "%s: unable to calculate mapped ranges from segments array.",
1090
0
       function );
1091
1092
0
      return( -1 );
1093
0
    }
1094
0
    internal_vector->flags &= ~( LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES );
1095
0
  }
1096
#if defined( HAVE_DEBUG_OUTPUT )
1097
  if( libcnotify_verbose != 0 )
1098
  {
1099
    libcnotify_printf(
1100
     "%s: requested offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
1101
     function,
1102
     element_value_offset,
1103
     element_value_offset );
1104
  }
1105
#endif
1106
65.5k
  if( internal_vector->size == 0 )
1107
0
  {
1108
0
    return( 0 );
1109
0
  }
1110
65.5k
  if( libcdata_array_get_number_of_entries(
1111
65.5k
       internal_vector->mapped_ranges_array,
1112
65.5k
       &number_of_segments,
1113
65.5k
       error ) != 1 )
1114
0
  {
1115
0
    libcerror_error_set(
1116
0
     error,
1117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1118
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1119
0
     "%s: unable to retrieve number of entries from mapped ranges array.",
1120
0
     function );
1121
1122
0
    return( -1 );
1123
0
  }
1124
  /* This assumes a fairly even distribution of the sizes of the segments
1125
   */
1126
65.5k
  initial_segment_index = (int) ( ( number_of_segments * element_value_offset ) / internal_vector->size );
1127
1128
  /* Look for the corresponding segment upwards in the array
1129
   */
1130
65.5k
  for( segment_index = initial_segment_index;
1131
127k
       segment_index < number_of_segments;
1132
65.5k
       segment_index++ )
1133
127k
  {
1134
127k
    if( libcdata_array_get_entry_by_index(
1135
127k
         internal_vector->mapped_ranges_array,
1136
127k
         segment_index,
1137
127k
         (intptr_t **) &mapped_range,
1138
127k
         error ) != 1 )
1139
0
    {
1140
0
      libcerror_error_set(
1141
0
       error,
1142
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1143
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1144
0
       "%s: unable to retrieve entry: %d from mapped ranges array.",
1145
0
       function,
1146
0
       segment_index );
1147
1148
0
      return( -1 );
1149
0
    }
1150
127k
    if( libfdata_mapped_range_get(
1151
127k
         mapped_range,
1152
127k
         &mapped_range_start_offset,
1153
127k
         &mapped_range_size,
1154
127k
         error ) != 1 )
1155
0
    {
1156
0
      libcerror_error_set(
1157
0
       error,
1158
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1159
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1160
0
       "%s: unable to retrieve values from mapped range: %d.",
1161
0
       function,
1162
0
       segment_index );
1163
1164
0
      return( -1 );
1165
0
    }
1166
127k
    mapped_range_end_offset = mapped_range_start_offset + (off64_t) mapped_range_size;
1167
1168
127k
    if( mapped_range_end_offset < mapped_range_start_offset )
1169
0
    {
1170
0
      libcerror_error_set(
1171
0
       error,
1172
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1173
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1174
0
       "%s: invalid segment: %d - mapped range value out of bounds.",
1175
0
       function,
1176
0
       segment_index );
1177
1178
0
      return( -1 );
1179
0
    }
1180
#if defined( HAVE_DEBUG_OUTPUT )
1181
    if( libcnotify_verbose != 0 )
1182
    {
1183
      libcnotify_printf(
1184
       "%s: segment: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1185
       function,
1186
       segment_index,
1187
       mapped_range_start_offset,
1188
       mapped_range_end_offset,
1189
       mapped_range_start_offset,
1190
       mapped_range_end_offset,
1191
       mapped_range_size );
1192
    }
1193
#endif
1194
    /* Check if the element value offset is in the mapped range
1195
     */
1196
127k
    if( ( element_value_offset >= mapped_range_start_offset )
1197
127k
     && ( element_value_offset < mapped_range_end_offset ) )
1198
65.1k
    {
1199
65.1k
      break;
1200
65.1k
    }
1201
    /* Check if the element value offset is out of bounds
1202
     */
1203
62.8k
    if( element_value_offset < mapped_range_start_offset )
1204
419
    {
1205
419
      segment_index = number_of_segments;
1206
1207
419
      break;
1208
419
    }
1209
62.8k
  }
1210
65.5k
  if( segment_index >= number_of_segments )
1211
425
  {
1212
    /* Look for the corresponding segment downwards in the array
1213
     */
1214
425
    for( segment_index = initial_segment_index;
1215
844
         segment_index >= 0;
1216
425
         segment_index-- )
1217
844
    {
1218
844
      if( libcdata_array_get_entry_by_index(
1219
844
           internal_vector->mapped_ranges_array,
1220
844
           segment_index,
1221
844
           (intptr_t **) &mapped_range,
1222
844
           error ) != 1 )
1223
6
      {
1224
6
        libcerror_error_set(
1225
6
         error,
1226
6
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1227
6
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1228
6
         "%s: unable to retrieve entry: %d from mapped ranges array.",
1229
6
         function,
1230
6
         segment_index );
1231
1232
6
        return( -1 );
1233
6
      }
1234
838
      if( libfdata_mapped_range_get(
1235
838
           mapped_range,
1236
838
           &mapped_range_start_offset,
1237
838
           &mapped_range_size,
1238
838
           error ) != 1 )
1239
0
      {
1240
0
        libcerror_error_set(
1241
0
         error,
1242
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1243
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1244
0
         "%s: unable to retrieve values from mapped range: %d.",
1245
0
         function,
1246
0
         segment_index );
1247
1248
0
        return( -1 );
1249
0
      }
1250
838
      mapped_range_end_offset = mapped_range_start_offset + (off64_t) mapped_range_size;
1251
1252
838
      if( mapped_range_end_offset < mapped_range_start_offset )
1253
0
      {
1254
0
        libcerror_error_set(
1255
0
         error,
1256
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1257
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1258
0
         "%s: invalid segment: %d - mapped range value out of bounds.",
1259
0
         function,
1260
0
         segment_index );
1261
1262
0
        return( -1 );
1263
0
      }
1264
#if defined( HAVE_DEBUG_OUTPUT )
1265
      if( libcnotify_verbose != 0 )
1266
      {
1267
        libcnotify_printf(
1268
         "%s: segment: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1269
         function,
1270
         segment_index,
1271
         mapped_range_start_offset,
1272
         mapped_range_end_offset,
1273
         mapped_range_start_offset,
1274
         mapped_range_end_offset,
1275
         mapped_range_size );
1276
      }
1277
#endif
1278
      /* Check if the element value offset is in the mapped range
1279
       */
1280
838
      if( ( element_value_offset >= mapped_range_start_offset )
1281
838
       && ( element_value_offset < mapped_range_end_offset ) )
1282
419
      {
1283
419
        break;
1284
419
      }
1285
      /* Check if the element value offset is out of bounds
1286
       */
1287
419
      if( element_value_offset > mapped_range_start_offset )
1288
0
      {
1289
0
        segment_index = -1;
1290
1291
0
        break;
1292
0
      }
1293
419
      segment_data_offset += (off64_t) mapped_range_size;
1294
419
    }
1295
425
  }
1296
65.5k
  if( ( segment_index >= 0 )
1297
65.5k
   && ( segment_index < number_of_segments ) )
1298
65.5k
  {
1299
#if defined( HAVE_DEBUG_OUTPUT )
1300
    if( libcnotify_verbose != 0 )
1301
    {
1302
      if( libcdata_array_get_entry_by_index(
1303
           internal_vector->segments_array,
1304
           segment_index,
1305
           (intptr_t **) &segment_data_range,
1306
           error ) != 1 )
1307
      {
1308
        libcerror_error_set(
1309
         error,
1310
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1311
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1312
         "%s: unable to retrieve entry: %d from segments array.",
1313
         function,
1314
         segment_index );
1315
1316
        return( -1 );
1317
      }
1318
      if( libfdata_range_get(
1319
           segment_data_range,
1320
           &segment_file_index,
1321
           &segment_offset,
1322
           &segment_size,
1323
           &segment_flags,
1324
           error ) != 1 )
1325
      {
1326
        libcerror_error_set(
1327
         error,
1328
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1329
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1330
         "%s: unable to retrieve segment: %d data range values.",
1331
         function,
1332
         segment_index );
1333
1334
        return( -1 );
1335
      }
1336
      libcnotify_printf(
1337
       "%s: segment: %03d\tfile index: %03d offset: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1338
       function,
1339
       segment_index,
1340
       segment_file_index,
1341
       segment_offset,
1342
       segment_offset + segment_size,
1343
       segment_offset,
1344
       segment_offset + segment_size,
1345
       segment_size );
1346
    }
1347
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1348
1349
65.5k
    calculated_element_index = (uint64_t) element_value_offset / internal_vector->element_data_size;
1350
1351
65.5k
    if( calculated_element_index > (uint64_t) INT_MAX )
1352
0
    {
1353
0
      libcerror_error_set(
1354
0
       error,
1355
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1356
0
       LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1357
0
       "%s: invalid element index value exceeds maximum.",
1358
0
       function );
1359
1360
0
      return( -1 );
1361
0
    }
1362
    /* The element data offset is relative from the start of the vector element not the underlying segment
1363
     */
1364
65.5k
    *element_index       = (int) calculated_element_index;
1365
65.5k
    *element_data_offset = element_value_offset % internal_vector->element_data_size;
1366
1367
65.5k
    result = 1;
1368
65.5k
  }
1369
#if defined( HAVE_DEBUG_OUTPUT )
1370
  if( libcnotify_verbose != 0 )
1371
  {
1372
    libcnotify_printf(
1373
     "\n" );
1374
  }
1375
#endif
1376
65.5k
  return( result );
1377
65.5k
}
1378
1379
/* Vector element value functions
1380
 */
1381
1382
/* Retrieves the value of a specific element
1383
 * Returns 1 if successful or -1 on error
1384
 */
1385
int libfdata_vector_get_element_value_by_index(
1386
     libfdata_vector_t *vector,
1387
     intptr_t *file_io_handle,
1388
     libfdata_cache_t *cache,
1389
     int element_index,
1390
     intptr_t **element_value,
1391
     uint8_t read_flags,
1392
     libcerror_error_t **error )
1393
305k
{
1394
305k
  libfcache_cache_value_t *cache_value        = NULL;
1395
305k
  libfdata_internal_vector_t *internal_vector = NULL;
1396
305k
  libfdata_range_t *segment_data_range        = NULL;
1397
305k
  static char *function                       = "libfdata_vector_get_element_value_by_index";
1398
305k
  off64_t cache_value_offset                  = (off64_t) -1;
1399
305k
  off64_t element_data_offset                 = 0;
1400
305k
  int64_t cache_value_timestamp               = 0;
1401
305k
  uint32_t element_data_flags                 = 0;
1402
305k
  int cache_value_file_index                  = -1;
1403
305k
  int element_data_file_index                 = -1;
1404
305k
  int result                                  = 0;
1405
1406
#if defined( HAVE_DEBUG_OUTPUT )
1407
  const char *hit_or_miss                     = NULL;
1408
#endif
1409
1410
305k
  if( vector == NULL )
1411
0
  {
1412
0
    libcerror_error_set(
1413
0
     error,
1414
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1415
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1416
0
     "%s: invalid vector.",
1417
0
     function );
1418
1419
0
    return( -1 );
1420
0
  }
1421
305k
  internal_vector = (libfdata_internal_vector_t *) vector;
1422
1423
305k
  if( internal_vector->read_element_data == NULL )
1424
0
  {
1425
0
    libcerror_error_set(
1426
0
     error,
1427
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1428
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1429
0
     "%s: invalid vector - missing read element data function.",
1430
0
     function );
1431
1432
0
    return( -1 );
1433
0
  }
1434
305k
  if( internal_vector->element_data_size == 0 )
1435
0
  {
1436
0
    libcerror_error_set(
1437
0
     error,
1438
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1439
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1440
0
     "%s: invalid vector - element data size value out of bounds.",
1441
0
     function );
1442
1443
0
    return( -1 );
1444
0
  }
1445
305k
  if( ( internal_vector->size == 0 )
1446
305k
   || ( internal_vector->size > (off64_t) INT64_MAX ) )
1447
168
  {
1448
168
    libcerror_error_set(
1449
168
     error,
1450
168
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1451
168
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1452
168
     "%s: invalid vector - size value out of bounds.",
1453
168
     function );
1454
1455
168
    return( -1 );
1456
168
  }
1457
304k
  if( ( element_index < 0 )
1458
304k
   || ( (uint64_t) element_index > ( (uint64_t) INT64_MAX / internal_vector->element_data_size ) ) )
1459
70
  {
1460
70
    libcerror_error_set(
1461
70
     error,
1462
70
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1463
70
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1464
70
     "%s: invalid element index value out of bounds.",
1465
70
     function );
1466
1467
70
    return( -1 );
1468
70
  }
1469
304k
  element_data_offset = (off64_t) ( element_index * internal_vector->element_data_size );
1470
1471
304k
  if( (size64_t) element_data_offset > internal_vector->size )
1472
1.39k
  {
1473
1.39k
    libcerror_error_set(
1474
1.39k
     error,
1475
1.39k
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1476
1.39k
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1477
1.39k
     "%s: invalid element index value out of bounds.",
1478
1.39k
     function );
1479
1480
1.39k
    return( -1 );
1481
1.39k
  }
1482
303k
  if( libfdata_segments_array_get_data_range_at_offset(
1483
303k
       internal_vector->segments_array,
1484
303k
       element_data_offset,
1485
303k
       &element_data_offset,
1486
303k
       &segment_data_range,
1487
303k
       error ) != 1 )
1488
23
  {
1489
23
    libcerror_error_set(
1490
23
     error,
1491
23
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1492
23
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1493
23
     "%s: unable to retrieve segment data range for offset: %" PRIi64 " (0x%08" PRIx64 ").",
1494
23
     function,
1495
23
     element_data_offset,
1496
23
     element_data_offset );
1497
1498
23
    return( -1 );
1499
23
  }
1500
303k
  if( segment_data_range == NULL )
1501
0
  {
1502
0
    libcerror_error_set(
1503
0
     error,
1504
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1505
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1506
0
     "%s: missing segment data range.",
1507
0
     function );
1508
1509
0
    return( -1 );
1510
0
  }
1511
303k
  if( segment_data_range->offset > ( (off64_t) INT64_MAX - element_data_offset ) )
1512
142
  {
1513
142
    libcerror_error_set(
1514
142
     error,
1515
142
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1516
142
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1517
142
     "%s: invalid element data offset value out of bounds.",
1518
142
     function );
1519
1520
142
    return( -1 );
1521
142
  }
1522
303k
  element_data_file_index = segment_data_range->file_index;
1523
303k
  element_data_offset    += segment_data_range->offset;
1524
303k
  element_data_flags      = segment_data_range->flags;
1525
1526
303k
  if( ( read_flags & LIBFDATA_READ_FLAG_IGNORE_CACHE ) == 0 )
1527
301k
  {
1528
301k
    result = libfcache_cache_get_value_by_identifier(
1529
301k
              (libfcache_cache_t *) cache,
1530
301k
              element_data_file_index,
1531
301k
              element_data_offset,
1532
301k
              internal_vector->timestamp,
1533
301k
              &cache_value,
1534
301k
              error );
1535
1536
301k
    if( result == -1 )
1537
0
    {
1538
0
      libcerror_error_set(
1539
0
       error,
1540
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1541
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1542
0
       "%s: unable to retrieve value from cache.",
1543
0
       function );
1544
1545
0
      return( -1 );
1546
0
    }
1547
#if defined( HAVE_DEBUG_OUTPUT )
1548
    if( libcnotify_verbose != 0 )
1549
    {
1550
      if( result == 0 )
1551
      {
1552
        hit_or_miss = "miss";
1553
      }
1554
      else
1555
      {
1556
        hit_or_miss = "hit";
1557
      }
1558
      libcnotify_printf(
1559
       "%s: cache: 0x%08" PRIjx " %s\n",
1560
       function,
1561
       (intptr_t) cache,
1562
       hit_or_miss );
1563
    }
1564
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1565
301k
  }
1566
303k
  if( result == 0 )
1567
136k
  {
1568
#if defined( HAVE_DEBUG_OUTPUT )
1569
    if( libcnotify_verbose != 0 )
1570
    {
1571
      libcnotify_printf(
1572
       "%s: reading element data at offset: %" PRIi64 " (0x%08" PRIx64 ") of size: %" PRIu64 "\n",
1573
       function,
1574
       element_data_offset,
1575
       element_data_offset,
1576
       internal_vector->element_data_size );
1577
    }
1578
#endif
1579
136k
    if( internal_vector->read_element_data(
1580
136k
         internal_vector->data_handle,
1581
136k
         file_io_handle,
1582
136k
         vector,
1583
136k
         cache,
1584
136k
         element_index,
1585
136k
         element_data_file_index,
1586
136k
         element_data_offset,
1587
136k
         internal_vector->element_data_size,
1588
136k
         element_data_flags,
1589
136k
         read_flags,
1590
136k
         error ) != 1 )
1591
3.91k
    {
1592
3.91k
      libcerror_error_set(
1593
3.91k
       error,
1594
3.91k
       LIBCERROR_ERROR_DOMAIN_IO,
1595
3.91k
       LIBCERROR_IO_ERROR_READ_FAILED,
1596
3.91k
       "%s: unable to read element data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1597
3.91k
       function,
1598
3.91k
       element_data_offset,
1599
3.91k
       element_data_offset );
1600
1601
3.91k
      return( -1 );
1602
3.91k
    }
1603
132k
    if( libfcache_cache_get_value_by_identifier(
1604
132k
         (libfcache_cache_t *) cache,
1605
132k
         element_data_file_index,
1606
132k
         element_data_offset,
1607
132k
         internal_vector->timestamp,
1608
132k
         &cache_value,
1609
132k
         error ) != 1 )
1610
0
    {
1611
0
      libcerror_error_set(
1612
0
       error,
1613
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1614
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1615
0
       "%s: unable to retrieve value from cache.",
1616
0
       function );
1617
1618
0
      return( -1 );
1619
0
    }
1620
132k
    if( libfcache_cache_value_get_identifier(
1621
132k
         cache_value,
1622
132k
         &cache_value_file_index,
1623
132k
         &cache_value_offset,
1624
132k
         &cache_value_timestamp,
1625
132k
         error ) != 1 )
1626
0
    {
1627
0
      libcerror_error_set(
1628
0
       error,
1629
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1630
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1631
0
       "%s: unable to retrieve cache value identifier.",
1632
0
       function );
1633
1634
0
      return( -1 );
1635
0
    }
1636
132k
    if( ( element_data_file_index != cache_value_file_index )
1637
132k
     || ( element_data_offset != cache_value_offset )
1638
132k
     || ( internal_vector->timestamp != cache_value_timestamp ) )
1639
0
    {
1640
0
      libcerror_error_set(
1641
0
       error,
1642
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1643
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1644
0
       "%s: invalid cache value - identifier value out of bounds.",
1645
0
       function );
1646
1647
0
      return( -1 );
1648
0
    }
1649
132k
  }
1650
299k
  if( libfcache_cache_value_get_value(
1651
299k
       cache_value,
1652
299k
       element_value,
1653
299k
       error ) != 1 )
1654
0
  {
1655
0
    libcerror_error_set(
1656
0
     error,
1657
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1658
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1659
0
     "%s: unable to retrieve element value.",
1660
0
     function );
1661
1662
0
    return( -1 );
1663
0
  }
1664
299k
  return( 1 );
1665
299k
}
1666
1667
/* Retrieves the value an element at a specific offset
1668
 * Returns 1 if successful or -1 on error
1669
 */
1670
int libfdata_vector_get_element_value_at_offset(
1671
     libfdata_vector_t *vector,
1672
     intptr_t *file_io_handle,
1673
     libfdata_cache_t *cache,
1674
     off64_t element_value_offset,
1675
     off64_t *element_data_offset,
1676
     intptr_t **element_value,
1677
     uint8_t read_flags,
1678
     libcerror_error_t **error )
1679
65.5k
{
1680
65.5k
  static char *function = "libfdata_vector_get_element_value_at_offset";
1681
65.5k
  int element_index     = 0;
1682
1683
65.5k
  if( libfdata_vector_get_element_index_at_offset(
1684
65.5k
       vector,
1685
65.5k
       element_value_offset,
1686
65.5k
       &element_index,
1687
65.5k
       element_data_offset,
1688
65.5k
       error ) != 1 )
1689
13
  {
1690
13
    libcerror_error_set(
1691
13
     error,
1692
13
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1693
13
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1694
13
     "%s: unable to retrieve element index at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1695
13
     function,
1696
13
     element_value_offset,
1697
13
     element_value_offset );
1698
1699
13
    return( -1 );
1700
13
  }
1701
65.5k
  if( libfdata_vector_get_element_value_by_index(
1702
65.5k
       vector,
1703
65.5k
       file_io_handle,
1704
65.5k
       cache,
1705
65.5k
       element_index,
1706
65.5k
       element_value,
1707
65.5k
       read_flags,
1708
65.5k
       error ) != 1 )
1709
499
  {
1710
499
    libcerror_error_set(
1711
499
     error,
1712
499
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1713
499
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1714
499
     "%s: unable to retrieve element: %d value.",
1715
499
     function,
1716
499
     element_index );
1717
1718
499
    return( -1 );
1719
499
  }
1720
65.0k
  return( 1 );
1721
65.5k
}
1722
1723
/* Sets the value of a specific element
1724
 *
1725
 * If the flag LIBFDATA_VECTOR_ELEMENT_VALUE_FLAG_MANAGED is set the vector
1726
 * takes over management of the value and the value is freed when
1727
 * no longer needed.
1728
 *
1729
 * Returns 1 if successful or -1 on error
1730
 */
1731
int libfdata_vector_set_element_value_by_index(
1732
     libfdata_vector_t *vector,
1733
     intptr_t *file_io_handle LIBFDATA_ATTRIBUTE_UNUSED,
1734
     libfdata_cache_t *cache,
1735
     int element_index,
1736
     intptr_t *element_value,
1737
     int (*free_element_value)(
1738
            intptr_t **element_value,
1739
            libcerror_error_t **error ),
1740
     uint8_t write_flags,
1741
     libcerror_error_t **error )
1742
132k
{
1743
132k
  libfdata_internal_vector_t *internal_vector = NULL;
1744
132k
  libfdata_range_t *segment_data_range        = NULL;
1745
132k
  static char *function                       = "libfdata_vector_set_element_value_by_index";
1746
132k
  off64_t element_data_offset                 = 0;
1747
1748
132k
  LIBFDATA_UNREFERENCED_PARAMETER( file_io_handle )
1749
1750
132k
  if( vector == NULL )
1751
0
  {
1752
0
    libcerror_error_set(
1753
0
     error,
1754
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1755
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1756
0
     "%s: invalid vector.",
1757
0
     function );
1758
1759
0
    return( -1 );
1760
0
  }
1761
132k
  internal_vector = (libfdata_internal_vector_t *) vector;
1762
1763
132k
  if( internal_vector->element_data_size == 0 )
1764
0
  {
1765
0
    libcerror_error_set(
1766
0
     error,
1767
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1768
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1769
0
     "%s: invalid vector - element data size value out of bounds.",
1770
0
     function );
1771
1772
0
    return( -1 );
1773
0
  }
1774
132k
  if( ( internal_vector->size == 0 )
1775
132k
   || ( internal_vector->size > (off64_t) INT64_MAX ) )
1776
0
  {
1777
0
    libcerror_error_set(
1778
0
     error,
1779
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1780
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1781
0
     "%s: invalid vector - size value out of bounds.",
1782
0
     function );
1783
1784
0
    return( -1 );
1785
0
  }
1786
132k
  if( ( element_index < 0 )
1787
132k
   || ( (uint64_t) element_index > ( (uint64_t) INT64_MAX / internal_vector->element_data_size ) ) )
1788
0
  {
1789
0
    libcerror_error_set(
1790
0
     error,
1791
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1792
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1793
0
     "%s: invalid element index value out of bounds.",
1794
0
     function );
1795
1796
0
    return( -1 );
1797
0
  }
1798
132k
  element_data_offset = (off64_t) ( element_index * internal_vector->element_data_size );
1799
1800
132k
  if( (size64_t) element_data_offset > internal_vector->size )
1801
0
  {
1802
0
    libcerror_error_set(
1803
0
     error,
1804
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1805
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1806
0
     "%s: invalid element index value out of bounds.",
1807
0
     function );
1808
1809
0
    return( -1 );
1810
0
  }
1811
132k
  if( libfdata_segments_array_get_data_range_at_offset(
1812
132k
       internal_vector->segments_array,
1813
132k
       element_data_offset,
1814
132k
       &element_data_offset,
1815
132k
       &segment_data_range,
1816
132k
       error ) != 1 )
1817
0
  {
1818
0
    libcerror_error_set(
1819
0
     error,
1820
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1821
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1822
0
     "%s: unable to retrieve segment data range for offset: %" PRIi64 " (0x%08" PRIx64 ").",
1823
0
     function,
1824
0
     element_data_offset,
1825
0
     element_data_offset );
1826
1827
0
    return( -1 );
1828
0
  }
1829
132k
  if( segment_data_range == NULL )
1830
0
  {
1831
0
    libcerror_error_set(
1832
0
     error,
1833
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1834
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1835
0
     "%s: missing segment data range.",
1836
0
     function );
1837
1838
0
    return( -1 );
1839
0
  }
1840
132k
  if( segment_data_range->offset > ( (off64_t) INT64_MAX - element_data_offset ) )
1841
0
  {
1842
0
    libcerror_error_set(
1843
0
     error,
1844
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1845
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1846
0
     "%s: invalid element data offset value out of bounds.",
1847
0
     function );
1848
1849
0
    return( -1 );
1850
0
  }
1851
132k
  element_data_offset += segment_data_range->offset;
1852
1853
132k
  if( libfcache_cache_set_value_by_identifier(
1854
132k
       (libfcache_cache_t *) cache,
1855
132k
       segment_data_range->file_index,
1856
132k
       element_data_offset,
1857
132k
       internal_vector->timestamp,
1858
132k
       element_value,
1859
132k
       free_element_value,
1860
132k
       write_flags,
1861
132k
       error ) != 1 )
1862
0
  {
1863
0
    libcerror_error_set(
1864
0
     error,
1865
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1866
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1867
0
     "%s: unable to set value in cache.",
1868
0
     function );
1869
1870
0
    return( -1 );
1871
0
  }
1872
132k
  return( 1 );
1873
132k
}
1874
1875
/* Retrieves the size
1876
 * Returns 1 if successful or -1 on error
1877
 */
1878
int libfdata_vector_get_size(
1879
     libfdata_vector_t *vector,
1880
     size64_t *size,
1881
     libcerror_error_t **error )
1882
1.68k
{
1883
1.68k
  libfdata_internal_vector_t *internal_vector = NULL;
1884
1.68k
  static char *function                       = "libfdata_vector_get_size";
1885
1886
1.68k
  if( vector == NULL )
1887
0
  {
1888
0
    libcerror_error_set(
1889
0
     error,
1890
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1891
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1892
0
     "%s: invalid vector.",
1893
0
     function );
1894
1895
0
    return( -1 );
1896
0
  }
1897
1.68k
  internal_vector = (libfdata_internal_vector_t *) vector;
1898
1899
1.68k
  if( size == NULL )
1900
0
  {
1901
0
    libcerror_error_set(
1902
0
     error,
1903
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1904
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1905
0
     "%s: invalid size.",
1906
0
     function );
1907
1908
0
    return( -1 );
1909
0
  }
1910
1.68k
  if( ( internal_vector->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
1911
0
  {
1912
0
    if( libfdata_segments_array_calculate_mapped_ranges(
1913
0
         internal_vector->segments_array,
1914
0
         internal_vector->mapped_ranges_array,
1915
0
         error ) != 1 )
1916
0
    {
1917
0
      libcerror_error_set(
1918
0
       error,
1919
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1920
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1921
0
       "%s: unable to calculate mapped ranges.",
1922
0
       function );
1923
1924
0
      return( -1 );
1925
0
    }
1926
0
    internal_vector->flags &= ~( LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES );
1927
0
  }
1928
1.68k
  *size = internal_vector->size;
1929
1930
1.68k
  return( 1 );
1931
1.68k
}
1932