1 /*
2 * The cache 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 "libfcache_cache.h"
27 #include "libfcache_cache_value.h"
28 #include "libfcache_definitions.h"
29 #include "libfcache_libcdata.h"
30 #include "libfcache_libcerror.h"
31 #include "libfcache_types.h"
32
33 /* Creates a cache
34 * Make sure the value cache is referencing, is set to NULL
35 * Returns 1 if successful or -1 on error
36 */
libfcache_cache_initialize(libfcache_cache_t ** cache,int maximum_cache_entries,libcerror_error_t ** error)37 int libfcache_cache_initialize(
38 libfcache_cache_t **cache,
39 int maximum_cache_entries,
40 libcerror_error_t **error )
41 {
42 libfcache_internal_cache_t *internal_cache = NULL;
43 static char *function = "libfcache_cache_initialize";
44
45 if( cache == NULL )
46 {
47 libcerror_error_set(
48 error,
49 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51 "%s: invalid cache.",
52 function );
53
54 return( -1 );
55 }
56 if( *cache != NULL )
57 {
58 libcerror_error_set(
59 error,
60 LIBCERROR_ERROR_DOMAIN_RUNTIME,
61 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62 "%s: invalid cache value already set.",
63 function );
64
65 return( -1 );
66 }
67 if( maximum_cache_entries <= 0 )
68 {
69 libcerror_error_set(
70 error,
71 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
72 LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
73 "%s: invalid maximum cache entries value zero or less.",
74 function );
75
76 return( -1 );
77 }
78 internal_cache = memory_allocate_structure(
79 libfcache_internal_cache_t );
80
81 if( internal_cache == NULL )
82 {
83 libcerror_error_set(
84 error,
85 LIBCERROR_ERROR_DOMAIN_MEMORY,
86 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
87 "%s: unable to create cache.",
88 function );
89
90 goto on_error;
91 }
92 if( memory_set(
93 internal_cache,
94 0,
95 sizeof( libfcache_internal_cache_t ) ) == NULL )
96 {
97 libcerror_error_set(
98 error,
99 LIBCERROR_ERROR_DOMAIN_MEMORY,
100 LIBCERROR_MEMORY_ERROR_SET_FAILED,
101 "%s: unable to clear cache.",
102 function );
103
104 memory_free(
105 internal_cache );
106
107 return( -1 );
108 }
109 if( libcdata_array_initialize(
110 &( internal_cache->entries_array ),
111 maximum_cache_entries,
112 error ) != 1 )
113 {
114 libcerror_error_set(
115 error,
116 LIBCERROR_ERROR_DOMAIN_RUNTIME,
117 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
118 "%s: unable to create entries array.",
119 function );
120
121 goto on_error;
122 }
123 if( libcdata_list_initialize(
124 &( internal_cache->entries_list ),
125 error ) != 1 )
126 {
127 libcerror_error_set(
128 error,
129 LIBCERROR_ERROR_DOMAIN_RUNTIME,
130 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
131 "%s: unable to create entries list.",
132 function );
133
134 goto on_error;
135 }
136 *cache = (libfcache_cache_t *) internal_cache;
137
138 return( 1 );
139
140 on_error:
141 if( internal_cache != NULL )
142 {
143 if( internal_cache->entries_array != NULL )
144 {
145 libcdata_array_free(
146 &( internal_cache->entries_array ),
147 NULL,
148 NULL );
149 }
150 memory_free(
151 internal_cache );
152 }
153 return( -1 );
154 }
155
156 /* Frees a cache
157 * Returns 1 if successful or -1 on error
158 */
libfcache_cache_free(libfcache_cache_t ** cache,libcerror_error_t ** error)159 int libfcache_cache_free(
160 libfcache_cache_t **cache,
161 libcerror_error_t **error )
162 {
163 libfcache_internal_cache_t *internal_cache = NULL;
164 static char *function = "libfcache_cache_free";
165 int result = 1;
166
167 if( cache == NULL )
168 {
169 libcerror_error_set(
170 error,
171 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
172 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
173 "%s: invalid cache.",
174 function );
175
176 return( -1 );
177 }
178 if( *cache != NULL )
179 {
180 internal_cache = (libfcache_internal_cache_t *) *cache;
181 *cache = NULL;
182
183 if( libcdata_list_free(
184 &( internal_cache->entries_list ),
185 NULL,
186 error ) != 1 )
187 {
188 libcerror_error_set(
189 error,
190 LIBCERROR_ERROR_DOMAIN_RUNTIME,
191 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
192 "%s: unable to free the entries list.",
193 function );
194
195 result = -1;
196 }
197 if( libcdata_array_free(
198 &( internal_cache->entries_array ),
199 (int (*)(intptr_t **, libcerror_error_t **)) &libfcache_cache_value_free,
200 error ) != 1 )
201 {
202 libcerror_error_set(
203 error,
204 LIBCERROR_ERROR_DOMAIN_RUNTIME,
205 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
206 "%s: unable to free the entries array.",
207 function );
208
209 result = -1;
210 }
211 memory_free(
212 internal_cache );
213 }
214 return( result );
215 }
216
217 /* Empties the cache
218 * Returns 1 if successful or -1 on error
219 */
libfcache_cache_empty(libfcache_cache_t * cache,libcerror_error_t ** error)220 int libfcache_cache_empty(
221 libfcache_cache_t *cache,
222 libcerror_error_t **error )
223 {
224 libfcache_internal_cache_t *internal_cache = NULL;
225 static char *function = "libfcache_cache_empty";
226
227 if( cache == NULL )
228 {
229 libcerror_error_set(
230 error,
231 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
232 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
233 "%s: invalid cache.",
234 function );
235
236 return( -1 );
237 }
238 internal_cache = (libfcache_internal_cache_t *) cache;
239
240 if( libcdata_list_empty(
241 internal_cache->entries_list,
242 NULL,
243 error ) != 1 )
244 {
245 libcerror_error_set(
246 error,
247 LIBCERROR_ERROR_DOMAIN_RUNTIME,
248 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
249 "%s: unable to empty entries list.",
250 function );
251
252 return( -1 );
253 }
254 if( libcdata_array_clear(
255 internal_cache->entries_array,
256 (int (*)(intptr_t **, libcerror_error_t **)) &libfcache_cache_value_free,
257 error ) != 1 )
258 {
259 libcerror_error_set(
260 error,
261 LIBCERROR_ERROR_DOMAIN_RUNTIME,
262 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
263 "%s: unable to clear entries array.",
264 function );
265
266 return( -1 );
267 }
268 internal_cache->number_of_cache_values = 0;
269
270 return( 1 );
271 }
272
273 /* Clones (duplicates) the cache, not the cache values
274 * Returns 1 if successful or -1 on error
275 */
libfcache_cache_clone(libfcache_cache_t ** destination_cache,libfcache_cache_t * source_cache,libcerror_error_t ** error)276 int libfcache_cache_clone(
277 libfcache_cache_t **destination_cache,
278 libfcache_cache_t *source_cache,
279 libcerror_error_t **error )
280 {
281 libfcache_internal_cache_t *internal_source_cache = NULL;
282 static char *function = "libfcache_cache_clone";
283 int number_of_cache_entries = 0;
284
285 if( destination_cache == NULL )
286 {
287 libcerror_error_set(
288 error,
289 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
290 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
291 "%s: invalid destination cache.",
292 function );
293
294 return( -1 );
295 }
296 if( *destination_cache != NULL )
297 {
298 libcerror_error_set(
299 error,
300 LIBCERROR_ERROR_DOMAIN_RUNTIME,
301 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
302 "%s: destination cache already set.",
303 function );
304
305 return( -1 );
306 }
307 if( source_cache == NULL )
308 {
309 *destination_cache = NULL;
310
311 return( 1 );
312 }
313 internal_source_cache = (libfcache_internal_cache_t *) source_cache;
314
315 if( libcdata_array_get_number_of_entries(
316 internal_source_cache->entries_array,
317 &number_of_cache_entries,
318 error ) != 1 )
319 {
320 libcerror_error_set(
321 error,
322 LIBCERROR_ERROR_DOMAIN_RUNTIME,
323 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
324 "%s: unable to retrieve number of cache entries from source entries array.",
325 function );
326
327 return( -1 );
328 }
329 if( libfcache_cache_initialize(
330 destination_cache,
331 number_of_cache_entries,
332 error ) != 1 )
333 {
334 libcerror_error_set(
335 error,
336 LIBCERROR_ERROR_DOMAIN_RUNTIME,
337 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
338 "%s: unable to create destination cache.",
339 function );
340
341 return( -1 );
342 }
343 return( 1 );
344 }
345
346 /* Resizes the cache
347 * Returns 1 if successful or -1 on error
348 */
libfcache_cache_resize(libfcache_cache_t * cache,int maximum_cache_entries,libcerror_error_t ** error)349 int libfcache_cache_resize(
350 libfcache_cache_t *cache,
351 int maximum_cache_entries,
352 libcerror_error_t **error )
353 {
354 libfcache_internal_cache_t *internal_cache = NULL;
355 static char *function = "libfcache_cache_resize";
356
357 if( cache == NULL )
358 {
359 libcerror_error_set(
360 error,
361 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
362 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
363 "%s: invalid cache.",
364 function );
365
366 return( -1 );
367 }
368 internal_cache = (libfcache_internal_cache_t *) cache;
369
370 if( libcdata_array_resize(
371 internal_cache->entries_array,
372 maximum_cache_entries,
373 (int (*)(intptr_t **, libcerror_error_t **)) &libfcache_cache_value_free,
374 error ) != 1 )
375 {
376 libcerror_error_set(
377 error,
378 LIBCERROR_ERROR_DOMAIN_RUNTIME,
379 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
380 "%s: unable to resize entries array.",
381 function );
382
383 return( -1 );
384 }
385 return( 1 );
386 }
387
388 /* Retrieves the number of entries of the cache
389 * Returns 1 if successful or -1 on error
390 */
libfcache_cache_get_number_of_entries(libfcache_cache_t * cache,int * number_of_entries,libcerror_error_t ** error)391 int libfcache_cache_get_number_of_entries(
392 libfcache_cache_t *cache,
393 int *number_of_entries,
394 libcerror_error_t **error )
395 {
396 libfcache_internal_cache_t *internal_cache = NULL;
397 static char *function = "libfcache_cache_get_number_of_entries";
398
399 if( cache == NULL )
400 {
401 libcerror_error_set(
402 error,
403 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
404 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
405 "%s: invalid cache.",
406 function );
407
408 return( -1 );
409 }
410 internal_cache = (libfcache_internal_cache_t *) cache;
411
412 if( libcdata_array_get_number_of_entries(
413 internal_cache->entries_array,
414 number_of_entries,
415 error ) != 1 )
416 {
417 libcerror_error_set(
418 error,
419 LIBCERROR_ERROR_DOMAIN_RUNTIME,
420 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
421 "%s: unable to retrieve number of entries from entries array.",
422 function );
423
424 return( -1 );
425 }
426 return( 1 );
427 }
428
429 /* Retrieves the number of cache values
430 * Returns 1 if successful or -1 on error
431 */
libfcache_cache_get_number_of_cache_values(libfcache_cache_t * cache,int * number_of_cache_values,libcerror_error_t ** error)432 int libfcache_cache_get_number_of_cache_values(
433 libfcache_cache_t *cache,
434 int *number_of_cache_values,
435 libcerror_error_t **error )
436 {
437 libfcache_internal_cache_t *internal_cache = NULL;
438 static char *function = "libfcache_cache_get_number_of_cache_values";
439
440 if( cache == NULL )
441 {
442 libcerror_error_set(
443 error,
444 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
445 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
446 "%s: invalid cache.",
447 function );
448
449 return( -1 );
450 }
451 internal_cache = (libfcache_internal_cache_t *) cache;
452
453 if( libcdata_list_get_number_of_elements(
454 internal_cache->entries_list,
455 number_of_cache_values,
456 error ) != 1 )
457 {
458 libcerror_error_set(
459 error,
460 LIBCERROR_ERROR_DOMAIN_RUNTIME,
461 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
462 "%s: unable to retrieve number of elements from entries list.",
463 function );
464
465 return( -1 );
466 }
467 return( 1 );
468 }
469
470 /* Clears the cache value for the specific index
471 * Returns 1 if successful or -1 on error
472 */
libfcache_cache_clear_value_by_index(libfcache_cache_t * cache,int cache_entry_index,libcerror_error_t ** error)473 int libfcache_cache_clear_value_by_index(
474 libfcache_cache_t *cache,
475 int cache_entry_index,
476 libcerror_error_t **error )
477 {
478 libfcache_cache_value_t *cache_value = NULL;
479 libfcache_internal_cache_t *internal_cache = NULL;
480 static char *function = "libfcache_cache_clear_value_by_index";
481
482 if( cache == NULL )
483 {
484 libcerror_error_set(
485 error,
486 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
487 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
488 "%s: invalid cache.",
489 function );
490
491 return( -1 );
492 }
493 internal_cache = (libfcache_internal_cache_t *) cache;
494
495 if( libcdata_array_get_entry_by_index(
496 internal_cache->entries_array,
497 cache_entry_index,
498 (intptr_t **) &cache_value,
499 error ) != 1 )
500 {
501 libcerror_error_set(
502 error,
503 LIBCERROR_ERROR_DOMAIN_RUNTIME,
504 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
505 "%s: unable to retrieve cache value: %d from entries array.",
506 function,
507 cache_entry_index );
508
509 return( -1 );
510 }
511 if( libfcache_cache_value_clear(
512 cache_value,
513 error ) != 1 )
514 {
515 libcerror_error_set(
516 error,
517 LIBCERROR_ERROR_DOMAIN_RUNTIME,
518 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
519 "%s: unable to clear cache value.",
520 function );
521
522 return( -1 );
523 }
524 return( 1 );
525 }
526
527 /* Retrieves the cache value that matches the file index, offset and timestamp
528 * Returns 1 if successful, 0 if no such value or -1 on error
529 */
libfcache_cache_get_value_by_identifier(libfcache_cache_t * cache,int file_index,off64_t offset,int64_t timestamp,libfcache_cache_value_t ** cache_value,libcerror_error_t ** error)530 int libfcache_cache_get_value_by_identifier(
531 libfcache_cache_t *cache,
532 int file_index,
533 off64_t offset,
534 int64_t timestamp,
535 libfcache_cache_value_t **cache_value,
536 libcerror_error_t **error )
537 {
538 libcdata_list_element_t *list_element = NULL;
539 libfcache_cache_value_t *safe_cache_value = NULL;
540 libfcache_internal_cache_t *internal_cache = NULL;
541 static char *function = "libfcache_cache_get_value_by_identifier";
542 off64_t cache_value_offset = 0;
543 int64_t cache_value_timestamp = 0;
544 int cache_value_file_index = 0;
545 int number_of_cache_values = 0;
546 int result = 0;
547
548 if( cache == NULL )
549 {
550 libcerror_error_set(
551 error,
552 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
553 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
554 "%s: invalid cache.",
555 function );
556
557 return( -1 );
558 }
559 internal_cache = (libfcache_internal_cache_t *) cache;
560
561 if( cache_value == NULL )
562 {
563 libcerror_error_set(
564 error,
565 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
566 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
567 "%s: invalid cache value.",
568 function );
569
570 return( -1 );
571 }
572 *cache_value = NULL;
573
574 if( libcdata_list_get_number_of_elements(
575 internal_cache->entries_list,
576 &number_of_cache_values,
577 error ) != 1 )
578 {
579 libcerror_error_set(
580 error,
581 LIBCERROR_ERROR_DOMAIN_RUNTIME,
582 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
583 "%s: unable to retrieve number of elements from entries list.",
584 function );
585
586 return( -1 );
587 }
588 if( libcdata_list_get_first_element(
589 internal_cache->entries_list,
590 &list_element,
591 error ) != 1 )
592 {
593 libcerror_error_set(
594 error,
595 LIBCERROR_ERROR_DOMAIN_RUNTIME,
596 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
597 "%s: unable to retrieve first list element.",
598 function );
599
600 return( -1 );
601 }
602 while( list_element != NULL )
603 {
604 if( libcdata_list_element_get_value(
605 list_element,
606 (intptr_t **) &safe_cache_value,
607 error ) != 1 )
608 {
609 libcerror_error_set(
610 error,
611 LIBCERROR_ERROR_DOMAIN_RUNTIME,
612 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
613 "%s: unable to retrieve cache value from list element.",
614 function );
615
616 return( -1 );
617 }
618 if( libfcache_cache_value_get_identifier(
619 safe_cache_value,
620 &cache_value_file_index,
621 &cache_value_offset,
622 &cache_value_timestamp,
623 error ) != 1 )
624 {
625 libcerror_error_set(
626 error,
627 LIBCERROR_ERROR_DOMAIN_RUNTIME,
628 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
629 "%s: unable to retrieve cache value identifier.",
630 function );
631
632 return( -1 );
633 }
634 if( ( cache_value_file_index == file_index )
635 && ( cache_value_offset == offset )
636 && ( cache_value_timestamp == timestamp ) )
637 {
638 result = 1;
639
640 break;
641 }
642 if( libcdata_list_element_get_next_element(
643 list_element,
644 &list_element,
645 error ) != 1 )
646 {
647 libcerror_error_set(
648 error,
649 LIBCERROR_ERROR_DOMAIN_RUNTIME,
650 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
651 "%s: unable to retrieve next list element.",
652 function );
653
654 return( -1 );
655 }
656 }
657 if( ( result != 0 )
658 && ( number_of_cache_values > 0 ) )
659 {
660 if( libcdata_list_remove_element(
661 internal_cache->entries_list,
662 list_element,
663 error ) != 1 )
664 {
665 libcerror_error_set(
666 error,
667 LIBCERROR_ERROR_DOMAIN_RUNTIME,
668 LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
669 "%s: unable to remove list element.",
670 function );
671
672 return( -1 );
673 }
674 if( libcdata_list_prepend_element(
675 internal_cache->entries_list,
676 list_element,
677 error ) != 1 )
678 {
679 libcerror_error_set(
680 error,
681 LIBCERROR_ERROR_DOMAIN_RUNTIME,
682 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
683 "%s: unable to prepend list element.",
684 function );
685
686 return( -1 );
687 }
688 *cache_value = safe_cache_value;
689 }
690 return( result );
691 }
692
693 /* Retrieves the cache value for the specific index
694 * Returns 1 if successful or -1 on error
695 */
libfcache_cache_get_value_by_index(libfcache_cache_t * cache,int cache_entry_index,libfcache_cache_value_t ** cache_value,libcerror_error_t ** error)696 int libfcache_cache_get_value_by_index(
697 libfcache_cache_t *cache,
698 int cache_entry_index,
699 libfcache_cache_value_t **cache_value,
700 libcerror_error_t **error )
701 {
702 libfcache_internal_cache_t *internal_cache = NULL;
703 static char *function = "libfcache_cache_get_value_by_index";
704
705 if( cache == NULL )
706 {
707 libcerror_error_set(
708 error,
709 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
710 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
711 "%s: invalid cache.",
712 function );
713
714 return( -1 );
715 }
716 internal_cache = (libfcache_internal_cache_t *) cache;
717
718 if( libcdata_array_get_entry_by_index(
719 internal_cache->entries_array,
720 cache_entry_index,
721 (intptr_t **) cache_value,
722 error ) != 1 )
723 {
724 libcerror_error_set(
725 error,
726 LIBCERROR_ERROR_DOMAIN_RUNTIME,
727 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
728 "%s: unable to retrieve cache value: %d from entries array.",
729 function,
730 cache_entry_index );
731
732 return( -1 );
733 }
734 return( 1 );
735 }
736
737 /* Sets the cache value for the file index, offset and timestamp
738 * Returns 1 if successful or -1 on error
739 */
libfcache_cache_set_value_by_identifier(libfcache_cache_t * cache,int file_index,off64_t offset,int64_t timestamp,intptr_t * value,int (* value_free_function)(intptr_t ** value,libcerror_error_t ** error),uint8_t flags,libcerror_error_t ** error)740 int libfcache_cache_set_value_by_identifier(
741 libfcache_cache_t *cache,
742 int file_index,
743 off64_t offset,
744 int64_t timestamp,
745 intptr_t *value,
746 int (*value_free_function)(
747 intptr_t **value,
748 libcerror_error_t **error ),
749 uint8_t flags,
750 libcerror_error_t **error )
751 {
752 libcdata_list_element_t *list_element = NULL;
753 libfcache_cache_value_t *cache_value = NULL;
754 libfcache_internal_cache_t *internal_cache = NULL;
755 static char *function = "libfcache_cache_set_value_by_identifier";
756 int cache_entry_index = 0;
757 int number_of_cache_entries = 0;
758 int number_of_cache_values = 0;
759
760 if( cache == NULL )
761 {
762 libcerror_error_set(
763 error,
764 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
765 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
766 "%s: invalid cache.",
767 function );
768
769 return( -1 );
770 }
771 internal_cache = (libfcache_internal_cache_t *) cache;
772
773 if( libcdata_array_get_number_of_entries(
774 internal_cache->entries_array,
775 &number_of_cache_entries,
776 error ) != 1 )
777 {
778 libcerror_error_set(
779 error,
780 LIBCERROR_ERROR_DOMAIN_RUNTIME,
781 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
782 "%s: unable to retrieve number of cache entries from entries array.",
783 function );
784
785 return( -1 );
786 }
787 if( libcdata_list_get_number_of_elements(
788 internal_cache->entries_list,
789 &number_of_cache_values,
790 error ) != 1 )
791 {
792 libcerror_error_set(
793 error,
794 LIBCERROR_ERROR_DOMAIN_RUNTIME,
795 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
796 "%s: unable to retrieve number of elements from entries list.",
797 function );
798
799 return( -1 );
800 }
801 if( number_of_cache_values < number_of_cache_entries )
802 {
803 cache_entry_index = number_of_cache_values;
804
805 if( libfcache_cache_value_initialize(
806 &cache_value,
807 error ) != 1 )
808 {
809 libcerror_error_set(
810 error,
811 LIBCERROR_ERROR_DOMAIN_RUNTIME,
812 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
813 "%s: unable to create cache value.",
814 function );
815
816 return( -1 );
817 }
818 if( libfcache_cache_value_set_cache_index(
819 cache_value,
820 cache_entry_index,
821 error ) != 1 )
822 {
823 libcerror_error_set(
824 error,
825 LIBCERROR_ERROR_DOMAIN_RUNTIME,
826 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
827 "%s: unable to set cache index in cache value.",
828 function );
829
830 libfcache_cache_value_free(
831 &cache_value,
832 NULL );
833
834 return( -1 );
835 }
836 if( libcdata_array_set_entry_by_index(
837 internal_cache->entries_array,
838 cache_entry_index,
839 (intptr_t *) cache_value,
840 error ) != 1 )
841 {
842 libcerror_error_set(
843 error,
844 LIBCERROR_ERROR_DOMAIN_RUNTIME,
845 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
846 "%s: unable to set cache value: %d in entries array.",
847 function,
848 cache_entry_index );
849
850 libfcache_cache_value_free(
851 &cache_value,
852 NULL );
853
854 return( -1 );
855 }
856 if( libcdata_list_prepend_value(
857 internal_cache->entries_list,
858 (intptr_t *) cache_value,
859 error ) != 1 )
860 {
861 libcerror_error_set(
862 error,
863 LIBCERROR_ERROR_DOMAIN_RUNTIME,
864 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
865 "%s: unable to prepend cache value: %d to entries list.",
866 function );
867
868 return( -1 );
869 }
870 }
871 else
872 {
873 if( libcdata_list_get_last_element(
874 internal_cache->entries_list,
875 &list_element,
876 error ) != 1 )
877 {
878 libcerror_error_set(
879 error,
880 LIBCERROR_ERROR_DOMAIN_RUNTIME,
881 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
882 "%s: unable to retrieve last list element.",
883 function );
884
885 return( -1 );
886 }
887 if( libcdata_list_element_get_value(
888 list_element,
889 (intptr_t **) &cache_value,
890 error ) != 1 )
891 {
892 libcerror_error_set(
893 error,
894 LIBCERROR_ERROR_DOMAIN_RUNTIME,
895 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
896 "%s: unable to retrieve cache value from list element.",
897 function );
898
899 return( -1 );
900 }
901 if( libfcache_cache_value_get_cache_index(
902 cache_value,
903 &cache_entry_index,
904 error ) != 1 )
905 {
906 libcerror_error_set(
907 error,
908 LIBCERROR_ERROR_DOMAIN_RUNTIME,
909 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
910 "%s: unable to retrieve cache index from cache value.",
911 function );
912
913 return( -1 );
914 }
915 if( libcdata_array_get_entry_by_index(
916 internal_cache->entries_array,
917 cache_entry_index,
918 (intptr_t **) &cache_value,
919 error ) != 1 )
920 {
921 libcerror_error_set(
922 error,
923 LIBCERROR_ERROR_DOMAIN_RUNTIME,
924 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
925 "%s: unable to retrieve cache value: %d from entries array.",
926 function,
927 cache_entry_index );
928
929 return( -1 );
930 }
931 }
932 if( libfcache_cache_value_set_identifier(
933 cache_value,
934 file_index,
935 offset,
936 timestamp,
937 error ) != 1 )
938 {
939 libcerror_error_set(
940 error,
941 LIBCERROR_ERROR_DOMAIN_RUNTIME,
942 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
943 "%s: unable to set identifier in cache value.",
944 function );
945
946 return( -1 );
947 }
948 if( libfcache_cache_value_set_value(
949 cache_value,
950 value,
951 value_free_function,
952 flags,
953 error ) != 1 )
954 {
955 libcerror_error_set(
956 error,
957 LIBCERROR_ERROR_DOMAIN_RUNTIME,
958 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
959 "%s: unable to set value in cache value.",
960 function );
961
962 return( -1 );
963 }
964 return( 1 );
965 }
966
967 /* Sets the cache value for the specific index
968 * Returns 1 if successful or -1 on error
969 */
libfcache_cache_set_value_by_index(libfcache_cache_t * cache,int cache_entry_index,int file_index,off64_t offset,int64_t timestamp,intptr_t * value,int (* value_free_function)(intptr_t ** value,libcerror_error_t ** error),uint8_t flags,libcerror_error_t ** error)970 int libfcache_cache_set_value_by_index(
971 libfcache_cache_t *cache,
972 int cache_entry_index,
973 int file_index,
974 off64_t offset,
975 int64_t timestamp,
976 intptr_t *value,
977 int (*value_free_function)(
978 intptr_t **value,
979 libcerror_error_t **error ),
980 uint8_t flags,
981 libcerror_error_t **error )
982 {
983 libfcache_cache_value_t *cache_value = NULL;
984 libfcache_internal_cache_t *internal_cache = NULL;
985 static char *function = "libfcache_cache_set_value_by_index";
986
987 if( cache == NULL )
988 {
989 libcerror_error_set(
990 error,
991 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
992 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
993 "%s: invalid cache.",
994 function );
995
996 return( -1 );
997 }
998 internal_cache = (libfcache_internal_cache_t *) cache;
999
1000 if( libcdata_array_get_entry_by_index(
1001 internal_cache->entries_array,
1002 cache_entry_index,
1003 (intptr_t **) &cache_value,
1004 error ) != 1 )
1005 {
1006 libcerror_error_set(
1007 error,
1008 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1009 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1010 "%s: unable to retrieve cache value: %d from entries array.",
1011 function,
1012 cache_entry_index );
1013
1014 return( -1 );
1015 }
1016 if( cache_value == NULL )
1017 {
1018 if( libfcache_cache_value_initialize(
1019 &cache_value,
1020 error ) != 1 )
1021 {
1022 libcerror_error_set(
1023 error,
1024 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1025 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1026 "%s: unable to create cache value.",
1027 function );
1028
1029 return( -1 );
1030 }
1031 if( libfcache_cache_value_set_cache_index(
1032 cache_value,
1033 cache_entry_index,
1034 error ) != 1 )
1035 {
1036 libcerror_error_set(
1037 error,
1038 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1039 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1040 "%s: unable to set cache index in cache value.",
1041 function );
1042
1043 libfcache_cache_value_free(
1044 &cache_value,
1045 NULL );
1046
1047 return( -1 );
1048 }
1049 if( libcdata_array_set_entry_by_index(
1050 internal_cache->entries_array,
1051 cache_entry_index,
1052 (intptr_t *) cache_value,
1053 error ) != 1 )
1054 {
1055 libcerror_error_set(
1056 error,
1057 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1058 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1059 "%s: unable to set cache value: %d in entries array.",
1060 function,
1061 cache_entry_index );
1062
1063 libfcache_cache_value_free(
1064 &cache_value,
1065 NULL );
1066
1067 return( -1 );
1068 }
1069 if( libcdata_list_prepend_value(
1070 internal_cache->entries_list,
1071 (intptr_t *) cache_value,
1072 error ) != 1 )
1073 {
1074 libcerror_error_set(
1075 error,
1076 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1077 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1078 "%s: unable to prepend cache value: %d to entries list.",
1079 function );
1080
1081 return( -1 );
1082 }
1083 }
1084 if( libfcache_cache_value_set_value(
1085 cache_value,
1086 value,
1087 value_free_function,
1088 flags,
1089 error ) != 1 )
1090 {
1091 libcerror_error_set(
1092 error,
1093 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1094 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1095 "%s: unable to set value in cache value.",
1096 function );
1097
1098 return( -1 );
1099 }
1100 if( libfcache_cache_value_set_identifier(
1101 cache_value,
1102 file_index,
1103 offset,
1104 timestamp,
1105 error ) != 1 )
1106 {
1107 libcerror_error_set(
1108 error,
1109 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1110 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1111 "%s: unable to set identifier in cache value.",
1112 function );
1113
1114 return( -1 );
1115 }
1116 return( 1 );
1117 }
1118
1119