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