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