1 /*
2  * Cache value 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_value.h"
27 #include "libfcache_definitions.h"
28 #include "libfcache_libcerror.h"
29 #include "libfcache_types.h"
30 
31 /* Creates a cache value
32  * Make sure the value cache_value is referencing, is set to NULL
33  * Returns 1 if successful or -1 on error
34  */
libfcache_cache_value_initialize(libfcache_cache_value_t ** cache_value,libcerror_error_t ** error)35 int libfcache_cache_value_initialize(
36      libfcache_cache_value_t **cache_value,
37      libcerror_error_t **error )
38 {
39 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
40 	static char *function                                  = "libfcache_cache_value_initialize";
41 
42 	if( cache_value == NULL )
43 	{
44 		libcerror_error_set(
45 		 error,
46 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
47 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
48 		 "%s: invalid cache value.",
49 		 function );
50 
51 		return( -1 );
52 	}
53 	if( *cache_value != NULL )
54 	{
55 		libcerror_error_set(
56 		 error,
57 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
58 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
59 		 "%s: invalid cache value value already set.",
60 		 function );
61 
62 		return( -1 );
63 	}
64 	internal_cache_value = memory_allocate_structure(
65 	                        libfcache_internal_cache_value_t );
66 
67 	if( internal_cache_value == NULL )
68 	{
69 		libcerror_error_set(
70 		 error,
71 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
72 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
73 		 "%s: unable to create cache value.",
74 		 function );
75 
76 		goto on_error;
77 	}
78 	if( memory_set(
79 	     internal_cache_value,
80 	     0,
81 	     sizeof( libfcache_internal_cache_value_t ) ) == NULL )
82 	{
83 		libcerror_error_set(
84 		 error,
85 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
86 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
87 		 "%s: unable to clear cache value.",
88 		 function );
89 
90 		goto on_error;
91 	}
92 	internal_cache_value->file_index = -1;
93 	internal_cache_value->offset     = (off64_t) -1;
94 
95 	*cache_value = (libfcache_cache_value_t *) internal_cache_value;
96 
97 	return( 1 );
98 
99 on_error:
100 	if( internal_cache_value != NULL )
101 	{
102 		memory_free(
103 		 internal_cache_value );
104 	}
105 	return( -1 );
106 }
107 
108 /* Frees a cache value
109  * Returns 1 if successful or -1 on error
110  */
libfcache_cache_value_free(libfcache_cache_value_t ** cache_value,libcerror_error_t ** error)111 int libfcache_cache_value_free(
112      libfcache_cache_value_t **cache_value,
113      libcerror_error_t **error )
114 {
115 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
116 	static char *function                                  = "libfcache_cache_value_free";
117 	int result                                             = 1;
118 
119 	if( cache_value == NULL )
120 	{
121 		libcerror_error_set(
122 		 error,
123 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
124 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
125 		 "%s: invalid cache value.",
126 		 function );
127 
128 		return( -1 );
129 	}
130 	if( *cache_value != NULL )
131 	{
132 		internal_cache_value = (libfcache_internal_cache_value_t *) *cache_value;
133 		*cache_value         = NULL;
134 
135 		if( internal_cache_value->value != NULL )
136 		{
137 			if( ( internal_cache_value->flags & LIBFCACHE_CACHE_VALUE_FLAG_MANAGED ) != 0 )
138 			{
139 				if( internal_cache_value->value_free_function == NULL )
140 				{
141 					libcerror_error_set(
142 					 error,
143 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
144 					 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
145 					 "%s: invalid cache value - missing value free function.",
146 					 function );
147 
148 					result = -1;
149 				}
150 				else if( internal_cache_value->value_free_function(
151 					  &( internal_cache_value->value ),
152 					  error ) != 1 )
153 				{
154 					libcerror_error_set(
155 					 error,
156 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
157 					 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
158 					 "%s: unable to free value.",
159 					 function );
160 
161 					result = -1;
162 				}
163 			}
164 		}
165 		memory_free(
166 		 internal_cache_value );
167 	}
168 	return( result );
169 }
170 
171 /* Clears the cache value
172  * This function does not free the value
173  * Returns 1 if successful or -1 on error
174  */
libfcache_cache_value_clear(libfcache_cache_value_t * cache_value,libcerror_error_t ** error)175 int libfcache_cache_value_clear(
176      libfcache_cache_value_t *cache_value,
177      libcerror_error_t **error )
178 {
179 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
180 	static char *function                                  = "libfcache_cache_value_free";
181 
182 	if( cache_value == NULL )
183 	{
184 		libcerror_error_set(
185 		 error,
186 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
187 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
188 		 "%s: invalid cache value.",
189 		 function );
190 
191 		return( -1 );
192 	}
193 	internal_cache_value = (libfcache_internal_cache_value_t *) cache_value;
194 
195 	if( memory_set(
196 	     internal_cache_value,
197 	     0,
198 	     sizeof( libfcache_internal_cache_value_t ) ) == NULL )
199 	{
200 		libcerror_error_set(
201 		 error,
202 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
203 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
204 		 "%s: unable to clear cache value.",
205 		 function );
206 
207 		return( -1 );
208 	}
209 	internal_cache_value->file_index = -1;
210 	internal_cache_value->offset     = (off64_t) -1;
211 
212 	return( 1 );
213 }
214 
215 /* Retrieves the cache value identifier
216  * Returns 1 if successful or -1 on error
217  */
libfcache_cache_value_get_identifier(libfcache_cache_value_t * cache_value,int * file_index,off64_t * offset,int64_t * timestamp,libcerror_error_t ** error)218 int libfcache_cache_value_get_identifier(
219      libfcache_cache_value_t *cache_value,
220      int *file_index,
221      off64_t *offset,
222      int64_t *timestamp,
223      libcerror_error_t **error )
224 {
225 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
226 	static char *function                                  = "libfcache_cache_value_get_identifier";
227 
228 	if( cache_value == NULL )
229 	{
230 		libcerror_error_set(
231 		 error,
232 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
233 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
234 		 "%s: invalid cache value.",
235 		 function );
236 
237 		return( -1 );
238 	}
239 	internal_cache_value = (libfcache_internal_cache_value_t *) cache_value;
240 
241 	if( file_index == NULL )
242 	{
243 		libcerror_error_set(
244 		 error,
245 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
246 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
247 		 "%s: invalid file index.",
248 		 function );
249 
250 		return( -1 );
251 	}
252 	if( offset == NULL )
253 	{
254 		libcerror_error_set(
255 		 error,
256 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
257 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
258 		 "%s: invalid offset.",
259 		 function );
260 
261 		return( -1 );
262 	}
263 	if( timestamp == NULL )
264 	{
265 		libcerror_error_set(
266 		 error,
267 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
268 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
269 		 "%s: invalid timestamp.",
270 		 function );
271 
272 		return( -1 );
273 	}
274 	*file_index = internal_cache_value->file_index;
275 	*offset     = internal_cache_value->offset;
276 	*timestamp  = internal_cache_value->timestamp;
277 
278 	return( 1 );
279 }
280 
281 /* Retrieves the cache value cache index
282  * Returns 1 if successful or -1 on error
283  */
libfcache_cache_value_get_cache_index(libfcache_cache_value_t * cache_value,int * cache_index,libcerror_error_t ** error)284 int libfcache_cache_value_get_cache_index(
285      libfcache_cache_value_t *cache_value,
286      int *cache_index,
287      libcerror_error_t **error )
288 {
289 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
290 	static char *function                                  = "libfcache_cache_value_get_cache_index";
291 
292 	if( cache_value == NULL )
293 	{
294 		libcerror_error_set(
295 		 error,
296 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
297 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
298 		 "%s: invalid cache value.",
299 		 function );
300 
301 		return( -1 );
302 	}
303 	internal_cache_value = (libfcache_internal_cache_value_t *) cache_value;
304 
305 	if( cache_index == NULL )
306 	{
307 		libcerror_error_set(
308 		 error,
309 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
310 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
311 		 "%s: invalid cache index.",
312 		 function );
313 
314 		return( -1 );
315 	}
316 	*cache_index = internal_cache_value->cache_index;
317 
318 	return( 1 );
319 }
320 
321 /* Sets the cache value identifier
322  * Returns 1 if successful or -1 on error
323  */
libfcache_cache_value_set_identifier(libfcache_cache_value_t * cache_value,int file_index,off64_t offset,int64_t timestamp,libcerror_error_t ** error)324 int libfcache_cache_value_set_identifier(
325      libfcache_cache_value_t *cache_value,
326      int file_index,
327      off64_t offset,
328      int64_t timestamp,
329      libcerror_error_t **error )
330 {
331 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
332 	static char *function                                  = "libfcache_cache_value_set_identifier";
333 
334 	if( cache_value == NULL )
335 	{
336 		libcerror_error_set(
337 		 error,
338 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
339 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
340 		 "%s: invalid cache value.",
341 		 function );
342 
343 		return( -1 );
344 	}
345 	internal_cache_value = (libfcache_internal_cache_value_t *) cache_value;
346 
347 	internal_cache_value->file_index = file_index;
348 	internal_cache_value->offset     = offset;
349 	internal_cache_value->timestamp  = timestamp;
350 
351 	return( 1 );
352 }
353 
354 /* Sets the cache value cache index
355  * Returns 1 if successful or -1 on error
356  */
libfcache_cache_value_set_cache_index(libfcache_cache_value_t * cache_value,int cache_index,libcerror_error_t ** error)357 int libfcache_cache_value_set_cache_index(
358      libfcache_cache_value_t *cache_value,
359      int cache_index,
360      libcerror_error_t **error )
361 {
362 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
363 	static char *function                                  = "libfcache_cache_value_set_cache_index";
364 
365 	if( cache_value == NULL )
366 	{
367 		libcerror_error_set(
368 		 error,
369 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
370 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
371 		 "%s: invalid cache value.",
372 		 function );
373 
374 		return( -1 );
375 	}
376 	internal_cache_value = (libfcache_internal_cache_value_t *) cache_value;
377 
378 	internal_cache_value->cache_index = cache_index;
379 
380 	return( 1 );
381 }
382 
383 /* Retrieves the cache value
384  * Returns 1 if successful or -1 on error
385  */
libfcache_cache_value_get_value(libfcache_cache_value_t * cache_value,intptr_t ** value,libcerror_error_t ** error)386 int libfcache_cache_value_get_value(
387      libfcache_cache_value_t *cache_value,
388      intptr_t **value,
389      libcerror_error_t **error )
390 {
391 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
392 	static char *function                                  = "libfcache_cache_value_get_value";
393 
394 	if( cache_value == NULL )
395 	{
396 		libcerror_error_set(
397 		 error,
398 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
399 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
400 		 "%s: invalid cache value.",
401 		 function );
402 
403 		return( -1 );
404 	}
405 	internal_cache_value = (libfcache_internal_cache_value_t *) cache_value;
406 
407 	if( value == NULL )
408 	{
409 		libcerror_error_set(
410 		 error,
411 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
412 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
413 		 "%s: invalid value.",
414 		 function );
415 
416 		return( -1 );
417 	}
418 	*value = internal_cache_value->value;
419 
420 	return( 1 );
421 }
422 
423 /* Sets the cache value
424  * Returns 1 if successful or -1 on error
425  */
libfcache_cache_value_set_value(libfcache_cache_value_t * cache_value,intptr_t * value,int (* value_free_function)(intptr_t ** value,libcerror_error_t ** error),uint8_t flags,libcerror_error_t ** error)426 int libfcache_cache_value_set_value(
427      libfcache_cache_value_t *cache_value,
428      intptr_t *value,
429      int (*value_free_function)(
430             intptr_t **value,
431             libcerror_error_t **error ),
432      uint8_t flags,
433      libcerror_error_t **error )
434 {
435 	libfcache_internal_cache_value_t *internal_cache_value = NULL;
436 	static char *function                                  = "libfcache_cache_value_set_value";
437 
438 	if( cache_value == NULL )
439 	{
440 		libcerror_error_set(
441 		 error,
442 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
443 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
444 		 "%s: invalid cache value.",
445 		 function );
446 
447 		return( -1 );
448 	}
449 	internal_cache_value = (libfcache_internal_cache_value_t *) cache_value;
450 
451 	if( ( flags & LIBFCACHE_CACHE_VALUE_FLAG_MANAGED ) != 0 )
452 	{
453 		if( value_free_function == NULL )
454 		{
455 			libcerror_error_set(
456 			 error,
457 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
458 			 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
459 			 "%s: invalid value free function.",
460 			 function );
461 
462 			return( -1 );
463 		}
464 	}
465 	if( ( internal_cache_value->flags & LIBFCACHE_CACHE_VALUE_FLAG_MANAGED ) != 0 )
466 	{
467 		if( internal_cache_value->value != NULL )
468 		{
469 			if( internal_cache_value->value_free_function == NULL )
470 			{
471 				libcerror_error_set(
472 				 error,
473 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
474 				 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
475 				 "%s: invalid cache value - missing free value function.",
476 				 function );
477 
478 				return( -1 );
479 			}
480 			if( internal_cache_value->value_free_function(
481 			     &( internal_cache_value->value ),
482 			     error ) != 1 )
483 			{
484 				libcerror_error_set(
485 				 error,
486 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
487 				 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
488 				 "%s: unable to free value.",
489 				 function );
490 
491 				return( -1 );
492 			}
493 		}
494 		internal_cache_value->flags &= ~( LIBFCACHE_CACHE_VALUE_FLAG_MANAGED );
495 	}
496 	internal_cache_value->value               = value;
497 	internal_cache_value->value_free_function = value_free_function;
498 	internal_cache_value->flags              |= flags;
499 
500 	return( 1 );
501 }
502 
503