Coverage Report

Created: 2023-06-07 06:53

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