Coverage Report

Created: 2024-02-25 07:20

/src/libscca/libuna/libuna_utf8_stream.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * UTF-8 stream functions
3
 *
4
 * Copyright (C) 2008-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libuna_definitions.h"
27
#include "libuna_libcerror.h"
28
#include "libuna_types.h"
29
#include "libuna_unicode_character.h"
30
#include "libuna_utf8_stream.h"
31
32
/* Copies an UTF-8 stream byte order mark (BOM)
33
 * Returns 1 if successful or -1 on error
34
 */
35
int libuna_utf8_stream_copy_byte_order_mark(
36
     uint8_t *utf8_stream,
37
     size_t utf8_stream_size,
38
     size_t *utf8_stream_index,
39
     libcerror_error_t **error )
40
0
{
41
0
  static char *function = "libuna_utf8_stream_copy_byte_order_mark";
42
43
0
  if( utf8_stream == NULL )
44
0
  {
45
0
    libcerror_error_set(
46
0
     error,
47
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49
0
     "%s: invalid UTF-8 stream.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
0
  if( utf8_stream_size > (size_t) SSIZE_MAX )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
59
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
60
0
     "%s: invalid UTF-8 stream size value exceeds maximum.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
0
  if( utf8_stream_index == NULL )
66
0
  {
67
0
    libcerror_error_set(
68
0
     error,
69
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
70
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
71
0
     "%s: invalid UTF-8 stream index.",
72
0
     function );
73
74
0
    return( -1 );
75
0
  }
76
0
  if( ( *utf8_stream_index + 3 ) > utf8_stream_size )
77
0
  {
78
0
    libcerror_error_set(
79
0
     error,
80
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
81
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
82
0
     "%s: UTF-8 stream too small.",
83
0
     function );
84
85
0
    return( -1 );
86
0
  }
87
0
  utf8_stream[ *utf8_stream_index     ] = 0xef;
88
0
  utf8_stream[ *utf8_stream_index + 1 ] = 0xbb;
89
0
  utf8_stream[ *utf8_stream_index + 2 ] = 0xbf;
90
91
0
  *utf8_stream_index += 3;
92
93
0
  return( 1 );
94
0
}
95
96
/* Determines the size of an UTF-8 stream from an UTF-8 string
97
 * Returns 1 if successful or -1 on error
98
 */
99
int libuna_utf8_stream_size_from_utf8(
100
     const libuna_utf8_character_t *utf8_string,
101
     size_t utf8_string_size,
102
     size_t *utf8_stream_size,
103
     libcerror_error_t **error )
104
0
{
105
0
  static char *function                        = "libuna_utf8_stream_size_from_utf8";
106
0
  libuna_unicode_character_t unicode_character = 0;
107
0
  size_t utf8_string_index                     = 0;
108
109
0
  if( utf8_string == NULL )
110
0
  {
111
0
    libcerror_error_set(
112
0
     error,
113
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
114
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
115
0
     "%s: invalid UTF-8 string.",
116
0
     function );
117
118
0
    return( -1 );
119
0
  }
120
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
121
0
  {
122
0
    libcerror_error_set(
123
0
     error,
124
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
125
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
126
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
127
0
     function );
128
129
0
    return( -1 );
130
0
  }
131
0
  if( utf8_stream_size == NULL )
132
0
  {
133
0
    libcerror_error_set(
134
0
     error,
135
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
136
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
137
0
     "%s: invalid UTF-8 stream size.",
138
0
     function );
139
140
0
    return( -1 );
141
0
  }
142
  /* Add the byte order mark
143
   */
144
0
  *utf8_stream_size = 3;
145
146
0
  while( utf8_string_index < utf8_string_size )
147
0
  {
148
    /* Convert the UTF-8 character bytes into an Unicode character
149
     */
150
0
    if( libuna_unicode_character_copy_from_utf8(
151
0
         &unicode_character,
152
0
         utf8_string,
153
0
         utf8_string_size,
154
0
         &utf8_string_index,
155
0
         error ) != 1 )
156
0
    {
157
0
      libcerror_error_set(
158
0
       error,
159
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
160
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
161
0
       "%s: unable to copy Unicode character from UTF-8.",
162
0
       function );
163
164
0
      return( -1 );
165
0
    }
166
    /* Determine how many UTF-8 character bytes are required
167
     */
168
0
    if( libuna_unicode_character_size_to_utf8(
169
0
         unicode_character,
170
0
         utf8_stream_size,
171
0
         error ) != 1 )
172
0
    {
173
0
      libcerror_error_set(
174
0
       error,
175
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
176
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
177
0
       "%s: unable to determine size of Unicode character in UTF-8.",
178
0
       function );
179
180
0
      return( -1 );
181
0
    }
182
0
    if( unicode_character == 0 )
183
0
    {
184
0
      break;
185
0
    }
186
0
  }
187
0
  return( 1 );
188
0
}
189
190
/* Copies an UTF-8 stream from an UTF-8 string
191
 * Returns 1 if successful or -1 on error
192
 */
193
int libuna_utf8_stream_copy_from_utf8(
194
     uint8_t *utf8_stream,
195
     size_t utf8_stream_size,
196
     const libuna_utf8_character_t *utf8_string,
197
     size_t utf8_string_size,
198
     libcerror_error_t **error )
199
0
{
200
0
  static char *function                        = "libuna_utf8_stream_copy_from_utf8";
201
0
  libuna_unicode_character_t unicode_character = 0;
202
0
  size_t utf8_stream_index                     = 0;
203
0
  size_t utf8_string_index                     = 0;
204
205
0
  if( utf8_stream == NULL )
206
0
  {
207
0
    libcerror_error_set(
208
0
     error,
209
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
210
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
211
0
     "%s: invalid UTF-8 stream.",
212
0
     function );
213
214
0
    return( -1 );
215
0
  }
216
0
  if( utf8_stream_size > (size_t) SSIZE_MAX )
217
0
  {
218
0
    libcerror_error_set(
219
0
     error,
220
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
221
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
222
0
     "%s: invalid UTF-8 stream size value exceeds maximum.",
223
0
     function );
224
225
0
    return( -1 );
226
0
  }
227
0
  if( utf8_string == NULL )
228
0
  {
229
0
    libcerror_error_set(
230
0
     error,
231
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
232
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
233
0
     "%s: invalid UTF-8 string.",
234
0
     function );
235
236
0
    return( -1 );
237
0
  }
238
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
239
0
  {
240
0
    libcerror_error_set(
241
0
     error,
242
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
243
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
244
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
245
0
     function );
246
247
0
    return( -1 );
248
0
  }
249
0
  if( utf8_stream_size < utf8_string_size )
250
0
  {
251
0
    libcerror_error_set(
252
0
     error,
253
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
254
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
255
0
     "%s: UTF-8 stream is too small.",
256
0
     function );
257
258
0
    return( -1 );
259
0
  }
260
0
  if( libuna_utf8_stream_copy_byte_order_mark(
261
0
       utf8_stream,
262
0
       utf8_stream_size,
263
0
       &utf8_stream_index,
264
0
       error ) != 1 )
265
0
  {
266
0
    libcerror_error_set(
267
0
     error,
268
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
269
0
     LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
270
0
     "%s: unable to copy UTF-8 byte order mark.",
271
0
     function );
272
273
0
    return( -1 );
274
0
  }
275
0
  while( utf8_string_index < utf8_string_size )
276
0
  {
277
    /* Convert the UTF-8 string bytes into an Unicode character
278
     */
279
0
    if( libuna_unicode_character_copy_from_utf8(
280
0
         &unicode_character,
281
0
         utf8_string,
282
0
         utf8_string_size,
283
0
         &utf8_string_index,
284
0
         error ) != 1 )
285
0
    {
286
0
      libcerror_error_set(
287
0
       error,
288
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
289
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
290
0
       "%s: unable to copy Unicode character from UTF-8 string.",
291
0
       function );
292
293
0
      return( -1 );
294
0
    }
295
    /* Convert the Unicode character into UTF-8 stream bytes
296
     */
297
0
    if( libuna_unicode_character_copy_to_utf8(
298
0
         unicode_character,
299
0
         utf8_stream,
300
0
         utf8_stream_size,
301
0
         &utf8_stream_index,
302
0
         error ) != 1 )
303
0
    {
304
0
      libcerror_error_set(
305
0
       error,
306
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
307
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
308
0
       "%s: unable to copy Unicode character to UTF-8 stream.",
309
0
       function );
310
311
0
      return( -1 );
312
0
    }
313
0
    if( unicode_character == 0 )
314
0
    {
315
0
      break;
316
0
    }
317
0
  }
318
0
  return( 1 );
319
0
}
320
321
/* Determines the size of an UTF-8 stream from an UTF-16 string
322
 * Returns 1 if successful or -1 on error
323
 */
324
int libuna_utf8_stream_size_from_utf16(
325
     const libuna_utf16_character_t *utf16_string,
326
     size_t utf16_string_size,
327
     size_t *utf8_stream_size,
328
     libcerror_error_t **error )
329
0
{
330
0
  static char *function                        = "libuna_utf8_stream_size_from_utf16";
331
0
  libuna_unicode_character_t unicode_character = 0;
332
0
  size_t utf16_string_index                    = 0;
333
334
0
  if( utf16_string == NULL )
335
0
  {
336
0
    libcerror_error_set(
337
0
     error,
338
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
339
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
340
0
     "%s: invalid UTF-16 string.",
341
0
     function );
342
343
0
    return( -1 );
344
0
  }
345
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
346
0
  {
347
0
    libcerror_error_set(
348
0
     error,
349
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
350
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
351
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
352
0
     function );
353
354
0
    return( -1 );
355
0
  }
356
0
  if( utf8_stream_size == NULL )
357
0
  {
358
0
    libcerror_error_set(
359
0
     error,
360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
362
0
     "%s: invalid UTF-8 stream size.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
  /* Add the byte order mark
368
   */
369
0
  *utf8_stream_size = 3;
370
371
0
  while( utf16_string_index < utf16_string_size )
372
0
  {
373
    /* Convert the UTF-16 character bytes into an Unicode character
374
     */
375
0
    if( libuna_unicode_character_copy_from_utf16(
376
0
         &unicode_character,
377
0
         utf16_string,
378
0
         utf16_string_size,
379
0
         &utf16_string_index,
380
0
         error ) != 1 )
381
0
    {
382
0
      libcerror_error_set(
383
0
       error,
384
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
385
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
386
0
       "%s: unable to copy Unicode character from UTF-16.",
387
0
       function );
388
389
0
      return( -1 );
390
0
    }
391
    /* Determine how many UTF-8 character bytes are required
392
     */
393
0
    if( libuna_unicode_character_size_to_utf8(
394
0
         unicode_character,
395
0
         utf8_stream_size,
396
0
         error ) != 1 )
397
0
    {
398
0
      libcerror_error_set(
399
0
       error,
400
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
401
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
402
0
       "%s: unable to determine size of Unicode character in UTF-8.",
403
0
       function );
404
405
0
      return( -1 );
406
0
    }
407
0
    if( unicode_character == 0 )
408
0
    {
409
0
      break;
410
0
    }
411
0
  }
412
0
  return( 1 );
413
0
}
414
415
/* Copies an UTF-8 stream from an UTF-16 string
416
 * Returns 1 if successful or -1 on error
417
 */
418
int libuna_utf8_stream_copy_from_utf16(
419
     uint8_t *utf8_stream,
420
     size_t utf8_stream_size,
421
     const libuna_utf16_character_t *utf16_string,
422
     size_t utf16_string_size,
423
     libcerror_error_t **error )
424
0
{
425
0
  static char *function                        = "libuna_utf8_stream_copy_from_utf16";
426
0
  libuna_unicode_character_t unicode_character = 0;
427
0
  size_t utf16_string_index                    = 0;
428
0
  size_t utf8_stream_index                     = 0;
429
430
0
  if( utf8_stream == NULL )
431
0
  {
432
0
    libcerror_error_set(
433
0
     error,
434
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
435
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
436
0
     "%s: invalid UTF-8 stream.",
437
0
     function );
438
439
0
    return( -1 );
440
0
  }
441
0
  if( utf8_stream_size > (size_t) SSIZE_MAX )
442
0
  {
443
0
    libcerror_error_set(
444
0
     error,
445
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
446
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
447
0
     "%s: invalid UTF-8 stream size value exceeds maximum.",
448
0
     function );
449
450
0
    return( -1 );
451
0
  }
452
0
  if( utf16_string == NULL )
453
0
  {
454
0
    libcerror_error_set(
455
0
     error,
456
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
457
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
458
0
     "%s: invalid UTF-16 string.",
459
0
     function );
460
461
0
    return( -1 );
462
0
  }
463
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
464
0
  {
465
0
    libcerror_error_set(
466
0
     error,
467
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
468
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
469
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
470
0
     function );
471
472
0
    return( -1 );
473
0
  }
474
0
  if( libuna_utf8_stream_copy_byte_order_mark(
475
0
       utf8_stream,
476
0
       utf8_stream_size,
477
0
       &utf8_stream_index,
478
0
       error ) != 1 )
479
0
  {
480
0
    libcerror_error_set(
481
0
     error,
482
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
483
0
     LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
484
0
     "%s: unable to copy UTF-8 byte order mark.",
485
0
     function );
486
487
0
    return( -1 );
488
0
  }
489
0
  while( utf16_string_index < utf16_string_size )
490
0
  {
491
    /* Convert the UTF-16 string bytes into an Unicode character
492
     */
493
0
    if( libuna_unicode_character_copy_from_utf16(
494
0
         &unicode_character,
495
0
         utf16_string,
496
0
         utf16_string_size,
497
0
         &utf16_string_index,
498
0
         error ) != 1 )
499
0
    {
500
0
      libcerror_error_set(
501
0
       error,
502
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
503
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
504
0
       "%s: unable to copy Unicode character from UTF-16 string.",
505
0
       function );
506
507
0
      return( -1 );
508
0
    }
509
    /* Convert the Unicode character into UTF-8 stream bytes
510
     */
511
0
    if( libuna_unicode_character_copy_to_utf8(
512
0
         unicode_character,
513
0
         utf8_stream,
514
0
         utf8_stream_size,
515
0
         &utf8_stream_index,
516
0
         error ) != 1 )
517
0
    {
518
0
      libcerror_error_set(
519
0
       error,
520
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
521
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
522
0
       "%s: unable to copy Unicode character to UTF-8 stream.",
523
0
       function );
524
525
0
      return( -1 );
526
0
    }
527
0
    if( unicode_character == 0 )
528
0
    {
529
0
      break;
530
0
    }
531
0
  }
532
0
  return( 1 );
533
0
}
534
535
/* Determines the size of an UTF-8 stream from an UTF-32 string
536
 * Returns 1 if successful or -1 on error
537
 */
538
int libuna_utf8_stream_size_from_utf32(
539
     const libuna_utf32_character_t *utf32_string,
540
     size_t utf32_string_size,
541
     size_t *utf8_stream_size,
542
     libcerror_error_t **error )
543
0
{
544
0
  static char *function                        = "libuna_utf8_stream_size_from_utf32";
545
0
  libuna_unicode_character_t unicode_character = 0;
546
0
  size_t utf32_string_index                    = 0;
547
548
0
  if( utf32_string == NULL )
549
0
  {
550
0
    libcerror_error_set(
551
0
     error,
552
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
553
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
554
0
     "%s: invalid UTF-32 string.",
555
0
     function );
556
557
0
    return( -1 );
558
0
  }
559
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
560
0
  {
561
0
    libcerror_error_set(
562
0
     error,
563
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
564
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
565
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
566
0
     function );
567
568
0
    return( -1 );
569
0
  }
570
0
  if( utf8_stream_size == NULL )
571
0
  {
572
0
    libcerror_error_set(
573
0
     error,
574
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
575
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
576
0
     "%s: invalid UTF-8 stream size.",
577
0
     function );
578
579
0
    return( -1 );
580
0
  }
581
  /* Add the byte order mark
582
   */
583
0
  *utf8_stream_size = 3;
584
585
0
  while( utf32_string_index < utf32_string_size )
586
0
  {
587
    /* Convert the UTF-32 character bytes into an Unicode character
588
     */
589
0
    if( libuna_unicode_character_copy_from_utf32(
590
0
         &unicode_character,
591
0
         utf32_string,
592
0
         utf32_string_size,
593
0
         &utf32_string_index,
594
0
         error ) != 1 )
595
0
    {
596
0
      libcerror_error_set(
597
0
       error,
598
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
599
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
600
0
       "%s: unable to copy Unicode character from UTF-32.",
601
0
       function );
602
603
0
      return( -1 );
604
0
    }
605
    /* Determine how many UTF-8 character bytes are required
606
     */
607
0
    if( libuna_unicode_character_size_to_utf8(
608
0
         unicode_character,
609
0
         utf8_stream_size,
610
0
         error ) != 1 )
611
0
    {
612
0
      libcerror_error_set(
613
0
       error,
614
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
615
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
616
0
       "%s: unable to determine size of Unicode character in UTF-8.",
617
0
       function );
618
619
0
      return( -1 );
620
0
    }
621
0
    if( unicode_character == 0 )
622
0
    {
623
0
      break;
624
0
    }
625
0
  }
626
0
  return( 1 );
627
0
}
628
629
/* Copies an UTF-8 stream from an UTF-32 string
630
 * Returns 1 if successful or -1 on error
631
 */
632
int libuna_utf8_stream_copy_from_utf32(
633
     uint8_t *utf8_stream,
634
     size_t utf8_stream_size,
635
     const libuna_utf32_character_t *utf32_string,
636
     size_t utf32_string_size,
637
     libcerror_error_t **error )
638
0
{
639
0
  static char *function                        = "libuna_utf8_stream_copy_from_utf32";
640
0
  libuna_unicode_character_t unicode_character = 0;
641
0
  size_t utf32_string_index                    = 0;
642
0
  size_t utf8_stream_index                     = 0;
643
644
0
  if( utf8_stream == NULL )
645
0
  {
646
0
    libcerror_error_set(
647
0
     error,
648
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
649
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
650
0
     "%s: invalid UTF-8 stream.",
651
0
     function );
652
653
0
    return( -1 );
654
0
  }
655
0
  if( utf8_stream_size > (size_t) SSIZE_MAX )
656
0
  {
657
0
    libcerror_error_set(
658
0
     error,
659
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
660
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
661
0
     "%s: invalid UTF-8 stream size value exceeds maximum.",
662
0
     function );
663
664
0
    return( -1 );
665
0
  }
666
0
  if( utf32_string == NULL )
667
0
  {
668
0
    libcerror_error_set(
669
0
     error,
670
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
671
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
672
0
     "%s: invalid UTF-32 string.",
673
0
     function );
674
675
0
    return( -1 );
676
0
  }
677
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
678
0
  {
679
0
    libcerror_error_set(
680
0
     error,
681
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
682
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
683
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
684
0
     function );
685
686
0
    return( -1 );
687
0
  }
688
0
  if( libuna_utf8_stream_copy_byte_order_mark(
689
0
       utf8_stream,
690
0
       utf8_stream_size,
691
0
       &utf8_stream_index,
692
0
       error ) != 1 )
693
0
  {
694
0
    libcerror_error_set(
695
0
     error,
696
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
697
0
     LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
698
0
     "%s: unable to copy UTF-8 byte order mark.",
699
0
     function );
700
701
0
    return( -1 );
702
0
  }
703
0
  while( utf32_string_index < utf32_string_size )
704
0
  {
705
    /* Convert the UTF-32 character bytes into an Unicode character
706
     */
707
0
    if( libuna_unicode_character_copy_from_utf32(
708
0
         &unicode_character,
709
0
         utf32_string,
710
0
         utf32_string_size,
711
0
         &utf32_string_index,
712
0
         error ) != 1 )
713
0
    {
714
0
      libcerror_error_set(
715
0
       error,
716
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
717
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
718
0
       "%s: unable to copy Unicode character from UTF-32.",
719
0
       function );
720
721
0
      return( -1 );
722
0
    }
723
    /* Convert the Unicode character into UTF-8 character bytes
724
     */
725
0
    if( libuna_unicode_character_copy_to_utf8(
726
0
         unicode_character,
727
0
         utf8_stream,
728
0
         utf8_stream_size,
729
0
         &utf8_stream_index,
730
0
         error ) != 1 )
731
0
    {
732
0
      libcerror_error_set(
733
0
       error,
734
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
735
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
736
0
       "%s: unable to copy Unicode character to UTF-8 stream.",
737
0
       function );
738
739
0
      return( -1 );
740
0
    }
741
0
    if( unicode_character == 0 )
742
0
    {
743
0
      break;
744
0
    }
745
0
  }
746
0
  return( 1 );
747
0
}
748