1 /*
2 * Floatingtime functions
3 *
4 * Copyright (C) 2009-2018, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This software 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 software 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 software. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <byte_stream.h>
24 #include <memory.h>
25 #include <types.h>
26
27 #include "libfdatetime_definitions.h"
28 #include "libfdatetime_date_time_values.h"
29 #include "libfdatetime_floatingtime.h"
30 #include "libfdatetime_libcerror.h"
31 #include "libfdatetime_types.h"
32
33 /* Creates a floatingtime
34 * Make sure the value floatingtime is referencing, is set to NULL
35 * Returns 1 if successful or -1 on error
36 */
libfdatetime_floatingtime_initialize(libfdatetime_floatingtime_t ** floatingtime,libcerror_error_t ** error)37 int libfdatetime_floatingtime_initialize(
38 libfdatetime_floatingtime_t **floatingtime,
39 libcerror_error_t **error )
40 {
41 libfdatetime_internal_floatingtime_t *internal_floatingtime = NULL;
42 static char *function = "libfdatetime_floatingtime_initialize";
43
44 if( floatingtime == NULL )
45 {
46 libcerror_error_set(
47 error,
48 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50 "%s: invalid floatingtime.",
51 function );
52
53 return( -1 );
54 }
55 if( *floatingtime != NULL )
56 {
57 libcerror_error_set(
58 error,
59 LIBCERROR_ERROR_DOMAIN_RUNTIME,
60 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61 "%s: invalid floatingtime value already set.",
62 function );
63
64 return( -1 );
65 }
66 internal_floatingtime = memory_allocate_structure(
67 libfdatetime_internal_floatingtime_t );
68
69 if( internal_floatingtime == NULL )
70 {
71 libcerror_error_set(
72 error,
73 LIBCERROR_ERROR_DOMAIN_MEMORY,
74 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
75 "%s: unable to create floatingtime.",
76 function );
77
78 goto on_error;
79 }
80 if( memory_set(
81 internal_floatingtime,
82 0,
83 sizeof( libfdatetime_internal_floatingtime_t ) ) == NULL )
84 {
85 libcerror_error_set(
86 error,
87 LIBCERROR_ERROR_DOMAIN_MEMORY,
88 LIBCERROR_MEMORY_ERROR_SET_FAILED,
89 "%s: unable to clear floatingtime.",
90 function );
91
92 goto on_error;
93 }
94 *floatingtime = (libfdatetime_floatingtime_t *) internal_floatingtime;
95
96 return( 1 );
97
98 on_error:
99 if( internal_floatingtime != NULL )
100 {
101 memory_free(
102 internal_floatingtime );
103 }
104 return( -1 );
105 }
106
107 /* Frees a floatingtime
108 * Returns 1 if successful or -1 on error
109 */
libfdatetime_floatingtime_free(libfdatetime_floatingtime_t ** floatingtime,libcerror_error_t ** error)110 int libfdatetime_floatingtime_free(
111 libfdatetime_floatingtime_t **floatingtime,
112 libcerror_error_t **error )
113 {
114 libfdatetime_internal_floatingtime_t *internal_floatingtime = NULL;
115 static char *function = "libfdatetime_floatingtime_free";
116
117 if( floatingtime == NULL )
118 {
119 libcerror_error_set(
120 error,
121 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123 "%s: invalid floatingtime.",
124 function );
125
126 return( -1 );
127 }
128 if( *floatingtime != NULL )
129 {
130 internal_floatingtime = (libfdatetime_internal_floatingtime_t *) *floatingtime;
131 *floatingtime = NULL;
132
133 memory_free(
134 internal_floatingtime );
135 }
136 return( 1 );
137 }
138
139 /* Converts a byte stream into a floatingtime
140 * Returns 1 if successful or -1 on error
141 */
libfdatetime_floatingtime_copy_from_byte_stream(libfdatetime_floatingtime_t * floatingtime,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,libcerror_error_t ** error)142 int libfdatetime_floatingtime_copy_from_byte_stream(
143 libfdatetime_floatingtime_t *floatingtime,
144 const uint8_t *byte_stream,
145 size_t byte_stream_size,
146 int byte_order,
147 libcerror_error_t **error )
148 {
149 libfdatetime_internal_floatingtime_t *internal_floatingtime = NULL;
150 static char *function = "libfdatetime_floatingtime_copy_from_byte_stream";
151
152 if( floatingtime == NULL )
153 {
154 libcerror_error_set(
155 error,
156 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
157 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
158 "%s: invalid floatingtime.",
159 function );
160
161 return( -1 );
162 }
163 internal_floatingtime = (libfdatetime_internal_floatingtime_t *) floatingtime;
164
165 if( byte_stream == NULL )
166 {
167 libcerror_error_set(
168 error,
169 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
170 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
171 "%s: invalid byte stream.",
172 function );
173
174 return( -1 );
175 }
176 if( byte_stream_size < 8 )
177 {
178 libcerror_error_set(
179 error,
180 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
181 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
182 "%s: byte stream too small.",
183 function );
184
185 return( -1 );
186 }
187 if( byte_stream_size > (size_t) SSIZE_MAX )
188 {
189 libcerror_error_set(
190 error,
191 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
192 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
193 "%s: byte stream size exceeds maximum.",
194 function );
195
196 return( -1 );
197 }
198 if( ( byte_order != LIBFDATETIME_ENDIAN_BIG )
199 && ( byte_order != LIBFDATETIME_ENDIAN_LITTLE ) )
200 {
201 libcerror_error_set(
202 error,
203 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
204 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
205 "%s: unsupported byte order.",
206 function );
207
208 return( -1 );
209 }
210 if( byte_order == LIBFDATETIME_ENDIAN_LITTLE )
211 {
212 byte_stream_copy_to_uint64_little_endian(
213 byte_stream,
214 internal_floatingtime->timestamp.integer );
215 }
216 else if( byte_order == LIBFDATETIME_ENDIAN_BIG )
217 {
218 byte_stream_copy_to_uint64_big_endian(
219 byte_stream,
220 internal_floatingtime->timestamp.integer );
221 }
222 return( 1 );
223 }
224
225 /* Converts a 64-bit value into a floatingtime
226 * Returns 1 if successful or -1 on error
227 */
libfdatetime_floatingtime_copy_from_64bit(libfdatetime_floatingtime_t * floatingtime,uint64_t value_64bit,libcerror_error_t ** error)228 int libfdatetime_floatingtime_copy_from_64bit(
229 libfdatetime_floatingtime_t *floatingtime,
230 uint64_t value_64bit,
231 libcerror_error_t **error )
232 {
233 libfdatetime_internal_floatingtime_t *internal_floatingtime = NULL;
234 static char *function = "libfdatetime_floatingtime_copy_from_64bit";
235
236 if( floatingtime == NULL )
237 {
238 libcerror_error_set(
239 error,
240 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
241 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
242 "%s: invalid floatingtime.",
243 function );
244
245 return( -1 );
246 }
247 internal_floatingtime = (libfdatetime_internal_floatingtime_t *) floatingtime;
248
249 internal_floatingtime->timestamp.integer = value_64bit;
250
251 return( 1 );
252 }
253
254 /* Converts a floatingtime into a 64-bit value
255 * Returns 1 if successful or -1 on error
256 */
libfdatetime_floatingtime_copy_to_64bit(libfdatetime_floatingtime_t * floatingtime,uint64_t * value_64bit,libcerror_error_t ** error)257 int libfdatetime_floatingtime_copy_to_64bit(
258 libfdatetime_floatingtime_t *floatingtime,
259 uint64_t *value_64bit,
260 libcerror_error_t **error )
261 {
262 libfdatetime_internal_floatingtime_t *internal_floatingtime = NULL;
263 static char *function = "libfdatetime_floatingtime_copy_from_64bit";
264
265 if( floatingtime == NULL )
266 {
267 libcerror_error_set(
268 error,
269 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
270 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
271 "%s: invalid floatingtime.",
272 function );
273
274 return( -1 );
275 }
276 internal_floatingtime = (libfdatetime_internal_floatingtime_t *) floatingtime;
277
278 if( value_64bit == NULL )
279 {
280 libcerror_error_set(
281 error,
282 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
283 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
284 "%s: invalid 64-bit value.",
285 function );
286
287 return( -1 );
288 }
289 *value_64bit = internal_floatingtime->timestamp.integer;
290
291 return( 1 );
292 }
293
294 /* Converts a floatingtime into date time values
295 * Returns 1 if successful or -1 on error
296 */
libfdatetime_internal_floatingtime_copy_to_date_time_values(libfdatetime_internal_floatingtime_t * internal_floatingtime,libfdatetime_date_time_values_t * date_time_values,libcerror_error_t ** error)297 int libfdatetime_internal_floatingtime_copy_to_date_time_values(
298 libfdatetime_internal_floatingtime_t *internal_floatingtime,
299 libfdatetime_date_time_values_t *date_time_values,
300 libcerror_error_t **error )
301 {
302 static char *function = "libfdatetime_internal_floatingtime_copy_to_date_time_values";
303 double floatingtimestamp = 0;
304 uint32_t days_in_century = 0;
305 uint16_t days_in_year = 0;
306 uint8_t days_in_month = 0;
307
308 if( internal_floatingtime == NULL )
309 {
310 libcerror_error_set(
311 error,
312 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
313 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
314 "%s: invalid floatingtime.",
315 function );
316
317 return( -1 );
318 }
319 if( date_time_values == NULL )
320 {
321 libcerror_error_set(
322 error,
323 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
324 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
325 "%s: invalid date time values.",
326 function );
327
328 return( -1 );
329 }
330 floatingtimestamp = internal_floatingtime->timestamp.floating_point;
331
332 if( ( floatingtimestamp <= -3650000.0 )
333 || ( floatingtimestamp >= 3650000.0 ) )
334 {
335 libcerror_error_set(
336 error,
337 LIBCERROR_ERROR_DOMAIN_RUNTIME,
338 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
339 "%s: invalid floatingtime - value out of bounds.",
340 function );
341
342 return( -1 );
343 }
344 /* Determine the number of years starting at '30 Dec 1899 00:00:00'
345 * correct the value to days within the year
346 */
347 date_time_values->year = 1899;
348 date_time_values->month = 12;
349 date_time_values->day = 30;
350
351 if( floatingtimestamp >= 2.0 )
352 {
353 date_time_values->year = 1900;
354 date_time_values->month = 1;
355 date_time_values->day = 1;
356
357 floatingtimestamp -= 2.0;
358 }
359 while( floatingtimestamp > 0.0 )
360 {
361 if( ( date_time_values->year % 400 ) == 0 )
362 {
363 days_in_century = 36525;
364 }
365 else
366 {
367 days_in_century = 36524;
368 }
369 if( floatingtimestamp <= days_in_century )
370 {
371 break;
372 }
373 floatingtimestamp -= days_in_century;
374
375 date_time_values->year += 100;
376 }
377 while( floatingtimestamp > 0.0 )
378 {
379 /* Check for a leap year
380 * The year is ( ( dividable by 4 ) and ( not dividable by 100 ) ) or ( dividable by 400 )
381 */
382 if( ( ( ( date_time_values->year % 4 ) == 0 )
383 && ( ( date_time_values->year % 100 ) != 0 ) )
384 || ( ( date_time_values->year % 400 ) == 0 ) )
385 {
386 days_in_year = 366;
387 }
388 else
389 {
390 days_in_year = 365;
391 }
392 if( floatingtimestamp <= days_in_year )
393 {
394 break;
395 }
396 floatingtimestamp -= days_in_year;
397
398 date_time_values->year += 1;
399 }
400 if( date_time_values->year > 9999 )
401 {
402 libcerror_error_set(
403 error,
404 LIBCERROR_ERROR_DOMAIN_RUNTIME,
405 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
406 "%s: invalid floatingtime - year value out of bounds.",
407 function );
408
409 return( -1 );
410 }
411 /* Determine the month correct the value to days within the month
412 */
413 while( floatingtimestamp > 0.0 )
414 {
415 /* February (2)
416 */
417 if( date_time_values->month == 2 )
418 {
419 if( ( ( ( date_time_values->year % 4 ) == 0 )
420 && ( ( date_time_values->year % 100 ) != 0 ) )
421 || ( ( date_time_values->year % 400 ) == 0 ) )
422 {
423 days_in_month = 29;
424 }
425 else
426 {
427 days_in_month = 28;
428 }
429 }
430 /* April (4), June (6), September (9), November (11)
431 */
432 else if( ( date_time_values->month == 4 )
433 || ( date_time_values->month == 6 )
434 || ( date_time_values->month == 9 )
435 || ( date_time_values->month == 11 ) )
436 {
437 days_in_month = 30;
438 }
439 /* January (1), March (3), May (5), July (7), August (8), October (10), December (12)
440 */
441 else if( ( date_time_values->month == 1 )
442 || ( date_time_values->month == 3 )
443 || ( date_time_values->month == 5 )
444 || ( date_time_values->month == 7 )
445 || ( date_time_values->month == 8 )
446 || ( date_time_values->month == 10 )
447 || ( date_time_values->month == 12 ) )
448 {
449 days_in_month = 31;
450 }
451 /* This should never happen, but just in case
452 */
453 else
454 {
455 libcerror_error_set(
456 error,
457 LIBCERROR_ERROR_DOMAIN_RUNTIME,
458 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
459 "%s: unsupported month: %d.",
460 function,
461 date_time_values->month );
462
463 return( -1 );
464 }
465 if( floatingtimestamp <= days_in_month )
466 {
467 break;
468 }
469 floatingtimestamp -= days_in_month;
470
471 date_time_values->month += 1;
472 }
473 /* Determine the day
474 */
475 date_time_values->day += (uint8_t) floatingtimestamp;
476 floatingtimestamp -= (int) floatingtimestamp;
477
478 /* There are 24 hours in a day correct the value to hours
479 */
480 floatingtimestamp *= 24.0;
481 date_time_values->hours = (uint8_t) floatingtimestamp;
482 floatingtimestamp -= date_time_values->hours;
483
484 /* There are 60 minutes in an hour correct the value to minutes
485 */
486 floatingtimestamp *= 60.0;
487 date_time_values->minutes = (uint8_t) floatingtimestamp;
488 floatingtimestamp -= date_time_values->minutes;
489
490 /* There are 60 seconds in a minute correct the value to seconds
491 */
492 floatingtimestamp *= 60.0;
493 date_time_values->seconds = (uint8_t) floatingtimestamp;
494 floatingtimestamp -= date_time_values->seconds;
495
496 /* There are 1000 milli seconds in a seconds correct the value to milli seconds
497 */
498 floatingtimestamp *= 1000.0;
499 date_time_values->milli_seconds = (uint8_t) floatingtimestamp;
500 floatingtimestamp -= date_time_values->milli_seconds;
501
502 /* There are 1000 micro seconds in a seconds correct the value to micro seconds
503 */
504 floatingtimestamp *= 1000.0;
505 date_time_values->micro_seconds = (uint8_t) floatingtimestamp;
506 floatingtimestamp -= date_time_values->micro_seconds;
507
508 /* There are 1000 nano seconds in a seconds correct the value to nano seconds
509 */
510 floatingtimestamp *= 1000.0;
511 date_time_values->nano_seconds = (uint8_t) floatingtimestamp;
512
513 return( 1 );
514 }
515
516 /* Deterimes the size of the string for the floatingtime
517 * The string size includes the end of string character
518 * Returns 1 if successful or -1 on error
519 */
libfdatetime_floatingtime_get_string_size(libfdatetime_floatingtime_t * floatingtime,size_t * string_size,uint32_t string_format_flags,libcerror_error_t ** error)520 int libfdatetime_floatingtime_get_string_size(
521 libfdatetime_floatingtime_t *floatingtime,
522 size_t *string_size,
523 uint32_t string_format_flags,
524 libcerror_error_t **error )
525 {
526 libfdatetime_date_time_values_t date_time_values;
527
528 static char *function = "libfdatetime_floatingtime_get_string_size";
529 int result = 0;
530
531 if( floatingtime == NULL )
532 {
533 libcerror_error_set(
534 error,
535 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
536 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
537 "%s: invalid floatingtime.",
538 function );
539
540 return( -1 );
541 }
542 if( string_size == NULL )
543 {
544 libcerror_error_set(
545 error,
546 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
547 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
548 "%s: invalid string size.",
549 function );
550
551 return( -1 );
552 }
553 result = libfdatetime_internal_floatingtime_copy_to_date_time_values(
554 (libfdatetime_internal_floatingtime_t *) floatingtime,
555 &date_time_values,
556 error );
557
558 if( result != 1 )
559 {
560 #if defined( HAVE_DEBUG_OUTPUT )
561 libcerror_error_set(
562 error,
563 LIBCERROR_ERROR_DOMAIN_RUNTIME,
564 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
565 "%s: unable to set date time values.",
566 function );
567
568 /* TODO debug print error */
569
570 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
571
572 if( ( error != NULL )
573 && ( *error != NULL ) )
574 {
575 libcerror_error_free(
576 error );
577 }
578 }
579 else
580 {
581 result = libfdatetime_date_time_values_get_string_size(
582 &date_time_values,
583 string_size,
584 string_format_flags,
585 error );
586
587 if( result == -1 )
588 {
589 libcerror_error_set(
590 error,
591 LIBCERROR_ERROR_DOMAIN_RUNTIME,
592 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
593 "%s: unable to get string size.",
594 function );
595
596 return( -1 );
597 }
598 }
599 if( result != 1 )
600 {
601 /* Make sure the string can hold the hexadecimal representation of the floatingtime
602 */
603 *string_size = 21;
604 }
605 return( 1 );
606 }
607
608 /* Converts the floatingtime into an UTF-8 string in hexadecimal representation
609 * The string size should include the end of string character
610 * Returns 1 if successful or -1 on error
611 */
libfdatetime_internal_floatingtime_copy_to_utf8_string_in_hexadecimal(libfdatetime_internal_floatingtime_t * internal_floatingtime,uint8_t * utf8_string,size_t utf8_string_size,size_t * utf8_string_index,libcerror_error_t ** error)612 int libfdatetime_internal_floatingtime_copy_to_utf8_string_in_hexadecimal(
613 libfdatetime_internal_floatingtime_t *internal_floatingtime,
614 uint8_t *utf8_string,
615 size_t utf8_string_size,
616 size_t *utf8_string_index,
617 libcerror_error_t **error )
618 {
619 static char *function = "libfdatetime_internal_floatingtime_copy_to_utf8_string_in_hexadecimal";
620 size_t string_index = 0;
621 uint8_t byte_value = 0;
622 int8_t byte_shift = 0;
623
624 if( internal_floatingtime == NULL )
625 {
626 libcerror_error_set(
627 error,
628 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
629 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
630 "%s: invalid floatingtime.",
631 function );
632
633 return( -1 );
634 }
635 if( utf8_string == NULL )
636 {
637 libcerror_error_set(
638 error,
639 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
640 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
641 "%s: invalid UTF-8 string.",
642 function );
643
644 return( -1 );
645 }
646 if( utf8_string_size > (size_t) SSIZE_MAX )
647 {
648 libcerror_error_set(
649 error,
650 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
651 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
652 "%s: invalid UTF-8 string size value exceeds maximum.",
653 function );
654
655 return( -1 );
656 }
657 if( utf8_string_index == NULL )
658 {
659 libcerror_error_set(
660 error,
661 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
662 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
663 "%s: invalid UTF-8 string index.",
664 function );
665
666 return( -1 );
667 }
668 if( ( utf8_string_size < 21 )
669 || ( *utf8_string_index > ( utf8_string_size - 21 ) ) )
670 {
671 libcerror_error_set(
672 error,
673 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
674 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
675 "%s: UTF-8 string is too small.",
676 function );
677
678 return( -1 );
679 }
680 string_index = *utf8_string_index;
681
682 utf8_string[ string_index++ ] = (uint8_t) '(';
683 utf8_string[ string_index++ ] = (uint8_t) '0';
684 utf8_string[ string_index++ ] = (uint8_t) 'x';
685
686 byte_shift = 60;
687
688 do
689 {
690 byte_value = ( internal_floatingtime->timestamp.integer >> byte_shift ) & 0x0f;
691
692 if( byte_value <= 9 )
693 {
694 utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
695 }
696 else
697 {
698 utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
699 }
700 byte_shift -= 4;
701 }
702 while( byte_shift >= 0 );
703
704 utf8_string[ string_index++ ] = (uint8_t) ')';
705
706 utf8_string[ string_index++ ] = 0;
707
708 *utf8_string_index = string_index;
709
710 return( 1 );
711 }
712
713 /* Converts the floatingtime into an UTF-8 string
714 * The string size should include the end of string character
715 * Returns 1 if successful or -1 on error
716 */
libfdatetime_floatingtime_copy_to_utf8_string(libfdatetime_floatingtime_t * floatingtime,uint8_t * utf8_string,size_t utf8_string_size,uint32_t string_format_flags,libcerror_error_t ** error)717 int libfdatetime_floatingtime_copy_to_utf8_string(
718 libfdatetime_floatingtime_t *floatingtime,
719 uint8_t *utf8_string,
720 size_t utf8_string_size,
721 uint32_t string_format_flags,
722 libcerror_error_t **error )
723 {
724 static char *function = "libfdatetime_floatingtime_copy_to_utf8_string";
725 size_t utf8_string_index = 0;
726
727 if( libfdatetime_floatingtime_copy_to_utf8_string_with_index(
728 floatingtime,
729 utf8_string,
730 utf8_string_size,
731 &utf8_string_index,
732 string_format_flags,
733 error ) != 1 )
734 {
735 libcerror_error_set(
736 error,
737 LIBCERROR_ERROR_DOMAIN_RUNTIME,
738 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
739 "%s: unable to copy floatingtime to UTF-8 string.",
740 function );
741
742 return( -1 );
743 }
744 return( 1 );
745 }
746
747 /* Converts the floatingtime into an UTF-8 string
748 * The string size should include the end of string character
749 * Returns 1 if successful or -1 on error
750 */
libfdatetime_floatingtime_copy_to_utf8_string_with_index(libfdatetime_floatingtime_t * floatingtime,uint8_t * utf8_string,size_t utf8_string_size,size_t * utf8_string_index,uint32_t string_format_flags,libcerror_error_t ** error)751 int libfdatetime_floatingtime_copy_to_utf8_string_with_index(
752 libfdatetime_floatingtime_t *floatingtime,
753 uint8_t *utf8_string,
754 size_t utf8_string_size,
755 size_t *utf8_string_index,
756 uint32_t string_format_flags,
757 libcerror_error_t **error )
758 {
759 libfdatetime_date_time_values_t date_time_values;
760
761 libfdatetime_internal_floatingtime_t *internal_floatingtime = NULL;
762 static char *function = "libfdatetime_floatingtime_copy_to_utf8_string_with_index";
763 int result = 0;
764
765 if( floatingtime == NULL )
766 {
767 libcerror_error_set(
768 error,
769 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
770 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
771 "%s: invalid floatingtime.",
772 function );
773
774 return( -1 );
775 }
776 internal_floatingtime = (libfdatetime_internal_floatingtime_t *) floatingtime;
777
778 result = libfdatetime_internal_floatingtime_copy_to_date_time_values(
779 internal_floatingtime,
780 &date_time_values,
781 error );
782
783 if( result != 1 )
784 {
785 #if defined( HAVE_DEBUG_OUTPUT )
786 libcerror_error_set(
787 error,
788 LIBCERROR_ERROR_DOMAIN_RUNTIME,
789 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
790 "%s: unable to set date time values.",
791 function );
792
793 /* TODO debug print error */
794
795 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
796
797 if( ( error != NULL )
798 && ( *error != NULL ) )
799 {
800 libcerror_error_free(
801 error );
802 }
803 }
804 else
805 {
806 result = libfdatetime_date_time_values_copy_to_utf8_string_with_index(
807 &date_time_values,
808 utf8_string,
809 utf8_string_size,
810 utf8_string_index,
811 string_format_flags,
812 error );
813
814 if( result == -1 )
815 {
816 libcerror_error_set(
817 error,
818 LIBCERROR_ERROR_DOMAIN_RUNTIME,
819 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
820 "%s: unable to copy date time values to UTF-8 string.",
821 function );
822
823 return( -1 );
824 }
825 }
826 if( result != 1 )
827 {
828 result = libfdatetime_internal_floatingtime_copy_to_utf8_string_in_hexadecimal(
829 internal_floatingtime,
830 utf8_string,
831 utf8_string_size,
832 utf8_string_index,
833 error );
834
835 if( result == -1 )
836 {
837 libcerror_error_set(
838 error,
839 LIBCERROR_ERROR_DOMAIN_RUNTIME,
840 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
841 "%s: unable to floatingtime to hexadecimal UTF-8 string.",
842 function );
843
844 return( -1 );
845 }
846 }
847 return( 1 );
848 }
849
850 /* Converts the floatingtime into an UTF-16 string in hexadecimal representation
851 * The string size should include the end of string character
852 * Returns 1 if successful or -1 on error
853 */
libfdatetime_internal_floatingtime_copy_to_utf16_string_in_hexadecimal(libfdatetime_internal_floatingtime_t * internal_floatingtime,uint16_t * utf16_string,size_t utf16_string_size,size_t * utf16_string_index,libcerror_error_t ** error)854 int libfdatetime_internal_floatingtime_copy_to_utf16_string_in_hexadecimal(
855 libfdatetime_internal_floatingtime_t *internal_floatingtime,
856 uint16_t *utf16_string,
857 size_t utf16_string_size,
858 size_t *utf16_string_index,
859 libcerror_error_t **error )
860 {
861 static char *function = "libfdatetime_internal_floatingtime_copy_to_utf16_string_in_hexadecimal";
862 size_t string_index = 0;
863 uint8_t byte_value = 0;
864 int8_t byte_shift = 0;
865
866 if( internal_floatingtime == NULL )
867 {
868 libcerror_error_set(
869 error,
870 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
871 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
872 "%s: invalid floatingtime.",
873 function );
874
875 return( -1 );
876 }
877 if( utf16_string == NULL )
878 {
879 libcerror_error_set(
880 error,
881 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
882 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
883 "%s: invalid UTF-16 string.",
884 function );
885
886 return( -1 );
887 }
888 if( utf16_string_size > (size_t) SSIZE_MAX )
889 {
890 libcerror_error_set(
891 error,
892 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
893 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
894 "%s: invalid UTF-16 string size value exceeds maximum.",
895 function );
896
897 return( -1 );
898 }
899 if( utf16_string_index == NULL )
900 {
901 libcerror_error_set(
902 error,
903 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
904 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
905 "%s: invalid UTF-16 string index.",
906 function );
907
908 return( -1 );
909 }
910 if( ( utf16_string_size < 21 )
911 || ( *utf16_string_index > ( utf16_string_size - 21 ) ) )
912 {
913 libcerror_error_set(
914 error,
915 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
916 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
917 "%s: UTF-16 string is too small.",
918 function );
919
920 return( -1 );
921 }
922 string_index = *utf16_string_index;
923
924 utf16_string[ string_index++ ] = (uint16_t) '(';
925 utf16_string[ string_index++ ] = (uint16_t) '0';
926 utf16_string[ string_index++ ] = (uint16_t) 'x';
927
928 byte_shift = 60;
929
930 do
931 {
932 byte_value = ( internal_floatingtime->timestamp.integer >> byte_shift ) & 0x0f;
933
934 if( byte_value <= 9 )
935 {
936 utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
937 }
938 else
939 {
940 utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
941 }
942 byte_shift -= 4;
943 }
944 while( byte_shift >= 0 );
945
946 utf16_string[ string_index++ ] = (uint16_t) ')';
947
948 utf16_string[ string_index++ ] = 0;
949
950 *utf16_string_index = string_index;
951
952 return( 1 );
953 }
954
955 /* Converts the floatingtime into an UTF-16 string
956 * The string size should include the end of string character
957 * Returns 1 if successful or -1 on error
958 */
libfdatetime_floatingtime_copy_to_utf16_string(libfdatetime_floatingtime_t * floatingtime,uint16_t * utf16_string,size_t utf16_string_size,uint32_t string_format_flags,libcerror_error_t ** error)959 int libfdatetime_floatingtime_copy_to_utf16_string(
960 libfdatetime_floatingtime_t *floatingtime,
961 uint16_t *utf16_string,
962 size_t utf16_string_size,
963 uint32_t string_format_flags,
964 libcerror_error_t **error )
965 {
966 static char *function = "libfdatetime_floatingtime_copy_to_utf16_string";
967 size_t utf16_string_index = 0;
968
969 if( libfdatetime_floatingtime_copy_to_utf16_string_with_index(
970 floatingtime,
971 utf16_string,
972 utf16_string_size,
973 &utf16_string_index,
974 string_format_flags,
975 error ) != 1 )
976 {
977 libcerror_error_set(
978 error,
979 LIBCERROR_ERROR_DOMAIN_RUNTIME,
980 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
981 "%s: unable to copy floatingtime to UTF-16 string.",
982 function );
983
984 return( -1 );
985 }
986 return( 1 );
987 }
988
989 /* Converts the floatingtime into an UTF-16 string
990 * The string size should include the end of string character
991 * Returns 1 if successful or -1 on error
992 */
libfdatetime_floatingtime_copy_to_utf16_string_with_index(libfdatetime_floatingtime_t * floatingtime,uint16_t * utf16_string,size_t utf16_string_size,size_t * utf16_string_index,uint32_t string_format_flags,libcerror_error_t ** error)993 int libfdatetime_floatingtime_copy_to_utf16_string_with_index(
994 libfdatetime_floatingtime_t *floatingtime,
995 uint16_t *utf16_string,
996 size_t utf16_string_size,
997 size_t *utf16_string_index,
998 uint32_t string_format_flags,
999 libcerror_error_t **error )
1000 {
1001 libfdatetime_date_time_values_t date_time_values;
1002
1003 libfdatetime_internal_floatingtime_t *internal_floatingtime = NULL;
1004 static char *function = "libfdatetime_floatingtime_copy_to_utf16_string_with_index";
1005 int result = 0;
1006
1007 if( floatingtime == NULL )
1008 {
1009 libcerror_error_set(
1010 error,
1011 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1012 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1013 "%s: invalid floatingtime.",
1014 function );
1015
1016 return( -1 );
1017 }
1018 internal_floatingtime = (libfdatetime_internal_floatingtime_t *) floatingtime;
1019
1020 result = libfdatetime_internal_floatingtime_copy_to_date_time_values(
1021 internal_floatingtime,
1022 &date_time_values,
1023 error );
1024
1025 if( result != 1 )
1026 {
1027 #if defined( HAVE_DEBUG_OUTPUT )
1028 libcerror_error_set(
1029 error,
1030 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1031 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1032 "%s: unable to set date time values.",
1033 function );
1034
1035 /* TODO debug print error */
1036
1037 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1038
1039 if( ( error != NULL )
1040 && ( *error != NULL ) )
1041 {
1042 libcerror_error_free(
1043 error );
1044 }
1045 }
1046 else
1047 {
1048 result = libfdatetime_date_time_values_copy_to_utf16_string_with_index(
1049 &date_time_values,
1050 utf16_string,
1051 utf16_string_size,
1052 utf16_string_index,
1053 string_format_flags,
1054 error );
1055
1056 if( result == -1 )
1057 {
1058 libcerror_error_set(
1059 error,
1060 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1061 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1062 "%s: unable to copy date time values to UTF-16 string.",
1063 function );
1064
1065 return( -1 );
1066 }
1067 }
1068 if( result != 1 )
1069 {
1070 result = libfdatetime_internal_floatingtime_copy_to_utf16_string_in_hexadecimal(
1071 internal_floatingtime,
1072 utf16_string,
1073 utf16_string_size,
1074 utf16_string_index,
1075 error );
1076
1077 if( result == -1 )
1078 {
1079 libcerror_error_set(
1080 error,
1081 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1082 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1083 "%s: unable to floatingtime to hexadecimal UTF-16 string.",
1084 function );
1085
1086 return( -1 );
1087 }
1088 }
1089 return( 1 );
1090 }
1091
1092 /* Converts the floatingtime into an UTF-32 string in hexadecimal representation
1093 * The string size should include the end of string character
1094 * Returns 1 if successful or -1 on error
1095 */
libfdatetime_internal_floatingtime_copy_to_utf32_string_in_hexadecimal(libfdatetime_internal_floatingtime_t * internal_floatingtime,uint32_t * utf32_string,size_t utf32_string_size,size_t * utf32_string_index,libcerror_error_t ** error)1096 int libfdatetime_internal_floatingtime_copy_to_utf32_string_in_hexadecimal(
1097 libfdatetime_internal_floatingtime_t *internal_floatingtime,
1098 uint32_t *utf32_string,
1099 size_t utf32_string_size,
1100 size_t *utf32_string_index,
1101 libcerror_error_t **error )
1102 {
1103 static char *function = "libfdatetime_internal_floatingtime_copy_to_utf32_string_in_hexadecimal";
1104 size_t string_index = 0;
1105 uint8_t byte_value = 0;
1106 int8_t byte_shift = 0;
1107
1108 if( internal_floatingtime == NULL )
1109 {
1110 libcerror_error_set(
1111 error,
1112 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1113 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1114 "%s: invalid floatingtime.",
1115 function );
1116
1117 return( -1 );
1118 }
1119 if( utf32_string == NULL )
1120 {
1121 libcerror_error_set(
1122 error,
1123 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1124 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1125 "%s: invalid UTF-32 string.",
1126 function );
1127
1128 return( -1 );
1129 }
1130 if( utf32_string_size > (size_t) SSIZE_MAX )
1131 {
1132 libcerror_error_set(
1133 error,
1134 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1135 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1136 "%s: invalid UTF-32 string size value exceeds maximum.",
1137 function );
1138
1139 return( -1 );
1140 }
1141 if( utf32_string_index == NULL )
1142 {
1143 libcerror_error_set(
1144 error,
1145 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1146 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1147 "%s: invalid UTF-32 string index.",
1148 function );
1149
1150 return( -1 );
1151 }
1152 if( ( utf32_string_size < 21 )
1153 || ( *utf32_string_index > ( utf32_string_size - 21 ) ) )
1154 {
1155 libcerror_error_set(
1156 error,
1157 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1158 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1159 "%s: UTF-32 string is too small.",
1160 function );
1161
1162 return( -1 );
1163 }
1164 string_index = *utf32_string_index;
1165
1166 utf32_string[ string_index++ ] = (uint32_t) '(';
1167 utf32_string[ string_index++ ] = (uint32_t) '0';
1168 utf32_string[ string_index++ ] = (uint32_t) 'x';
1169
1170 byte_shift = 60;
1171
1172 do
1173 {
1174 byte_value = ( internal_floatingtime->timestamp.integer >> byte_shift ) & 0x0f;
1175
1176 if( byte_value <= 9 )
1177 {
1178 utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1179 }
1180 else
1181 {
1182 utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1183 }
1184 byte_shift -= 4;
1185 }
1186 while( byte_shift >= 0 );
1187
1188 utf32_string[ string_index++ ] = (uint32_t) ')';
1189
1190 utf32_string[ string_index++ ] = 0;
1191
1192 *utf32_string_index = string_index;
1193
1194 return( 1 );
1195 }
1196
1197 /* Converts the floatingtime into an UTF-32 string
1198 * The string size should include the end of string character
1199 * Returns 1 if successful or -1 on error
1200 */
libfdatetime_floatingtime_copy_to_utf32_string(libfdatetime_floatingtime_t * floatingtime,uint32_t * utf32_string,size_t utf32_string_size,uint32_t string_format_flags,libcerror_error_t ** error)1201 int libfdatetime_floatingtime_copy_to_utf32_string(
1202 libfdatetime_floatingtime_t *floatingtime,
1203 uint32_t *utf32_string,
1204 size_t utf32_string_size,
1205 uint32_t string_format_flags,
1206 libcerror_error_t **error )
1207 {
1208 static char *function = "libfdatetime_floatingtime_copy_to_utf32_string";
1209 size_t utf32_string_index = 0;
1210
1211 if( libfdatetime_floatingtime_copy_to_utf32_string_with_index(
1212 floatingtime,
1213 utf32_string,
1214 utf32_string_size,
1215 &utf32_string_index,
1216 string_format_flags,
1217 error ) != 1 )
1218 {
1219 libcerror_error_set(
1220 error,
1221 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1222 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1223 "%s: unable to copy floatingtime to UTF-32 string.",
1224 function );
1225
1226 return( -1 );
1227 }
1228 return( 1 );
1229 }
1230
1231 /* Converts the floatingtime into an UTF-32 string
1232 * The string size should include the end of string character
1233 * Returns 1 if successful or -1 on error
1234 */
libfdatetime_floatingtime_copy_to_utf32_string_with_index(libfdatetime_floatingtime_t * floatingtime,uint32_t * utf32_string,size_t utf32_string_size,size_t * utf32_string_index,uint32_t string_format_flags,libcerror_error_t ** error)1235 int libfdatetime_floatingtime_copy_to_utf32_string_with_index(
1236 libfdatetime_floatingtime_t *floatingtime,
1237 uint32_t *utf32_string,
1238 size_t utf32_string_size,
1239 size_t *utf32_string_index,
1240 uint32_t string_format_flags,
1241 libcerror_error_t **error )
1242 {
1243 libfdatetime_date_time_values_t date_time_values;
1244
1245 libfdatetime_internal_floatingtime_t *internal_floatingtime = NULL;
1246 static char *function = "libfdatetime_floatingtime_copy_to_utf32_string_with_index";
1247 int result = 0;
1248
1249 if( floatingtime == NULL )
1250 {
1251 libcerror_error_set(
1252 error,
1253 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1254 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1255 "%s: invalid floatingtime.",
1256 function );
1257
1258 return( -1 );
1259 }
1260 internal_floatingtime = (libfdatetime_internal_floatingtime_t *) floatingtime;
1261
1262 result = libfdatetime_internal_floatingtime_copy_to_date_time_values(
1263 internal_floatingtime,
1264 &date_time_values,
1265 error );
1266
1267 if( result != 1 )
1268 {
1269 #if defined( HAVE_DEBUG_OUTPUT )
1270 libcerror_error_set(
1271 error,
1272 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1273 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1274 "%s: unable to set date time values.",
1275 function );
1276
1277 /* TODO debug print error */
1278
1279 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1280
1281 if( ( error != NULL )
1282 && ( *error != NULL ) )
1283 {
1284 libcerror_error_free(
1285 error );
1286 }
1287 }
1288 else
1289 {
1290 result = libfdatetime_date_time_values_copy_to_utf32_string_with_index(
1291 &date_time_values,
1292 utf32_string,
1293 utf32_string_size,
1294 utf32_string_index,
1295 string_format_flags,
1296 error );
1297
1298 if( result == -1 )
1299 {
1300 libcerror_error_set(
1301 error,
1302 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1303 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1304 "%s: unable to copy date time values to UTF-32 string.",
1305 function );
1306
1307 return( -1 );
1308 }
1309 }
1310 if( result != 1 )
1311 {
1312 result = libfdatetime_internal_floatingtime_copy_to_utf32_string_in_hexadecimal(
1313 internal_floatingtime,
1314 utf32_string,
1315 utf32_string_size,
1316 utf32_string_index,
1317 error );
1318
1319 if( result == -1 )
1320 {
1321 libcerror_error_set(
1322 error,
1323 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1324 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1325 "%s: unable to floatingtime to hexadecimal UTF-32 string.",
1326 function );
1327
1328 return( -1 );
1329 }
1330 }
1331 return( 1 );
1332 }
1333
1334