Coverage Report

Created: 2024-02-25 07:19

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