Coverage Report

Created: 2024-02-25 07:20

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