Coverage Report

Created: 2024-02-25 07:20

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