Coverage Report

Created: 2023-06-07 06:53

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