Coverage Report

Created: 2026-07-10 07:32

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