Coverage Report

Created: 2024-02-25 07:20

/src/libwrc/libuna/libuna_utf32_stream.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * UTF-32 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 <types.h>
24
25
#include "libuna_definitions.h"
26
#include "libuna_libcerror.h"
27
#include "libuna_types.h"
28
#include "libuna_unicode_character.h"
29
#include "libuna_utf32_stream.h"
30
31
/* Copies an UTF-32 stream byte order mark (BOM)
32
 * Returns 1 if successful or -1 on error
33
 */
34
int libuna_utf32_stream_copy_byte_order_mark(
35
     uint8_t *utf32_stream,
36
     size_t utf32_stream_size,
37
     size_t *utf32_stream_index,
38
     int byte_order,
39
     libcerror_error_t **error )
40
0
{
41
0
  static char *function = "libuna_utf32_stream_copy_byte_order_mark";
42
43
0
  if( utf32_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-32 stream.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
0
  if( utf32_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-32 stream size value exceeds maximum.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
0
  if( utf32_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-32 stream index.",
72
0
     function );
73
74
0
    return( -1 );
75
0
  }
76
0
  if( ( *utf32_stream_index + 4 ) > utf32_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-32 stream too small.",
83
0
     function );
84
85
0
    return( -1 );
86
0
  }
87
0
  if( ( byte_order != LIBUNA_ENDIAN_BIG )
88
0
   && ( byte_order != LIBUNA_ENDIAN_LITTLE ) )
89
0
  {
90
0
    libcerror_error_set(
91
0
     error,
92
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
93
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
94
0
     "%s: unsupported byte order.",
95
0
     function );
96
97
0
    return( -1 );
98
0
  }
99
0
  if( byte_order == LIBUNA_ENDIAN_BIG )
100
0
  {
101
0
    utf32_stream[ *utf32_stream_index     ] = 0x00;
102
0
    utf32_stream[ *utf32_stream_index + 1 ] = 0x00;
103
0
    utf32_stream[ *utf32_stream_index + 2 ] = 0xfe;
104
0
    utf32_stream[ *utf32_stream_index + 3 ] = 0xff;
105
0
  }
106
0
  else if( byte_order == LIBUNA_ENDIAN_LITTLE )
107
0
  {
108
0
    utf32_stream[ *utf32_stream_index     ] = 0xff;
109
0
    utf32_stream[ *utf32_stream_index + 1 ] = 0xfe;
110
0
    utf32_stream[ *utf32_stream_index + 2 ] = 0x00;
111
0
    utf32_stream[ *utf32_stream_index + 3 ] = 0x00;
112
0
  }
113
0
  *utf32_stream_index += 4;
114
115
0
  return( 1 );
116
0
}
117
118
/* Determines the size of an UTF-32 stream from an UTF-8 string
119
 * Returns 1 if successful or -1 on error
120
 */
121
int libuna_utf32_stream_size_from_utf8(
122
     const libuna_utf8_character_t *utf8_string,
123
     size_t utf8_string_size,
124
     size_t *utf32_stream_size,
125
     libcerror_error_t **error )
126
0
{
127
0
  static char *function                        = "libuna_utf32_stream_size_from_utf8";
128
0
  libuna_unicode_character_t unicode_character = 0;
129
0
  size_t safe_utf32_stream_size                = 0;
130
0
  size_t utf8_string_index                     = 0;
131
132
0
  if( utf8_string == NULL )
133
0
  {
134
0
    libcerror_error_set(
135
0
     error,
136
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
137
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
138
0
     "%s: invalid UTF-8 string.",
139
0
     function );
140
141
0
    return( -1 );
142
0
  }
143
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
144
0
  {
145
0
    libcerror_error_set(
146
0
     error,
147
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
148
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
149
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
150
0
     function );
151
152
0
    return( -1 );
153
0
  }
154
0
  if( utf32_stream_size == NULL )
155
0
  {
156
0
    libcerror_error_set(
157
0
     error,
158
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
159
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
160
0
     "%s: invalid UTF-32 stream size.",
161
0
     function );
162
163
0
    return( -1 );
164
0
  }
165
  /* Add the byte order mark
166
   */
167
0
  safe_utf32_stream_size = 1;
168
169
0
  while( utf8_string_index < utf8_string_size )
170
0
  {
171
    /* Convert the UTF-8 character bytes into an Unicode character
172
     */
173
0
    if( libuna_unicode_character_copy_from_utf8(
174
0
         &unicode_character,
175
0
         utf8_string,
176
0
         utf8_string_size,
177
0
         &utf8_string_index,
178
0
         error ) != 1 )
179
0
    {
180
0
      libcerror_error_set(
181
0
       error,
182
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
183
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
184
0
       "%s: unable to copy Unicode character from UTF-8.",
185
0
       function );
186
187
0
      return( -1 );
188
0
    }
189
    /* Determine how many UTF-32 character bytes are required
190
     */
191
0
    if( libuna_unicode_character_size_to_utf32(
192
0
         unicode_character,
193
0
         &safe_utf32_stream_size,
194
0
         error ) != 1 )
195
0
    {
196
0
      libcerror_error_set(
197
0
       error,
198
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
199
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
200
0
       "%s: unable to determine size of Unicode character in UTF-32.",
201
0
       function );
202
203
0
      return( -1 );
204
0
    }
205
0
    if( unicode_character == 0 )
206
0
    {
207
0
      break;
208
0
    }
209
0
  }
210
  /* Convert the number of characters into bytes
211
   */
212
0
  *utf32_stream_size = safe_utf32_stream_size * 4;
213
214
0
  return( 1 );
215
0
}
216
217
/* Copies an UTF-32 stream from an UTF-8 string
218
 * Returns 1 if successful or -1 on error
219
 */
220
int libuna_utf32_stream_copy_from_utf8(
221
     uint8_t *utf32_stream,
222
     size_t utf32_stream_size,
223
     int byte_order,
224
     const libuna_utf8_character_t *utf8_string,
225
     size_t utf8_string_size,
226
     libcerror_error_t **error )
227
0
{
228
0
  static char *function                        = "libuna_utf32_stream_copy_from_utf8";
229
0
  libuna_unicode_character_t unicode_character = 0;
230
0
  size_t utf32_stream_index                    = 0;
231
0
  size_t utf8_string_index                     = 0;
232
233
0
  if( utf32_stream == NULL )
234
0
  {
235
0
    libcerror_error_set(
236
0
     error,
237
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
238
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
239
0
     "%s: invalid UTF-32 stream.",
240
0
     function );
241
242
0
    return( -1 );
243
0
  }
244
0
  if( utf32_stream_size > (size_t) SSIZE_MAX )
245
0
  {
246
0
    libcerror_error_set(
247
0
     error,
248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
249
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
250
0
     "%s: invalid UTF-32 stream size value exceeds maximum.",
251
0
     function );
252
253
0
    return( -1 );
254
0
  }
255
0
  if( ( byte_order != LIBUNA_ENDIAN_BIG )
256
0
   && ( byte_order != LIBUNA_ENDIAN_LITTLE ) )
257
0
  {
258
0
    libcerror_error_set(
259
0
     error,
260
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
261
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
262
0
     "%s: unsupported byte order.",
263
0
     function );
264
265
0
    return( -1 );
266
0
  }
267
0
  if( utf8_string == NULL )
268
0
  {
269
0
    libcerror_error_set(
270
0
     error,
271
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
272
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
273
0
     "%s: invalid UTF-8 string.",
274
0
     function );
275
276
0
    return( -1 );
277
0
  }
278
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
279
0
  {
280
0
    libcerror_error_set(
281
0
     error,
282
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
283
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
284
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
285
0
     function );
286
287
0
    return( -1 );
288
0
  }
289
0
  if( libuna_utf32_stream_copy_byte_order_mark(
290
0
       utf32_stream,
291
0
       utf32_stream_size,
292
0
       &utf32_stream_index,
293
0
       byte_order,
294
0
       error ) != 1 )
295
0
  {
296
0
    libcerror_error_set(
297
0
     error,
298
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
299
0
     LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
300
0
     "%s: unable to copy UTF-32 byte order mark.",
301
0
     function );
302
303
0
    return( -1 );
304
0
  }
305
0
  while( utf8_string_index < utf8_string_size )
306
0
  {
307
    /* Convert the UTF-8 string bytes into an Unicode character
308
     */
309
0
    if( libuna_unicode_character_copy_from_utf8(
310
0
         &unicode_character,
311
0
         utf8_string,
312
0
         utf8_string_size,
313
0
         &utf8_string_index,
314
0
         error ) != 1 )
315
0
    {
316
0
      libcerror_error_set(
317
0
       error,
318
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
319
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
320
0
       "%s: unable to copy Unicode character from UTF-8 string.",
321
0
       function );
322
323
0
      return( -1 );
324
0
    }
325
    /* Convert the Unicode character into UTF-32 stream bytes
326
     */
327
0
    if( libuna_unicode_character_copy_to_utf32_stream(
328
0
         unicode_character,
329
0
         utf32_stream,
330
0
         utf32_stream_size,
331
0
         &utf32_stream_index,
332
0
         byte_order,
333
0
         error ) != 1 )
334
0
    {
335
0
      libcerror_error_set(
336
0
       error,
337
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
338
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
339
0
       "%s: unable to copy Unicode character to UTF-32 stream.",
340
0
       function );
341
342
0
      return( -1 );
343
0
    }
344
0
    if( unicode_character == 0 )
345
0
    {
346
0
      break;
347
0
    }
348
0
  }
349
0
  return( 1 );
350
0
}
351
352
/* Determines the size of an UTF-32 stream from an UTF-16 string
353
 * Returns 1 if successful or -1 on error
354
 */
355
int libuna_utf32_stream_size_from_utf16(
356
     const libuna_utf16_character_t *utf16_string,
357
     size_t utf16_string_size,
358
     size_t *utf32_stream_size,
359
     libcerror_error_t **error )
360
0
{
361
0
  static char *function                        = "libuna_utf32_stream_size_from_utf16";
362
0
  libuna_unicode_character_t unicode_character = 0;
363
0
  size_t safe_utf32_stream_size                = 0;
364
0
  size_t utf16_string_index                    = 0;
365
366
0
  if( utf16_string == NULL )
367
0
  {
368
0
    libcerror_error_set(
369
0
     error,
370
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
371
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
372
0
     "%s: invalid UTF-16 string.",
373
0
     function );
374
375
0
    return( -1 );
376
0
  }
377
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
378
0
  {
379
0
    libcerror_error_set(
380
0
     error,
381
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
382
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
383
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
384
0
     function );
385
386
0
    return( -1 );
387
0
  }
388
0
  if( utf32_stream_size == NULL )
389
0
  {
390
0
    libcerror_error_set(
391
0
     error,
392
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
393
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
394
0
     "%s: invalid UTF-32 stream size.",
395
0
     function );
396
397
0
    return( -1 );
398
0
  }
399
  /* Add the byte order mark
400
   */
401
0
  safe_utf32_stream_size = 1;
402
403
0
  while( utf16_string_index < utf16_string_size )
404
0
  {
405
    /* Convert the UTF-16 character bytes into an Unicode character
406
     */
407
0
    if( libuna_unicode_character_copy_from_utf16(
408
0
         &unicode_character,
409
0
         utf16_string,
410
0
         utf16_string_size,
411
0
         &utf16_string_index,
412
0
         error ) != 1 )
413
0
    {
414
0
      libcerror_error_set(
415
0
       error,
416
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
417
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
418
0
       "%s: unable to copy Unicode character from UTF-16.",
419
0
       function );
420
421
0
      return( -1 );
422
0
    }
423
    /* Determine how many UTF-32 character bytes are required
424
     */
425
0
    if( libuna_unicode_character_size_to_utf32(
426
0
         unicode_character,
427
0
         &safe_utf32_stream_size,
428
0
         error ) != 1 )
429
0
    {
430
0
      libcerror_error_set(
431
0
       error,
432
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
433
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
434
0
       "%s: unable to determine size of Unicode character in UTF-32.",
435
0
       function );
436
437
0
      return( -1 );
438
0
    }
439
0
    if( unicode_character == 0 )
440
0
    {
441
0
      break;
442
0
    }
443
0
  }
444
  /* Convert the number of characters into bytes
445
   */
446
0
  *utf32_stream_size = safe_utf32_stream_size * 4;
447
448
0
  return( 1 );
449
0
}
450
451
/* Copies an UTF-32 stream from an UTF-16 string
452
 * Returns 1 if successful or -1 on error
453
 */
454
int libuna_utf32_stream_copy_from_utf16(
455
     uint8_t *utf32_stream,
456
     size_t utf32_stream_size,
457
     int byte_order,
458
     const libuna_utf16_character_t *utf16_string,
459
     size_t utf16_string_size,
460
     libcerror_error_t **error )
461
0
{
462
0
  static char *function                        = "libuna_utf32_stream_copy_from_utf16";
463
0
  libuna_unicode_character_t unicode_character = 0;
464
0
  size_t utf16_string_index                    = 0;
465
0
  size_t utf32_stream_index                    = 0;
466
467
0
  if( utf32_stream == NULL )
468
0
  {
469
0
    libcerror_error_set(
470
0
     error,
471
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
472
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
473
0
     "%s: invalid UTF-32 stream.",
474
0
     function );
475
476
0
    return( -1 );
477
0
  }
478
0
  if( utf32_stream_size > (size_t) SSIZE_MAX )
479
0
  {
480
0
    libcerror_error_set(
481
0
     error,
482
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
483
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
484
0
     "%s: invalid UTF-32 stream size value exceeds maximum.",
485
0
     function );
486
487
0
    return( -1 );
488
0
  }
489
0
  if( ( byte_order != LIBUNA_ENDIAN_BIG )
490
0
   && ( byte_order != LIBUNA_ENDIAN_LITTLE ) )
491
0
  {
492
0
    libcerror_error_set(
493
0
     error,
494
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
495
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
496
0
     "%s: unsupported byte order.",
497
0
     function );
498
499
0
    return( -1 );
500
0
  }
501
0
  if( utf16_string == NULL )
502
0
  {
503
0
    libcerror_error_set(
504
0
     error,
505
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
506
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
507
0
     "%s: invalid UTF-16 string.",
508
0
     function );
509
510
0
    return( -1 );
511
0
  }
512
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
513
0
  {
514
0
    libcerror_error_set(
515
0
     error,
516
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
517
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
518
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
519
0
     function );
520
521
0
    return( -1 );
522
0
  }
523
0
  if( libuna_utf32_stream_copy_byte_order_mark(
524
0
       utf32_stream,
525
0
       utf32_stream_size,
526
0
       &utf32_stream_index,
527
0
       byte_order,
528
0
       error ) != 1 )
529
0
  {
530
0
    libcerror_error_set(
531
0
     error,
532
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
533
0
     LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
534
0
     "%s: unable to copy UTF-32 byte order mark.",
535
0
     function );
536
537
0
    return( -1 );
538
0
  }
539
0
  while( utf16_string_index < utf16_string_size )
540
0
  {
541
    /* Convert the UTF-16 string bytes into an Unicode character
542
     */
543
0
    if( libuna_unicode_character_copy_from_utf16(
544
0
         &unicode_character,
545
0
         utf16_string,
546
0
         utf16_string_size,
547
0
         &utf16_string_index,
548
0
         error ) != 1 )
549
0
    {
550
0
      libcerror_error_set(
551
0
       error,
552
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
553
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
554
0
       "%s: unable to copy Unicode character from UTF-16 string.",
555
0
       function );
556
557
0
      return( -1 );
558
0
    }
559
    /* Convert the Unicode character into UTF-32 stream bytes
560
     */
561
0
    if( libuna_unicode_character_copy_to_utf32_stream(
562
0
         unicode_character,
563
0
         utf32_stream,
564
0
         utf32_stream_size,
565
0
         &utf32_stream_index,
566
0
         byte_order,
567
0
         error ) != 1 )
568
0
    {
569
0
      libcerror_error_set(
570
0
       error,
571
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
572
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
573
0
       "%s: unable to copy Unicode character to UTF-32 stream.",
574
0
       function );
575
576
0
      return( -1 );
577
0
    }
578
0
    if( unicode_character == 0 )
579
0
    {
580
0
      break;
581
0
    }
582
0
  }
583
0
  return( 1 );
584
0
}
585
586
/* Determines the size of an UTF-32 stream from an UTF-32 string
587
 * Returns 1 if successful or -1 on error
588
 */
589
int libuna_utf32_stream_size_from_utf32(
590
     const libuna_utf32_character_t *utf32_string,
591
     size_t utf32_string_size,
592
     size_t *utf32_stream_size,
593
     libcerror_error_t **error )
594
0
{
595
0
  static char *function                        = "libuna_utf32_stream_size_from_utf32";
596
0
  libuna_unicode_character_t unicode_character = 0;
597
0
  size_t safe_utf32_stream_size                = 0;
598
0
  size_t utf32_string_index                    = 0;
599
600
0
  if( utf32_string == NULL )
601
0
  {
602
0
    libcerror_error_set(
603
0
     error,
604
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
605
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
606
0
     "%s: invalid UTF-32 string.",
607
0
     function );
608
609
0
    return( -1 );
610
0
  }
611
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
612
0
  {
613
0
    libcerror_error_set(
614
0
     error,
615
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
616
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
617
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
618
0
     function );
619
620
0
    return( -1 );
621
0
  }
622
0
  if( utf32_stream_size == NULL )
623
0
  {
624
0
    libcerror_error_set(
625
0
     error,
626
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
627
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
628
0
     "%s: invalid UTF-32 stream size.",
629
0
     function );
630
631
0
    return( -1 );
632
0
  }
633
  /* Add the byte order mark
634
   */
635
0
  safe_utf32_stream_size = 1;
636
637
0
  while( utf32_string_index < utf32_string_size )
638
0
  {
639
    /* Convert the UTF-32 character bytes into an Unicode character
640
     */
641
0
    if( libuna_unicode_character_copy_from_utf32(
642
0
         &unicode_character,
643
0
         utf32_string,
644
0
         utf32_string_size,
645
0
         &utf32_string_index,
646
0
         error ) != 1 )
647
0
    {
648
0
      libcerror_error_set(
649
0
       error,
650
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
651
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
652
0
       "%s: unable to copy Unicode character from UTF-32.",
653
0
       function );
654
655
0
      return( -1 );
656
0
    }
657
    /* Determine how many UTF-32 character bytes are required
658
     */
659
0
    if( libuna_unicode_character_size_to_utf32(
660
0
         unicode_character,
661
0
         &safe_utf32_stream_size,
662
0
         error ) != 1 )
663
0
    {
664
0
      libcerror_error_set(
665
0
       error,
666
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
667
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
668
0
       "%s: unable to determine size of Unicode character in UTF-32.",
669
0
       function );
670
671
0
      return( -1 );
672
0
    }
673
0
    if( unicode_character == 0 )
674
0
    {
675
0
      break;
676
0
    }
677
0
  }
678
  /* Convert the number of characters into bytes
679
   */
680
0
  *utf32_stream_size = safe_utf32_stream_size * 4;
681
682
0
  return( 1 );
683
0
}
684
685
/* Copies an UTF-32 stream from an UTF-32 string
686
 * Returns 1 if successful or -1 on error
687
 */
688
int libuna_utf32_stream_copy_from_utf32(
689
     uint8_t *utf32_stream,
690
     size_t utf32_stream_size,
691
     int byte_order,
692
     const libuna_utf32_character_t *utf32_string,
693
     size_t utf32_string_size,
694
     libcerror_error_t **error )
695
0
{
696
0
  static char *function                        = "libuna_utf32_stream_copy_from_utf32";
697
0
  libuna_unicode_character_t unicode_character = 0;
698
0
  size_t utf32_stream_index                    = 0;
699
0
  size_t utf32_string_index                    = 0;
700
701
0
  if( utf32_stream == NULL )
702
0
  {
703
0
    libcerror_error_set(
704
0
     error,
705
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
706
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
707
0
     "%s: invalid UTF-32 stream.",
708
0
     function );
709
710
0
    return( -1 );
711
0
  }
712
0
  if( utf32_stream_size > (size_t) SSIZE_MAX )
713
0
  {
714
0
    libcerror_error_set(
715
0
     error,
716
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
717
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
718
0
     "%s: invalid UTF-32 stream size value exceeds maximum.",
719
0
     function );
720
721
0
    return( -1 );
722
0
  }
723
0
  if( ( byte_order != LIBUNA_ENDIAN_BIG )
724
0
   && ( byte_order != LIBUNA_ENDIAN_LITTLE ) )
725
0
  {
726
0
    libcerror_error_set(
727
0
     error,
728
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
729
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
730
0
     "%s: unsupported byte order.",
731
0
     function );
732
733
0
    return( -1 );
734
0
  }
735
0
  if( utf32_string == NULL )
736
0
  {
737
0
    libcerror_error_set(
738
0
     error,
739
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
740
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
741
0
     "%s: invalid UTF-32 string.",
742
0
     function );
743
744
0
    return( -1 );
745
0
  }
746
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
747
0
  {
748
0
    libcerror_error_set(
749
0
     error,
750
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
751
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
752
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
753
0
     function );
754
755
0
    return( -1 );
756
0
  }
757
0
  if( libuna_utf32_stream_copy_byte_order_mark(
758
0
       utf32_stream,
759
0
       utf32_stream_size,
760
0
       &utf32_stream_index,
761
0
       byte_order,
762
0
       error ) != 1 )
763
0
  {
764
0
    libcerror_error_set(
765
0
     error,
766
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
767
0
     LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
768
0
     "%s: unable to copy UTF-32 byte order mark.",
769
0
     function );
770
771
0
    return( -1 );
772
0
  }
773
0
  while( utf32_string_index < utf32_string_size )
774
0
  {
775
    /* Convert the UTF-32 string bytes into an Unicode character
776
     */
777
0
    if( libuna_unicode_character_copy_from_utf32(
778
0
         &unicode_character,
779
0
         utf32_string,
780
0
         utf32_string_size,
781
0
         &utf32_string_index,
782
0
         error ) != 1 )
783
0
    {
784
0
      libcerror_error_set(
785
0
       error,
786
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
787
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
788
0
       "%s: unable to copy Unicode character from UTF-32 string.",
789
0
       function );
790
791
0
      return( -1 );
792
0
    }
793
    /* Convert the Unicode character into UTF-32 stream bytes
794
     */
795
0
    if( libuna_unicode_character_copy_to_utf32_stream(
796
0
         unicode_character,
797
0
         utf32_stream,
798
0
         utf32_stream_size,
799
0
         &utf32_stream_index,
800
0
         byte_order,
801
0
         error ) != 1 )
802
0
    {
803
0
      libcerror_error_set(
804
0
       error,
805
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
806
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
807
0
       "%s: unable to copy Unicode character to UTF-32 stream.",
808
0
       function );
809
810
0
      return( -1 );
811
0
    }
812
0
    if( unicode_character == 0 )
813
0
    {
814
0
      break;
815
0
    }
816
0
  }
817
0
  return( 1 );
818
0
}
819