Coverage Report

Created: 2026-07-10 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libmsiecf/libfvalue/libfvalue_integer.c
Line
Count
Source
1
/*
2
 * Integer value functions
3
 *
4
 * Copyright (C) 2010-2026, 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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libfvalue_definitions.h"
28
#include "libfvalue_integer.h"
29
#include "libfvalue_libcerror.h"
30
31
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
32
#define byte_stream_copy_to_uint16_native_endian byte_stream_copy_to_uint16_big_endian
33
#define byte_stream_copy_to_uint32_native_endian byte_stream_copy_to_uint32_big_endian
34
#define byte_stream_copy_to_uint64_native_endian byte_stream_copy_to_uint64_big_endian
35
36
#elif _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_LITTLE
37
0
#define byte_stream_copy_to_uint16_native_endian byte_stream_copy_to_uint16_little_endian
38
0
#define byte_stream_copy_to_uint32_native_endian byte_stream_copy_to_uint32_little_endian
39
0
#define byte_stream_copy_to_uint64_native_endian byte_stream_copy_to_uint64_little_endian
40
41
#elif _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_MIDDLE
42
#define byte_stream_copy_to_uint16_native_endian byte_stream_copy_to_uint16_little_endian
43
44
#error "Unsupported middle-endian host byte-order"
45
#endif
46
47
/* Creates an integer
48
 * Make sure the value integer is referencing, is set to NULL
49
 * Returns 1 if successful or -1 on error
50
 */
51
int libfvalue_integer_initialize(
52
     libfvalue_integer_t **integer,
53
     libcerror_error_t **error )
54
0
{
55
0
  static char *function = "libfvalue_integer_initialize";
56
57
0
  if( integer == NULL )
58
0
  {
59
0
    libcerror_error_set(
60
0
     error,
61
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
62
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
63
0
     "%s: invalid integer.",
64
0
     function );
65
66
0
    return( -1 );
67
0
  }
68
0
  if( *integer != NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
73
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
74
0
     "%s: invalid integer value already set.",
75
0
     function );
76
77
0
    return( -1 );
78
0
  }
79
0
  *integer = memory_allocate_structure(
80
0
              libfvalue_integer_t );
81
82
0
  if( *integer == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
88
0
     "%s: unable to create integer.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
0
  if( memory_set(
94
0
       *integer,
95
0
       0,
96
0
       sizeof( libfvalue_integer_t ) ) == NULL )
97
0
  {
98
0
    libcerror_error_set(
99
0
     error,
100
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
101
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
102
0
     "%s: unable to clear integer.",
103
0
     function );
104
105
0
    goto on_error;
106
0
  }
107
0
  return( 1 );
108
109
0
on_error:
110
0
  if( *integer != NULL )
111
0
  {
112
0
    memory_free(
113
0
     *integer );
114
115
0
    *integer = NULL;
116
0
  }
117
0
  return( -1 );
118
0
}
119
120
/* Frees an integer
121
 * Returns 1 if successful or -1 on error
122
 */
123
int libfvalue_integer_free(
124
     libfvalue_integer_t **integer,
125
     libcerror_error_t **error )
126
0
{
127
0
  static char *function = "libfvalue_integer_free";
128
129
0
  if( integer == NULL )
130
0
  {
131
0
    libcerror_error_set(
132
0
     error,
133
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
134
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
135
0
     "%s: invalid integer.",
136
0
     function );
137
138
0
    return( -1 );
139
0
  }
140
0
  if( *integer != NULL )
141
0
  {
142
0
    memory_free(
143
0
     *integer );
144
145
0
    *integer = NULL;
146
0
  }
147
0
  return( 1 );
148
0
}
149
150
/* Clones an integer
151
 * Returns 1 if successful or -1 on error
152
 */
153
int libfvalue_integer_clone(
154
     libfvalue_integer_t **destination_integer,
155
     libfvalue_integer_t *source_integer,
156
     libcerror_error_t **error )
157
0
{
158
0
  static char *function = "libfvalue_integer_clone";
159
160
0
  if( destination_integer == 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 destination integer.",
167
0
     function );
168
169
0
    return( -1 );
170
0
  }
171
0
  if( *destination_integer != NULL )
172
0
  {
173
0
    libcerror_error_set(
174
0
     error,
175
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
176
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
177
0
     "%s: destination integer already set.",
178
0
     function );
179
180
0
    return( -1 );
181
0
  }
182
0
  if( source_integer == NULL )
183
0
  {
184
0
    *destination_integer = NULL;
185
186
0
    return( 1 );
187
0
  }
188
0
  *destination_integer = memory_allocate_structure(
189
0
                          libfvalue_integer_t );
190
191
0
  if( *destination_integer == NULL )
192
0
  {
193
0
    libcerror_error_set(
194
0
     error,
195
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
196
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
197
0
     "%s: unable to create destination integer.",
198
0
     function );
199
200
0
    goto on_error;
201
0
  }
202
0
  if( memory_copy(
203
0
       *destination_integer,
204
0
       source_integer,
205
0
       sizeof( libfvalue_integer_t ) ) == NULL )
206
0
  {
207
0
    libcerror_error_set(
208
0
     error,
209
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
210
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
211
0
     "%s: unable to copy integer.",
212
0
     function );
213
214
0
    goto on_error;
215
0
  }
216
0
  return( 1 );
217
218
0
on_error:
219
0
  if( *destination_integer != NULL )
220
0
  {
221
0
    memory_free(
222
0
     *destination_integer );
223
224
0
    *destination_integer = NULL;
225
0
  }
226
0
  return( -1 );
227
0
}
228
229
/* Copies the integer from a byte stream
230
 * Returns 1 if successful or -1 on error
231
 */
232
int libfvalue_integer_copy_from_byte_stream(
233
     libfvalue_integer_t *integer,
234
     const uint8_t *byte_stream,
235
     size_t byte_stream_size,
236
     int encoding,
237
     libcerror_error_t **error )
238
0
{
239
0
  static char *function = "libfvalue_integer_copy_from_byte_stream";
240
241
0
  if( integer == NULL )
242
0
  {
243
0
    libcerror_error_set(
244
0
     error,
245
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
246
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
247
0
     "%s: invalid integer.",
248
0
     function );
249
250
0
    return( -1 );
251
0
  }
252
0
  if( byte_stream == NULL )
253
0
  {
254
0
    libcerror_error_set(
255
0
     error,
256
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
257
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
258
0
     "%s: invalid byte stream.",
259
0
     function );
260
261
0
    return( -1 );
262
0
  }
263
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
264
0
  {
265
0
    libcerror_error_set(
266
0
     error,
267
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
268
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
269
0
     "%s: invalid byte stream size value exceeds maximum.",
270
0
     function );
271
272
0
    return( -1 );
273
0
  }
274
0
  if( ( encoding != LIBFVALUE_ENDIAN_BIG )
275
0
   && ( encoding != LIBFVALUE_ENDIAN_LITTLE )
276
0
   && ( encoding != LIBFVALUE_ENDIAN_NATIVE ) )
277
0
  {
278
0
    libcerror_error_set(
279
0
     error,
280
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
281
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
282
0
     "%s: unsupported encoding.",
283
0
     function );
284
285
0
    return( -1 );
286
0
  }
287
0
  switch( byte_stream_size )
288
0
  {
289
0
    case 1:
290
0
      integer->value = (uint64_t) *( (uint8_t *) byte_stream );
291
292
0
      break;
293
294
0
    case 2:
295
0
      if( encoding == LIBFVALUE_ENDIAN_BIG )
296
0
      {
297
0
        byte_stream_copy_to_uint16_big_endian(
298
0
         byte_stream,
299
0
         integer->value );
300
0
      }
301
0
      else if( encoding == LIBFVALUE_ENDIAN_LITTLE )
302
0
      {
303
0
        byte_stream_copy_to_uint16_little_endian(
304
0
         byte_stream,
305
0
         integer->value );
306
0
      }
307
0
      else
308
0
      {
309
0
        byte_stream_copy_to_uint16_native_endian(
310
0
         byte_stream,
311
0
         integer->value );
312
0
      }
313
0
      break;
314
315
0
    case 4:
316
0
      if( encoding == LIBFVALUE_ENDIAN_BIG )
317
0
      {
318
0
        byte_stream_copy_to_uint32_big_endian(
319
0
         byte_stream,
320
0
         integer->value );
321
0
      }
322
0
      else if( encoding == LIBFVALUE_ENDIAN_LITTLE )
323
0
      {
324
0
        byte_stream_copy_to_uint32_little_endian(
325
0
         byte_stream,
326
0
         integer->value );
327
0
      }
328
0
      else
329
0
      {
330
0
        byte_stream_copy_to_uint32_native_endian(
331
0
         byte_stream,
332
0
         integer->value );
333
0
      }
334
0
      break;
335
336
0
    case 8:
337
0
      if( encoding == LIBFVALUE_ENDIAN_BIG )
338
0
      {
339
0
        byte_stream_copy_to_uint64_big_endian(
340
0
         byte_stream,
341
0
         integer->value );
342
0
      }
343
0
      else if( encoding == LIBFVALUE_ENDIAN_LITTLE )
344
0
      {
345
0
        byte_stream_copy_to_uint64_little_endian(
346
0
         byte_stream,
347
0
         integer->value );
348
0
      }
349
0
      else
350
0
      {
351
0
        byte_stream_copy_to_uint64_native_endian(
352
0
         byte_stream,
353
0
         integer->value );
354
0
      }
355
0
      break;
356
357
0
    default:
358
0
      libcerror_error_set(
359
0
       error,
360
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
362
0
       "%s: unsupported byte stream size: %" PRIzd ".",
363
0
       function,
364
0
       byte_stream_size );
365
366
0
      return( -1 );
367
0
  }
368
0
  integer->value_size = byte_stream_size * 8;
369
370
0
  return( 1 );
371
0
}
372
373
/* Copies the integer from an integer value
374
 * Returns 1 if successful or -1 on error
375
 */
376
int libfvalue_integer_copy_from_integer(
377
     libfvalue_integer_t *integer,
378
     uint64_t integer_value,
379
     size_t integer_value_size,
380
     libcerror_error_t **error )
381
0
{
382
0
  static char *function = "libfvalue_integer_copy_from_integer";
383
384
0
  if( integer == NULL )
385
0
  {
386
0
    libcerror_error_set(
387
0
     error,
388
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
389
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
390
0
     "%s: invalid integer.",
391
0
     function );
392
393
0
    return( -1 );
394
0
  }
395
0
  if( ( integer_value_size != 8 )
396
0
   && ( integer_value_size != 16 )
397
0
   && ( integer_value_size != 32 )
398
0
   && ( integer_value_size != 64 ) )
399
0
  {
400
0
    libcerror_error_set(
401
0
     error,
402
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
403
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
404
0
     "%s: unsupported integer value size.",
405
0
     function );
406
407
0
    return( -1 );
408
0
  }
409
0
  integer->value      = integer_value;
410
0
  integer->value_size = integer_value_size;
411
412
0
  return( 1 );
413
0
}
414
415
/* Copies the integer to an integer value
416
 * Returns 1 if successful or -1 on error
417
 */
418
int libfvalue_integer_copy_to_integer(
419
     libfvalue_integer_t *integer,
420
     uint64_t *integer_value,
421
     size_t *integer_value_size,
422
     libcerror_error_t **error )
423
0
{
424
0
  static char *function = "libfvalue_integer_copy_to_integer";
425
426
0
  if( integer == NULL )
427
0
  {
428
0
    libcerror_error_set(
429
0
     error,
430
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
431
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
432
0
     "%s: invalid integer.",
433
0
     function );
434
435
0
    return( -1 );
436
0
  }
437
0
  if( integer_value == NULL )
438
0
  {
439
0
    libcerror_error_set(
440
0
     error,
441
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
442
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
443
0
     "%s: invalid integer value.",
444
0
     function );
445
446
0
    return( -1 );
447
0
  }
448
0
  if( integer_value_size == NULL )
449
0
  {
450
0
    libcerror_error_set(
451
0
     error,
452
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
453
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
454
0
     "%s: invalid integer value size.",
455
0
     function );
456
457
0
    return( -1 );
458
0
  }
459
0
  *integer_value      = integer->value;
460
0
  *integer_value_size = integer->value_size;
461
462
0
  return( 1 );
463
0
}
464
465
/* Retrieves the size of a string of the integer
466
 * Returns 1 if successful or -1 on error
467
 */
468
int libfvalue_integer_get_string_size(
469
     libfvalue_integer_t *integer,
470
     size_t *string_size,
471
     uint32_t string_format_flags,
472
     libcerror_error_t **error )
473
0
{
474
0
  static char *function = "libfvalue_integer_get_string_size";
475
476
0
  if( integer == NULL )
477
0
  {
478
0
    libcerror_error_set(
479
0
     error,
480
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
481
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
482
0
     "%s: invalid integer.",
483
0
     function );
484
485
0
    return( -1 );
486
0
  }
487
0
  if( libfvalue_string_size_from_integer(
488
0
       string_size,
489
0
       integer->value,
490
0
       integer->value_size,
491
0
       string_format_flags,
492
0
       error ) != 1 )
493
0
  {
494
0
    libcerror_error_set(
495
0
     error,
496
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
497
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
498
0
     "%s: unable to determine size of string of %" PRIzd "-bit integer.",
499
0
     function,
500
0
     integer->value_size );
501
502
0
    return( -1 );
503
0
  }
504
0
  return( 1 );
505
0
}
506
507
/* Copies the integer from an UTF-8 encoded string
508
 * Returns 1 if successful or -1 on error
509
 */
510
int libfvalue_integer_copy_from_utf8_string_with_index(
511
     libfvalue_integer_t *integer,
512
     uint8_t *utf8_string,
513
     size_t utf8_string_length,
514
     size_t *utf8_string_index,
515
     uint32_t string_format_flags,
516
     libcerror_error_t **error )
517
0
{
518
0
  static char *function = "libfvalue_integer_copy_from_utf8_string_with_index";
519
520
0
  if( integer == NULL )
521
0
  {
522
0
    libcerror_error_set(
523
0
     error,
524
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
525
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
526
0
     "%s: invalid integer.",
527
0
     function );
528
529
0
    return( -1 );
530
0
  }
531
0
  if( libfvalue_utf8_string_with_index_copy_to_integer(
532
0
       utf8_string,
533
0
       utf8_string_length,
534
0
       utf8_string_index,
535
0
       &( integer->value ),
536
0
       integer->value_size,
537
0
       string_format_flags,
538
0
       error ) != 1 )
539
0
  {
540
0
    libcerror_error_set(
541
0
     error,
542
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
543
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
544
0
     "%s: unable to copy %" PRIzd "-bit integer from UTF-8 string.",
545
0
     function,
546
0
     integer->value_size );
547
548
0
    return( -1 );
549
0
  }
550
0
  return( 1 );
551
0
}
552
553
/* Copies the integer to an UTF-8 encoded string
554
 * Returns 1 if successful or -1 on error
555
 */
556
int libfvalue_integer_copy_to_utf8_string_with_index(
557
     libfvalue_integer_t *integer,
558
     uint8_t *utf8_string,
559
     size_t utf8_string_size,
560
     size_t *utf8_string_index,
561
     uint32_t string_format_flags,
562
     libcerror_error_t **error )
563
0
{
564
0
  static char *function = "libfvalue_integer_copy_to_utf8_string_with_index";
565
566
0
  if( integer == NULL )
567
0
  {
568
0
    libcerror_error_set(
569
0
     error,
570
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
571
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
572
0
     "%s: invalid integer.",
573
0
     function );
574
575
0
    return( -1 );
576
0
  }
577
0
  if( libfvalue_utf8_string_with_index_copy_from_integer(
578
0
       utf8_string,
579
0
       utf8_string_size,
580
0
       utf8_string_index,
581
0
       integer->value,
582
0
       integer->value_size,
583
0
       string_format_flags,
584
0
       error ) != 1 )
585
0
  {
586
0
    libcerror_error_set(
587
0
     error,
588
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
589
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
590
0
     "%s: unable to copy %" PRIzd "-bit integer to UTF-8 string.",
591
0
     function,
592
0
     integer->value_size );
593
594
0
    return( -1 );
595
0
  }
596
0
  return( 1 );
597
0
}
598
599
/* Copies the integer from an UTF-16 encoded string
600
 * Returns 1 if successful or -1 on error
601
 */
602
int libfvalue_integer_copy_from_utf16_string_with_index(
603
     libfvalue_integer_t *integer,
604
     uint16_t *utf16_string,
605
     size_t utf16_string_length,
606
     size_t *utf16_string_index,
607
     uint32_t string_format_flags,
608
     libcerror_error_t **error )
609
0
{
610
0
  static char *function = "libfvalue_integer_copy_from_utf16_string_with_index";
611
612
0
  if( integer == NULL )
613
0
  {
614
0
    libcerror_error_set(
615
0
     error,
616
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
617
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
618
0
     "%s: invalid integer.",
619
0
     function );
620
621
0
    return( -1 );
622
0
  }
623
0
  if( libfvalue_utf16_string_with_index_copy_to_integer(
624
0
       utf16_string,
625
0
       utf16_string_length,
626
0
       utf16_string_index,
627
0
       &( integer->value ),
628
0
       integer->value_size,
629
0
       string_format_flags,
630
0
       error ) != 1 )
631
0
  {
632
0
    libcerror_error_set(
633
0
     error,
634
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
635
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
636
0
     "%s: unable to copy %" PRIzd "-bit integer from UTF-16 string.",
637
0
     function,
638
0
     integer->value_size );
639
640
0
    return( -1 );
641
0
  }
642
0
  return( 1 );
643
0
}
644
645
/* Copies the integer to an UTF-16 encoded string
646
 * Returns 1 if successful or -1 on error
647
 */
648
int libfvalue_integer_copy_to_utf16_string_with_index(
649
     libfvalue_integer_t *integer,
650
     uint16_t *utf16_string,
651
     size_t utf16_string_size,
652
     size_t *utf16_string_index,
653
     uint32_t string_format_flags,
654
     libcerror_error_t **error )
655
0
{
656
0
  static char *function = "libfvalue_integer_copy_to_utf16_string_with_index";
657
658
0
  if( integer == NULL )
659
0
  {
660
0
    libcerror_error_set(
661
0
     error,
662
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
663
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
664
0
     "%s: invalid integer.",
665
0
     function );
666
667
0
    return( -1 );
668
0
  }
669
0
  if( libfvalue_utf16_string_with_index_copy_from_integer(
670
0
       utf16_string,
671
0
       utf16_string_size,
672
0
       utf16_string_index,
673
0
       integer->value,
674
0
       integer->value_size,
675
0
       string_format_flags,
676
0
       error ) != 1 )
677
0
  {
678
0
    libcerror_error_set(
679
0
     error,
680
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
681
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
682
0
     "%s: unable to copy %" PRIzd "-bit integer to UTF-16 string.",
683
0
     function,
684
0
     integer->value_size );
685
686
0
    return( -1 );
687
0
  }
688
0
  return( 1 );
689
0
}
690
691
/* Copies the integer from an UTF-32 encoded string
692
 * Returns 1 if successful or -1 on error
693
 */
694
int libfvalue_integer_copy_from_utf32_string_with_index(
695
     libfvalue_integer_t *integer,
696
     uint32_t *utf32_string,
697
     size_t utf32_string_length,
698
     size_t *utf32_string_index,
699
     uint32_t string_format_flags,
700
     libcerror_error_t **error )
701
0
{
702
0
  static char *function = "libfvalue_integer_copy_from_utf32_string_with_index";
703
704
0
  if( integer == NULL )
705
0
  {
706
0
    libcerror_error_set(
707
0
     error,
708
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
709
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
710
0
     "%s: invalid integer.",
711
0
     function );
712
713
0
    return( -1 );
714
0
  }
715
0
  if( libfvalue_utf32_string_with_index_copy_to_integer(
716
0
       utf32_string,
717
0
       utf32_string_length,
718
0
       utf32_string_index,
719
0
       &( integer->value ),
720
0
       integer->value_size,
721
0
       string_format_flags,
722
0
       error ) != 1 )
723
0
  {
724
0
    libcerror_error_set(
725
0
     error,
726
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
727
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
728
0
     "%s: unable to copy %" PRIzd "-bit integer from UTF-32 string.",
729
0
     function,
730
0
     integer->value_size );
731
732
0
    return( -1 );
733
0
  }
734
0
  return( 1 );
735
0
}
736
737
/* Copies the integer to an UTF-32 encoded string
738
 * Returns 1 if successful or -1 on error
739
 */
740
int libfvalue_integer_copy_to_utf32_string_with_index(
741
     libfvalue_integer_t *integer,
742
     uint32_t *utf32_string,
743
     size_t utf32_string_size,
744
     size_t *utf32_string_index,
745
     uint32_t string_format_flags,
746
     libcerror_error_t **error )
747
0
{
748
0
  static char *function = "libfvalue_integer_copy_to_utf32_string_with_index";
749
750
0
  if( integer == NULL )
751
0
  {
752
0
    libcerror_error_set(
753
0
     error,
754
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
755
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
756
0
     "%s: invalid integer.",
757
0
     function );
758
759
0
    return( -1 );
760
0
  }
761
0
  if( libfvalue_utf32_string_with_index_copy_from_integer(
762
0
       utf32_string,
763
0
       utf32_string_size,
764
0
       utf32_string_index,
765
0
       integer->value,
766
0
       integer->value_size,
767
0
       string_format_flags,
768
0
       error ) != 1 )
769
0
  {
770
0
    libcerror_error_set(
771
0
     error,
772
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
773
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
774
0
     "%s: unable to copy %" PRIzd "-bit integer to UTF-32 string.",
775
0
     function,
776
0
     integer->value_size );
777
778
0
    return( -1 );
779
0
  }
780
0
  return( 1 );
781
0
}
782
783
/* Determines the size of a string of an integer value
784
 * The integer value size is in bits
785
 * Returns 1 if successful or -1 on error
786
 */
787
int libfvalue_string_size_from_integer(
788
     size_t *string_size,
789
     uint64_t integer_value,
790
     size_t integer_value_size,
791
     uint32_t string_format_flags,
792
     libcerror_error_t **error )
793
0
{
794
0
  static char *function       = "libfvalue_string_size_from_integer";
795
0
  uint64_t divider            = 0;
796
0
  uint32_t string_format_type = 0;
797
0
  uint32_t supported_flags    = 0;
798
0
  uint8_t is_signed           = 0;
799
0
  int8_t bit_shift            = 0;
800
801
0
  if( string_size == NULL )
802
0
  {
803
0
    libcerror_error_set(
804
0
     error,
805
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
806
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
807
0
     "%s: invalid string size.",
808
0
     function );
809
810
0
    return( -1 );
811
0
  }
812
0
  if( ( integer_value_size != 8 )
813
0
   && ( integer_value_size != 16 )
814
0
   && ( integer_value_size != 32 )
815
0
   && ( integer_value_size != 64 ) )
816
0
  {
817
0
    libcerror_error_set(
818
0
     error,
819
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
820
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
821
0
     "%s: unsupported integer value size.",
822
0
     function );
823
824
0
    return( -1 );
825
0
  }
826
0
  supported_flags = 0x000000ffUL
827
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED
828
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED
829
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR;
830
831
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
832
0
  {
833
0
    libcerror_error_set(
834
0
     error,
835
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
836
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
837
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
838
0
     function,
839
0
     string_format_flags );
840
841
0
    return( -1 );
842
0
  }
843
0
  string_format_type = string_format_flags & 0x000000ffUL;
844
845
0
  if( ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL )
846
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
847
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN ) )
848
0
  {
849
0
    libcerror_error_set(
850
0
     error,
851
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
852
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
853
0
     "%s: unsupported string format type.",
854
0
     function );
855
856
0
    return( -1 );
857
0
  }
858
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
859
0
  {
860
0
    if( integer_value == 0 )
861
0
    {
862
0
      *string_size = 6;
863
0
    }
864
0
    else
865
0
    {
866
0
      *string_size = 5;
867
0
    }
868
0
  }
869
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
870
0
  {
871
0
    *string_size = ( integer_value_size >> 2 ) + 1;
872
873
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
874
0
    {
875
0
      *string_size += 2;
876
0
    }
877
0
  }
878
0
  else
879
0
  {
880
    /* The string is at least a single digit with an end of string character
881
     */
882
0
    *string_size = 2;
883
884
0
    bit_shift = (uint8_t) ( integer_value_size - 1 );
885
886
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED ) != 0 )
887
0
    {
888
0
      is_signed = (uint8_t) ( integer_value >> bit_shift );
889
890
0
      if( is_signed != 0 )
891
0
      {
892
0
        *string_size += 1;
893
894
0
        integer_value &= ~( (uint64_t) 1 << bit_shift );
895
896
0
        if( integer_value == 0 )
897
0
        {
898
0
          integer_value |= (uint64_t) 1 << bit_shift;
899
0
        }
900
0
      }
901
0
    }
902
0
    divider = 1;
903
904
0
    while( ( integer_value / divider ) >= 10 )
905
0
    {
906
0
      divider *= 10;
907
908
0
      *string_size += 1;
909
0
    }
910
0
  }
911
0
  return( 1 );
912
0
}
913
914
/* Copies an UTF-8 encoded string from an integer value
915
 * The integer value size is in bits
916
 * Returns 1 if successful or -1 on error
917
 */
918
int libfvalue_utf8_string_copy_from_integer(
919
     uint8_t *utf8_string,
920
     size_t utf8_string_size,
921
     uint64_t integer_value,
922
     size_t integer_value_size,
923
     uint32_t string_format_flags,
924
     libcerror_error_t **error )
925
0
{
926
0
  static char *function    = "libfvalue_utf8_string_copy_from_integer";
927
0
  size_t utf8_string_index = 0;
928
929
0
  if( libfvalue_utf8_string_with_index_copy_from_integer(
930
0
       utf8_string,
931
0
       utf8_string_size,
932
0
       &utf8_string_index,
933
0
       integer_value,
934
0
       integer_value_size,
935
0
       string_format_flags,
936
0
       error ) != 1 )
937
0
  {
938
0
    libcerror_error_set(
939
0
     error,
940
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
941
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
942
0
     "%s: unable to copy integer value to UTF-8 string.",
943
0
     function );
944
945
0
    return( -1 );
946
0
  }
947
0
  return( 1 );
948
0
}
949
950
/* Copies an UTF-8 encoded string of from integer value
951
 * The integer value size is in bits
952
 * Returns 1 if successful or -1 on error
953
 */
954
int libfvalue_utf8_string_with_index_copy_from_integer(
955
     uint8_t *utf8_string,
956
     size_t utf8_string_size,
957
     size_t *utf8_string_index,
958
     uint64_t integer_value,
959
     size_t integer_value_size,
960
     uint32_t string_format_flags,
961
     libcerror_error_t **error )
962
9.83k
{
963
9.83k
  static char *function         = "libfvalue_utf8_string_with_index_copy_from_integer";
964
9.83k
  size_t safe_utf8_string_index = 0;
965
9.83k
  uint64_t divider              = 0;
966
9.83k
  uint32_t string_format_type   = 0;
967
9.83k
  uint32_t supported_flags      = 0;
968
9.83k
  uint8_t byte_value            = 0;
969
9.83k
  uint8_t is_signed             = 0;
970
9.83k
  uint8_t number_of_characters  = 0;
971
9.83k
  int8_t bit_shift              = 0;
972
973
9.83k
  if( utf8_string == NULL )
974
0
  {
975
0
    libcerror_error_set(
976
0
     error,
977
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
978
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
979
0
     "%s: invalid UTF-8 string.",
980
0
     function );
981
982
0
    return( -1 );
983
0
  }
984
9.83k
  if( utf8_string_size > (size_t) SSIZE_MAX )
985
0
  {
986
0
    libcerror_error_set(
987
0
     error,
988
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
989
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
990
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
991
0
     function );
992
993
0
    return( -1 );
994
0
  }
995
9.83k
  if( utf8_string_index == NULL )
996
0
  {
997
0
    libcerror_error_set(
998
0
     error,
999
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1000
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1001
0
     "%s: invalid UTF-8 string index.",
1002
0
     function );
1003
1004
0
    return( -1 );
1005
0
  }
1006
9.83k
  if( *utf8_string_index >= utf8_string_size )
1007
0
  {
1008
0
    libcerror_error_set(
1009
0
     error,
1010
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1011
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1012
0
     "%s: invalid UTF-8 string index value out of bounds.",
1013
0
     function );
1014
1015
0
    return( -1 );
1016
0
  }
1017
9.83k
  safe_utf8_string_index = *utf8_string_index;
1018
1019
9.83k
  if( ( integer_value_size != 8 )
1020
1.65k
   && ( integer_value_size != 16 )
1021
0
   && ( integer_value_size != 32 )
1022
0
   && ( integer_value_size != 64 ) )
1023
0
  {
1024
0
    libcerror_error_set(
1025
0
     error,
1026
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1027
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1028
0
     "%s: unsupported integer value size.",
1029
0
     function );
1030
1031
0
    return( -1 );
1032
0
  }
1033
9.83k
  supported_flags = 0x000000ffUL
1034
9.83k
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED
1035
9.83k
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED
1036
9.83k
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR;
1037
1038
9.83k
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1039
0
  {
1040
0
    libcerror_error_set(
1041
0
     error,
1042
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1043
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1044
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1045
0
     function,
1046
0
     string_format_flags );
1047
1048
0
    return( -1 );
1049
0
  }
1050
9.83k
  string_format_type = string_format_flags & 0x000000ffUL;
1051
1052
9.83k
  if( ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL )
1053
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1054
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN ) )
1055
0
  {
1056
0
    libcerror_error_set(
1057
0
     error,
1058
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1059
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1060
0
     "%s: unsupported string format type.",
1061
0
     function );
1062
1063
0
    return( -1 );
1064
0
  }
1065
9.83k
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
1066
0
  {
1067
0
    if( integer_value == 0 )
1068
0
    {
1069
0
      number_of_characters = 6;
1070
0
    }
1071
0
    else
1072
0
    {
1073
0
      number_of_characters = 5;
1074
0
    }
1075
0
  }
1076
9.83k
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1077
0
  {
1078
0
    number_of_characters = (uint8_t) ( integer_value_size >> 2 ) + 1;
1079
1080
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
1081
0
    {
1082
0
      number_of_characters += 2;
1083
0
    }
1084
0
  }
1085
9.83k
  else
1086
9.83k
  {
1087
    /* The string is at least a single digit with an end of string character
1088
     */
1089
9.83k
    number_of_characters = 2;
1090
1091
9.83k
    bit_shift = (uint8_t) ( integer_value_size - 1 );
1092
1093
9.83k
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED ) != 0 )
1094
0
    {
1095
0
      is_signed = (uint8_t) ( integer_value >> bit_shift );
1096
1097
0
      if( is_signed != 0 )
1098
0
      {
1099
0
        number_of_characters += 1;
1100
1101
0
        integer_value &= ~( (uint64_t) 1 << bit_shift );
1102
1103
0
        if( integer_value == 0 )
1104
0
        {
1105
0
          integer_value |= (uint64_t) 1 << bit_shift;
1106
0
        }
1107
0
      }
1108
0
    }
1109
9.83k
    divider = 1;
1110
1111
16.4k
    while( ( integer_value / divider ) >= 10 )
1112
6.63k
    {
1113
6.63k
      divider *= 10;
1114
1115
6.63k
      number_of_characters += 1;
1116
6.63k
    }
1117
9.83k
  }
1118
9.83k
  if( ( number_of_characters > utf8_string_size )
1119
9.82k
   || ( safe_utf8_string_index > ( utf8_string_size - number_of_characters ) ) )
1120
16
  {
1121
16
    libcerror_error_set(
1122
16
     error,
1123
16
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1124
16
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1125
16
     "%s: UTF-8 string size too small.",
1126
16
     function );
1127
1128
16
    return( -1 );
1129
16
  }
1130
9.82k
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
1131
0
  {
1132
0
    if( integer_value == 0 )
1133
0
    {
1134
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'f';
1135
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'a';
1136
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'l';
1137
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 's';
1138
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'e';
1139
0
    }
1140
0
    else
1141
0
    {
1142
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 't';
1143
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'r';
1144
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'u';
1145
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'e';
1146
0
    }
1147
0
  }
1148
9.82k
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1149
0
  {
1150
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
1151
0
    {
1152
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0';
1153
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'x';
1154
0
    }
1155
0
    bit_shift = (uint8_t) ( integer_value_size - 4 );
1156
1157
0
    do
1158
0
    {
1159
0
      byte_value = (uint8_t) ( ( integer_value >> bit_shift ) & 0x0f );
1160
1161
0
      if( byte_value <= 9 )
1162
0
      {
1163
0
        utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0' + byte_value;
1164
0
      }
1165
0
      else
1166
0
      {
1167
0
        utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'a' + byte_value - 10;
1168
0
      }
1169
0
      bit_shift -= 4;
1170
0
    }
1171
0
    while( bit_shift >= 0 );
1172
0
  }
1173
9.82k
  else
1174
9.82k
  {
1175
9.82k
    if( is_signed != 0 )
1176
0
    {
1177
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '-';
1178
0
    }
1179
16.1k
    while( divider > 1 )
1180
6.33k
    {
1181
6.33k
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0' + (uint8_t) ( integer_value / divider );
1182
1183
6.33k
      integer_value %= divider;
1184
1185
6.33k
      divider /= 10;
1186
6.33k
    }
1187
9.82k
    utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0' + (uint8_t) ( integer_value / divider );
1188
9.82k
  }
1189
9.82k
  utf8_string[ safe_utf8_string_index++ ] = 0;
1190
1191
9.82k
  *utf8_string_index = safe_utf8_string_index;
1192
1193
9.82k
  return( 1 );
1194
9.83k
}
1195
1196
/* Copies an UTF-8 encoded string to an integer value
1197
 * The integer value size is in bits
1198
 * Returns 1 if successful or -1 on error
1199
 */
1200
int libfvalue_utf8_string_copy_to_integer(
1201
     const uint8_t *utf8_string,
1202
     size_t utf8_string_length,
1203
     uint64_t *integer_value,
1204
     size_t integer_value_size,
1205
     uint32_t string_format_flags,
1206
     libcerror_error_t **error )
1207
652k
{
1208
652k
  static char *function    = "libfvalue_utf8_string_copy_to_integer";
1209
652k
  size_t utf8_string_index = 0;
1210
1211
652k
  if( libfvalue_utf8_string_with_index_copy_to_integer(
1212
652k
       utf8_string,
1213
652k
       utf8_string_length,
1214
652k
       &utf8_string_index,
1215
652k
       integer_value,
1216
652k
       integer_value_size,
1217
652k
       string_format_flags,
1218
652k
       error ) != 1 )
1219
1.38k
  {
1220
1.38k
    libcerror_error_set(
1221
1.38k
     error,
1222
1.38k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1223
1.38k
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1224
1.38k
     "%s: unable to copy UTF-8 string to integer value.",
1225
1.38k
     function );
1226
1227
1.38k
    return( -1 );
1228
1.38k
  }
1229
650k
  return( 1 );
1230
652k
}
1231
1232
/* Copies an UTF-8 encoded string to an integer value
1233
 * The integer value size is in bits
1234
 * Returns 1 if successful or -1 on error
1235
 */
1236
int libfvalue_utf8_string_with_index_copy_to_integer(
1237
     const uint8_t *utf8_string,
1238
     size_t utf8_string_length,
1239
     size_t *utf8_string_index,
1240
     uint64_t *integer_value,
1241
     size_t integer_value_size,
1242
     uint32_t string_format_flags,
1243
     libcerror_error_t **error )
1244
652k
{
1245
652k
  static char *function         = "libfvalue_utf8_string_with_index_copy_to_integer";
1246
652k
  size_t maximum_string_index   = 0;
1247
652k
  size_t safe_utf8_string_index = 0;
1248
652k
  uint64_t divider              = 0;
1249
652k
  uint64_t value_64bit          = 0;
1250
652k
  uint32_t string_format_type   = 0;
1251
652k
  uint32_t supported_flags      = 0;
1252
652k
  uint8_t byte_value            = 0;
1253
652k
  uint8_t character_value       = 0;
1254
652k
  int8_t bit_shift              = 0;
1255
652k
  int8_t sign                   = 1;
1256
1257
652k
  if( utf8_string == NULL )
1258
0
  {
1259
0
    libcerror_error_set(
1260
0
     error,
1261
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1262
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1263
0
     "%s: invalid UTF-8 string.",
1264
0
     function );
1265
1266
0
    return( -1 );
1267
0
  }
1268
652k
  if( utf8_string_length > (size_t) SSIZE_MAX )
1269
2
  {
1270
2
    libcerror_error_set(
1271
2
     error,
1272
2
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1273
2
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1274
2
     "%s: invalid UTF-8 string size value exceeds maximum.",
1275
2
     function );
1276
1277
2
    return( -1 );
1278
2
  }
1279
652k
  if( utf8_string_index == NULL )
1280
0
  {
1281
0
    libcerror_error_set(
1282
0
     error,
1283
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1284
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1285
0
     "%s: invalid UTF-8 string index.",
1286
0
     function );
1287
1288
0
    return( -1 );
1289
0
  }
1290
652k
  if( *utf8_string_index >= utf8_string_length )
1291
15
  {
1292
15
    libcerror_error_set(
1293
15
     error,
1294
15
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1295
15
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1296
15
     "%s: invalid UTF-8 string index value out of bounds.",
1297
15
     function );
1298
1299
15
    return( -1 );
1300
15
  }
1301
651k
  safe_utf8_string_index = *utf8_string_index;
1302
1303
651k
  if( integer_value == NULL )
1304
0
  {
1305
0
    libcerror_error_set(
1306
0
     error,
1307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1309
0
     "%s: invalid integer value.",
1310
0
     function );
1311
1312
0
    return( -1 );
1313
0
  }
1314
651k
  if( ( integer_value_size != 8 )
1315
650k
   && ( integer_value_size != 16 )
1316
649k
   && ( integer_value_size != 32 )
1317
647k
   && ( integer_value_size != 64 ) )
1318
0
  {
1319
0
    libcerror_error_set(
1320
0
     error,
1321
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1322
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1323
0
     "%s: unsupported integer value size.",
1324
0
     function );
1325
1326
0
    return( -1 );
1327
0
  }
1328
651k
  supported_flags = 0x000000ffUL
1329
651k
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED
1330
651k
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED
1331
651k
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR;
1332
1333
651k
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1334
0
  {
1335
0
    libcerror_error_set(
1336
0
     error,
1337
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1338
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1339
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1340
0
     function,
1341
0
     string_format_flags );
1342
1343
0
    return( -1 );
1344
0
  }
1345
651k
  string_format_type = string_format_flags & 0x000000ffUL;
1346
1347
651k
  if( ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL )
1348
749
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1349
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN ) )
1350
0
  {
1351
0
    libcerror_error_set(
1352
0
     error,
1353
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1354
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1355
0
     "%s: unsupported string format type.",
1356
0
     function );
1357
1358
0
    return( -1 );
1359
0
  }
1360
651k
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
1361
0
  {
1362
0
    if( integer_value == 0 )
1363
0
    {
1364
0
      maximum_string_index = 5;
1365
0
    }
1366
0
    else
1367
0
    {
1368
0
      maximum_string_index = 4;
1369
0
    }
1370
0
  }
1371
651k
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1372
749
  {
1373
749
    maximum_string_index = (size_t) ( integer_value_size >> 2 );
1374
1375
749
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
1376
0
    {
1377
0
      maximum_string_index += 2;
1378
0
    }
1379
749
  }
1380
651k
  else
1381
651k
  {
1382
    /* The string is at least a single digit with an end of string character
1383
     */
1384
651k
    maximum_string_index = 2;
1385
1386
651k
    bit_shift = (uint8_t) ( integer_value_size - 1 );
1387
1388
651k
    divider = 1;
1389
1390
651k
    value_64bit = ~( ( ~( (uint64_t) 1 << bit_shift ) >> bit_shift ) << bit_shift );
1391
1392
12.9M
    while( ( value_64bit / divider ) >= 10 )
1393
12.3M
    {
1394
12.3M
      divider *= 10;
1395
1396
12.3M
      maximum_string_index += 1;
1397
12.3M
    }
1398
651k
  }
1399
651k
  maximum_string_index += safe_utf8_string_index;
1400
1401
651k
  if( maximum_string_index > (size_t) SSIZE_MAX )
1402
0
  {
1403
0
    libcerror_error_set(
1404
0
     error,
1405
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1406
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1407
0
     "%s: invalid maximum string index value exceeds maximum.",
1408
0
     function );
1409
1410
0
    return( -1 );
1411
0
  }
1412
651k
  value_64bit = 0;
1413
1414
651k
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
1415
0
  {
1416
/* TODO */
1417
0
  }
1418
651k
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1419
749
  {
1420
749
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
1421
0
    {
1422
0
      character_value = utf8_string[ safe_utf8_string_index++ ];
1423
1424
0
      if( character_value != (uint8_t) '0' )
1425
0
      {
1426
0
        libcerror_error_set(
1427
0
         error,
1428
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1429
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1430
0
         "%s: unsupported character value: 0x%02" PRIx8 " at index: %d.",
1431
0
         function,
1432
0
         character_value,
1433
0
         safe_utf8_string_index );
1434
1435
0
        return( -1 );
1436
0
      }
1437
0
      character_value = utf8_string[ safe_utf8_string_index++ ];
1438
1439
0
      if( character_value != (uint8_t) 'x' )
1440
0
      {
1441
0
        libcerror_error_set(
1442
0
         error,
1443
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1444
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1445
0
         "%s: unsupported character value: 0x%02" PRIx8 " at index: %d.",
1446
0
         function,
1447
0
         character_value,
1448
0
         safe_utf8_string_index );
1449
1450
0
        return( -1 );
1451
0
      }
1452
0
    }
1453
4.39k
    while( safe_utf8_string_index < utf8_string_length )
1454
3.70k
    {
1455
3.70k
      character_value = utf8_string[ safe_utf8_string_index ];
1456
1457
3.70k
      if( character_value == 0 )
1458
10
      {
1459
10
        break;
1460
10
      }
1461
3.69k
      if( safe_utf8_string_index > (size_t) maximum_string_index )
1462
4
      {
1463
4
        libcerror_error_set(
1464
4
         error,
1465
4
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1466
4
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE,
1467
4
         "%s: string too large.",
1468
4
         function );
1469
1470
4
        return( -1 );
1471
4
      }
1472
3.68k
      value_64bit <<= 4;
1473
1474
3.68k
      if( ( character_value >= (uint8_t) '0' )
1475
3.67k
       && ( character_value <= (uint8_t) '9' ) )
1476
1.40k
      {
1477
1.40k
        byte_value = character_value - (uint8_t) '0';
1478
1.40k
      }
1479
2.28k
      else if( ( character_value >= (uint8_t) 'A' )
1480
2.27k
            && ( character_value <= (uint8_t) 'F' ) )
1481
592
      {
1482
592
        byte_value = character_value - (uint8_t) 'A' + 10;
1483
592
      }
1484
1.69k
      else if( ( character_value >= (uint8_t) 'a' )
1485
1.67k
            && ( character_value <= (uint8_t) 'f' ) )
1486
1.65k
      {
1487
1.65k
        byte_value = character_value - (uint8_t) 'a' + 10;
1488
1.65k
      }
1489
36
      else
1490
36
      {
1491
36
        libcerror_error_set(
1492
36
         error,
1493
36
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1494
36
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1495
36
         "%s: unsupported character value: 0x%02" PRIx8 " at index: %d.",
1496
36
         function,
1497
36
         character_value,
1498
36
         safe_utf8_string_index );
1499
1500
36
        return( -1 );
1501
36
      }
1502
3.65k
      value_64bit += byte_value;
1503
1504
3.65k
      safe_utf8_string_index++;
1505
3.65k
    }
1506
749
  }
1507
651k
  else
1508
651k
  {
1509
651k
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED ) != 0 )
1510
0
    {
1511
0
      character_value = utf8_string[ safe_utf8_string_index ];
1512
1513
      /* In the maximum possible string one character is substituted for the sign
1514
       */
1515
0
      if( character_value == (uint8_t) '-' )
1516
0
      {
1517
0
        safe_utf8_string_index++;
1518
1519
0
        sign = -1;
1520
0
      }
1521
0
      else if( character_value == (uint8_t) '+' )
1522
0
      {
1523
0
        safe_utf8_string_index++;
1524
0
      }
1525
0
    }
1526
1.11M
    while( safe_utf8_string_index < utf8_string_length )
1527
1.11M
    {
1528
1.11M
      character_value = utf8_string[ safe_utf8_string_index ];
1529
1530
1.11M
      if( character_value == 0 )
1531
648k
      {
1532
648k
        break;
1533
648k
      }
1534
464k
      if( safe_utf8_string_index > (size_t) maximum_string_index )
1535
18
      {
1536
18
        libcerror_error_set(
1537
18
         error,
1538
18
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1539
18
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE,
1540
18
         "%s: string too large.",
1541
18
         function );
1542
1543
18
        return( -1 );
1544
18
      }
1545
464k
      value_64bit *= 10;
1546
1547
464k
      if( ( character_value < (uint8_t) '0' )
1548
464k
       || ( character_value > (uint8_t) '9' ) )
1549
1.30k
      {
1550
1.30k
        libcerror_error_set(
1551
1.30k
         error,
1552
1.30k
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1553
1.30k
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1554
1.30k
         "%s: unsupported character value: 0x%02" PRIx8 " at index: %d.",
1555
1.30k
         function,
1556
1.30k
         character_value,
1557
1.30k
         safe_utf8_string_index );
1558
1559
1.30k
        return( -1 );
1560
1.30k
      }
1561
463k
      character_value -= (uint8_t) '0';
1562
1563
463k
      value_64bit += character_value;
1564
1565
463k
      safe_utf8_string_index++;
1566
463k
    }
1567
649k
    if( ( sign == -1 )
1568
0
     && ( value_64bit != 0 ) )
1569
0
    {
1570
0
      value_64bit = ~( value_64bit - 1 );
1571
0
    }
1572
649k
  }
1573
650k
  *utf8_string_index = safe_utf8_string_index;
1574
650k
  *integer_value     = value_64bit;
1575
1576
650k
  return( 1 );
1577
651k
}
1578
1579
/* Copies an UTF-16 encoded string of an integer value
1580
 * The integer value size is in bits
1581
 * Returns 1 if successful or -1 on error
1582
 */
1583
int libfvalue_utf16_string_copy_from_integer(
1584
     uint16_t *utf16_string,
1585
     size_t utf16_string_size,
1586
     uint64_t integer_value,
1587
     size_t integer_value_size,
1588
     uint32_t string_format_flags,
1589
     libcerror_error_t **error )
1590
0
{
1591
0
  static char *function     = "libfvalue_utf16_string_copy_from_integer";
1592
0
  size_t utf16_string_index = 0;
1593
1594
0
  if( libfvalue_utf16_string_with_index_copy_from_integer(
1595
0
       utf16_string,
1596
0
       utf16_string_size,
1597
0
       &utf16_string_index,
1598
0
       integer_value,
1599
0
       integer_value_size,
1600
0
       string_format_flags,
1601
0
       error ) != 1 )
1602
0
  {
1603
0
    libcerror_error_set(
1604
0
     error,
1605
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1606
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1607
0
     "%s: unable to copy integer value to UTF-16 string.",
1608
0
     function );
1609
1610
0
    return( -1 );
1611
0
  }
1612
0
  return( 1 );
1613
0
}
1614
1615
/* Copies an UTF-16 encoded string of an integer value
1616
 * The integer value size is in bits
1617
 * Returns 1 if successful or -1 on error
1618
 */
1619
int libfvalue_utf16_string_with_index_copy_from_integer(
1620
     uint16_t *utf16_string,
1621
     size_t utf16_string_size,
1622
     size_t *utf16_string_index,
1623
     uint64_t integer_value,
1624
     size_t integer_value_size,
1625
     uint32_t string_format_flags,
1626
     libcerror_error_t **error )
1627
0
{
1628
0
  static char *function          = "libfvalue_utf16_string_with_index_copy_from_integer";
1629
0
  size_t safe_utf16_string_index = 0;
1630
0
  uint64_t divider               = 0;
1631
0
  uint32_t string_format_type    = 0;
1632
0
  uint32_t supported_flags       = 0;
1633
0
  uint8_t byte_value             = 0;
1634
0
  uint8_t is_signed              = 0;
1635
0
  uint8_t number_of_characters   = 0;
1636
0
  int8_t bit_shift               = 0;
1637
1638
0
  if( utf16_string == NULL )
1639
0
  {
1640
0
    libcerror_error_set(
1641
0
     error,
1642
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1643
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1644
0
     "%s: invalid UTF-16 string.",
1645
0
     function );
1646
1647
0
    return( -1 );
1648
0
  }
1649
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
1650
0
  {
1651
0
    libcerror_error_set(
1652
0
     error,
1653
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1654
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1655
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
1656
0
     function );
1657
1658
0
    return( -1 );
1659
0
  }
1660
0
  if( utf16_string_index == NULL )
1661
0
  {
1662
0
    libcerror_error_set(
1663
0
     error,
1664
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1665
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1666
0
     "%s: invalid UTF-16 string index.",
1667
0
     function );
1668
1669
0
    return( -1 );
1670
0
  }
1671
0
  if( *utf16_string_index >= utf16_string_size )
1672
0
  {
1673
0
    libcerror_error_set(
1674
0
     error,
1675
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1676
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1677
0
     "%s: invalid UTF-16 string index value out of bounds.",
1678
0
     function );
1679
1680
0
    return( -1 );
1681
0
  }
1682
0
  safe_utf16_string_index = *utf16_string_index;
1683
1684
0
  if( ( integer_value_size != 8 )
1685
0
   && ( integer_value_size != 16 )
1686
0
   && ( integer_value_size != 32 )
1687
0
   && ( integer_value_size != 64 ) )
1688
0
  {
1689
0
    libcerror_error_set(
1690
0
     error,
1691
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1692
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1693
0
     "%s: unsupported integer value size.",
1694
0
     function );
1695
1696
0
    return( -1 );
1697
0
  }
1698
0
  supported_flags = 0x000000ffUL
1699
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED
1700
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED
1701
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR;
1702
1703
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1704
0
  {
1705
0
    libcerror_error_set(
1706
0
     error,
1707
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1708
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1709
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1710
0
     function,
1711
0
     string_format_flags );
1712
1713
0
    return( -1 );
1714
0
  }
1715
0
  string_format_type = string_format_flags & 0x000000ffUL;
1716
1717
0
  if( ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL )
1718
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1719
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN ) )
1720
0
  {
1721
0
    libcerror_error_set(
1722
0
     error,
1723
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1724
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1725
0
     "%s: unsupported string format type.",
1726
0
     function );
1727
1728
0
    return( -1 );
1729
0
  }
1730
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
1731
0
  {
1732
0
    if( integer_value == 0 )
1733
0
    {
1734
0
      number_of_characters = 6;
1735
0
    }
1736
0
    else
1737
0
    {
1738
0
      number_of_characters = 5;
1739
0
    }
1740
0
  }
1741
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1742
0
  {
1743
0
    number_of_characters = (uint8_t) ( integer_value_size >> 2 ) + 1;
1744
1745
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
1746
0
    {
1747
0
      number_of_characters += 2;
1748
0
    }
1749
0
  }
1750
0
  else
1751
0
  {
1752
    /* The string is at least a single digit with an end of string character
1753
     */
1754
0
    number_of_characters = 2;
1755
1756
0
    bit_shift = (uint8_t) ( integer_value_size - 1 );
1757
1758
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED ) != 0 )
1759
0
    {
1760
0
      is_signed = (uint8_t) ( integer_value >> bit_shift );
1761
1762
0
      if( is_signed != 0 )
1763
0
      {
1764
0
        number_of_characters += 1;
1765
1766
0
        integer_value &= ~( (uint64_t) 1 << bit_shift );
1767
1768
0
        if( integer_value == 0 )
1769
0
        {
1770
0
          integer_value |= (uint64_t) 1 << bit_shift;
1771
0
        }
1772
0
      }
1773
0
    }
1774
0
    divider = 1;
1775
1776
0
    while( ( integer_value / divider ) >= 10 )
1777
0
    {
1778
0
      divider *= 10;
1779
1780
0
      number_of_characters += 1;
1781
0
    }
1782
0
  }
1783
0
  if( ( number_of_characters > utf16_string_size )
1784
0
   || ( safe_utf16_string_index > ( utf16_string_size - number_of_characters ) ) )
1785
0
  {
1786
0
    libcerror_error_set(
1787
0
     error,
1788
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1789
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1790
0
     "%s: UTF-16 string size too small.",
1791
0
     function );
1792
1793
0
    return( -1 );
1794
0
  }
1795
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
1796
0
  {
1797
0
    if( integer_value == 0 )
1798
0
    {
1799
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'f';
1800
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'a';
1801
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'l';
1802
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 's';
1803
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'e';
1804
0
    }
1805
0
    else
1806
0
    {
1807
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 't';
1808
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'r';
1809
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'u';
1810
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'e';
1811
0
    }
1812
0
  }
1813
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
1814
0
  {
1815
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
1816
0
    {
1817
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0';
1818
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'x';
1819
0
    }
1820
0
    bit_shift = (uint8_t) ( integer_value_size - 4 );
1821
1822
0
    do
1823
0
    {
1824
0
      byte_value = (uint16_t) ( ( integer_value >> bit_shift ) & 0x0f );
1825
1826
0
      if( byte_value <= 9 )
1827
0
      {
1828
0
        utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0' + byte_value;
1829
0
      }
1830
0
      else
1831
0
      {
1832
0
        utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1833
0
      }
1834
0
      bit_shift -= 4;
1835
0
    }
1836
0
    while( bit_shift >= 0 );
1837
0
  }
1838
0
  else
1839
0
  {
1840
0
    if( is_signed != 0 )
1841
0
    {
1842
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '-';
1843
0
    }
1844
0
    while( divider > 1 )
1845
0
    {
1846
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0' + (uint16_t) ( integer_value / divider );
1847
1848
0
      integer_value %= divider;
1849
1850
0
      divider /= 10;
1851
0
    }
1852
0
    utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0' + (uint16_t) ( integer_value / divider );
1853
0
  }
1854
0
  utf16_string[ safe_utf16_string_index++ ] = 0;
1855
1856
0
  *utf16_string_index = safe_utf16_string_index;
1857
1858
0
  return( 1 );
1859
0
}
1860
1861
/* Copies an UTF-16 encoded string to an integer value
1862
 * The integer value size is in bits
1863
 * Returns 1 if successful or -1 on error
1864
 */
1865
int libfvalue_utf16_string_copy_to_integer(
1866
     const uint16_t *utf16_string,
1867
     size_t utf16_string_length,
1868
     uint64_t *integer_value,
1869
     size_t integer_value_size,
1870
     uint32_t string_format_flags,
1871
     libcerror_error_t **error )
1872
0
{
1873
0
  static char *function     = "libfvalue_utf16_string_copy_to_integer";
1874
0
  size_t utf16_string_index = 0;
1875
1876
0
  if( libfvalue_utf16_string_with_index_copy_to_integer(
1877
0
       utf16_string,
1878
0
       utf16_string_length,
1879
0
       &utf16_string_index,
1880
0
       integer_value,
1881
0
       integer_value_size,
1882
0
       string_format_flags,
1883
0
       error ) != 1 )
1884
0
  {
1885
0
    libcerror_error_set(
1886
0
     error,
1887
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1888
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1889
0
     "%s: unable to copy UTF-16 string to integer value.",
1890
0
     function );
1891
1892
0
    return( -1 );
1893
0
  }
1894
0
  return( 1 );
1895
0
}
1896
1897
/* Copies an UTF-16 encoded string to an integer value
1898
 * The integer value size is in bits
1899
 * Returns 1 if successful or -1 on error
1900
 */
1901
int libfvalue_utf16_string_with_index_copy_to_integer(
1902
     const uint16_t *utf16_string,
1903
     size_t utf16_string_length,
1904
     size_t *utf16_string_index,
1905
     uint64_t *integer_value,
1906
     size_t integer_value_size,
1907
     uint32_t string_format_flags,
1908
     libcerror_error_t **error )
1909
0
{
1910
0
  static char *function          = "libfvalue_utf16_string_with_index_copy_to_integer";
1911
0
  size_t maximum_string_index    = 0;
1912
0
  size_t safe_utf16_string_index = 0;
1913
0
  uint64_t divider               = 0;
1914
0
  uint64_t value_64bit           = 0;
1915
0
  uint32_t string_format_type    = 0;
1916
0
  uint32_t supported_flags       = 0;
1917
0
  uint16_t character_value       = 0;
1918
0
  uint8_t byte_value             = 0;
1919
0
  int8_t bit_shift               = 0;
1920
0
  int8_t sign                    = 1;
1921
1922
0
  if( utf16_string == NULL )
1923
0
  {
1924
0
    libcerror_error_set(
1925
0
     error,
1926
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1927
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1928
0
     "%s: invalid UTF-16 string.",
1929
0
     function );
1930
1931
0
    return( -1 );
1932
0
  }
1933
0
  if( utf16_string_length > (size_t) SSIZE_MAX )
1934
0
  {
1935
0
    libcerror_error_set(
1936
0
     error,
1937
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1938
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1939
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
1940
0
     function );
1941
1942
0
    return( -1 );
1943
0
  }
1944
0
  if( utf16_string_index == NULL )
1945
0
  {
1946
0
    libcerror_error_set(
1947
0
     error,
1948
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1949
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1950
0
     "%s: invalid UTF-16 string index.",
1951
0
     function );
1952
1953
0
    return( -1 );
1954
0
  }
1955
0
  if( *utf16_string_index >= utf16_string_length )
1956
0
  {
1957
0
    libcerror_error_set(
1958
0
     error,
1959
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1960
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1961
0
     "%s: invalid UTF-16 string index value out of bounds.",
1962
0
     function );
1963
1964
0
    return( -1 );
1965
0
  }
1966
0
  safe_utf16_string_index = *utf16_string_index;
1967
1968
0
  if( integer_value == NULL )
1969
0
  {
1970
0
    libcerror_error_set(
1971
0
     error,
1972
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1973
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1974
0
     "%s: invalid integer value.",
1975
0
     function );
1976
1977
0
    return( -1 );
1978
0
  }
1979
0
  if( ( integer_value_size != 8 )
1980
0
   && ( integer_value_size != 16 )
1981
0
   && ( integer_value_size != 32 )
1982
0
   && ( integer_value_size != 64 ) )
1983
0
  {
1984
0
    libcerror_error_set(
1985
0
     error,
1986
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1987
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1988
0
     "%s: unsupported integer value size.",
1989
0
     function );
1990
1991
0
    return( -1 );
1992
0
  }
1993
0
  supported_flags = 0x000000ffUL
1994
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED
1995
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED
1996
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR;
1997
1998
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1999
0
  {
2000
0
    libcerror_error_set(
2001
0
     error,
2002
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2003
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2004
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
2005
0
     function,
2006
0
     string_format_flags );
2007
2008
0
    return( -1 );
2009
0
  }
2010
0
  string_format_type = string_format_flags & 0x000000ffUL;
2011
2012
0
  if( ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL )
2013
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2014
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN ) )
2015
0
  {
2016
0
    libcerror_error_set(
2017
0
     error,
2018
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2019
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2020
0
     "%s: unsupported string format type.",
2021
0
     function );
2022
2023
0
    return( -1 );
2024
0
  }
2025
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
2026
0
  {
2027
0
    if( integer_value == 0 )
2028
0
    {
2029
0
      maximum_string_index = 5;
2030
0
    }
2031
0
    else
2032
0
    {
2033
0
      maximum_string_index = 4;
2034
0
    }
2035
0
  }
2036
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2037
0
  {
2038
0
    maximum_string_index = (size_t) ( integer_value_size >> 2 );
2039
2040
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
2041
0
    {
2042
0
      maximum_string_index += 2;
2043
0
    }
2044
0
  }
2045
0
  else
2046
0
  {
2047
    /* The string is at least a single digit with an end of string character
2048
     */
2049
0
    maximum_string_index = 2;
2050
2051
0
    bit_shift = (uint8_t) ( integer_value_size - 1 );
2052
2053
0
    divider = 1;
2054
2055
0
    value_64bit = ~( ( ~( (uint64_t) 1 << bit_shift ) >> bit_shift ) << bit_shift );
2056
2057
0
    while( ( value_64bit / divider ) >= 10 )
2058
0
    {
2059
0
      divider *= 10;
2060
2061
0
      maximum_string_index += 1;
2062
0
    }
2063
0
  }
2064
0
  maximum_string_index += safe_utf16_string_index;
2065
2066
0
  if( maximum_string_index > (size_t) SSIZE_MAX )
2067
0
  {
2068
0
    libcerror_error_set(
2069
0
     error,
2070
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2071
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
2072
0
     "%s: invalid maximum string index value exceeds maximum.",
2073
0
     function );
2074
2075
0
    return( -1 );
2076
0
  }
2077
0
  value_64bit = 0;
2078
2079
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
2080
0
  {
2081
/* TODO */
2082
0
  }
2083
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2084
0
  {
2085
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
2086
0
    {
2087
0
      character_value = utf16_string[ safe_utf16_string_index++ ];
2088
2089
0
      if( character_value != (uint16_t) '0' )
2090
0
      {
2091
0
        libcerror_error_set(
2092
0
         error,
2093
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2094
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2095
0
         "%s: unsupported character value: 0x04%" PRIx16 " at index: %d.",
2096
0
         function,
2097
0
         character_value,
2098
0
         safe_utf16_string_index );
2099
2100
0
        return( -1 );
2101
0
      }
2102
0
      character_value = utf16_string[ safe_utf16_string_index++ ];
2103
2104
0
      if( character_value != (uint16_t) 'x' )
2105
0
      {
2106
0
        libcerror_error_set(
2107
0
         error,
2108
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2109
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2110
0
         "%s: unsupported character value: 0x04%" PRIx16 " at index: %d.",
2111
0
         function,
2112
0
         character_value,
2113
0
         safe_utf16_string_index );
2114
2115
0
        return( -1 );
2116
0
      }
2117
0
    }
2118
0
    while( safe_utf16_string_index < utf16_string_length )
2119
0
    {
2120
0
      character_value = utf16_string[ safe_utf16_string_index ];
2121
2122
0
      if( character_value == 0 )
2123
0
      {
2124
0
        break;
2125
0
      }
2126
0
      if( safe_utf16_string_index > (size_t) maximum_string_index )
2127
0
      {
2128
0
        libcerror_error_set(
2129
0
         error,
2130
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2131
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE,
2132
0
         "%s: string too large.",
2133
0
         function );
2134
2135
0
        return( -1 );
2136
0
      }
2137
0
      value_64bit <<= 4;
2138
2139
0
      if( ( character_value >= (uint16_t) '0' )
2140
0
       && ( character_value <= (uint16_t) '9' ) )
2141
0
      {
2142
0
        byte_value = (uint8_t) ( character_value - (uint16_t) '0' );
2143
0
      }
2144
0
      else if( ( character_value >= (uint16_t) 'A' )
2145
0
            && ( character_value <= (uint16_t) 'F' ) )
2146
0
      {
2147
0
        byte_value = (uint8_t) ( character_value - (uint16_t) 'A' + 10 );
2148
0
      }
2149
0
      else if( ( character_value >= (uint16_t) 'a' )
2150
0
            && ( character_value <= (uint16_t) 'f' ) )
2151
0
      {
2152
0
        byte_value = (uint8_t) ( character_value - (uint16_t) 'a' + 10 );
2153
0
      }
2154
0
      else
2155
0
      {
2156
0
        libcerror_error_set(
2157
0
         error,
2158
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2159
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2160
0
         "%s: unsupported character value: 0x04%" PRIx16 " at index: %d.",
2161
0
         function,
2162
0
         character_value,
2163
0
         safe_utf16_string_index );
2164
2165
0
        return( -1 );
2166
0
      }
2167
0
      value_64bit += byte_value;
2168
2169
0
      safe_utf16_string_index++;
2170
0
    }
2171
0
  }
2172
0
  else
2173
0
  {
2174
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED ) != 0 )
2175
0
    {
2176
0
      character_value = utf16_string[ safe_utf16_string_index ];
2177
2178
      /* In the maximum possible string one character is substituted for the sign
2179
       */
2180
0
      if( character_value == (uint16_t) '-' )
2181
0
      {
2182
0
        safe_utf16_string_index++;
2183
2184
0
        sign = -1;
2185
0
      }
2186
0
      else if( character_value == (uint16_t) '+' )
2187
0
      {
2188
0
        safe_utf16_string_index++;
2189
0
      }
2190
0
    }
2191
0
    while( safe_utf16_string_index < utf16_string_length )
2192
0
    {
2193
0
      character_value = utf16_string[ safe_utf16_string_index ];
2194
2195
0
      if( character_value == 0 )
2196
0
      {
2197
0
        break;
2198
0
      }
2199
0
      if( safe_utf16_string_index > (size_t) maximum_string_index )
2200
0
      {
2201
0
        libcerror_error_set(
2202
0
         error,
2203
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2204
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE,
2205
0
         "%s: string too large.",
2206
0
         function );
2207
2208
0
        return( -1 );
2209
0
      }
2210
0
      value_64bit *= 10;
2211
2212
0
      if( ( character_value < (uint16_t) '0' )
2213
0
       || ( character_value > (uint16_t) '9' ) )
2214
0
      {
2215
0
        libcerror_error_set(
2216
0
         error,
2217
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2218
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2219
0
         "%s: unsupported character value: 0x04%" PRIx16 " at index: %d.",
2220
0
         function,
2221
0
         character_value,
2222
0
         safe_utf16_string_index );
2223
2224
0
        return( -1 );
2225
0
      }
2226
0
      character_value = (uint8_t) ( character_value - (uint16_t) '0' );
2227
2228
0
      value_64bit += character_value;
2229
2230
0
      safe_utf16_string_index++;
2231
0
    }
2232
0
    if( ( sign == -1 )
2233
0
     && ( value_64bit != 0 ) )
2234
0
    {
2235
0
      value_64bit = ~( value_64bit - 1 );
2236
0
    }
2237
0
  }
2238
0
  *utf16_string_index = safe_utf16_string_index;
2239
0
  *integer_value      = value_64bit;
2240
2241
0
  return( 1 );
2242
0
}
2243
2244
/* Copies an UTF-32 encoded string of an integer value
2245
 * The integer value size is in bits
2246
 * Returns 1 if successful or -1 on error
2247
 */
2248
int libfvalue_utf32_string_copy_from_integer(
2249
     uint32_t *utf32_string,
2250
     size_t utf32_string_size,
2251
     uint64_t integer_value,
2252
     size_t integer_value_size,
2253
     uint32_t string_format_flags,
2254
     libcerror_error_t **error )
2255
0
{
2256
0
  static char *function     = "libfvalue_utf32_string_copy_from_integer";
2257
0
  size_t utf32_string_index = 0;
2258
2259
0
  if( libfvalue_utf32_string_with_index_copy_from_integer(
2260
0
       utf32_string,
2261
0
       utf32_string_size,
2262
0
       &utf32_string_index,
2263
0
       integer_value,
2264
0
       integer_value_size,
2265
0
       string_format_flags,
2266
0
       error ) != 1 )
2267
0
  {
2268
0
    libcerror_error_set(
2269
0
     error,
2270
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2271
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2272
0
     "%s: unable to copy integer value to UTF-32 string.",
2273
0
     function );
2274
2275
0
    return( -1 );
2276
0
  }
2277
0
  return( 1 );
2278
0
}
2279
2280
/* Copies an UTF-32 encoded string of an integer value
2281
 * The integer value size is in bits
2282
 * Returns 1 if successful or -1 on error
2283
 */
2284
int libfvalue_utf32_string_with_index_copy_from_integer(
2285
     uint32_t *utf32_string,
2286
     size_t utf32_string_size,
2287
     size_t *utf32_string_index,
2288
     uint64_t integer_value,
2289
     size_t integer_value_size,
2290
     uint32_t string_format_flags,
2291
     libcerror_error_t **error )
2292
0
{
2293
0
  static char *function          = "libfvalue_utf32_string_with_index_copy_from_integer";
2294
0
  size_t safe_utf32_string_index = 0;
2295
0
  uint64_t divider               = 0;
2296
0
  uint32_t string_format_type    = 0;
2297
0
  uint32_t supported_flags       = 0;
2298
0
  uint8_t byte_value             = 0;
2299
0
  uint8_t is_signed              = 0;
2300
0
  uint8_t number_of_characters   = 0;
2301
0
  int8_t bit_shift               = 0;
2302
2303
0
  if( utf32_string == NULL )
2304
0
  {
2305
0
    libcerror_error_set(
2306
0
     error,
2307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2309
0
     "%s: invalid UTF-32 string.",
2310
0
     function );
2311
2312
0
    return( -1 );
2313
0
  }
2314
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
2315
0
  {
2316
0
    libcerror_error_set(
2317
0
     error,
2318
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2319
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2320
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
2321
0
     function );
2322
2323
0
    return( -1 );
2324
0
  }
2325
0
  if( utf32_string_index == NULL )
2326
0
  {
2327
0
    libcerror_error_set(
2328
0
     error,
2329
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2330
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2331
0
     "%s: invalid UTF-32 string index.",
2332
0
     function );
2333
2334
0
    return( -1 );
2335
0
  }
2336
0
  if( *utf32_string_index >= utf32_string_size )
2337
0
  {
2338
0
    libcerror_error_set(
2339
0
     error,
2340
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2341
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2342
0
     "%s: invalid UTF-32 string index value out of bounds.",
2343
0
     function );
2344
2345
0
    return( -1 );
2346
0
  }
2347
0
  safe_utf32_string_index = *utf32_string_index;
2348
2349
0
  if( ( integer_value_size != 8 )
2350
0
   && ( integer_value_size != 16 )
2351
0
   && ( integer_value_size != 32 )
2352
0
   && ( integer_value_size != 64 ) )
2353
0
  {
2354
0
    libcerror_error_set(
2355
0
     error,
2356
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2357
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2358
0
     "%s: unsupported integer value size.",
2359
0
     function );
2360
2361
0
    return( -1 );
2362
0
  }
2363
0
  supported_flags = 0x000000ffUL
2364
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED
2365
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED
2366
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR;
2367
2368
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
2369
0
  {
2370
0
    libcerror_error_set(
2371
0
     error,
2372
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2373
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2374
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
2375
0
     function,
2376
0
     string_format_flags );
2377
2378
0
    return( -1 );
2379
0
  }
2380
0
  string_format_type = string_format_flags & 0x000000ffUL;
2381
2382
0
  if( ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL )
2383
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2384
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN ) )
2385
0
  {
2386
0
    libcerror_error_set(
2387
0
     error,
2388
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2389
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2390
0
     "%s: unsupported string format type.",
2391
0
     function );
2392
2393
0
    return( -1 );
2394
0
  }
2395
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
2396
0
  {
2397
0
    if( integer_value == 0 )
2398
0
    {
2399
0
      number_of_characters = 6;
2400
0
    }
2401
0
    else
2402
0
    {
2403
0
      number_of_characters = 5;
2404
0
    }
2405
0
  }
2406
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2407
0
  {
2408
0
    number_of_characters = (uint8_t) ( integer_value_size >> 2 ) + 1;
2409
2410
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
2411
0
    {
2412
0
      number_of_characters += 2;
2413
0
    }
2414
0
  }
2415
0
  else
2416
0
  {
2417
    /* The string is at least a single digit with an end of string character
2418
     */
2419
0
    number_of_characters = 2;
2420
2421
0
    bit_shift = (uint8_t) ( integer_value_size - 1 );
2422
2423
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED ) != 0 )
2424
0
    {
2425
0
      is_signed = (uint8_t) ( integer_value >> bit_shift );
2426
2427
0
      if( is_signed != 0 )
2428
0
      {
2429
0
        number_of_characters += 1;
2430
2431
0
        integer_value &= ~( (uint64_t) 1 << bit_shift );
2432
2433
0
        if( integer_value == 0 )
2434
0
        {
2435
0
          integer_value |= (uint64_t) 1 << bit_shift;
2436
0
        }
2437
0
      }
2438
0
    }
2439
0
    divider = 1;
2440
2441
0
    while( ( integer_value / divider ) >= 10 )
2442
0
    {
2443
0
      divider *= 10;
2444
2445
0
      number_of_characters += 1;
2446
0
    }
2447
0
  }
2448
0
  if( ( number_of_characters > utf32_string_size )
2449
0
   || ( safe_utf32_string_index > ( utf32_string_size - number_of_characters ) ) )
2450
0
  {
2451
0
    libcerror_error_set(
2452
0
     error,
2453
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2454
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2455
0
     "%s: UTF-32 string size too small.",
2456
0
     function );
2457
2458
0
    return( -1 );
2459
0
  }
2460
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
2461
0
  {
2462
0
    if( integer_value == 0 )
2463
0
    {
2464
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'f';
2465
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'a';
2466
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'l';
2467
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 's';
2468
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'e';
2469
0
    }
2470
0
    else
2471
0
    {
2472
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 't';
2473
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'r';
2474
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'u';
2475
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'e';
2476
0
    }
2477
0
  }
2478
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2479
0
  {
2480
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
2481
0
    {
2482
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) '0';
2483
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'x';
2484
0
    }
2485
0
    bit_shift = (uint8_t) ( integer_value_size - 4 );
2486
2487
0
    do
2488
0
    {
2489
0
      byte_value = (uint32_t) ( ( integer_value >> bit_shift ) & 0x0f );
2490
2491
0
      if( byte_value <= 9 )
2492
0
      {
2493
0
        utf32_string[ safe_utf32_string_index++ ] = (uint32_t) '0' + byte_value;
2494
0
      }
2495
0
      else
2496
0
      {
2497
0
        utf32_string[ safe_utf32_string_index++ ] = (uint32_t) 'a' + byte_value - 10;
2498
0
      }
2499
0
      bit_shift -= 4;
2500
0
    }
2501
0
    while( bit_shift >= 0 );
2502
0
  }
2503
0
  else
2504
0
  {
2505
0
    if( is_signed != 0 )
2506
0
    {
2507
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) '-';
2508
0
    }
2509
0
    while( divider > 1 )
2510
0
    {
2511
0
      utf32_string[ safe_utf32_string_index++ ] = (uint32_t) '0' + (uint32_t) ( integer_value / divider );
2512
2513
0
      integer_value %= divider;
2514
2515
0
      divider /= 10;
2516
0
    }
2517
0
    utf32_string[ safe_utf32_string_index++ ] = (uint32_t) '0' + (uint32_t) ( integer_value / divider );
2518
0
  }
2519
0
  utf32_string[ safe_utf32_string_index++ ] = 0;
2520
2521
0
  *utf32_string_index = safe_utf32_string_index;
2522
2523
0
  return( 1 );
2524
0
}
2525
2526
/* Copies an UTF-32 encoded string to an integer value
2527
 * The integer value size is in bits
2528
 * Returns 1 if successful or -1 on error
2529
 */
2530
int libfvalue_utf32_string_copy_to_integer(
2531
     const uint32_t *utf32_string,
2532
     size_t utf32_string_length,
2533
     uint64_t *integer_value,
2534
     size_t integer_value_size,
2535
     uint32_t string_format_flags,
2536
     libcerror_error_t **error )
2537
0
{
2538
0
  static char *function     = "libfvalue_utf32_string_copy_to_integer";
2539
0
  size_t utf32_string_index = 0;
2540
2541
0
  if( libfvalue_utf32_string_with_index_copy_to_integer(
2542
0
       utf32_string,
2543
0
       utf32_string_length,
2544
0
       &utf32_string_index,
2545
0
       integer_value,
2546
0
       integer_value_size,
2547
0
       string_format_flags,
2548
0
       error ) != 1 )
2549
0
  {
2550
0
    libcerror_error_set(
2551
0
     error,
2552
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2553
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2554
0
     "%s: unable to copy UTF-32 string to integer value.",
2555
0
     function );
2556
2557
0
    return( -1 );
2558
0
  }
2559
0
  return( 1 );
2560
0
}
2561
2562
/* Copies an UTF-32 encoded string to an integer value
2563
 * The integer value size is in bits
2564
 * Returns 1 if successful or -1 on error
2565
 */
2566
int libfvalue_utf32_string_with_index_copy_to_integer(
2567
     const uint32_t *utf32_string,
2568
     size_t utf32_string_length,
2569
     size_t *utf32_string_index,
2570
     uint64_t *integer_value,
2571
     size_t integer_value_size,
2572
     uint32_t string_format_flags,
2573
     libcerror_error_t **error )
2574
0
{
2575
0
  static char *function          = "libfvalue_utf32_string_with_index_copy_to_integer";
2576
0
  size_t maximum_string_index    = 0;
2577
0
  size_t safe_utf32_string_index = 0;
2578
0
  uint64_t divider               = 0;
2579
0
  uint64_t value_64bit           = 0;
2580
0
  uint32_t character_value       = 0;
2581
0
  uint32_t string_format_type    = 0;
2582
0
  uint32_t supported_flags       = 0;
2583
0
  uint8_t byte_value             = 0;
2584
0
  int8_t bit_shift               = 0;
2585
0
  int8_t sign                    = 1;
2586
2587
0
  if( utf32_string == NULL )
2588
0
  {
2589
0
    libcerror_error_set(
2590
0
     error,
2591
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2592
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2593
0
     "%s: invalid UTF-32 string.",
2594
0
     function );
2595
2596
0
    return( -1 );
2597
0
  }
2598
0
  if( utf32_string_length > (size_t) SSIZE_MAX )
2599
0
  {
2600
0
    libcerror_error_set(
2601
0
     error,
2602
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2603
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2604
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
2605
0
     function );
2606
2607
0
    return( -1 );
2608
0
  }
2609
0
  if( utf32_string_index == NULL )
2610
0
  {
2611
0
    libcerror_error_set(
2612
0
     error,
2613
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2614
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2615
0
     "%s: invalid UTF-32 string index.",
2616
0
     function );
2617
2618
0
    return( -1 );
2619
0
  }
2620
0
  if( *utf32_string_index >= utf32_string_length )
2621
0
  {
2622
0
    libcerror_error_set(
2623
0
     error,
2624
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2625
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2626
0
     "%s: invalid UTF-32 string index value out of bounds.",
2627
0
     function );
2628
2629
0
    return( -1 );
2630
0
  }
2631
0
  safe_utf32_string_index = *utf32_string_index;
2632
2633
0
  if( integer_value == NULL )
2634
0
  {
2635
0
    libcerror_error_set(
2636
0
     error,
2637
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2638
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2639
0
     "%s: invalid integer value.",
2640
0
     function );
2641
2642
0
    return( -1 );
2643
0
  }
2644
0
  if( ( integer_value_size != 8 )
2645
0
   && ( integer_value_size != 16 )
2646
0
   && ( integer_value_size != 32 )
2647
0
   && ( integer_value_size != 64 ) )
2648
0
  {
2649
0
    libcerror_error_set(
2650
0
     error,
2651
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2652
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2653
0
     "%s: unsupported integer value size.",
2654
0
     function );
2655
2656
0
    return( -1 );
2657
0
  }
2658
0
  supported_flags = 0x000000ffUL
2659
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED
2660
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED
2661
0
                  | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR;
2662
2663
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
2664
0
  {
2665
0
    libcerror_error_set(
2666
0
     error,
2667
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2668
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2669
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
2670
0
     function,
2671
0
     string_format_flags );
2672
2673
0
    return( -1 );
2674
0
  }
2675
0
  string_format_type = string_format_flags & 0x000000ffUL;
2676
2677
0
  if( ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL )
2678
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2679
0
   && ( string_format_type != LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN ) )
2680
0
  {
2681
0
    libcerror_error_set(
2682
0
     error,
2683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2684
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2685
0
     "%s: unsupported string format type.",
2686
0
     function );
2687
2688
0
    return( -1 );
2689
0
  }
2690
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
2691
0
  {
2692
0
    if( integer_value == 0 )
2693
0
    {
2694
0
      maximum_string_index = 5;
2695
0
    }
2696
0
    else
2697
0
    {
2698
0
      maximum_string_index = 4;
2699
0
    }
2700
0
  }
2701
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2702
0
  {
2703
0
    maximum_string_index = (size_t) ( integer_value_size >> 2 );
2704
2705
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
2706
0
    {
2707
0
      maximum_string_index += 2;
2708
0
    }
2709
0
  }
2710
0
  else
2711
0
  {
2712
    /* The string is at least a single digit with an end of string character
2713
     */
2714
0
    maximum_string_index = 2;
2715
2716
0
    bit_shift = (uint8_t) ( integer_value_size - 1 );
2717
2718
0
    divider = 1;
2719
2720
0
    value_64bit = ~( ( ~( (uint64_t) 1 << bit_shift ) >> bit_shift ) << bit_shift );
2721
2722
0
    while( ( value_64bit / divider ) >= 10 )
2723
0
    {
2724
0
      divider *= 10;
2725
2726
0
      maximum_string_index += 1;
2727
0
    }
2728
0
  }
2729
0
  maximum_string_index += safe_utf32_string_index;
2730
2731
0
  if( maximum_string_index > (size_t) SSIZE_MAX )
2732
0
  {
2733
0
    libcerror_error_set(
2734
0
     error,
2735
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2736
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
2737
0
     "%s: invalid maximum string index value exceeds maximum.",
2738
0
     function );
2739
2740
0
    return( -1 );
2741
0
  }
2742
0
  value_64bit = 0;
2743
2744
0
  if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN )
2745
0
  {
2746
/* TODO */
2747
0
  }
2748
0
  else if( string_format_type == LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL )
2749
0
  {
2750
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR ) == 0 )
2751
0
    {
2752
0
      character_value = utf32_string[ safe_utf32_string_index++ ];
2753
2754
0
      if( character_value != (uint32_t) '0' )
2755
0
      {
2756
0
        libcerror_error_set(
2757
0
         error,
2758
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2759
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2760
0
         "%s: unsupported character value: 0x08%" PRIx32 " at index: %d.",
2761
0
         function,
2762
0
         character_value,
2763
0
         safe_utf32_string_index );
2764
2765
0
        return( -1 );
2766
0
      }
2767
0
      character_value = utf32_string[ safe_utf32_string_index++ ];
2768
2769
0
      if( character_value != (uint32_t) 'x' )
2770
0
      {
2771
0
        libcerror_error_set(
2772
0
         error,
2773
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2774
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2775
0
         "%s: unsupported character value: 0x08%" PRIx32 " at index: %d.",
2776
0
         function,
2777
0
         character_value,
2778
0
         safe_utf32_string_index );
2779
2780
0
        return( -1 );
2781
0
      }
2782
0
    }
2783
0
    while( safe_utf32_string_index < utf32_string_length )
2784
0
    {
2785
0
      character_value = utf32_string[ safe_utf32_string_index ];
2786
2787
0
      if( character_value == 0 )
2788
0
      {
2789
0
        break;
2790
0
      }
2791
0
      if( safe_utf32_string_index > (size_t) maximum_string_index )
2792
0
      {
2793
0
        libcerror_error_set(
2794
0
         error,
2795
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2796
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE,
2797
0
         "%s: string too large.",
2798
0
         function );
2799
2800
0
        return( -1 );
2801
0
      }
2802
0
      value_64bit <<= 4;
2803
2804
0
      if( ( character_value >= (uint32_t) '0' )
2805
0
       && ( character_value <= (uint32_t) '9' ) )
2806
0
      {
2807
0
        byte_value = (uint8_t) ( character_value - (uint32_t) '0' );
2808
0
      }
2809
0
      else if( ( character_value >= (uint32_t) 'A' )
2810
0
            && ( character_value <= (uint32_t) 'F' ) )
2811
0
      {
2812
0
        byte_value = (uint8_t) ( character_value - (uint32_t) 'A' + 10 );
2813
0
      }
2814
0
      else if( ( character_value >= (uint32_t) 'a' )
2815
0
            && ( character_value <= (uint32_t) 'f' ) )
2816
0
      {
2817
0
        byte_value = (uint8_t) ( character_value - (uint32_t) 'a' + 10 );
2818
0
      }
2819
0
      else
2820
0
      {
2821
0
        libcerror_error_set(
2822
0
         error,
2823
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2824
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2825
0
         "%s: unsupported character value: 0x08%" PRIx32 " at index: %d.",
2826
0
         function,
2827
0
         character_value,
2828
0
         safe_utf32_string_index );
2829
2830
0
        return( -1 );
2831
0
      }
2832
0
      value_64bit += byte_value;
2833
2834
0
      safe_utf32_string_index++;
2835
0
    }
2836
0
  }
2837
0
  else
2838
0
  {
2839
0
    if( ( string_format_flags & LIBFVALUE_INTEGER_FORMAT_FLAG_SIGNED ) != 0 )
2840
0
    {
2841
0
      character_value = utf32_string[ safe_utf32_string_index ];
2842
2843
      /* In the maximum possible string one character is substituted for the sign
2844
       */
2845
0
      if( character_value == (uint32_t) '-' )
2846
0
      {
2847
0
        safe_utf32_string_index++;
2848
2849
0
        sign = -1;
2850
0
      }
2851
0
      else if( character_value == (uint32_t) '+' )
2852
0
      {
2853
0
        safe_utf32_string_index++;
2854
0
      }
2855
0
    }
2856
0
    while( safe_utf32_string_index < utf32_string_length )
2857
0
    {
2858
0
      character_value = utf32_string[ safe_utf32_string_index ];
2859
2860
0
      if( character_value == 0 )
2861
0
      {
2862
0
        break;
2863
0
      }
2864
0
      if( safe_utf32_string_index > (size_t) maximum_string_index )
2865
0
      {
2866
0
        libcerror_error_set(
2867
0
         error,
2868
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2869
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE,
2870
0
         "%s: string too large.",
2871
0
         function );
2872
2873
0
        return( -1 );
2874
0
      }
2875
0
      value_64bit *= 10;
2876
2877
0
      if( ( character_value < (uint32_t) '0' )
2878
0
       || ( character_value > (uint32_t) '9' ) )
2879
0
      {
2880
0
        libcerror_error_set(
2881
0
         error,
2882
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2883
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2884
0
         "%s: unsupported character value: 0x08%" PRIx32 " at index: %d.",
2885
0
         function,
2886
0
         character_value,
2887
0
         safe_utf32_string_index );
2888
2889
0
        return( -1 );
2890
0
      }
2891
0
      character_value = (uint8_t) ( character_value - (uint32_t) '0' );
2892
2893
0
      value_64bit += character_value;
2894
2895
0
      safe_utf32_string_index++;
2896
0
    }
2897
0
    if( ( sign == -1 )
2898
0
     && ( value_64bit != 0 ) )
2899
0
    {
2900
0
      value_64bit = ~( value_64bit - 1 );
2901
0
    }
2902
0
  }
2903
0
  *utf32_string_index = safe_utf32_string_index;
2904
0
  *integer_value      = value_64bit;
2905
2906
0
  return( 1 );
2907
0
}
2908