Coverage Report

Created: 2024-02-25 07:20

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