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