Coverage Report

Created: 2023-06-07 06:53

/src/libevt/libuna/libuna_unicode_character.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Unicode character 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_base64_stream.h"
26
#include "libuna_codepage_iso_8859_2.h"
27
#include "libuna_codepage_iso_8859_3.h"
28
#include "libuna_codepage_iso_8859_4.h"
29
#include "libuna_codepage_iso_8859_5.h"
30
#include "libuna_codepage_iso_8859_6.h"
31
#include "libuna_codepage_iso_8859_7.h"
32
#include "libuna_codepage_iso_8859_8.h"
33
#include "libuna_codepage_iso_8859_9.h"
34
#include "libuna_codepage_iso_8859_10.h"
35
#include "libuna_codepage_iso_8859_13.h"
36
#include "libuna_codepage_iso_8859_14.h"
37
#include "libuna_codepage_iso_8859_15.h"
38
#include "libuna_codepage_iso_8859_16.h"
39
#include "libuna_codepage_koi8_r.h"
40
#include "libuna_codepage_koi8_u.h"
41
#include "libuna_codepage_mac_arabic.h"
42
#include "libuna_codepage_mac_celtic.h"
43
#include "libuna_codepage_mac_centraleurroman.h"
44
#include "libuna_codepage_mac_croatian.h"
45
#include "libuna_codepage_mac_cyrillic.h"
46
#include "libuna_codepage_mac_dingbats.h"
47
#include "libuna_codepage_mac_farsi.h"
48
#include "libuna_codepage_mac_gaelic.h"
49
#include "libuna_codepage_mac_greek.h"
50
#include "libuna_codepage_mac_icelandic.h"
51
#include "libuna_codepage_mac_inuit.h"
52
#include "libuna_codepage_mac_roman.h"
53
#include "libuna_codepage_mac_romanian.h"
54
#include "libuna_codepage_mac_russian.h"
55
#include "libuna_codepage_mac_symbol.h"
56
#include "libuna_codepage_mac_thai.h"
57
#include "libuna_codepage_mac_turkish.h"
58
#include "libuna_codepage_mac_ukrainian.h"
59
#include "libuna_codepage_windows_874.h"
60
#include "libuna_codepage_windows_932.h"
61
#include "libuna_codepage_windows_936.h"
62
#include "libuna_codepage_windows_949.h"
63
#include "libuna_codepage_windows_950.h"
64
#include "libuna_codepage_windows_1250.h"
65
#include "libuna_codepage_windows_1251.h"
66
#include "libuna_codepage_windows_1252.h"
67
#include "libuna_codepage_windows_1253.h"
68
#include "libuna_codepage_windows_1254.h"
69
#include "libuna_codepage_windows_1255.h"
70
#include "libuna_codepage_windows_1256.h"
71
#include "libuna_codepage_windows_1257.h"
72
#include "libuna_codepage_windows_1258.h"
73
#include "libuna_definitions.h"
74
#include "libuna_libcerror.h"
75
#include "libuna_types.h"
76
#include "libuna_unicode_character.h"
77
#include "libuna_unused.h"
78
79
/* Valid directly encoded characters: A-Z, a-z, 0-9, '\', '(', ')', ',', '-', '.', '/', ':', '?'
80
 * Valid directly encoded whitespace: '\t', '\n', '\r', ' '
81
 * Valid optional directly encoded characters: '!', '"', '#', '$', '%', '&', '*', ';', '<', '=', '>', '@', '[', ']', '^', '_', '`', '{', '|', '}'
82
 */
83
uint8_t libuna_unicode_character_utf7_valid_directly_encoded_character[ 256 ] = {
84
  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
85
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86
  1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
87
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
88
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
89
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
90
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
91
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
92
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
97
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
98
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
100
101
/* Valid UTF-7 base64 characters: A-Z, a-z, 0-9, '+' and '/'
102
 */
103
uint8_t libuna_unicode_character_utf7_valid_base64_character[ 256 ] = {
104
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
107
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
108
  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
109
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
110
  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
111
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
112
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
120
121
/* Determines the size of a byte stream character from an Unicode character
122
 * Adds the size to the byte stream character size value
123
 * Returns 1 if successful, 0 if the byte stream character is valid but not supported since it requires special handling or -1 on error
124
 */
125
int libuna_unicode_character_size_to_byte_stream(
126
     libuna_unicode_character_t unicode_character,
127
     int codepage,
128
     size_t *byte_stream_character_size,
129
     libcerror_error_t **error )
130
0
{
131
0
  static char *function                  = "libuna_unicode_character_size_to_byte_stream";
132
0
  size_t safe_byte_stream_character_size = 0;
133
0
  int result                             = 1;
134
135
0
  if( byte_stream_character_size == NULL )
136
0
  {
137
0
    libcerror_error_set(
138
0
     error,
139
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
140
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
141
0
     "%s: invalid byte stream character size.",
142
0
     function );
143
144
0
    return( -1 );
145
0
  }
146
0
  safe_byte_stream_character_size = *byte_stream_character_size;
147
148
0
  switch( codepage )
149
0
  {
150
0
    case LIBUNA_CODEPAGE_ASCII:
151
0
    case LIBUNA_CODEPAGE_ISO_8859_1:
152
0
    case LIBUNA_CODEPAGE_ISO_8859_2:
153
0
    case LIBUNA_CODEPAGE_ISO_8859_3:
154
0
    case LIBUNA_CODEPAGE_ISO_8859_4:
155
0
    case LIBUNA_CODEPAGE_ISO_8859_5:
156
0
    case LIBUNA_CODEPAGE_ISO_8859_6:
157
0
    case LIBUNA_CODEPAGE_ISO_8859_7:
158
0
    case LIBUNA_CODEPAGE_ISO_8859_8:
159
0
    case LIBUNA_CODEPAGE_ISO_8859_9:
160
0
    case LIBUNA_CODEPAGE_ISO_8859_10:
161
0
    case LIBUNA_CODEPAGE_ISO_8859_11:
162
0
    case LIBUNA_CODEPAGE_ISO_8859_13:
163
0
    case LIBUNA_CODEPAGE_ISO_8859_14:
164
0
    case LIBUNA_CODEPAGE_ISO_8859_15:
165
0
    case LIBUNA_CODEPAGE_ISO_8859_16:
166
0
    case LIBUNA_CODEPAGE_KOI8_R:
167
0
    case LIBUNA_CODEPAGE_KOI8_U:
168
0
    case LIBUNA_CODEPAGE_MAC_ARABIC:
169
0
    case LIBUNA_CODEPAGE_MAC_CELTIC:
170
0
    case LIBUNA_CODEPAGE_MAC_CENTRALEURROMAN:
171
0
    case LIBUNA_CODEPAGE_MAC_CROATIAN:
172
0
    case LIBUNA_CODEPAGE_MAC_CYRILLIC:
173
0
    case LIBUNA_CODEPAGE_MAC_DINGBATS:
174
0
    case LIBUNA_CODEPAGE_MAC_FARSI:
175
0
    case LIBUNA_CODEPAGE_MAC_GAELIC:
176
0
    case LIBUNA_CODEPAGE_MAC_GREEK:
177
0
    case LIBUNA_CODEPAGE_MAC_ICELANDIC:
178
0
    case LIBUNA_CODEPAGE_MAC_INUIT:
179
0
    case LIBUNA_CODEPAGE_MAC_ROMAN:
180
0
    case LIBUNA_CODEPAGE_MAC_ROMANIAN:
181
0
    case LIBUNA_CODEPAGE_MAC_RUSSIAN:
182
0
    case LIBUNA_CODEPAGE_MAC_TURKISH:
183
0
    case LIBUNA_CODEPAGE_MAC_UKRAINIAN:
184
0
    case LIBUNA_CODEPAGE_WINDOWS_874:
185
0
    case LIBUNA_CODEPAGE_WINDOWS_1250:
186
0
    case LIBUNA_CODEPAGE_WINDOWS_1251:
187
0
    case LIBUNA_CODEPAGE_WINDOWS_1252:
188
0
    case LIBUNA_CODEPAGE_WINDOWS_1253:
189
0
    case LIBUNA_CODEPAGE_WINDOWS_1254:
190
0
    case LIBUNA_CODEPAGE_WINDOWS_1255:
191
0
    case LIBUNA_CODEPAGE_WINDOWS_1256:
192
0
    case LIBUNA_CODEPAGE_WINDOWS_1257:
193
0
    case LIBUNA_CODEPAGE_WINDOWS_1258:
194
0
      safe_byte_stream_character_size += 1;
195
0
      break;
196
197
0
    case LIBUNA_CODEPAGE_MAC_SYMBOL:
198
0
      result = libuna_codepage_mac_symbol_unicode_character_size_to_byte_stream(
199
0
                unicode_character,
200
0
                &safe_byte_stream_character_size,
201
0
                error );
202
0
      break;
203
204
0
    case LIBUNA_CODEPAGE_MAC_THAI:
205
0
      result = libuna_codepage_mac_thai_unicode_character_size_to_byte_stream(
206
0
                unicode_character,
207
0
                &safe_byte_stream_character_size,
208
0
                error );
209
0
      break;
210
211
0
    case LIBUNA_CODEPAGE_WINDOWS_932:
212
0
      result = libuna_codepage_windows_932_unicode_character_size_to_byte_stream(
213
0
                unicode_character,
214
0
                &safe_byte_stream_character_size,
215
0
                error );
216
0
      break;
217
218
0
    case LIBUNA_CODEPAGE_WINDOWS_936:
219
0
      result = libuna_codepage_windows_936_unicode_character_size_to_byte_stream(
220
0
                unicode_character,
221
0
                &safe_byte_stream_character_size,
222
0
                error );
223
0
      break;
224
225
0
    case LIBUNA_CODEPAGE_WINDOWS_949:
226
0
      result = libuna_codepage_windows_949_unicode_character_size_to_byte_stream(
227
0
                unicode_character,
228
0
                &safe_byte_stream_character_size,
229
0
                error );
230
0
      break;
231
232
0
    case LIBUNA_CODEPAGE_WINDOWS_950:
233
0
      result = libuna_codepage_windows_950_unicode_character_size_to_byte_stream(
234
0
                unicode_character,
235
0
                &safe_byte_stream_character_size,
236
0
                error );
237
0
      break;
238
239
0
    default:
240
0
      libcerror_error_set(
241
0
       error,
242
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
243
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
244
0
       "%s: unsupported codepage: %d.",
245
0
       function,
246
0
       codepage );
247
248
0
      return( -1 );
249
0
  }
250
0
  if( result == -1 )
251
0
  {
252
0
    libcerror_error_set(
253
0
     error,
254
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
255
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
256
0
     "%s: unable to determine byte stream character size.",
257
0
     function );
258
259
0
    return( -1 );
260
0
  }
261
0
  *byte_stream_character_size = safe_byte_stream_character_size;
262
263
0
  return( result );
264
0
}
265
266
/* Copies an Unicode character from a byte stream
267
 * Returns 1 if successful, 0 if the byte stream character is valid but not supported since it requires special handling or -1 on error
268
 */
269
int libuna_unicode_character_copy_from_byte_stream(
270
     libuna_unicode_character_t *unicode_character,
271
     const uint8_t *byte_stream,
272
     size_t byte_stream_size,
273
     size_t *byte_stream_index,
274
     int codepage,
275
     libcerror_error_t **error )
276
188k
{
277
188k
  static char *function                             = "libuna_unicode_character_copy_from_byte_stream";
278
188k
  libuna_unicode_character_t safe_unicode_character = 0;
279
188k
  size_t safe_byte_stream_index                     = 0;
280
188k
  uint8_t byte_stream_character                     = 0;
281
188k
  int result                                        = 1;
282
283
188k
  if( unicode_character == NULL )
284
0
  {
285
0
    libcerror_error_set(
286
0
     error,
287
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
288
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
289
0
     "%s: invalid Unicode character.",
290
0
     function );
291
292
0
    return( -1 );
293
0
  }
294
188k
  if( byte_stream == NULL )
295
0
  {
296
0
    libcerror_error_set(
297
0
     error,
298
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
299
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
300
0
     "%s: invalid byte stream.",
301
0
     function );
302
303
0
    return( -1 );
304
0
  }
305
188k
  if( byte_stream_size > (size_t) SSIZE_MAX )
306
0
  {
307
0
    libcerror_error_set(
308
0
     error,
309
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
310
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
311
0
     "%s: invalid byte stream size value exceeds maximum.",
312
0
     function );
313
314
0
    return( -1 );
315
0
  }
316
188k
  if( byte_stream_index == NULL )
317
0
  {
318
0
    libcerror_error_set(
319
0
     error,
320
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
321
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
322
0
     "%s: invalid byte stream index.",
323
0
     function );
324
325
0
    return( -1 );
326
0
  }
327
188k
  safe_byte_stream_index = *byte_stream_index;
328
329
188k
  if( safe_byte_stream_index >= byte_stream_size )
330
0
  {
331
0
    libcerror_error_set(
332
0
     error,
333
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
334
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
335
0
     "%s: byte stream too small.",
336
0
     function );
337
338
0
    return( -1 );
339
0
  }
340
188k
  byte_stream_character = byte_stream[ safe_byte_stream_index ];
341
342
188k
  switch( codepage )
343
188k
  {
344
106k
    case LIBUNA_CODEPAGE_ASCII:
345
106k
      if( byte_stream_character < 0x80 )
346
103k
      {
347
103k
        safe_unicode_character = byte_stream_character;
348
103k
      }
349
2.59k
      else
350
2.59k
      {
351
2.59k
        safe_unicode_character = 0xfffd;
352
2.59k
      }
353
106k
      safe_byte_stream_index += 1;
354
355
106k
      break;
356
357
0
    case LIBUNA_CODEPAGE_ISO_8859_1:
358
0
      safe_unicode_character = byte_stream_character;
359
360
0
      safe_byte_stream_index += 1;
361
362
0
      break;
363
364
0
    case LIBUNA_CODEPAGE_ISO_8859_2:
365
0
      if( byte_stream_character < 0xa0 )
366
0
      {
367
0
        safe_unicode_character = byte_stream_character;
368
0
      }
369
0
      else
370
0
      {
371
0
        byte_stream_character -= 0xa0;
372
373
0
        safe_unicode_character = libuna_codepage_iso_8859_2_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
374
0
      }
375
0
      safe_byte_stream_index += 1;
376
377
0
      break;
378
379
0
    case LIBUNA_CODEPAGE_ISO_8859_3:
380
0
      if( byte_stream_character < 0xa0 )
381
0
      {
382
0
        safe_unicode_character = byte_stream_character;
383
0
      }
384
0
      else
385
0
      {
386
0
        byte_stream_character -= 0xa0;
387
388
0
        safe_unicode_character = libuna_codepage_iso_8859_3_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
389
0
      }
390
0
      safe_byte_stream_index += 1;
391
392
0
      break;
393
394
0
    case LIBUNA_CODEPAGE_ISO_8859_4:
395
0
      if( byte_stream_character < 0xa0 )
396
0
      {
397
0
        safe_unicode_character = byte_stream_character;
398
0
      }
399
0
      else
400
0
      {
401
0
        byte_stream_character -= 0xa0;
402
403
0
        safe_unicode_character = libuna_codepage_iso_8859_4_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
404
0
      }
405
0
      safe_byte_stream_index += 1;
406
407
0
      break;
408
409
0
    case LIBUNA_CODEPAGE_ISO_8859_5:
410
0
      if( byte_stream_character < 0xa0 )
411
0
      {
412
0
        safe_unicode_character = byte_stream_character;
413
0
      }
414
0
      else
415
0
      {
416
0
        byte_stream_character -= 0xa0;
417
418
0
        safe_unicode_character = libuna_codepage_iso_8859_5_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
419
0
      }
420
0
      safe_byte_stream_index += 1;
421
422
0
      break;
423
424
0
    case LIBUNA_CODEPAGE_ISO_8859_6:
425
0
      if( byte_stream_character < 0xa0 )
426
0
      {
427
0
        safe_unicode_character = byte_stream_character;
428
0
      }
429
0
      else
430
0
      {
431
0
        byte_stream_character -= 0xa0;
432
433
0
        safe_unicode_character = libuna_codepage_iso_8859_6_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
434
0
      }
435
0
      safe_byte_stream_index += 1;
436
437
0
      break;
438
439
0
    case LIBUNA_CODEPAGE_ISO_8859_7:
440
0
      if( byte_stream_character < 0xa0 )
441
0
      {
442
0
        safe_unicode_character = byte_stream_character;
443
0
      }
444
0
      else
445
0
      {
446
0
        byte_stream_character -= 0xa0;
447
448
0
        safe_unicode_character = libuna_codepage_iso_8859_7_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
449
0
      }
450
0
      safe_byte_stream_index += 1;
451
452
0
      break;
453
454
0
    case LIBUNA_CODEPAGE_ISO_8859_8:
455
0
      if( byte_stream_character < 0xa0 )
456
0
      {
457
0
        safe_unicode_character = byte_stream_character;
458
0
      }
459
0
      else
460
0
      {
461
0
        byte_stream_character -= 0xa0;
462
463
0
        safe_unicode_character = libuna_codepage_iso_8859_8_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
464
0
      }
465
0
      safe_byte_stream_index += 1;
466
467
0
      break;
468
469
0
    case LIBUNA_CODEPAGE_ISO_8859_9:
470
0
      if( byte_stream_character < 0xd0 )
471
0
      {
472
0
        safe_unicode_character = byte_stream_character;
473
0
      }
474
0
      else
475
0
      {
476
0
        byte_stream_character -= 0xd0;
477
478
0
        safe_unicode_character = libuna_codepage_iso_8859_9_byte_stream_to_unicode_base_0xd0[ byte_stream_character ];
479
0
      }
480
0
      safe_byte_stream_index += 1;
481
482
0
      break;
483
484
0
    case LIBUNA_CODEPAGE_ISO_8859_10:
485
0
      if( byte_stream_character < 0xa0 )
486
0
      {
487
0
        safe_unicode_character = byte_stream_character;
488
0
      }
489
0
      else
490
0
      {
491
0
        byte_stream_character -= 0xa0;
492
493
0
        safe_unicode_character = libuna_codepage_iso_8859_10_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
494
0
      }
495
0
      safe_byte_stream_index += 1;
496
497
0
      break;
498
499
0
    case LIBUNA_CODEPAGE_ISO_8859_11:
500
0
      if( byte_stream_character < 0xa1 )
501
0
      {
502
0
        safe_unicode_character = byte_stream_character;
503
0
      }
504
0
      else if( byte_stream_character < 0xdb )
505
0
      {
506
0
        safe_unicode_character = byte_stream_character + 0x0d60;
507
0
      }
508
0
      else if( byte_stream_character < 0xdf )
509
0
      {
510
0
        safe_unicode_character = 0xfffd;
511
0
      }
512
0
      else if( byte_stream_character < 0xfc )
513
0
      {
514
0
        safe_unicode_character = byte_stream_character + 0x0d60;
515
0
      }
516
0
      else
517
0
      {
518
0
        safe_unicode_character = 0xfffd;
519
0
      }
520
0
      safe_byte_stream_index += 1;
521
522
0
      break;
523
524
0
    case LIBUNA_CODEPAGE_ISO_8859_13:
525
0
      if( byte_stream_character < 0xa0 )
526
0
      {
527
0
        safe_unicode_character = byte_stream_character;
528
0
      }
529
0
      else
530
0
      {
531
0
        byte_stream_character -= 0xa0;
532
533
0
        safe_unicode_character = libuna_codepage_iso_8859_13_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
534
0
      }
535
0
      safe_byte_stream_index += 1;
536
537
0
      break;
538
539
0
    case LIBUNA_CODEPAGE_ISO_8859_14:
540
0
      if( byte_stream_character < 0xa0 )
541
0
      {
542
0
        safe_unicode_character = byte_stream_character;
543
0
      }
544
0
      else
545
0
      {
546
0
        byte_stream_character -= 0xa0;
547
548
0
        safe_unicode_character = libuna_codepage_iso_8859_14_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
549
0
      }
550
0
      safe_byte_stream_index += 1;
551
552
0
      break;
553
554
0
    case LIBUNA_CODEPAGE_ISO_8859_15:
555
0
      if( ( byte_stream_character >= 0xa0 )
556
0
       && ( byte_stream_character < 0xc0 ) )
557
0
      {
558
0
        byte_stream_character -= 0xa0;
559
560
0
        safe_unicode_character = libuna_codepage_iso_8859_15_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
561
0
      }
562
0
      else
563
0
      {
564
0
        safe_unicode_character = byte_stream_character;
565
0
      }
566
0
      safe_byte_stream_index += 1;
567
568
0
      break;
569
570
0
    case LIBUNA_CODEPAGE_ISO_8859_16:
571
0
      if( byte_stream_character < 0xa0 )
572
0
      {
573
0
        safe_unicode_character = byte_stream_character;
574
0
      }
575
0
      else
576
0
      {
577
0
        byte_stream_character -= 0xa0;
578
579
0
        safe_unicode_character = libuna_codepage_iso_8859_16_byte_stream_to_unicode_base_0xa0[ byte_stream_character ];
580
0
      }
581
0
      safe_byte_stream_index += 1;
582
583
0
      break;
584
585
0
    case LIBUNA_CODEPAGE_KOI8_R:
586
0
      result = libuna_codepage_koi8_r_copy_from_byte_stream(
587
0
                &safe_unicode_character,
588
0
                byte_stream,
589
0
                byte_stream_size,
590
0
                &safe_byte_stream_index,
591
0
                error );
592
0
      break;
593
594
0
    case LIBUNA_CODEPAGE_KOI8_U:
595
0
      result = libuna_codepage_koi8_u_copy_from_byte_stream(
596
0
                &safe_unicode_character,
597
0
                byte_stream,
598
0
                byte_stream_size,
599
0
                &safe_byte_stream_index,
600
0
                error );
601
0
      break;
602
603
0
    case LIBUNA_CODEPAGE_MAC_ARABIC:
604
0
      result = libuna_codepage_mac_arabic_copy_from_byte_stream(
605
0
                &safe_unicode_character,
606
0
                byte_stream,
607
0
                byte_stream_size,
608
0
                &safe_byte_stream_index,
609
0
                error );
610
0
      break;
611
612
0
    case LIBUNA_CODEPAGE_MAC_CELTIC:
613
0
      result = libuna_codepage_mac_celtic_copy_from_byte_stream(
614
0
                &safe_unicode_character,
615
0
                byte_stream,
616
0
                byte_stream_size,
617
0
                &safe_byte_stream_index,
618
0
                error );
619
0
      break;
620
621
0
    case LIBUNA_CODEPAGE_MAC_CENTRALEURROMAN:
622
0
      result = libuna_codepage_mac_centraleurroman_copy_from_byte_stream(
623
0
                &safe_unicode_character,
624
0
                byte_stream,
625
0
                byte_stream_size,
626
0
                &safe_byte_stream_index,
627
0
                error );
628
0
      break;
629
630
0
    case LIBUNA_CODEPAGE_MAC_CROATIAN:
631
0
      result = libuna_codepage_mac_croatian_copy_from_byte_stream(
632
0
                &safe_unicode_character,
633
0
                byte_stream,
634
0
                byte_stream_size,
635
0
                &safe_byte_stream_index,
636
0
                error );
637
0
      break;
638
639
0
    case LIBUNA_CODEPAGE_MAC_CYRILLIC:
640
0
      result = libuna_codepage_mac_cyrillic_copy_from_byte_stream(
641
0
                &safe_unicode_character,
642
0
                byte_stream,
643
0
                byte_stream_size,
644
0
                &safe_byte_stream_index,
645
0
                error );
646
0
      break;
647
648
0
    case LIBUNA_CODEPAGE_MAC_DINGBATS:
649
0
      result = libuna_codepage_mac_dingbats_copy_from_byte_stream(
650
0
                &safe_unicode_character,
651
0
                byte_stream,
652
0
                byte_stream_size,
653
0
                &safe_byte_stream_index,
654
0
                error );
655
0
      break;
656
657
0
    case LIBUNA_CODEPAGE_MAC_FARSI:
658
0
      result = libuna_codepage_mac_farsi_copy_from_byte_stream(
659
0
                &safe_unicode_character,
660
0
                byte_stream,
661
0
                byte_stream_size,
662
0
                &safe_byte_stream_index,
663
0
                error );
664
0
      break;
665
666
0
    case LIBUNA_CODEPAGE_MAC_GAELIC:
667
0
      result = libuna_codepage_mac_gaelic_copy_from_byte_stream(
668
0
                &safe_unicode_character,
669
0
                byte_stream,
670
0
                byte_stream_size,
671
0
                &safe_byte_stream_index,
672
0
                error );
673
0
      break;
674
675
0
    case LIBUNA_CODEPAGE_MAC_GREEK:
676
0
      result = libuna_codepage_mac_greek_copy_from_byte_stream(
677
0
                &safe_unicode_character,
678
0
                byte_stream,
679
0
                byte_stream_size,
680
0
                &safe_byte_stream_index,
681
0
                error );
682
0
      break;
683
684
0
    case LIBUNA_CODEPAGE_MAC_ICELANDIC:
685
0
      result = libuna_codepage_mac_icelandic_copy_from_byte_stream(
686
0
                &safe_unicode_character,
687
0
                byte_stream,
688
0
                byte_stream_size,
689
0
                &safe_byte_stream_index,
690
0
                error );
691
0
      break;
692
693
0
    case LIBUNA_CODEPAGE_MAC_INUIT:
694
0
      result = libuna_codepage_mac_inuit_copy_from_byte_stream(
695
0
                &safe_unicode_character,
696
0
                byte_stream,
697
0
                byte_stream_size,
698
0
                &safe_byte_stream_index,
699
0
                error );
700
0
      break;
701
702
0
    case LIBUNA_CODEPAGE_MAC_ROMAN:
703
0
      result = libuna_codepage_mac_roman_copy_from_byte_stream(
704
0
                &safe_unicode_character,
705
0
                byte_stream,
706
0
                byte_stream_size,
707
0
                &safe_byte_stream_index,
708
0
                error );
709
0
      break;
710
711
0
    case LIBUNA_CODEPAGE_MAC_ROMANIAN:
712
0
      result = libuna_codepage_mac_romanian_copy_from_byte_stream(
713
0
                &safe_unicode_character,
714
0
                byte_stream,
715
0
                byte_stream_size,
716
0
                &safe_byte_stream_index,
717
0
                error );
718
0
      break;
719
720
0
    case LIBUNA_CODEPAGE_MAC_RUSSIAN:
721
0
      result = libuna_codepage_mac_russian_copy_from_byte_stream(
722
0
                &safe_unicode_character,
723
0
                byte_stream,
724
0
                byte_stream_size,
725
0
                &safe_byte_stream_index,
726
0
                error );
727
0
      break;
728
729
0
    case LIBUNA_CODEPAGE_MAC_SYMBOL:
730
0
      result = libuna_codepage_mac_symbol_copy_from_byte_stream(
731
0
                &safe_unicode_character,
732
0
                byte_stream,
733
0
                byte_stream_size,
734
0
                &safe_byte_stream_index,
735
0
                error );
736
0
      break;
737
738
0
    case LIBUNA_CODEPAGE_MAC_THAI:
739
0
      result = libuna_codepage_mac_thai_copy_from_byte_stream(
740
0
                &safe_unicode_character,
741
0
                byte_stream,
742
0
                byte_stream_size,
743
0
                &safe_byte_stream_index,
744
0
                error );
745
0
      break;
746
747
0
    case LIBUNA_CODEPAGE_MAC_TURKISH:
748
0
      result = libuna_codepage_mac_turkish_copy_from_byte_stream(
749
0
                &safe_unicode_character,
750
0
                byte_stream,
751
0
                byte_stream_size,
752
0
                &safe_byte_stream_index,
753
0
                error );
754
0
      break;
755
756
0
    case LIBUNA_CODEPAGE_MAC_UKRAINIAN:
757
0
      result = libuna_codepage_mac_ukrainian_copy_from_byte_stream(
758
0
                &safe_unicode_character,
759
0
                byte_stream,
760
0
                byte_stream_size,
761
0
                &safe_byte_stream_index,
762
0
                error );
763
0
      break;
764
765
0
    case LIBUNA_CODEPAGE_WINDOWS_874:
766
0
      result = libuna_codepage_windows_874_copy_from_byte_stream(
767
0
                &safe_unicode_character,
768
0
                byte_stream,
769
0
                byte_stream_size,
770
0
                &safe_byte_stream_index,
771
0
                error );
772
0
      break;
773
774
0
    case LIBUNA_CODEPAGE_WINDOWS_932:
775
0
      result = libuna_codepage_windows_932_copy_from_byte_stream(
776
0
                &safe_unicode_character,
777
0
                byte_stream,
778
0
                byte_stream_size,
779
0
                &safe_byte_stream_index,
780
0
                error );
781
0
      break;
782
783
0
    case LIBUNA_CODEPAGE_WINDOWS_936:
784
0
      result = libuna_codepage_windows_936_copy_from_byte_stream(
785
0
                &safe_unicode_character,
786
0
                byte_stream,
787
0
                byte_stream_size,
788
0
                &safe_byte_stream_index,
789
0
                error );
790
0
      break;
791
792
0
    case LIBUNA_CODEPAGE_WINDOWS_949:
793
0
      result = libuna_codepage_windows_949_copy_from_byte_stream(
794
0
                &safe_unicode_character,
795
0
                byte_stream,
796
0
                byte_stream_size,
797
0
                &safe_byte_stream_index,
798
0
                error );
799
0
      break;
800
801
0
    case LIBUNA_CODEPAGE_WINDOWS_950:
802
0
      result = libuna_codepage_windows_950_copy_from_byte_stream(
803
0
                &safe_unicode_character,
804
0
                byte_stream,
805
0
                byte_stream_size,
806
0
                &safe_byte_stream_index,
807
0
                error );
808
0
      break;
809
810
0
    case LIBUNA_CODEPAGE_WINDOWS_1250:
811
0
      result = libuna_codepage_windows_1250_copy_from_byte_stream(
812
0
                &safe_unicode_character,
813
0
                byte_stream,
814
0
                byte_stream_size,
815
0
                &safe_byte_stream_index,
816
0
                error );
817
0
      break;
818
819
0
    case LIBUNA_CODEPAGE_WINDOWS_1251:
820
0
      result = libuna_codepage_windows_1251_copy_from_byte_stream(
821
0
                &safe_unicode_character,
822
0
                byte_stream,
823
0
                byte_stream_size,
824
0
                &safe_byte_stream_index,
825
0
                error );
826
0
      break;
827
828
81.9k
    case LIBUNA_CODEPAGE_WINDOWS_1252:
829
81.9k
      result = libuna_codepage_windows_1252_copy_from_byte_stream(
830
81.9k
                &safe_unicode_character,
831
81.9k
                byte_stream,
832
81.9k
                byte_stream_size,
833
81.9k
                &safe_byte_stream_index,
834
81.9k
                error );
835
81.9k
      break;
836
837
0
    case LIBUNA_CODEPAGE_WINDOWS_1253:
838
0
      result = libuna_codepage_windows_1253_copy_from_byte_stream(
839
0
                &safe_unicode_character,
840
0
                byte_stream,
841
0
                byte_stream_size,
842
0
                &safe_byte_stream_index,
843
0
                error );
844
0
      break;
845
846
0
    case LIBUNA_CODEPAGE_WINDOWS_1254:
847
0
      result = libuna_codepage_windows_1254_copy_from_byte_stream(
848
0
                &safe_unicode_character,
849
0
                byte_stream,
850
0
                byte_stream_size,
851
0
                &safe_byte_stream_index,
852
0
                error );
853
0
      break;
854
855
0
    case LIBUNA_CODEPAGE_WINDOWS_1255:
856
0
      result = libuna_codepage_windows_1255_copy_from_byte_stream(
857
0
                &safe_unicode_character,
858
0
                byte_stream,
859
0
                byte_stream_size,
860
0
                &safe_byte_stream_index,
861
0
                error );
862
0
      break;
863
864
0
    case LIBUNA_CODEPAGE_WINDOWS_1256:
865
0
      result = libuna_codepage_windows_1256_copy_from_byte_stream(
866
0
                &safe_unicode_character,
867
0
                byte_stream,
868
0
                byte_stream_size,
869
0
                &safe_byte_stream_index,
870
0
                error );
871
0
      break;
872
873
0
    case LIBUNA_CODEPAGE_WINDOWS_1257:
874
0
      result = libuna_codepage_windows_1257_copy_from_byte_stream(
875
0
                &safe_unicode_character,
876
0
                byte_stream,
877
0
                byte_stream_size,
878
0
                &safe_byte_stream_index,
879
0
                error );
880
0
      break;
881
882
0
    case LIBUNA_CODEPAGE_WINDOWS_1258:
883
0
      result = libuna_codepage_windows_1258_copy_from_byte_stream(
884
0
                &safe_unicode_character,
885
0
                byte_stream,
886
0
                byte_stream_size,
887
0
                &safe_byte_stream_index,
888
0
                error );
889
0
      break;
890
891
0
    default:
892
0
      libcerror_error_set(
893
0
       error,
894
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
895
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
896
0
      "%s: unsupported codepage: %d.",
897
0
       function,
898
0
       codepage );
899
900
0
      return( -1 );
901
188k
  }
902
188k
  if( result == -1 )
903
0
  {
904
0
    libcerror_error_set(
905
0
     error,
906
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
907
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
908
0
     "%s: unable to copy Unicode character from byte stream.",
909
0
     function );
910
911
0
    return( -1 );
912
0
  }
913
188k
  *unicode_character = safe_unicode_character;
914
188k
  *byte_stream_index = safe_byte_stream_index;
915
916
188k
  return( result );
917
188k
}
918
919
/* Copies an Unicode character to a byte stream
920
 * Returns 1 if successful, 0 if the Unicode character is valid but not supported since it requires special handling or -1 on error
921
 */
922
int libuna_unicode_character_copy_to_byte_stream(
923
     libuna_unicode_character_t unicode_character,
924
     uint8_t *byte_stream,
925
     size_t byte_stream_size,
926
     size_t *byte_stream_index,
927
     int codepage,
928
     libcerror_error_t **error )
929
0
{
930
0
  static char *function         = "libuna_unicode_character_copy_to_byte_stream";
931
0
  size_t safe_byte_stream_index = 0;
932
0
  int result                    = 1;
933
934
0
  if( byte_stream == NULL )
935
0
  {
936
0
    libcerror_error_set(
937
0
     error,
938
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
939
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
940
0
     "%s: invalid byte stream.",
941
0
     function );
942
943
0
    return( -1 );
944
0
  }
945
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
946
0
  {
947
0
    libcerror_error_set(
948
0
     error,
949
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
950
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
951
0
     "%s: invalid byte stream size value exceeds maximum.",
952
0
     function );
953
954
0
    return( -1 );
955
0
  }
956
0
  if( byte_stream_index == NULL )
957
0
  {
958
0
    libcerror_error_set(
959
0
     error,
960
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
961
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
962
0
     "%s: invalid byte stream index.",
963
0
     function );
964
965
0
    return( -1 );
966
0
  }
967
0
  safe_byte_stream_index = *byte_stream_index;
968
969
0
  if( safe_byte_stream_index >= byte_stream_size )
970
0
  {
971
0
    libcerror_error_set(
972
0
     error,
973
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
974
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
975
0
     "%s: byte stream too small.",
976
0
     function );
977
978
0
    return( -1 );
979
0
  }
980
0
  switch( codepage )
981
0
  {
982
0
    case LIBUNA_CODEPAGE_ASCII:
983
0
      if( unicode_character < 0x0080 )
984
0
      {
985
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
986
0
      }
987
0
      else
988
0
      {
989
0
        byte_stream[ safe_byte_stream_index ] = 0x1a;
990
0
      }
991
0
      safe_byte_stream_index += 1;
992
993
0
      break;
994
995
0
    case LIBUNA_CODEPAGE_ISO_8859_1:
996
0
      if( unicode_character < 0x0100 )
997
0
      {
998
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
999
0
      }
1000
0
      else
1001
0
      {
1002
0
        byte_stream[ safe_byte_stream_index ] = 0x1a;
1003
0
      }
1004
0
      safe_byte_stream_index += 1;
1005
1006
0
      break;
1007
1008
0
    case LIBUNA_CODEPAGE_ISO_8859_2:
1009
0
      if( unicode_character < 0x00a0 )
1010
0
      {
1011
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1012
0
      }
1013
0
      else if( ( unicode_character >= 0x00a0 )
1014
0
            && ( unicode_character < 0x0120 ) )
1015
0
      {
1016
0
        unicode_character -= 0x00a0;
1017
1018
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x00a0[ unicode_character ];
1019
0
      }
1020
0
      else if( ( unicode_character >= 0x0138 )
1021
0
            && ( unicode_character < 0x0180 ) )
1022
0
      {
1023
0
        unicode_character -= 0x0138;
1024
1025
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x0138[ unicode_character ];
1026
0
      }
1027
0
      else if( ( unicode_character >= 0x02d8 )
1028
0
            && ( unicode_character < 0x02e0 ) )
1029
0
      {
1030
0
        unicode_character -= 0x02d8;
1031
1032
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x02d8[ unicode_character ];
1033
0
      }
1034
0
      else if( unicode_character == 0x02c7 )
1035
0
      {
1036
0
        byte_stream[ safe_byte_stream_index ] = 0xb7;
1037
0
      }
1038
0
      else
1039
0
      {
1040
0
        byte_stream[ safe_byte_stream_index ] = 0x1a;
1041
0
      }
1042
0
      safe_byte_stream_index += 1;
1043
1044
0
      break;
1045
1046
0
    case LIBUNA_CODEPAGE_ISO_8859_3:
1047
0
      if( unicode_character < 0x00a0 )
1048
0
      {
1049
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1050
0
      }
1051
0
      else if( ( unicode_character >= 0x00a0 )
1052
0
            && ( unicode_character < 0x0100 ) )
1053
0
      {
1054
0
        unicode_character -= 0x00a0;
1055
1056
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x00a0[ unicode_character ];
1057
0
      }
1058
0
      else if( ( unicode_character >= 0x0108 )
1059
0
            && ( unicode_character < 0x0110 ) )
1060
0
      {
1061
0
        unicode_character -= 0x0108;
1062
1063
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0108[ unicode_character ];
1064
0
      }
1065
0
      else if( ( unicode_character >= 0x0118 )
1066
0
            && ( unicode_character < 0x0128 ) )
1067
0
      {
1068
0
        unicode_character -= 0x0118;
1069
1070
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0118[ unicode_character ];
1071
0
      }
1072
0
      else if( ( unicode_character >= 0x0130 )
1073
0
            && ( unicode_character < 0x0138 ) )
1074
0
      {
1075
0
        unicode_character -= 0x0130;
1076
1077
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0130[ unicode_character ];
1078
0
      }
1079
0
      else if( ( unicode_character >= 0x0158 )
1080
0
            && ( unicode_character < 0x0160 ) )
1081
0
      {
1082
0
        unicode_character -= 0x0158;
1083
1084
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0158[ unicode_character ];
1085
0
      }
1086
0
      else switch( unicode_character )
1087
0
      {
1088
0
        case 0x016c:
1089
0
          byte_stream[ safe_byte_stream_index ] = 0xdd;
1090
0
          break;
1091
1092
0
        case 0x016d:
1093
0
          byte_stream[ safe_byte_stream_index ] = 0xfd;
1094
0
          break;
1095
1096
0
        case 0x017b:
1097
0
          byte_stream[ safe_byte_stream_index ] = 0xaf;
1098
0
          break;
1099
1100
0
        case 0x017c:
1101
0
          byte_stream[ safe_byte_stream_index ] = 0xbf;
1102
0
          break;
1103
1104
0
        case 0x02d8:
1105
0
          byte_stream[ safe_byte_stream_index ] = 0xa2;
1106
0
          break;
1107
1108
0
        case 0x02d9:
1109
0
          byte_stream[ safe_byte_stream_index ] = 0xff;
1110
0
          break;
1111
1112
0
        default:
1113
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1114
0
          break;
1115
0
      }
1116
0
      safe_byte_stream_index += 1;
1117
1118
0
      break;
1119
1120
0
    case LIBUNA_CODEPAGE_ISO_8859_4:
1121
0
      if( unicode_character < 0x00a0 )
1122
0
      {
1123
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1124
0
      }
1125
0
      else if( ( unicode_character >= 0x00a0 )
1126
0
            && ( unicode_character < 0x0158 ) )
1127
0
      {
1128
0
        unicode_character -= 0x00a0;
1129
1130
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_4_unicode_to_byte_stream_base_0x00a0[ unicode_character ];
1131
0
      }
1132
0
      else if( ( unicode_character >= 0x0160 )
1133
0
            && ( unicode_character < 0x0180 ) )
1134
0
      {
1135
0
        unicode_character -= 0x0160;
1136
1137
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_4_unicode_to_byte_stream_base_0x0160[ unicode_character ];
1138
0
      }
1139
0
      else switch( unicode_character )
1140
0
      {
1141
0
        case 0x02c7:
1142
0
          byte_stream[ safe_byte_stream_index ] = 0xb7;
1143
0
          break;
1144
1145
0
        case 0x02d9:
1146
0
          byte_stream[ safe_byte_stream_index ] = 0xff;
1147
0
          break;
1148
1149
0
        case 0x02db:
1150
0
          byte_stream[ safe_byte_stream_index ] = 0xb2;
1151
0
          break;
1152
1153
0
        default:
1154
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1155
0
          break;
1156
0
      }
1157
0
      safe_byte_stream_index += 1;
1158
1159
0
      break;
1160
1161
0
    case LIBUNA_CODEPAGE_ISO_8859_5:
1162
0
      if( unicode_character < 0x00a1 )
1163
0
      {
1164
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1165
0
      }
1166
0
      else if( ( unicode_character >= 0x0400 )
1167
0
            && ( unicode_character < 0x0460 ) )
1168
0
      {
1169
0
        unicode_character -= 0x0400;
1170
1171
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_5_unicode_to_byte_stream_base_0x0400[ unicode_character ];
1172
0
      }
1173
0
      else switch( unicode_character )
1174
0
      {
1175
0
        case 0x00a7:
1176
0
          byte_stream[ safe_byte_stream_index ] = 0xfd;
1177
0
          break;
1178
1179
0
        case 0x00ad:
1180
0
          byte_stream[ safe_byte_stream_index ] = 0xad;
1181
0
          break;
1182
1183
0
        case 0x2116:
1184
0
          byte_stream[ safe_byte_stream_index ] = 0xf0;
1185
0
          break;
1186
1187
0
        default:
1188
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1189
0
          break;
1190
0
      }
1191
0
      safe_byte_stream_index += 1;
1192
1193
0
      break;
1194
1195
0
    case LIBUNA_CODEPAGE_ISO_8859_6:
1196
0
      if( unicode_character < 0x00a1 )
1197
0
      {
1198
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1199
0
      }
1200
0
      else if( ( unicode_character >= 0x0618 )
1201
0
            && ( unicode_character < 0x658 ) )
1202
0
      {
1203
0
        unicode_character -= 0x0618;
1204
1205
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_6_unicode_to_byte_stream_base_0x0618[ unicode_character ];
1206
0
      }
1207
0
      else switch( unicode_character )
1208
0
      {
1209
0
        case 0x00a4:
1210
0
          byte_stream[ safe_byte_stream_index ] = 0xa4;
1211
0
          break;
1212
1213
0
        case 0x00ad:
1214
0
          byte_stream[ safe_byte_stream_index ] = 0xad;
1215
0
          break;
1216
1217
0
        case 0x060c:
1218
0
          byte_stream[ safe_byte_stream_index ] = 0xac;
1219
0
          break;
1220
1221
0
        default:
1222
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1223
0
          break;
1224
0
      }
1225
0
      safe_byte_stream_index += 1;
1226
1227
0
      break;
1228
1229
0
    case LIBUNA_CODEPAGE_ISO_8859_7:
1230
0
      if( unicode_character < 0x00a0 )
1231
0
      {
1232
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1233
0
      }
1234
0
      else if( ( unicode_character >= 0x00a0 )
1235
0
            && ( unicode_character < 0x00b8 ) )
1236
0
      {
1237
0
        unicode_character -= 0x00a0;
1238
1239
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_7_unicode_to_byte_stream_base_0x00a0[ unicode_character ];
1240
0
      }
1241
0
      else if( ( unicode_character >= 0x0380 )
1242
0
            && ( unicode_character < 0x03d0 ) )
1243
0
      {
1244
0
        unicode_character -= 0x0380;
1245
1246
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_7_unicode_to_byte_stream_base_0x0380[ unicode_character ];
1247
0
      }
1248
0
      else switch( unicode_character )
1249
0
      {
1250
0
        case 0x00bb:
1251
0
          byte_stream[ safe_byte_stream_index ] = 0xbb;
1252
0
          break;
1253
1254
0
        case 0x00bd:
1255
0
          byte_stream[ safe_byte_stream_index ] = 0xbd;
1256
0
          break;
1257
1258
0
        case 0x037a:
1259
0
          byte_stream[ safe_byte_stream_index ] = 0xaa;
1260
0
          break;
1261
1262
0
        case 0x2015:
1263
0
          byte_stream[ safe_byte_stream_index ] = 0xaf;
1264
0
          break;
1265
1266
0
        case 0x2018:
1267
0
          byte_stream[ safe_byte_stream_index ] = 0xa1;
1268
0
          break;
1269
1270
0
        case 0x2019:
1271
0
          byte_stream[ safe_byte_stream_index ] = 0xa2;
1272
0
          break;
1273
1274
0
        case 0x20ac:
1275
0
          byte_stream[ safe_byte_stream_index ] = 0xa4;
1276
0
          break;
1277
1278
0
        case 0x20af:
1279
0
          byte_stream[ safe_byte_stream_index ] = 0xa5;
1280
0
          break;
1281
1282
0
        default:
1283
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1284
0
          break;
1285
0
      }
1286
0
      safe_byte_stream_index += 1;
1287
1288
0
      break;
1289
1290
0
    case LIBUNA_CODEPAGE_ISO_8859_8:
1291
0
      if( unicode_character < 0x00a0 )
1292
0
      {
1293
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1294
0
      }
1295
0
      else if( ( unicode_character >= 0x00a0 )
1296
0
            && ( unicode_character < 0x00c0 ) )
1297
0
      {
1298
0
        unicode_character -= 0x00a0;
1299
1300
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_8_unicode_to_byte_stream_base_0x00a0[ unicode_character ];
1301
0
      }
1302
0
      else if( ( unicode_character >= 0x05d0 )
1303
0
            && ( unicode_character < 0x05f0 ) )
1304
0
      {
1305
0
        unicode_character -= 0x05d0;
1306
1307
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_8_unicode_to_byte_stream_base_0x05d0[ unicode_character ];
1308
0
      }
1309
0
      else switch( unicode_character )
1310
0
      {
1311
0
        case 0x00d7:
1312
0
          byte_stream[ safe_byte_stream_index ] = 0xaa;
1313
0
          break;
1314
1315
0
        case 0x00f7:
1316
0
          byte_stream[ safe_byte_stream_index ] = 0xba;
1317
0
          break;
1318
1319
0
        case 0x200e:
1320
0
          byte_stream[ safe_byte_stream_index ] = 0xfd;
1321
0
          break;
1322
1323
0
        case 0x200f:
1324
0
          byte_stream[ safe_byte_stream_index ] = 0xfe;
1325
0
          break;
1326
1327
0
        case 0x2017:
1328
0
          byte_stream[ safe_byte_stream_index ] = 0xdf;
1329
0
          break;
1330
1331
0
        default:
1332
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1333
0
          break;
1334
0
      }
1335
0
      safe_byte_stream_index += 1;
1336
1337
0
      break;
1338
1339
0
    case LIBUNA_CODEPAGE_ISO_8859_9:
1340
0
      if( unicode_character < 0x00d0 )
1341
0
      {
1342
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1343
0
      }
1344
0
      else if( ( unicode_character >= 0x00d0 )
1345
0
            && ( unicode_character < 0x0100 ) )
1346
0
      {
1347
0
        unicode_character -= 0x00d0;
1348
1349
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_9_unicode_to_byte_stream_base_0x00d0[ unicode_character ];
1350
0
      }
1351
0
      else switch( unicode_character )
1352
0
      {
1353
0
        case 0x011e:
1354
0
          byte_stream[ safe_byte_stream_index ] = 0xd0;
1355
0
          break;
1356
1357
0
        case 0x011f:
1358
0
          byte_stream[ safe_byte_stream_index ] = 0xf0;
1359
0
          break;
1360
1361
0
        case 0x0130:
1362
0
          byte_stream[ safe_byte_stream_index ] = 0xdd;
1363
0
          break;
1364
1365
0
        case 0x0131:
1366
0
          byte_stream[ safe_byte_stream_index ] = 0xfd;
1367
0
          break;
1368
1369
0
        case 0x015e:
1370
0
          byte_stream[ safe_byte_stream_index ] = 0xde;
1371
0
          break;
1372
1373
0
        case 0x015f:
1374
0
          byte_stream[ safe_byte_stream_index ] = 0xfe;
1375
0
          break;
1376
1377
0
        default:
1378
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1379
0
          break;
1380
0
      }
1381
0
      safe_byte_stream_index += 1;
1382
1383
0
      break;
1384
1385
0
    case LIBUNA_CODEPAGE_ISO_8859_10:
1386
0
      if( unicode_character < 0x00a1 )
1387
0
      {
1388
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1389
0
      }
1390
0
      else if( ( unicode_character >= 0x00c0 )
1391
0
            && ( unicode_character < 0x0150 ) )
1392
0
      {
1393
0
        unicode_character -= 0x00c0;
1394
1395
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_10_unicode_to_byte_stream_base_0x00c0[ unicode_character ];
1396
0
      }
1397
0
      else if( ( unicode_character >= 0x0160 )
1398
0
            && ( unicode_character < 0x0170 ) )
1399
0
      {
1400
0
        unicode_character -= 0x0160;
1401
1402
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_10_unicode_to_byte_stream_base_0x0160[ unicode_character ];
1403
0
      }
1404
0
      else switch( unicode_character )
1405
0
      {
1406
0
        case 0x00a7:
1407
0
          byte_stream[ safe_byte_stream_index ] = 0xa7;
1408
0
          break;
1409
1410
0
        case 0x00ad:
1411
0
          byte_stream[ safe_byte_stream_index ] = 0xad;
1412
0
          break;
1413
1414
0
        case 0x00b0:
1415
0
          byte_stream[ safe_byte_stream_index ] = 0xb0;
1416
0
          break;
1417
1418
0
        case 0x00b7:
1419
0
          byte_stream[ safe_byte_stream_index ] = 0xb7;
1420
0
          break;
1421
1422
0
        case 0x0172:
1423
0
          byte_stream[ safe_byte_stream_index ] = 0xd9;
1424
0
          break;
1425
1426
0
        case 0x0173:
1427
0
          byte_stream[ safe_byte_stream_index ] = 0xf9;
1428
0
          break;
1429
1430
0
        case 0x017d:
1431
0
          byte_stream[ safe_byte_stream_index ] = 0xac;
1432
0
          break;
1433
1434
0
        case 0x017e:
1435
0
          byte_stream[ safe_byte_stream_index ] = 0xbc;
1436
0
          break;
1437
1438
0
        case 0x2015:
1439
0
          byte_stream[ safe_byte_stream_index ] = 0xbd;
1440
0
          break;
1441
1442
0
        default:
1443
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1444
0
          break;
1445
0
      }
1446
0
      safe_byte_stream_index += 1;
1447
1448
0
      break;
1449
1450
0
    case LIBUNA_CODEPAGE_ISO_8859_11:
1451
0
      if( unicode_character < 0x00a1 )
1452
0
      {
1453
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1454
0
      }
1455
0
      else if( ( unicode_character >= 0x0e01 )
1456
0
            && ( unicode_character < 0x0e3b ) )
1457
0
      {
1458
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) ( unicode_character - 0x0d60 );
1459
0
      }
1460
0
      else if( ( unicode_character >= 0x0e3f )
1461
0
            && ( unicode_character < 0x0e5c ) )
1462
0
      {
1463
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) ( unicode_character - 0x0d60 );
1464
0
      }
1465
0
      else
1466
0
      {
1467
0
        byte_stream[ safe_byte_stream_index ] = 0x1a;
1468
0
      }
1469
0
      safe_byte_stream_index += 1;
1470
1471
0
      break;
1472
1473
0
    case LIBUNA_CODEPAGE_ISO_8859_13:
1474
0
      if( unicode_character < 0x00a0 )
1475
0
      {
1476
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1477
0
      }
1478
0
      else if( ( unicode_character >= 0x00a0 )
1479
0
            && ( unicode_character < 0x0180 ) )
1480
0
      {
1481
0
        unicode_character -= 0x00a0;
1482
1483
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_13_unicode_to_byte_stream_base_0x00a0[ unicode_character ];
1484
0
      }
1485
0
      else if( ( unicode_character >= 0x2018 )
1486
0
             && ( unicode_character < 0x2020 ) )
1487
0
      {
1488
0
        unicode_character -= 0x2018;
1489
1490
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_13_unicode_to_byte_stream_base_0x2018[ unicode_character ];
1491
0
      }
1492
0
      else
1493
0
      {
1494
0
        byte_stream[ safe_byte_stream_index ] = 0x1a;
1495
0
      }
1496
0
      safe_byte_stream_index += 1;
1497
1498
0
      break;
1499
1500
0
    case LIBUNA_CODEPAGE_ISO_8859_14:
1501
0
      if( unicode_character < 0x00a1 )
1502
0
      {
1503
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1504
0
      }
1505
0
      else if( ( unicode_character >= 0x00c0 )
1506
0
            && ( unicode_character < 0x0100 ) )
1507
0
      {
1508
0
        unicode_character -= 0x00c0;
1509
1510
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x00c0[ unicode_character ];
1511
0
      }
1512
0
      else if( ( unicode_character >= 0x0170 )
1513
0
            && ( unicode_character < 0x0178 ) )
1514
0
      {
1515
0
        unicode_character -= 0x0170;
1516
1517
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x0170[ unicode_character ];
1518
0
      }
1519
0
      else if( ( unicode_character >= 0x1e80 )
1520
0
            && ( unicode_character < 0x1e88 ) )
1521
0
      {
1522
0
        unicode_character -= 0x1e80;
1523
1524
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x1e80[ unicode_character ];
1525
0
      }
1526
0
      else switch( unicode_character )
1527
0
      {
1528
0
        case 0x00a3:
1529
0
          byte_stream[ safe_byte_stream_index ] = 0xa3;
1530
0
          break;
1531
1532
0
        case 0x00a7:
1533
0
          byte_stream[ safe_byte_stream_index ] = 0xa7;
1534
0
          break;
1535
1536
0
        case 0x00a9:
1537
0
          byte_stream[ safe_byte_stream_index ] = 0xa9;
1538
0
          break;
1539
1540
0
        case 0x00ad:
1541
0
          byte_stream[ safe_byte_stream_index ] = 0xad;
1542
0
          break;
1543
1544
0
        case 0x00ae:
1545
0
          byte_stream[ safe_byte_stream_index ] = 0xae;
1546
0
          break;
1547
1548
0
        case 0x00b6:
1549
0
          byte_stream[ safe_byte_stream_index ] = 0xb6;
1550
0
          break;
1551
1552
0
        case 0x010a:
1553
0
          byte_stream[ safe_byte_stream_index ] = 0xa4;
1554
0
          break;
1555
1556
0
        case 0x010b:
1557
0
          byte_stream[ safe_byte_stream_index ] = 0xa5;
1558
0
          break;
1559
1560
0
        case 0x0120:
1561
0
          byte_stream[ safe_byte_stream_index ] = 0xb2;
1562
0
          break;
1563
1564
0
        case 0x0121:
1565
0
          byte_stream[ safe_byte_stream_index ] = 0xb3;
1566
0
          break;
1567
1568
0
        case 0x0178:
1569
0
          byte_stream[ safe_byte_stream_index ] = 0xaf;
1570
0
          break;
1571
1572
0
        case 0x1e02:
1573
0
          byte_stream[ safe_byte_stream_index ] = 0xa1;
1574
0
          break;
1575
1576
0
        case 0x1e03:
1577
0
          byte_stream[ safe_byte_stream_index ] = 0xa2;
1578
0
          break;
1579
1580
0
        case 0x1e0a:
1581
0
          byte_stream[ safe_byte_stream_index ] = 0xa6;
1582
0
          break;
1583
1584
0
        case 0x1e0b:
1585
0
          byte_stream[ safe_byte_stream_index ] = 0xab;
1586
0
          break;
1587
1588
0
        case 0x1e1e:
1589
0
          byte_stream[ safe_byte_stream_index ] = 0xb0;
1590
0
          break;
1591
1592
0
        case 0x1e1f:
1593
0
          byte_stream[ safe_byte_stream_index ] = 0xb1;
1594
0
          break;
1595
1596
0
        case 0x1e40:
1597
0
          byte_stream[ safe_byte_stream_index ] = 0xb4;
1598
0
          break;
1599
1600
0
        case 0x1e41:
1601
0
          byte_stream[ safe_byte_stream_index ] = 0xb5;
1602
0
          break;
1603
1604
0
        case 0x1e56:
1605
0
          byte_stream[ safe_byte_stream_index ] = 0xb7;
1606
0
          break;
1607
1608
0
        case 0x1e57:
1609
0
          byte_stream[ safe_byte_stream_index ] = 0xb9;
1610
0
          break;
1611
1612
0
        case 0x1e60:
1613
0
          byte_stream[ safe_byte_stream_index ] = 0xbb;
1614
0
          break;
1615
1616
0
        case 0x1e61:
1617
0
          byte_stream[ safe_byte_stream_index ] = 0xbf;
1618
0
          break;
1619
1620
0
        case 0x1e6a:
1621
0
          byte_stream[ safe_byte_stream_index ] = 0xd7;
1622
0
          break;
1623
1624
0
        case 0x1e6b:
1625
0
          byte_stream[ safe_byte_stream_index ] = 0xf7;
1626
0
          break;
1627
1628
0
        case 0x1ef2:
1629
0
          byte_stream[ safe_byte_stream_index ] = 0xac;
1630
0
          break;
1631
1632
0
        case 0x1ef3:
1633
0
          byte_stream[ safe_byte_stream_index ] = 0xbc;
1634
0
          break;
1635
1636
0
        default:
1637
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1638
0
          break;
1639
0
      }
1640
0
      safe_byte_stream_index += 1;
1641
1642
0
      break;
1643
1644
0
    case LIBUNA_CODEPAGE_ISO_8859_15:
1645
0
      if( unicode_character < 0x00a0 )
1646
0
      {
1647
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1648
0
      }
1649
0
      else if( ( unicode_character >= 0x00a0 )
1650
0
            && ( unicode_character < 0x00c0 ) )
1651
0
      {
1652
0
        unicode_character -= 0x00a0;
1653
1654
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_15_unicode_to_byte_stream_base_0x00a0[ unicode_character ];
1655
0
      }
1656
0
      else if( unicode_character < 0x0100 )
1657
0
      {
1658
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1659
0
      }
1660
0
      else switch( unicode_character )
1661
0
      {
1662
0
        case 0x0152:
1663
0
          byte_stream[ safe_byte_stream_index ] = 0xbc;
1664
0
          break;
1665
1666
0
        case 0x0153:
1667
0
          byte_stream[ safe_byte_stream_index ] = 0xbd;
1668
0
          break;
1669
1670
0
        case 0x0160:
1671
0
          byte_stream[ safe_byte_stream_index ] = 0xa6;
1672
0
          break;
1673
1674
0
        case 0x0161:
1675
0
          byte_stream[ safe_byte_stream_index ] = 0xa8;
1676
0
          break;
1677
1678
0
        case 0x0178:
1679
0
          byte_stream[ safe_byte_stream_index ] = 0xbe;
1680
0
          break;
1681
1682
0
        case 0x017d:
1683
0
          byte_stream[ safe_byte_stream_index ] = 0xb4;
1684
0
          break;
1685
1686
0
        case 0x017e:
1687
0
          byte_stream[ safe_byte_stream_index ] = 0xb8;
1688
0
          break;
1689
1690
0
        case 0x20ac:
1691
0
          byte_stream[ safe_byte_stream_index ] = 0xa4;
1692
0
          break;
1693
1694
0
        default:
1695
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1696
0
          break;
1697
0
      }
1698
0
      safe_byte_stream_index += 1;
1699
1700
0
      break;
1701
1702
0
    case LIBUNA_CODEPAGE_ISO_8859_16:
1703
0
      if( unicode_character < 0x00a1 )
1704
0
      {
1705
0
        byte_stream[ safe_byte_stream_index ] = (uint8_t) unicode_character;
1706
0
      }
1707
0
      else if( ( unicode_character >= 0x00a8 )
1708
0
            && ( unicode_character < 0x0108 ) )
1709
0
      {
1710
0
        unicode_character -= 0x00a8;
1711
1712
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x00a8[ unicode_character ];
1713
0
      }
1714
0
      else if( ( unicode_character >= 0x0140 )
1715
0
            && ( unicode_character < 0x0148 ) )
1716
0
      {
1717
0
        unicode_character -= 0x0140;
1718
1719
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0140[ unicode_character ];
1720
0
      }
1721
0
      else if( ( unicode_character >= 0x0150 )
1722
0
            && ( unicode_character < 0x0158 ) )
1723
0
      {
1724
0
        unicode_character -= 0x0150;
1725
1726
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0150[ unicode_character ];
1727
0
      }
1728
0
      else if( ( unicode_character >= 0x0178 )
1729
0
            && ( unicode_character < 0x0180 ) )
1730
0
      {
1731
0
        unicode_character -= 0x0178;
1732
1733
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0178[ unicode_character ];
1734
0
      }
1735
0
      else if( ( unicode_character >= 0x0218 )
1736
0
            && ( unicode_character < 0x0220 ) )
1737
0
      {
1738
0
        unicode_character -= 0x0218;
1739
1740
0
        byte_stream[ safe_byte_stream_index ] = libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0218[ unicode_character ];
1741
0
      }
1742
0
      else switch( unicode_character )
1743
0
      {
1744
0
        case 0x00a7:
1745
0
          byte_stream[ safe_byte_stream_index ] = 0xa7;
1746
0
          break;
1747
1748
0
        case 0x010c:
1749
0
          byte_stream[ safe_byte_stream_index ] = 0xb2;
1750
0
          break;
1751
1752
0
        case 0x010d:
1753
0
          byte_stream[ safe_byte_stream_index ] = 0xb9;
1754
0
          break;
1755
1756
0
        case 0x0110:
1757
0
          byte_stream[ safe_byte_stream_index ] = 0xd0;
1758
0
          break;
1759
1760
0
        case 0x0111:
1761
0
          byte_stream[ safe_byte_stream_index ] = 0xf0;
1762
0
          break;
1763
1764
0
        case 0x0118:
1765
0
          byte_stream[ safe_byte_stream_index ] = 0xdd;
1766
0
          break;
1767
1768
0
        case 0x0119:
1769
0
          byte_stream[ safe_byte_stream_index ] = 0xfd;
1770
0
          break;
1771
1772
0
        case 0x015a:
1773
0
          byte_stream[ safe_byte_stream_index ] = 0xd7;
1774
0
          break;
1775
1776
0
        case 0x015b:
1777
0
          byte_stream[ safe_byte_stream_index ] = 0xf7;
1778
0
          break;
1779
1780
0
        case 0x0160:
1781
0
          byte_stream[ safe_byte_stream_index ] = 0xa6;
1782
0
          break;
1783
1784
0
        case 0x0161:
1785
0
          byte_stream[ safe_byte_stream_index ] = 0xa8;
1786
0
          break;
1787
1788
0
        case 0x0170:
1789
0
          byte_stream[ safe_byte_stream_index ] = 0xd8;
1790
0
          break;
1791
1792
0
        case 0x0171:
1793
0
          byte_stream[ safe_byte_stream_index ] = 0xf8;
1794
0
          break;
1795
1796
0
        case 0x201d:
1797
0
          byte_stream[ safe_byte_stream_index ] = 0xb5;
1798
0
          break;
1799
1800
0
        case 0x201e:
1801
0
          byte_stream[ safe_byte_stream_index ] = 0xa5;
1802
0
          break;
1803
1804
0
        case 0x20ac:
1805
0
          byte_stream[ safe_byte_stream_index ] = 0xa4;
1806
0
          break;
1807
1808
0
        default:
1809
0
          byte_stream[ safe_byte_stream_index ] = 0x1a;
1810
0
          break;
1811
0
      }
1812
0
      safe_byte_stream_index += 1;
1813
1814
0
      break;
1815
1816
0
    case LIBUNA_CODEPAGE_KOI8_R:
1817
0
      result = libuna_codepage_koi8_r_copy_to_byte_stream(
1818
0
                unicode_character,
1819
0
                byte_stream,
1820
0
                byte_stream_size,
1821
0
                &safe_byte_stream_index,
1822
0
                error );
1823
0
      break;
1824
1825
0
    case LIBUNA_CODEPAGE_KOI8_U:
1826
0
      result = libuna_codepage_koi8_u_copy_to_byte_stream(
1827
0
                unicode_character,
1828
0
                byte_stream,
1829
0
                byte_stream_size,
1830
0
                &safe_byte_stream_index,
1831
0
                error );
1832
0
      break;
1833
1834
0
    case LIBUNA_CODEPAGE_MAC_ARABIC:
1835
0
      result = libuna_codepage_mac_arabic_copy_to_byte_stream(
1836
0
                unicode_character,
1837
0
                byte_stream,
1838
0
                byte_stream_size,
1839
0
                &safe_byte_stream_index,
1840
0
                error );
1841
0
      break;
1842
1843
0
    case LIBUNA_CODEPAGE_MAC_CELTIC:
1844
0
      result = libuna_codepage_mac_celtic_copy_to_byte_stream(
1845
0
                unicode_character,
1846
0
                byte_stream,
1847
0
                byte_stream_size,
1848
0
                &safe_byte_stream_index,
1849
0
                error );
1850
0
      break;
1851
1852
0
    case LIBUNA_CODEPAGE_MAC_CENTRALEURROMAN:
1853
0
      result = libuna_codepage_mac_centraleurroman_copy_to_byte_stream(
1854
0
                unicode_character,
1855
0
                byte_stream,
1856
0
                byte_stream_size,
1857
0
                &safe_byte_stream_index,
1858
0
                error );
1859
0
      break;
1860
1861
0
    case LIBUNA_CODEPAGE_MAC_CROATIAN:
1862
0
      result = libuna_codepage_mac_croatian_copy_to_byte_stream(
1863
0
                unicode_character,
1864
0
                byte_stream,
1865
0
                byte_stream_size,
1866
0
                &safe_byte_stream_index,
1867
0
                error );
1868
0
      break;
1869
1870
0
    case LIBUNA_CODEPAGE_MAC_CYRILLIC:
1871
0
      result = libuna_codepage_mac_cyrillic_copy_to_byte_stream(
1872
0
                unicode_character,
1873
0
                byte_stream,
1874
0
                byte_stream_size,
1875
0
                &safe_byte_stream_index,
1876
0
                error );
1877
0
      break;
1878
1879
0
    case LIBUNA_CODEPAGE_MAC_DINGBATS:
1880
0
      result = libuna_codepage_mac_dingbats_copy_to_byte_stream(
1881
0
                unicode_character,
1882
0
                byte_stream,
1883
0
                byte_stream_size,
1884
0
                &safe_byte_stream_index,
1885
0
                error );
1886
0
      break;
1887
1888
0
    case LIBUNA_CODEPAGE_MAC_FARSI:
1889
0
      result = libuna_codepage_mac_farsi_copy_to_byte_stream(
1890
0
                unicode_character,
1891
0
                byte_stream,
1892
0
                byte_stream_size,
1893
0
                &safe_byte_stream_index,
1894
0
                error );
1895
0
      break;
1896
1897
0
    case LIBUNA_CODEPAGE_MAC_GAELIC:
1898
0
      result = libuna_codepage_mac_gaelic_copy_to_byte_stream(
1899
0
                unicode_character,
1900
0
                byte_stream,
1901
0
                byte_stream_size,
1902
0
                &safe_byte_stream_index,
1903
0
                error );
1904
0
      break;
1905
1906
0
    case LIBUNA_CODEPAGE_MAC_GREEK:
1907
0
      result = libuna_codepage_mac_greek_copy_to_byte_stream(
1908
0
                unicode_character,
1909
0
                byte_stream,
1910
0
                byte_stream_size,
1911
0
                &safe_byte_stream_index,
1912
0
                error );
1913
0
      break;
1914
1915
0
    case LIBUNA_CODEPAGE_MAC_ICELANDIC:
1916
0
      result = libuna_codepage_mac_icelandic_copy_to_byte_stream(
1917
0
                unicode_character,
1918
0
                byte_stream,
1919
0
                byte_stream_size,
1920
0
                &safe_byte_stream_index,
1921
0
                error );
1922
0
      break;
1923
1924
0
    case LIBUNA_CODEPAGE_MAC_INUIT:
1925
0
      result = libuna_codepage_mac_inuit_copy_to_byte_stream(
1926
0
                unicode_character,
1927
0
                byte_stream,
1928
0
                byte_stream_size,
1929
0
                &safe_byte_stream_index,
1930
0
                error );
1931
0
      break;
1932
1933
0
    case LIBUNA_CODEPAGE_MAC_ROMAN:
1934
0
      result = libuna_codepage_mac_roman_copy_to_byte_stream(
1935
0
                unicode_character,
1936
0
                byte_stream,
1937
0
                byte_stream_size,
1938
0
                &safe_byte_stream_index,
1939
0
                error );
1940
0
      break;
1941
1942
0
    case LIBUNA_CODEPAGE_MAC_ROMANIAN:
1943
0
      result = libuna_codepage_mac_romanian_copy_to_byte_stream(
1944
0
                unicode_character,
1945
0
                byte_stream,
1946
0
                byte_stream_size,
1947
0
                &safe_byte_stream_index,
1948
0
                error );
1949
0
      break;
1950
1951
0
    case LIBUNA_CODEPAGE_MAC_RUSSIAN:
1952
0
      result = libuna_codepage_mac_russian_copy_to_byte_stream(
1953
0
                unicode_character,
1954
0
                byte_stream,
1955
0
                byte_stream_size,
1956
0
                &safe_byte_stream_index,
1957
0
                error );
1958
0
      break;
1959
1960
0
    case LIBUNA_CODEPAGE_MAC_SYMBOL:
1961
0
      result = libuna_codepage_mac_symbol_copy_to_byte_stream(
1962
0
                unicode_character,
1963
0
                byte_stream,
1964
0
                byte_stream_size,
1965
0
                &safe_byte_stream_index,
1966
0
                error );
1967
0
      break;
1968
1969
0
    case LIBUNA_CODEPAGE_MAC_THAI:
1970
0
      result = libuna_codepage_mac_thai_copy_to_byte_stream(
1971
0
                unicode_character,
1972
0
                byte_stream,
1973
0
                byte_stream_size,
1974
0
                &safe_byte_stream_index,
1975
0
                error );
1976
0
      break;
1977
1978
0
    case LIBUNA_CODEPAGE_MAC_TURKISH:
1979
0
      result = libuna_codepage_mac_turkish_copy_to_byte_stream(
1980
0
                unicode_character,
1981
0
                byte_stream,
1982
0
                byte_stream_size,
1983
0
                &safe_byte_stream_index,
1984
0
                error );
1985
0
      break;
1986
1987
0
    case LIBUNA_CODEPAGE_MAC_UKRAINIAN:
1988
0
      result = libuna_codepage_mac_ukrainian_copy_to_byte_stream(
1989
0
                unicode_character,
1990
0
                byte_stream,
1991
0
                byte_stream_size,
1992
0
                &safe_byte_stream_index,
1993
0
                error );
1994
0
      break;
1995
1996
0
    case LIBUNA_CODEPAGE_WINDOWS_874:
1997
0
      result = libuna_codepage_windows_874_copy_to_byte_stream(
1998
0
                unicode_character,
1999
0
                byte_stream,
2000
0
                byte_stream_size,
2001
0
                &safe_byte_stream_index,
2002
0
                error );
2003
0
      break;
2004
2005
0
    case LIBUNA_CODEPAGE_WINDOWS_932:
2006
0
      result = libuna_codepage_windows_932_copy_to_byte_stream(
2007
0
                unicode_character,
2008
0
                byte_stream,
2009
0
                byte_stream_size,
2010
0
                &safe_byte_stream_index,
2011
0
                error );
2012
0
      break;
2013
2014
0
    case LIBUNA_CODEPAGE_WINDOWS_936:
2015
0
      result = libuna_codepage_windows_936_copy_to_byte_stream(
2016
0
                unicode_character,
2017
0
                byte_stream,
2018
0
                byte_stream_size,
2019
0
                &safe_byte_stream_index,
2020
0
                error );
2021
0
      break;
2022
2023
0
    case LIBUNA_CODEPAGE_WINDOWS_949:
2024
0
      result = libuna_codepage_windows_949_copy_to_byte_stream(
2025
0
                unicode_character,
2026
0
                byte_stream,
2027
0
                byte_stream_size,
2028
0
                &safe_byte_stream_index,
2029
0
                error );
2030
0
      break;
2031
2032
0
    case LIBUNA_CODEPAGE_WINDOWS_950:
2033
0
      result = libuna_codepage_windows_950_copy_to_byte_stream(
2034
0
                unicode_character,
2035
0
                byte_stream,
2036
0
                byte_stream_size,
2037
0
                &safe_byte_stream_index,
2038
0
                error );
2039
0
      break;
2040
2041
0
    case LIBUNA_CODEPAGE_WINDOWS_1250:
2042
0
      result = libuna_codepage_windows_1250_copy_to_byte_stream(
2043
0
                unicode_character,
2044
0
                byte_stream,
2045
0
                byte_stream_size,
2046
0
                &safe_byte_stream_index,
2047
0
                error );
2048
0
      break;
2049
2050
0
    case LIBUNA_CODEPAGE_WINDOWS_1251:
2051
0
      result = libuna_codepage_windows_1251_copy_to_byte_stream(
2052
0
                unicode_character,
2053
0
                byte_stream,
2054
0
                byte_stream_size,
2055
0
                &safe_byte_stream_index,
2056
0
                error );
2057
0
      break;
2058
2059
0
    case LIBUNA_CODEPAGE_WINDOWS_1252:
2060
0
      result = libuna_codepage_windows_1252_copy_to_byte_stream(
2061
0
                unicode_character,
2062
0
                byte_stream,
2063
0
                byte_stream_size,
2064
0
                &safe_byte_stream_index,
2065
0
                error );
2066
0
      break;
2067
2068
0
    case LIBUNA_CODEPAGE_WINDOWS_1253:
2069
0
      result = libuna_codepage_windows_1253_copy_to_byte_stream(
2070
0
                unicode_character,
2071
0
                byte_stream,
2072
0
                byte_stream_size,
2073
0
                &safe_byte_stream_index,
2074
0
                error );
2075
0
      break;
2076
2077
0
    case LIBUNA_CODEPAGE_WINDOWS_1254:
2078
0
      result = libuna_codepage_windows_1254_copy_to_byte_stream(
2079
0
                unicode_character,
2080
0
                byte_stream,
2081
0
                byte_stream_size,
2082
0
                &safe_byte_stream_index,
2083
0
                error );
2084
0
      break;
2085
2086
0
    case LIBUNA_CODEPAGE_WINDOWS_1255:
2087
0
      result = libuna_codepage_windows_1255_copy_to_byte_stream(
2088
0
                unicode_character,
2089
0
                byte_stream,
2090
0
                byte_stream_size,
2091
0
                &safe_byte_stream_index,
2092
0
                error );
2093
0
      break;
2094
2095
0
    case LIBUNA_CODEPAGE_WINDOWS_1256:
2096
0
      result = libuna_codepage_windows_1256_copy_to_byte_stream(
2097
0
                unicode_character,
2098
0
                byte_stream,
2099
0
                byte_stream_size,
2100
0
                &safe_byte_stream_index,
2101
0
                error );
2102
0
      break;
2103
2104
0
    case LIBUNA_CODEPAGE_WINDOWS_1257:
2105
0
      result = libuna_codepage_windows_1257_copy_to_byte_stream(
2106
0
                unicode_character,
2107
0
                byte_stream,
2108
0
                byte_stream_size,
2109
0
                &safe_byte_stream_index,
2110
0
                error );
2111
0
      break;
2112
2113
0
    case LIBUNA_CODEPAGE_WINDOWS_1258:
2114
0
      result = libuna_codepage_windows_1258_copy_to_byte_stream(
2115
0
                unicode_character,
2116
0
                byte_stream,
2117
0
                byte_stream_size,
2118
0
                &safe_byte_stream_index,
2119
0
                error );
2120
0
      break;
2121
2122
0
    default:
2123
0
      libcerror_error_set(
2124
0
       error,
2125
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2126
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2127
0
      "%s: unsupported codepage: %d.",
2128
0
       function,
2129
0
             codepage );
2130
2131
0
      return( -1 );
2132
0
  }
2133
0
  if( result == -1 )
2134
0
  {
2135
0
    libcerror_error_set(
2136
0
     error,
2137
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2138
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2139
0
     "%s: unable to copy Unicode character to byte stream.",
2140
0
     function );
2141
2142
0
    return( -1 );
2143
0
  }
2144
0
  *byte_stream_index = safe_byte_stream_index;
2145
2146
0
  return( result );
2147
0
}
2148
2149
/* Determines the size of an UTF-7 stream character from an Unicode character
2150
 * Adds the size to the UTF-7 stream character size value
2151
 * Returns 1 if successful or -1 on error
2152
 */
2153
int libuna_unicode_character_size_to_utf7_stream(
2154
     libuna_unicode_character_t unicode_character,
2155
     size_t *utf7_stream_character_size,
2156
     uint32_t *utf7_stream_base64_data,
2157
     libcerror_error_t **error )
2158
0
{
2159
0
  static char *function                    = "libuna_unicode_character_size_to_utf7_stream";
2160
0
  libuna_utf16_character_t utf16_surrogate = 0;
2161
0
  size_t safe_utf7_stream_character_size   = 0;
2162
0
  uint32_t base64_triplet                  = 0;
2163
0
  uint32_t safe_utf7_stream_base64_data    = 0;
2164
0
  uint8_t base64_encode_character          = 0;
2165
0
  uint8_t byte_bit_shift                   = 0;
2166
0
  uint8_t current_byte                     = 0;
2167
0
  uint8_t number_of_bytes                  = 0;
2168
2169
0
  if( utf7_stream_character_size == NULL )
2170
0
  {
2171
0
    libcerror_error_set(
2172
0
     error,
2173
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2174
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2175
0
     "%s: invalid UTF-7 stream character size.",
2176
0
     function );
2177
2178
0
    return( -1 );
2179
0
  }
2180
0
  if( utf7_stream_base64_data == NULL )
2181
0
  {
2182
0
    libcerror_error_set(
2183
0
     error,
2184
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2185
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2186
0
     "%s: invalid UTF-7 stream base64 data.",
2187
0
     function );
2188
2189
0
    return( -1 );
2190
0
  }
2191
0
  safe_utf7_stream_character_size = *utf7_stream_character_size;
2192
0
  safe_utf7_stream_base64_data    = *utf7_stream_base64_data;
2193
2194
  /* Determine if the Unicode character is valid
2195
   */
2196
0
  if( unicode_character > LIBUNA_UNICODE_CHARACTER_MAX )
2197
0
  {
2198
0
    unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
2199
0
  }
2200
  /* The + character must be escaped
2201
   */
2202
0
  if( unicode_character == (libuna_unicode_character_t) '+' )
2203
0
  {
2204
0
  }
2205
  /* Allow for the end of string character
2206
   */
2207
0
  else if( unicode_character == 0 )
2208
0
  {
2209
0
  }
2210
0
  else if( ( unicode_character >= 256 )
2211
0
        || ( libuna_unicode_character_utf7_valid_directly_encoded_character[ (uint8_t) unicode_character ] == 0 ) )
2212
0
  {
2213
0
    base64_encode_character = 1;
2214
0
  }
2215
0
  if( base64_encode_character == 0 )
2216
0
  {
2217
0
    if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) != 0 )
2218
0
    {
2219
0
      safe_utf7_stream_base64_data = 0;
2220
0
    }
2221
0
    safe_utf7_stream_character_size += 1;
2222
2223
    /* The + character must be escaped
2224
     */
2225
0
    if( unicode_character == (libuna_unicode_character_t) '+' )
2226
0
    {
2227
0
      safe_utf7_stream_character_size += 1;
2228
0
    }
2229
0
  }
2230
0
  else
2231
0
  {
2232
    /* Escape the base64 encoded characters with a +
2233
     */
2234
0
    if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) == 0 )
2235
0
    {
2236
0
      safe_utf7_stream_character_size += 1;
2237
0
    }
2238
    /* Otherwise continue the previously base64 encoded characters
2239
     */
2240
0
    else
2241
0
    {
2242
0
      base64_triplet  = safe_utf7_stream_base64_data & 0x00ffffff;
2243
0
      number_of_bytes = ( safe_utf7_stream_base64_data >> 24 ) & 0x03;
2244
0
      current_byte    = ( safe_utf7_stream_base64_data >> 28 ) & 0x03;
2245
2246
0
      if( number_of_bytes > 0 )
2247
0
      {
2248
0
        if( safe_utf7_stream_character_size < (size_t) ( number_of_bytes + 1 ) )
2249
0
        {
2250
0
          libcerror_error_set(
2251
0
           error,
2252
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2253
0
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2254
0
           "%s: invalid UTF-7 stream character size value out of bounds.",
2255
0
           function );
2256
2257
0
          return( -1 );
2258
0
        }
2259
        /* Correct the size for the last partial base64 stream
2260
         */
2261
0
        safe_utf7_stream_character_size -= number_of_bytes + 1;
2262
0
      }
2263
0
      if( safe_utf7_stream_character_size < 1 )
2264
0
      {
2265
0
        libcerror_error_set(
2266
0
         error,
2267
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2268
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2269
0
         "%s: invalid UTF-7 stream character size value out of bounds.",
2270
0
         function );
2271
2272
0
        return( -1 );
2273
0
      }
2274
      /* Correct the size for the base64 stream termination character
2275
       */
2276
0
      safe_utf7_stream_character_size -= 1;
2277
0
    }
2278
0
    safe_utf7_stream_base64_data = LIBUNA_UTF7_IS_BASE64_ENCODED;
2279
2280
0
    if( unicode_character > LIBUNA_UNICODE_BASIC_MULTILINGUAL_PLANE_MAX )
2281
0
    {
2282
0
      unicode_character -= 0x010000;
2283
2284
0
      utf16_surrogate = (libuna_utf16_character_t) ( ( unicode_character >> 10 ) + LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START );
2285
2286
0
      byte_bit_shift   = 16 - ( current_byte * 8 );
2287
0
      base64_triplet  += (uint32_t) ( ( utf16_surrogate >> 8 ) & 0xff ) << byte_bit_shift;
2288
0
      current_byte    += 1;
2289
0
      number_of_bytes += 1;
2290
2291
0
      if( number_of_bytes == 3 )
2292
0
      {
2293
0
        safe_utf7_stream_character_size += 4;
2294
0
        number_of_bytes                  = 0;
2295
0
        current_byte                     = 0;
2296
0
        base64_triplet                   = 0;
2297
0
      }
2298
0
      byte_bit_shift   = 16 - ( current_byte * 8 );
2299
0
      base64_triplet  += (uint32_t) ( utf16_surrogate & 0xff ) << byte_bit_shift;
2300
0
      current_byte    += 1;
2301
0
      number_of_bytes += 1;
2302
2303
0
      if( number_of_bytes == 3 )
2304
0
      {
2305
0
        safe_utf7_stream_character_size += 4;
2306
0
        number_of_bytes                  = 0;
2307
0
        current_byte                     = 0;
2308
0
        base64_triplet                   = 0;
2309
0
      }
2310
0
      unicode_character = (libuna_utf16_character_t) ( ( unicode_character & 0x03ff ) + LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START );
2311
0
    }
2312
0
    byte_bit_shift   = 16 - ( current_byte * 8 );
2313
0
    base64_triplet  += (uint32_t) ( ( unicode_character >> 8 ) & 0xff ) << byte_bit_shift;
2314
0
    current_byte    += 1;
2315
0
    number_of_bytes += 1;
2316
2317
0
    if( number_of_bytes == 3 )
2318
0
    {
2319
0
      safe_utf7_stream_character_size += 4;
2320
0
      number_of_bytes                  = 0;
2321
0
      current_byte                     = 0;
2322
0
      base64_triplet                   = 0;
2323
0
    }
2324
0
    byte_bit_shift   = 16 - ( current_byte * 8 );
2325
0
    base64_triplet  += (uint32_t) ( unicode_character & 0xff ) << byte_bit_shift;
2326
0
    current_byte    += 1;
2327
0
    number_of_bytes += 1;
2328
2329
0
    if( number_of_bytes == 3 )
2330
0
    {
2331
0
      safe_utf7_stream_character_size += 4;
2332
0
      number_of_bytes                  = 0;
2333
0
      current_byte                     = 0;
2334
0
      base64_triplet                   = 0;
2335
0
    }
2336
    /* Terminate the base64 encoded characters
2337
     */
2338
0
    if( number_of_bytes > 0 )
2339
0
    {
2340
0
      safe_utf7_stream_character_size += number_of_bytes + 1;
2341
0
    }
2342
0
    safe_utf7_stream_character_size += 1;
2343
0
  }
2344
0
  if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) != 0 )
2345
0
  {
2346
0
    safe_utf7_stream_base64_data  = LIBUNA_UTF7_IS_BASE64_ENCODED;
2347
0
    safe_utf7_stream_base64_data |= (uint32_t) current_byte << 28;
2348
0
    safe_utf7_stream_base64_data |= (uint32_t) number_of_bytes << 24;
2349
0
    safe_utf7_stream_base64_data |= base64_triplet & 0x00ffffff;
2350
0
  }
2351
0
  *utf7_stream_character_size = safe_utf7_stream_character_size;
2352
0
  *utf7_stream_base64_data    = safe_utf7_stream_base64_data;
2353
2354
0
  return( 1 );
2355
0
}
2356
2357
/* Copies an Unicode character from an UTF-7 stream
2358
 * The bits of the base64 data contain:
2359
 *   0 - 23 the base64 triplet
2360
 *  24 - 25 the number of bytes in the triplet
2361
 *  26 - 27 unused
2362
 *  28 - 29 the current byte
2363
 *       30 unused
2364
 *       31 flag to indicate the current UTF-7 characters are (modified) base64 encoded
2365
 *
2366
 * Returns 1 if successful or -1 on error
2367
 */
2368
int libuna_unicode_character_copy_from_utf7_stream(
2369
     libuna_unicode_character_t *unicode_character,
2370
     const uint8_t *utf7_stream,
2371
     size_t utf7_stream_size,
2372
     size_t *utf7_stream_index,
2373
     uint32_t *utf7_stream_base64_data,
2374
     libcerror_error_t **error )
2375
0
{
2376
0
  static char *function                             = "libuna_unicode_character_copy_from_utf7_stream";
2377
0
  libuna_unicode_character_t safe_unicode_character = 0;
2378
0
  libuna_utf16_character_t utf16_surrogate          = 0;
2379
0
  size_t safe_utf7_stream_index                     = 0;
2380
0
  uint32_t base64_triplet                           = 0;
2381
0
  uint32_t safe_utf7_stream_base64_data             = 0;
2382
0
  uint8_t byte_bit_shift                            = 0;
2383
0
  uint8_t current_byte                              = 0;
2384
0
  uint8_t number_of_bytes                           = 0;
2385
0
  uint8_t padding_size                              = 0;
2386
0
  uint8_t utf7_character_value                      = 0;
2387
2388
0
  if( unicode_character == NULL )
2389
0
  {
2390
0
    libcerror_error_set(
2391
0
     error,
2392
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2393
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2394
0
     "%s: invalid Unicode character.",
2395
0
     function );
2396
2397
0
    return( -1 );
2398
0
  }
2399
0
  if( utf7_stream == NULL )
2400
0
  {
2401
0
    libcerror_error_set(
2402
0
     error,
2403
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2404
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2405
0
     "%s: invalid UTF-7 stream.",
2406
0
     function );
2407
2408
0
    return( -1 );
2409
0
  }
2410
0
  if( utf7_stream_size > (size_t) SSIZE_MAX )
2411
0
  {
2412
0
    libcerror_error_set(
2413
0
     error,
2414
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2415
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2416
0
     "%s: invalid UTF-7 stream size value exceeds maximum.",
2417
0
     function );
2418
2419
0
    return( -1 );
2420
0
  }
2421
0
  if( utf7_stream_index == NULL )
2422
0
  {
2423
0
    libcerror_error_set(
2424
0
     error,
2425
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2426
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2427
0
     "%s: invalid UTF-7 stream index.",
2428
0
     function );
2429
2430
0
    return( -1 );
2431
0
  }
2432
0
  if( utf7_stream_base64_data == NULL )
2433
0
  {
2434
0
    libcerror_error_set(
2435
0
     error,
2436
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2437
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2438
0
     "%s: invalid UTF-7 base64 data.",
2439
0
     function );
2440
2441
0
    return( -1 );
2442
0
  }
2443
0
  safe_utf7_stream_index       = *utf7_stream_index;
2444
0
  safe_utf7_stream_base64_data = *utf7_stream_base64_data;
2445
2446
0
  if( safe_utf7_stream_index >= utf7_stream_size )
2447
0
  {
2448
0
    libcerror_error_set(
2449
0
     error,
2450
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2451
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2452
0
     "%s: UTF-7 stream too small.",
2453
0
     function );
2454
2455
0
    return( -1 );
2456
0
  }
2457
0
  if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) != 0 )
2458
0
  {
2459
0
    base64_triplet  = safe_utf7_stream_base64_data & 0x00ffffff;
2460
0
    number_of_bytes = ( safe_utf7_stream_base64_data >> 24 ) & 0x03;
2461
0
    current_byte    = ( safe_utf7_stream_base64_data >> 28 ) & 0x03;
2462
2463
0
    if( current_byte >= number_of_bytes )
2464
0
    {
2465
0
      if( safe_utf7_stream_index >= utf7_stream_size )
2466
0
      {
2467
0
        libcerror_error_set(
2468
0
         error,
2469
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2470
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2471
0
         "%s: invalid UTF-7 stream character size value out of bounds.",
2472
0
         function );
2473
2474
0
        return( -1 );
2475
0
      }
2476
0
      utf7_character_value = utf7_stream[ safe_utf7_stream_index ];
2477
2478
      /* Any character not in the modified base64 alphabet terminates the base64 encoded sequence
2479
       */
2480
0
      if( libuna_unicode_character_utf7_valid_base64_character[ utf7_character_value ] == 0 )
2481
0
      {
2482
0
        safe_utf7_stream_base64_data = 0;
2483
0
      }
2484
0
    }
2485
0
  }
2486
0
  if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) == 0 )
2487
0
  {
2488
0
    if( safe_utf7_stream_index >= utf7_stream_size )
2489
0
    {
2490
0
      libcerror_error_set(
2491
0
       error,
2492
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2493
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2494
0
       "%s: invalid UTF-7 stream character size value out of bounds.",
2495
0
       function );
2496
2497
0
      return( -1 );
2498
0
    }
2499
0
    utf7_character_value = utf7_stream[ safe_utf7_stream_index ];
2500
2501
    /* Determine if the character is modified base64 encoded
2502
     * or a + character
2503
     */
2504
0
    if( utf7_character_value == (uint8_t) '+' )
2505
0
    {
2506
0
      if( ( safe_utf7_stream_index + 1 ) >= utf7_stream_size )
2507
0
      {
2508
0
        libcerror_error_set(
2509
0
         error,
2510
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2511
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2512
0
         "%s: invalid UTF-7 stream character size value out of bounds.",
2513
0
         function );
2514
2515
0
        return( -1 );
2516
0
      }
2517
0
      if( utf7_stream[ safe_utf7_stream_index + 1 ] != (uint8_t) '-' )
2518
0
      {
2519
0
        safe_utf7_stream_base64_data = LIBUNA_UTF7_IS_BASE64_ENCODED;
2520
2521
0
        safe_utf7_stream_index++;
2522
0
      }
2523
0
    }
2524
    /* Allow for the end of string character
2525
     */
2526
0
    else if( utf7_character_value == 0 )
2527
0
    {
2528
0
    }
2529
0
    else if( libuna_unicode_character_utf7_valid_directly_encoded_character[ utf7_character_value ] == 0 )
2530
0
    {
2531
0
      libcerror_error_set(
2532
0
       error,
2533
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2534
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2535
0
       "%s: invalid directly encoded UTF-7 character byte: 0x%02" PRIx8 ".",
2536
0
       function,
2537
0
       utf7_character_value );
2538
2539
0
      return( -1 );
2540
0
    }
2541
0
  }
2542
0
  if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) == 0 )
2543
0
  {
2544
0
    safe_unicode_character = utf7_stream[ safe_utf7_stream_index++ ];
2545
2546
0
    if( ( safe_unicode_character == (libuna_unicode_character_t) '+' )
2547
0
     && ( utf7_stream[ safe_utf7_stream_index ] == (uint8_t) '-' ) )
2548
0
    {
2549
0
      safe_utf7_stream_index++;
2550
0
    }
2551
0
  }
2552
0
  else if( ( number_of_bytes == 0 )
2553
0
        || ( current_byte >= number_of_bytes ) )
2554
0
  {
2555
0
    if( libuna_base64_triplet_copy_from_base64_stream(
2556
0
         &base64_triplet,
2557
0
         utf7_stream,
2558
0
         utf7_stream_size - 1,
2559
0
         &safe_utf7_stream_index,
2560
0
         &padding_size,
2561
0
         LIBUNA_BASE64_VARIANT_UTF7,
2562
0
         error ) != 1 )
2563
0
    {
2564
0
      libcerror_error_set(
2565
0
       error,
2566
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
2567
0
       LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
2568
0
       "%s: unable to copy base64 encoded UTF-7 characters.",
2569
0
       function );
2570
2571
0
      return( -1 );
2572
0
    }
2573
0
    if( padding_size > 2 )
2574
0
    {
2575
0
      libcerror_error_set(
2576
0
       error,
2577
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2578
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2579
0
       "%s: unsupported padding in base64 encoded UTF-7 characters.",
2580
0
       function );
2581
2582
0
      return( -1 );
2583
0
    }
2584
0
    number_of_bytes = 3 - padding_size;
2585
0
    current_byte    = 0;
2586
0
  }
2587
0
  if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) != 0 )
2588
0
  {
2589
0
    byte_bit_shift         = 16 - ( current_byte * 8 );
2590
0
    safe_unicode_character = ( ( base64_triplet >> byte_bit_shift ) & 0x000000ffUL ) << 8;
2591
0
    current_byte          += 1;
2592
2593
0
    if( current_byte >= number_of_bytes )
2594
0
    {
2595
0
      if( libuna_base64_triplet_copy_from_base64_stream(
2596
0
           &base64_triplet,
2597
0
           utf7_stream,
2598
0
           utf7_stream_size - 1,
2599
0
           &safe_utf7_stream_index,
2600
0
           &padding_size,
2601
0
           LIBUNA_BASE64_VARIANT_UTF7,
2602
0
           error ) != 1 )
2603
0
      {
2604
0
        libcerror_error_set(
2605
0
         error,
2606
0
         LIBCERROR_ERROR_DOMAIN_CONVERSION,
2607
0
         LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
2608
0
         "%s: unable to copy base64 encoded UTF-7 characters.",
2609
0
         function );
2610
2611
0
        return( -1 );
2612
0
      }
2613
0
      if( padding_size > 2 )
2614
0
      {
2615
0
        libcerror_error_set(
2616
0
         error,
2617
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2618
0
         LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2619
0
         "%s: unsupported padding in base64 encoded UTF-7 characters.",
2620
0
         function );
2621
2622
0
        return( -1 );
2623
0
      }
2624
0
      number_of_bytes = 3 - padding_size;
2625
0
      current_byte    = 0;
2626
0
    }
2627
0
    byte_bit_shift          = 16 - ( current_byte * 8 );
2628
0
    safe_unicode_character += ( base64_triplet >> byte_bit_shift ) & 0x000000ffUL;
2629
0
    current_byte           += 1;
2630
2631
0
    if( ( safe_unicode_character >= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START )
2632
0
     && ( safe_unicode_character <= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_END ) )
2633
0
    {
2634
0
      if( current_byte >= number_of_bytes )
2635
0
      {
2636
0
        if( libuna_base64_triplet_copy_from_base64_stream(
2637
0
             &base64_triplet,
2638
0
             utf7_stream,
2639
0
             utf7_stream_size - 1,
2640
0
             &safe_utf7_stream_index,
2641
0
             &padding_size,
2642
0
             LIBUNA_BASE64_VARIANT_UTF7,
2643
0
             error ) != 1 )
2644
0
        {
2645
0
          libcerror_error_set(
2646
0
           error,
2647
0
           LIBCERROR_ERROR_DOMAIN_CONVERSION,
2648
0
           LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
2649
0
           "%s: unable to copy base64 encoded UTF-7 characters.",
2650
0
           function );
2651
2652
0
          return( -1 );
2653
0
        }
2654
0
        if( padding_size > 2 )
2655
0
        {
2656
0
          libcerror_error_set(
2657
0
           error,
2658
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2659
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2660
0
           "%s: unsupported padding in base64 encoded UTF-7 characters.",
2661
0
           function );
2662
2663
0
          return( -1 );
2664
0
        }
2665
0
        number_of_bytes = 3 - padding_size;
2666
0
        current_byte    = 0;
2667
0
      }
2668
0
      byte_bit_shift  = 16 - ( current_byte * 8 );
2669
0
      utf16_surrogate = ( ( base64_triplet >> byte_bit_shift ) & 0x000000ffUL ) << 8;
2670
0
      current_byte   += 1;
2671
2672
0
      if( current_byte >= number_of_bytes )
2673
0
      {
2674
0
        if( libuna_base64_triplet_copy_from_base64_stream(
2675
0
             &base64_triplet,
2676
0
             utf7_stream,
2677
0
             utf7_stream_size - 1,
2678
0
             &safe_utf7_stream_index,
2679
0
             &padding_size,
2680
0
             LIBUNA_BASE64_VARIANT_UTF7,
2681
0
             error ) != 1 )
2682
0
        {
2683
0
          libcerror_error_set(
2684
0
           error,
2685
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2686
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2687
0
           "%s: unable to retrieve base64 encoded UTF-7 characters.",
2688
0
           function );
2689
2690
0
          return( -1 );
2691
0
        }
2692
0
        if( padding_size > 2 )
2693
0
        {
2694
0
          libcerror_error_set(
2695
0
           error,
2696
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2697
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2698
0
           "%s: unsupported padding in base64 encoded UTF-7 characters.",
2699
0
           function );
2700
2701
0
          return( -1 );
2702
0
        }
2703
0
        number_of_bytes = 3 - padding_size;
2704
0
        current_byte    = 0;
2705
0
      }
2706
0
      byte_bit_shift   = 16 - ( current_byte * 8 );
2707
0
      utf16_surrogate += ( base64_triplet >> byte_bit_shift ) & 0x000000ffUL;
2708
0
      current_byte    += 1;
2709
2710
      /* Determine if the UTF-16 character is within the low surrogate range
2711
       */
2712
0
      if( ( utf16_surrogate >= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START )
2713
0
       && ( utf16_surrogate <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
2714
0
      {
2715
0
        safe_unicode_character  -= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START;
2716
0
        safe_unicode_character <<= 10;
2717
0
        safe_unicode_character  += utf16_surrogate - LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START;
2718
0
        safe_unicode_character  += 0x010000;
2719
0
      }
2720
0
      else
2721
0
      {
2722
0
        safe_unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
2723
0
      }
2724
0
    }
2725
0
    if( safe_utf7_stream_index >= utf7_stream_size )
2726
0
    {
2727
0
      libcerror_error_set(
2728
0
       error,
2729
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2730
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2731
0
       "%s: UTF-7 stream too small.",
2732
0
       function );
2733
2734
0
      return( -1 );
2735
0
    }
2736
0
    if( ( current_byte >= number_of_bytes )
2737
0
     && ( utf7_stream[ safe_utf7_stream_index ] == (uint8_t) '-' ) )
2738
0
    {
2739
0
      safe_utf7_stream_base64_data = 0;
2740
2741
0
      safe_utf7_stream_index++;
2742
0
    }
2743
0
  }
2744
0
  if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) != 0 )
2745
0
  {
2746
0
    safe_utf7_stream_base64_data  = LIBUNA_UTF7_IS_BASE64_ENCODED;
2747
0
    safe_utf7_stream_base64_data |= (uint32_t) current_byte << 28;
2748
0
    safe_utf7_stream_base64_data |= (uint32_t) number_of_bytes << 24;
2749
0
    safe_utf7_stream_base64_data |= base64_triplet & 0x00ffffff;
2750
0
  }
2751
0
  *unicode_character       = safe_unicode_character;
2752
0
  *utf7_stream_index       = safe_utf7_stream_index;
2753
0
  *utf7_stream_base64_data = safe_utf7_stream_base64_data;
2754
2755
0
  return( 1 );
2756
0
}
2757
2758
/* Copies an Unicode character into a UTF-7 stream
2759
 * The bits of the base64 data contain:
2760
 *   0 - 23 the base64 triplet
2761
 *  24 - 25 the number of bytes in the triplet
2762
 *  26 - 27 unused
2763
 *  28 - 29 the current byte
2764
 *       30 unused
2765
 *       31 flag to indicate the current UTF-7 characters are (modified) base64 encoded
2766
 *
2767
 * Returns 1 if successful or -1 on error
2768
 */
2769
int libuna_unicode_character_copy_to_utf7_stream(
2770
     libuna_unicode_character_t unicode_character,
2771
     uint8_t *utf7_stream,
2772
     size_t utf7_stream_size,
2773
     size_t *utf7_stream_index,
2774
     uint32_t *utf7_stream_base64_data,
2775
     libcerror_error_t **error )
2776
0
{
2777
0
  static char *function                    = "libuna_unicode_character_copy_to_utf7_stream";
2778
0
  libuna_utf16_character_t utf16_surrogate = 0;
2779
0
  size_t safe_utf7_stream_index            = 0;
2780
0
  uint32_t base64_triplet                  = 0;
2781
0
  uint32_t safe_utf7_stream_base64_data    = 0;
2782
0
  uint8_t base64_encode_character          = 0;
2783
0
  uint8_t byte_bit_shift                   = 0;
2784
0
  uint8_t current_byte                     = 0;
2785
0
  uint8_t number_of_bytes                  = 0;
2786
2787
0
  if( utf7_stream == NULL )
2788
0
  {
2789
0
    libcerror_error_set(
2790
0
     error,
2791
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2792
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2793
0
     "%s: invalid UTF-7 stream.",
2794
0
     function );
2795
2796
0
    return( -1 );
2797
0
  }
2798
0
  if( utf7_stream_size > (size_t) SSIZE_MAX )
2799
0
  {
2800
0
    libcerror_error_set(
2801
0
     error,
2802
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2803
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2804
0
     "%s: invalid UTF-7 stream size value exceeds maximum.",
2805
0
     function );
2806
2807
0
    return( -1 );
2808
0
  }
2809
0
  if( utf7_stream_index == NULL )
2810
0
  {
2811
0
    libcerror_error_set(
2812
0
     error,
2813
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2814
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2815
0
     "%s: invalid UTF-7 stream index.",
2816
0
     function );
2817
2818
0
    return( -1 );
2819
0
  }
2820
0
  if( utf7_stream_base64_data == NULL )
2821
0
  {
2822
0
    libcerror_error_set(
2823
0
     error,
2824
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2825
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2826
0
     "%s: invalid UTF-7 stream base64 data.",
2827
0
     function );
2828
2829
0
    return( -1 );
2830
0
  }
2831
0
  safe_utf7_stream_index       = *utf7_stream_index;
2832
0
  safe_utf7_stream_base64_data = *utf7_stream_base64_data;
2833
2834
  /* Determine if the Unicode character is valid
2835
   */
2836
0
  if( unicode_character > LIBUNA_UNICODE_CHARACTER_MAX )
2837
0
  {
2838
0
    unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
2839
0
  }
2840
  /* A-Z is not a continous range on an EBCDIC based system
2841
   * it consists of the ranges: A-I, J-R, S-Z
2842
   */
2843
0
  if( ( unicode_character >= 0x41 )
2844
0
   && ( unicode_character <= 0x49 ) )
2845
0
  {
2846
0
    unicode_character = ( unicode_character - 0x41 ) + (libuna_unicode_character_t) 'A';
2847
0
  }
2848
0
  else if( ( unicode_character >= 0x4a )
2849
0
        && ( unicode_character <= 0x52 ) )
2850
0
  {
2851
0
    unicode_character = ( unicode_character - 0x4a ) + (libuna_unicode_character_t) 'J';
2852
0
  }
2853
0
  else if( ( unicode_character >= 0x53 )
2854
0
        && ( unicode_character <= 0x5a ) )
2855
0
  {
2856
0
    unicode_character = ( unicode_character - 0x53 ) + (libuna_unicode_character_t) 'S';
2857
0
  }
2858
  /* a-z is not a continous range on an EBCDIC based system
2859
   * it consists of the ranges: a-i, j-r, s-z
2860
   */
2861
0
  else if( ( unicode_character >= 0x61 )
2862
0
        && ( unicode_character <= 0x69 ) )
2863
0
  {
2864
0
    unicode_character = ( unicode_character - 0x61 ) + (libuna_unicode_character_t) 'a';
2865
0
  }
2866
0
  else if( ( unicode_character >= 0x6a )
2867
0
        && ( unicode_character <= 0x72 ) )
2868
0
  {
2869
0
    unicode_character = ( unicode_character - 0x6a ) + (libuna_unicode_character_t) 'j';
2870
0
  }
2871
0
  else if( ( unicode_character >= 0x73 )
2872
0
        && ( unicode_character <= 0x7a ) )
2873
0
  {
2874
0
    unicode_character = ( unicode_character - 0x73 ) + (libuna_unicode_character_t) 's';
2875
0
  }
2876
  /* 0-9
2877
   */
2878
0
  else if( ( unicode_character >= 0x30 )
2879
0
        && ( unicode_character <= 0x39 ) )
2880
0
  {
2881
0
    unicode_character = ( unicode_character - 0x30 ) + (libuna_unicode_character_t) '0';
2882
0
  }
2883
  /* The + character must be escaped
2884
   */
2885
0
  else if( unicode_character == (libuna_unicode_character_t) '+' )
2886
0
  {
2887
0
  }
2888
  /* Allow for the end of string character
2889
   */
2890
0
  else if( unicode_character == 0 )
2891
0
  {
2892
0
  }
2893
0
  else if( ( unicode_character >= 256 )
2894
0
        || ( libuna_unicode_character_utf7_valid_directly_encoded_character[ (uint8_t) unicode_character ] == 0 ) )
2895
0
  {
2896
0
    base64_encode_character = 1;
2897
0
  }
2898
0
  if( base64_encode_character == 0 )
2899
0
  {
2900
0
    if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) != 0 )
2901
0
    {
2902
0
      safe_utf7_stream_base64_data = 0;
2903
0
    }
2904
0
    if( safe_utf7_stream_index >= utf7_stream_size )
2905
0
    {
2906
0
      libcerror_error_set(
2907
0
       error,
2908
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2909
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2910
0
       "%s: UTF-7 stream too small.",
2911
0
       function );
2912
2913
0
      return( -1 );
2914
0
    }
2915
0
    utf7_stream[ safe_utf7_stream_index++ ] = (uint8_t) unicode_character;
2916
2917
    /* The + character must be escaped
2918
     */
2919
0
    if( unicode_character == (libuna_unicode_character_t) '+' )
2920
0
    {
2921
0
      if( safe_utf7_stream_index >= utf7_stream_size )
2922
0
      {
2923
0
        libcerror_error_set(
2924
0
         error,
2925
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2926
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2927
0
         "%s: UTF-7 stream too small.",
2928
0
         function );
2929
2930
0
        return( -1 );
2931
0
      }
2932
0
      utf7_stream[ safe_utf7_stream_index++ ] = (uint8_t) '-';
2933
0
    }
2934
0
  }
2935
0
  else
2936
0
  {
2937
    /* Escape the base64 encoded chracters with a +
2938
     */
2939
0
    if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) == 0 )
2940
0
    {
2941
0
      if( safe_utf7_stream_index >= utf7_stream_size )
2942
0
      {
2943
0
        libcerror_error_set(
2944
0
         error,
2945
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2946
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2947
0
         "%s: UTF-7 stream too small.",
2948
0
         function );
2949
2950
0
        return( -1 );
2951
0
      }
2952
0
      utf7_stream[ safe_utf7_stream_index++ ] = (uint8_t) '+';
2953
0
    }
2954
    /* Otherwise continue the previously base64 encoded characters
2955
     */
2956
0
    else
2957
0
    {
2958
0
      base64_triplet  = safe_utf7_stream_base64_data & 0x00ffffff;
2959
0
      number_of_bytes = ( safe_utf7_stream_base64_data >> 24 ) & 0x03;
2960
0
      current_byte    = ( safe_utf7_stream_base64_data >> 28 ) & 0x03;
2961
2962
0
      if( number_of_bytes > 0 )
2963
0
      {
2964
        /* Correct the index for the last partial base64 stream
2965
         */
2966
0
        safe_utf7_stream_index -= number_of_bytes + 1;
2967
0
      }
2968
      /* Correct the index for the base64 stream termination character
2969
       */
2970
0
      safe_utf7_stream_index -= 1;
2971
0
    }
2972
0
    safe_utf7_stream_base64_data = LIBUNA_UTF7_IS_BASE64_ENCODED;
2973
2974
0
    if( unicode_character > LIBUNA_UNICODE_BASIC_MULTILINGUAL_PLANE_MAX )
2975
0
    {
2976
0
      unicode_character -= 0x010000;
2977
2978
0
      utf16_surrogate = (libuna_utf16_character_t) ( ( unicode_character >> 10 )
2979
0
                      + LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START );
2980
2981
0
      byte_bit_shift   = 16 - ( current_byte * 8 );
2982
0
      base64_triplet  += (uint32_t) ( ( utf16_surrogate >> 8 ) & 0xff ) << byte_bit_shift;
2983
0
      current_byte    += 1;
2984
0
      number_of_bytes += 1;
2985
2986
0
      if( number_of_bytes == 3 )
2987
0
      {
2988
0
        if( libuna_base64_triplet_copy_to_base64_stream(
2989
0
             base64_triplet,
2990
0
             utf7_stream,
2991
0
             utf7_stream_size,
2992
0
             &safe_utf7_stream_index,
2993
0
             0,
2994
0
             LIBUNA_BASE64_VARIANT_UTF7,
2995
0
             error ) != 1 )
2996
0
        {
2997
0
          libcerror_error_set(
2998
0
           error,
2999
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
3000
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3001
0
           "%s: unable to set base64 encoded UTF-7 characters.",
3002
0
           function );
3003
3004
0
          return( -1 );
3005
0
        }
3006
0
        number_of_bytes = 0;
3007
0
        current_byte    = 0;
3008
0
        base64_triplet  = 0;
3009
0
      }
3010
0
      byte_bit_shift   = 16 - ( current_byte * 8 );
3011
0
      base64_triplet  += (uint32_t) ( utf16_surrogate & 0xff ) << byte_bit_shift;
3012
0
      current_byte    += 1;
3013
0
      number_of_bytes += 1;
3014
3015
0
      if( number_of_bytes == 3 )
3016
0
      {
3017
0
        if( libuna_base64_triplet_copy_to_base64_stream(
3018
0
             base64_triplet,
3019
0
             utf7_stream,
3020
0
             utf7_stream_size,
3021
0
             &safe_utf7_stream_index,
3022
0
             0,
3023
0
             LIBUNA_BASE64_VARIANT_UTF7,
3024
0
             error ) != 1 )
3025
0
        {
3026
0
          libcerror_error_set(
3027
0
           error,
3028
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
3029
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3030
0
           "%s: unable to set base64 encoded UTF-7 characters.",
3031
0
           function );
3032
3033
0
          return( -1 );
3034
0
        }
3035
0
        number_of_bytes = 0;
3036
0
        current_byte    = 0;
3037
0
        base64_triplet  = 0;
3038
0
      }
3039
0
      unicode_character = (libuna_utf16_character_t) ( ( unicode_character & 0x03ff )
3040
0
                        + LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START );
3041
0
    }
3042
0
    byte_bit_shift   = 16 - ( current_byte * 8 );
3043
0
    base64_triplet  += (uint32_t) ( ( unicode_character >> 8 ) & 0xff ) << byte_bit_shift;
3044
0
    current_byte    += 1;
3045
0
    number_of_bytes += 1;
3046
3047
0
    if( number_of_bytes == 3 )
3048
0
    {
3049
0
      if( libuna_base64_triplet_copy_to_base64_stream(
3050
0
           base64_triplet,
3051
0
           utf7_stream,
3052
0
           utf7_stream_size,
3053
0
           &safe_utf7_stream_index,
3054
0
           0,
3055
0
           LIBUNA_BASE64_VARIANT_UTF7,
3056
0
           error ) != 1 )
3057
0
      {
3058
0
        libcerror_error_set(
3059
0
         error,
3060
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3061
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3062
0
         "%s: unable to set base64 encoded UTF-7 characters.",
3063
0
         function );
3064
3065
0
        return( -1 );
3066
0
      }
3067
0
      number_of_bytes = 0;
3068
0
      current_byte    = 0;
3069
0
      base64_triplet  = 0;
3070
0
    }
3071
0
    byte_bit_shift   = 16 - ( current_byte * 8 );
3072
0
    base64_triplet  += (uint32_t) ( unicode_character & 0xff ) << byte_bit_shift;
3073
0
    current_byte    += 1;
3074
0
    number_of_bytes += 1;
3075
3076
0
    if( number_of_bytes == 3 )
3077
0
    {
3078
0
      if( libuna_base64_triplet_copy_to_base64_stream(
3079
0
           base64_triplet,
3080
0
           utf7_stream,
3081
0
           utf7_stream_size,
3082
0
           &safe_utf7_stream_index,
3083
0
           0,
3084
0
           LIBUNA_BASE64_VARIANT_UTF7,
3085
0
           error ) != 1 )
3086
0
      {
3087
0
        libcerror_error_set(
3088
0
         error,
3089
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3090
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3091
0
         "%s: unable to set base64 encoded UTF-7 characters.",
3092
0
         function );
3093
3094
0
        return( -1 );
3095
0
      }
3096
0
      number_of_bytes = 0;
3097
0
      current_byte    = 0;
3098
0
      base64_triplet  = 0;
3099
0
    }
3100
    /* Terminate the base64 encoded characters
3101
     */
3102
0
    if( number_of_bytes > 0 )
3103
0
    {
3104
0
      if( libuna_base64_triplet_copy_to_base64_stream(
3105
0
           base64_triplet,
3106
0
           utf7_stream,
3107
0
           utf7_stream_size,
3108
0
           &safe_utf7_stream_index,
3109
0
           3 - number_of_bytes,
3110
0
           LIBUNA_BASE64_VARIANT_UTF7,
3111
0
           error ) != 1 )
3112
0
      {
3113
0
        libcerror_error_set(
3114
0
         error,
3115
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3116
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3117
0
         "%s: unable to set base64 encoded UTF-7 characters.",
3118
0
         function );
3119
3120
0
        return( -1 );
3121
0
      }
3122
0
    }
3123
0
    if( safe_utf7_stream_index >= utf7_stream_size )
3124
0
    {
3125
0
      libcerror_error_set(
3126
0
       error,
3127
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3128
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3129
0
       "%s: UTF-7 stream too small.",
3130
0
       function );
3131
3132
0
      return( -1 );
3133
0
    }
3134
0
    utf7_stream[ safe_utf7_stream_index++ ] = (uint8_t) '-';
3135
0
  }
3136
0
  if( ( safe_utf7_stream_base64_data & LIBUNA_UTF7_IS_BASE64_ENCODED ) != 0 )
3137
0
  {
3138
0
    safe_utf7_stream_base64_data  = LIBUNA_UTF7_IS_BASE64_ENCODED;
3139
0
    safe_utf7_stream_base64_data |= (uint32_t) current_byte << 28;
3140
0
    safe_utf7_stream_base64_data |= (uint32_t) number_of_bytes << 24;
3141
0
    safe_utf7_stream_base64_data |= base64_triplet & 0x00ffffff;
3142
0
  }
3143
0
  *utf7_stream_index       = safe_utf7_stream_index;
3144
0
  *utf7_stream_base64_data = safe_utf7_stream_base64_data;
3145
3146
0
  return( 1 );
3147
0
}
3148
3149
/* Determines the size of an UTF-8 character from an Unicode character
3150
 * Adds the size to the UTF-8 character size value
3151
 * Returns 1 if successful or -1 on error
3152
 */
3153
int libuna_unicode_character_size_to_utf8(
3154
     libuna_unicode_character_t unicode_character,
3155
     size_t *utf8_character_size,
3156
     libcerror_error_t **error )
3157
4.19M
{
3158
4.19M
  static char *function           = "libuna_unicode_character_size_to_utf8";
3159
4.19M
  size_t safe_utf8_character_size = 0;
3160
3161
4.19M
  if( utf8_character_size == NULL )
3162
0
  {
3163
0
    libcerror_error_set(
3164
0
     error,
3165
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3166
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3167
0
     "%s: invalid UTF-8 character size.",
3168
0
     function );
3169
3170
0
    return( -1 );
3171
0
  }
3172
4.19M
  if( unicode_character < 0x00000080UL )
3173
1.08M
  {
3174
1.08M
    safe_utf8_character_size += 1;
3175
1.08M
  }
3176
3.10M
  else if( unicode_character < 0x00000800UL )
3177
279k
  {
3178
279k
    safe_utf8_character_size += 2;
3179
279k
  }
3180
2.82M
  else if( unicode_character < 0x00010000UL )
3181
2.81M
  {
3182
2.81M
    safe_utf8_character_size += 3;
3183
2.81M
  }
3184
11.2k
  else if( unicode_character > LIBUNA_UNICODE_CHARACTER_MAX )
3185
0
  {
3186
0
    safe_utf8_character_size += 3;
3187
0
  }
3188
11.2k
  else
3189
11.2k
  {
3190
11.2k
    safe_utf8_character_size += 4;
3191
11.2k
  }
3192
3193
/* If UTF-8 USC support is needed it should be implemented in
3194
 * utf8_usc or something, but for now leave this here as a reminder
3195
3196
  else if( unicode_character < 0x010000 )
3197
  {
3198
    safe_utf8_character_size += 3;
3199
  }
3200
  else if( unicode_character > LIBUNA_UNICODE_CHARACTER_MAX )
3201
  {
3202
    safe_utf8_character_size += 2;
3203
  }
3204
  else if( unicode_character < 0x0200000 )
3205
  {
3206
    safe_utf8_character_size += 4;
3207
  }
3208
  else if( unicode_character < 0x0400000 )
3209
  {
3210
    safe_utf8_character_size += 5;
3211
  }
3212
  else
3213
  {
3214
    safe_utf8_character_size += 6;
3215
  }
3216
*/
3217
4.19M
  *utf8_character_size += safe_utf8_character_size;
3218
3219
4.19M
  return( 1 );
3220
4.19M
}
3221
3222
/* Copies an Unicode character from an UTF-8 string
3223
 * Returns 1 if successful or -1 on error
3224
 */
3225
int libuna_unicode_character_copy_from_utf8(
3226
     libuna_unicode_character_t *unicode_character,
3227
     const libuna_utf8_character_t *utf8_string,
3228
     size_t utf8_string_size,
3229
     size_t *utf8_string_index,
3230
     libcerror_error_t **error )
3231
355k
{
3232
355k
  static char *function                             = "libuna_unicode_character_copy_from_utf8";
3233
355k
  libuna_unicode_character_t safe_unicode_character = 0;
3234
355k
  size_t safe_utf8_string_index                     = 0;
3235
355k
  uint8_t byte_value1                               = 0;
3236
355k
  uint8_t byte_value2                               = 0;
3237
355k
  uint8_t byte_value3                               = 0;
3238
355k
  uint8_t byte_value4                               = 0;
3239
355k
  uint8_t byte_value5                               = 0;
3240
355k
  uint8_t utf8_character_additional_bytes           = 0;
3241
3242
355k
  if( unicode_character == NULL )
3243
0
  {
3244
0
    libcerror_error_set(
3245
0
     error,
3246
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3247
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3248
0
     "%s: invalid Unicode character.",
3249
0
     function );
3250
3251
0
    return( -1 );
3252
0
  }
3253
355k
  if( utf8_string == NULL )
3254
0
  {
3255
0
    libcerror_error_set(
3256
0
     error,
3257
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3258
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3259
0
     "%s: invalid UTF-8 string.",
3260
0
     function );
3261
3262
0
    return( -1 );
3263
0
  }
3264
355k
  if( utf8_string_size > (size_t) SSIZE_MAX )
3265
0
  {
3266
0
    libcerror_error_set(
3267
0
     error,
3268
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3269
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3270
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
3271
0
     function );
3272
3273
0
    return( -1 );
3274
0
  }
3275
355k
  if( utf8_string_index == NULL )
3276
0
  {
3277
0
    libcerror_error_set(
3278
0
     error,
3279
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3280
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3281
0
     "%s: invalid UTF-8 string index.",
3282
0
     function );
3283
3284
0
    return( -1 );
3285
0
  }
3286
355k
  safe_utf8_string_index = *utf8_string_index;
3287
3288
355k
  if( safe_utf8_string_index >= utf8_string_size )
3289
0
  {
3290
0
    libcerror_error_set(
3291
0
     error,
3292
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3293
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3294
0
     "%s: UTF-8 string too small.",
3295
0
     function );
3296
3297
0
    return( -1 );
3298
0
  }
3299
  /* Determine the number of additional bytes of the UTF-8 character
3300
   */
3301
355k
  byte_value1 = utf8_string[ safe_utf8_string_index ];
3302
3303
355k
  if( byte_value1 < 0xc0 )
3304
305k
  {
3305
305k
    utf8_character_additional_bytes = 0;
3306
305k
  }
3307
49.6k
  else if( byte_value1 < 0xe0 )
3308
11.2k
  {
3309
11.2k
    utf8_character_additional_bytes = 1;
3310
11.2k
  }
3311
38.4k
  else if( byte_value1 < 0xf0 )
3312
27.3k
  {
3313
27.3k
    utf8_character_additional_bytes = 2;
3314
27.3k
  }
3315
11.0k
  else if( byte_value1 < 0xf8 )
3316
10.2k
  {
3317
10.2k
    utf8_character_additional_bytes = 3;
3318
10.2k
  }
3319
810
  else if( byte_value1 < 0xfc )
3320
151
  {
3321
151
    utf8_character_additional_bytes = 4;
3322
151
  }
3323
659
  else
3324
659
  {
3325
659
    utf8_character_additional_bytes = 5;
3326
659
  }
3327
355k
  if( ( ( (size_t) utf8_character_additional_bytes + 1 ) > utf8_string_size )
3328
355k
   || ( safe_utf8_string_index > ( utf8_string_size - ( utf8_character_additional_bytes + 1 ) ) ) )
3329
427
  {
3330
427
    libcerror_error_set(
3331
427
     error,
3332
427
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3333
427
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3334
427
     "%s: missing UTF-8 character bytes.",
3335
427
     function );
3336
3337
427
    return( -1 );
3338
427
  }
3339
  /* Determine the UTF-8 character and make sure it is valid
3340
   * Unicode limits the UTF-8 character to consist of a maximum of 4 bytes
3341
   * while ISO 10646 Universal Character Set (UCS) allows up to 6 bytes
3342
   */
3343
354k
  if( byte_value1 > 0xf4 )
3344
776
  {
3345
776
    libcerror_error_set(
3346
776
     error,
3347
776
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3348
776
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3349
776
     "%s: invalid 1st UTF-8 character byte: 0x%02" PRIx8 ".",
3350
776
     function,
3351
776
     byte_value1 );
3352
3353
776
    return( -1 );
3354
776
  }
3355
353k
  safe_unicode_character = byte_value1;
3356
3357
353k
  if( utf8_character_additional_bytes == 0 )
3358
305k
  {
3359
305k
    if( ( byte_value1 >= 0x80 )
3360
305k
     && ( byte_value1 < 0xc2 ) )
3361
713
    {
3362
713
      libcerror_error_set(
3363
713
       error,
3364
713
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3365
713
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3366
713
       "%s: invalid 1st UTF-8 character byte: 0x%02" PRIx8 ".",
3367
713
       function,
3368
713
       byte_value1 );
3369
3370
713
      return( -1 );
3371
713
    }
3372
305k
  }
3373
353k
  if( utf8_character_additional_bytes >= 1 )
3374
48.4k
  {
3375
48.4k
    byte_value2 = utf8_string[ safe_utf8_string_index + 1 ];
3376
3377
48.4k
    if( byte_value2 > 0xbf )
3378
153
    {
3379
153
      libcerror_error_set(
3380
153
       error,
3381
153
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3382
153
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3383
153
       "%s: invalid 2nd UTF-8 character byte: 0x%02" PRIx8 ".",
3384
153
       function,
3385
153
       byte_value2 );
3386
3387
153
      return( -1 );
3388
153
    }
3389
48.3k
    if( ( byte_value1 == 0xe0 )
3390
48.3k
     && ( byte_value2 < 0xa0 ) )
3391
144
    {
3392
144
      libcerror_error_set(
3393
144
       error,
3394
144
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3395
144
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3396
144
       "%s: invalid 2nd UTF-8 character byte: 0x%02" PRIx8 ".",
3397
144
       function,
3398
144
       byte_value2 );
3399
3400
144
      return( -1 );
3401
144
    }
3402
48.1k
    else if( ( byte_value1 == 0xed )
3403
48.1k
          && ( byte_value2 > 0x9f ) )
3404
47
    {
3405
47
      libcerror_error_set(
3406
47
       error,
3407
47
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3408
47
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3409
47
       "%s: invalid 2nd UTF-8 character byte: 0x%02" PRIx8 ".",
3410
47
       function,
3411
47
       byte_value2 );
3412
3413
47
      return( -1 );
3414
47
    }
3415
48.1k
    else if( ( byte_value1 == 0xf0 )
3416
48.1k
          && ( byte_value2 < 0x90 ) )
3417
184
    {
3418
184
      libcerror_error_set(
3419
184
       error,
3420
184
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3421
184
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3422
184
       "%s: invalid 2nd UTF-8 character byte: 0x%02" PRIx8 ".",
3423
184
       function,
3424
184
       byte_value2 );
3425
3426
184
      return( -1 );
3427
184
    }
3428
47.9k
    else if( ( byte_value1 == 0xf4 )
3429
47.9k
          && ( byte_value2 > 0x8f ) )
3430
48
    {
3431
48
      libcerror_error_set(
3432
48
       error,
3433
48
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3434
48
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3435
48
       "%s: invalid 2nd UTF-8 character byte: 0x%02" PRIx8 ".",
3436
48
       function,
3437
48
       byte_value2 );
3438
3439
48
      return( -1 );
3440
48
    }
3441
47.8k
    else if( byte_value2 < 0x80 )
3442
688
    {
3443
688
      libcerror_error_set(
3444
688
       error,
3445
688
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3446
688
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3447
688
       "%s: invalid 2nd UTF-8 character byte: 0x%02" PRIx8 ".",
3448
688
       function,
3449
688
       byte_value2 );
3450
3451
688
      return( -1 );
3452
688
    }
3453
47.2k
    safe_unicode_character <<= 6;
3454
47.2k
    safe_unicode_character += byte_value2;
3455
3456
47.2k
    if( utf8_character_additional_bytes == 1 )
3457
10.9k
    {
3458
10.9k
      safe_unicode_character -= 0x03080;
3459
10.9k
    }
3460
47.2k
  }
3461
351k
  if( utf8_character_additional_bytes >= 2 )
3462
36.2k
  {
3463
36.2k
    byte_value3 = utf8_string[ safe_utf8_string_index + 2 ];
3464
3465
36.2k
    if( ( byte_value3 < 0x80 )
3466
36.2k
     || ( byte_value3 > 0xbf ) )
3467
345
    {
3468
345
      libcerror_error_set(
3469
345
       error,
3470
345
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3471
345
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3472
345
       "%s: invalid 3rd UTF-8 character byte: 0x%02" PRIx8 ".",
3473
345
       function,
3474
345
       byte_value3 );
3475
3476
345
      return( -1 );
3477
345
    }
3478
35.9k
    safe_unicode_character <<= 6;
3479
35.9k
    safe_unicode_character += byte_value3;
3480
3481
35.9k
    if( utf8_character_additional_bytes == 2 )
3482
26.4k
    {
3483
26.4k
      safe_unicode_character -= 0x0e2080;
3484
26.4k
    }
3485
35.9k
  }
3486
351k
  if( utf8_character_additional_bytes >= 3 )
3487
9.47k
  {
3488
9.47k
    byte_value4 = utf8_string[ safe_utf8_string_index + 3 ];
3489
3490
9.47k
    if( ( byte_value4 < 0x80 )
3491
9.47k
     || ( byte_value4 > 0xbf ) )
3492
174
    {
3493
174
      libcerror_error_set(
3494
174
       error,
3495
174
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3496
174
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3497
174
       "%s: invalid 4th UTF-8 character byte: 0x%02" PRIx8 ".",
3498
174
       function,
3499
174
       byte_value4 );
3500
3501
174
      return( -1 );
3502
174
    }
3503
9.29k
    safe_unicode_character <<= 6;
3504
9.29k
    safe_unicode_character += byte_value4;
3505
3506
9.29k
    if( utf8_character_additional_bytes == 3 )
3507
9.29k
    {
3508
9.29k
      safe_unicode_character -= 0x03c82080;
3509
9.29k
    }
3510
9.29k
  }
3511
351k
  if( utf8_character_additional_bytes >= 4 )
3512
0
  {
3513
0
    byte_value5 = utf8_string[ safe_utf8_string_index + 4 ];
3514
3515
0
    if( ( byte_value5 < 0x80 )
3516
0
     || ( byte_value5 > 0xbf ) )
3517
0
    {
3518
0
      libcerror_error_set(
3519
0
       error,
3520
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3521
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3522
0
       "%s: invalid 5th UTF-8 character byte: 0x%02" PRIx8 ".",
3523
0
       function,
3524
0
       byte_value5 );
3525
3526
0
      return( -1 );
3527
0
    }
3528
0
    safe_unicode_character <<= 6;
3529
0
    safe_unicode_character += byte_value5;
3530
3531
0
    if( utf8_character_additional_bytes == 4 )
3532
0
    {
3533
0
      safe_unicode_character -= 0x0fa082080;
3534
0
    }
3535
0
  }
3536
351k
  if( utf8_character_additional_bytes == 5 )
3537
0
  {
3538
0
    if( ( utf8_string[ safe_utf8_string_index + 5 ] < 0x80 )
3539
0
      || ( utf8_string[ safe_utf8_string_index + 5 ] > 0xbf ) )
3540
0
    {
3541
0
      libcerror_error_set(
3542
0
       error,
3543
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3544
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3545
0
       "%s: invalid 6th UTF-8 character byte: 0x%02" PRIx8 ".",
3546
0
       function,
3547
0
       utf8_string[ safe_utf8_string_index + 5 ] );
3548
3549
0
      return( -1 );
3550
0
    }
3551
0
    safe_unicode_character <<= 6;
3552
0
    safe_unicode_character += utf8_string[ safe_utf8_string_index + 5 ];
3553
0
    safe_unicode_character -= 0x082082080;
3554
0
  }
3555
  /* Determine if the Unicode character is valid
3556
   */
3557
351k
  if( safe_unicode_character > LIBUNA_UNICODE_CHARACTER_MAX )
3558
0
  {
3559
0
    safe_unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
3560
0
  }
3561
351k
  *unicode_character = safe_unicode_character;
3562
351k
  *utf8_string_index = safe_utf8_string_index + 1 + utf8_character_additional_bytes;
3563
3564
351k
  return( 1 );
3565
351k
}
3566
3567
/* Copies an Unicode character into a UTF-8 string
3568
 * Returns 1 if successful or -1 on error
3569
 */
3570
int libuna_unicode_character_copy_to_utf8(
3571
     libuna_unicode_character_t unicode_character,
3572
     libuna_utf8_character_t *utf8_string,
3573
     size_t utf8_string_size,
3574
     size_t *utf8_string_index,
3575
     libcerror_error_t **error )
3576
3.74M
{
3577
3.74M
  static char *function                   = "libuna_unicode_character_copy_to_utf8";
3578
3.74M
  size_t safe_utf8_string_index           = 0;
3579
3.74M
  size_t utf8_character_iterator          = 0;
3580
3.74M
  uint8_t utf8_character_additional_bytes = 0;
3581
3.74M
  uint8_t utf8_first_character_mark       = 0;
3582
3583
3.74M
  if( utf8_string == NULL )
3584
0
  {
3585
0
    libcerror_error_set(
3586
0
     error,
3587
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3588
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3589
0
     "%s: invalid UTF-8 string.",
3590
0
     function );
3591
3592
0
    return( -1 );
3593
0
  }
3594
3.74M
  if( utf8_string_size > (size_t) SSIZE_MAX )
3595
0
  {
3596
0
    libcerror_error_set(
3597
0
     error,
3598
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3599
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3600
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
3601
0
     function );
3602
3603
0
    return( -1 );
3604
0
  }
3605
3.74M
  if( utf8_string_index == NULL )
3606
0
  {
3607
0
    libcerror_error_set(
3608
0
     error,
3609
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3610
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3611
0
     "%s: invalid UTF-8 string index.",
3612
0
     function );
3613
3614
0
    return( -1 );
3615
0
  }
3616
3.74M
  safe_utf8_string_index = *utf8_string_index;
3617
3618
3.74M
  if( safe_utf8_string_index >= utf8_string_size )
3619
350
  {
3620
350
    libcerror_error_set(
3621
350
     error,
3622
350
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3623
350
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3624
350
     "%s: UTF-8 string too small.",
3625
350
     function );
3626
3627
350
    return( -1 );
3628
350
  }
3629
  /* Determine if the Unicode character is valid
3630
   */
3631
3.74M
  if( unicode_character > LIBUNA_UNICODE_CHARACTER_MAX )
3632
0
  {
3633
0
    unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
3634
0
  }
3635
  /* Determine how many UTF-8 character bytes are required
3636
   */
3637
3.74M
  if( unicode_character < 0x080 )
3638
1.00M
  {
3639
1.00M
    utf8_character_additional_bytes = 0;
3640
1.00M
    utf8_first_character_mark       = 0;
3641
1.00M
  }
3642
2.73M
  else if( unicode_character < 0x0800 )
3643
194k
  {
3644
194k
    utf8_character_additional_bytes = 1;
3645
194k
    utf8_first_character_mark       = 0x0c0;
3646
194k
  }
3647
2.54M
  else if( unicode_character < 0x010000 )
3648
2.54M
  {
3649
2.54M
    utf8_character_additional_bytes = 2;
3650
2.54M
    utf8_first_character_mark       = 0x0e0;
3651
2.54M
  }
3652
4.23k
  else if( unicode_character < 0x0200000 )
3653
4.23k
  {
3654
4.23k
    utf8_character_additional_bytes = 3;
3655
4.23k
    utf8_first_character_mark       = 0x0f0;
3656
4.23k
  }
3657
0
  else if( unicode_character < 0x0400000 )
3658
0
  {
3659
0
    utf8_character_additional_bytes = 4;
3660
0
    utf8_first_character_mark       = 0x0f8;
3661
0
  }
3662
0
  else
3663
0
  {
3664
0
    utf8_character_additional_bytes = 5;
3665
0
    utf8_first_character_mark       = 0x0fc;
3666
0
  }
3667
  /* Convert Unicode character into UTF-8 character bytes
3668
   */
3669
3.74M
  if( ( utf8_character_additional_bytes > utf8_string_size )
3670
3.74M
   || ( safe_utf8_string_index >= ( utf8_string_size - utf8_character_additional_bytes ) ) )
3671
406
  {
3672
406
    libcerror_error_set(
3673
406
     error,
3674
406
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3675
406
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3676
406
     "%s: UTF-8 string too small.",
3677
406
     function );
3678
3679
406
    return( -1 );
3680
406
  }
3681
3.74M
  for( utf8_character_iterator = safe_utf8_string_index + utf8_character_additional_bytes;
3682
9.03M
       utf8_character_iterator > safe_utf8_string_index;
3683
5.28M
       utf8_character_iterator-- )
3684
5.28M
  {
3685
5.28M
    utf8_string[ utf8_character_iterator ] = (libuna_utf8_character_t) ( ( unicode_character & 0x0bf ) | 0x080 );
3686
3687
5.28M
    unicode_character >>= 6;
3688
5.28M
  }
3689
3.74M
  utf8_string[ safe_utf8_string_index ] = (libuna_utf8_character_t) ( unicode_character | utf8_first_character_mark );
3690
3691
3.74M
  *utf8_string_index = safe_utf8_string_index + 1 + utf8_character_additional_bytes;
3692
3693
3.74M
  return( 1 );
3694
3.74M
}
3695
3696
/* Determines the size of an UTF-16 character from an Unicode character
3697
 * Adds the size to the UTF-16 character size value
3698
 * Returns 1 if successful or -1 on error
3699
 */
3700
int libuna_unicode_character_size_to_utf16(
3701
     libuna_unicode_character_t unicode_character,
3702
     size_t *utf16_character_size,
3703
     libcerror_error_t **error )
3704
1.54k
{
3705
1.54k
  static char *function = "libuna_unicode_character_size_to_utf16";
3706
3707
1.54k
  if( utf16_character_size == NULL )
3708
0
  {
3709
0
    libcerror_error_set(
3710
0
     error,
3711
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3712
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3713
0
     "%s: invalid UTF-16 character size.",
3714
0
     function );
3715
3716
0
    return( -1 );
3717
0
  }
3718
1.54k
  if( ( unicode_character > LIBUNA_UNICODE_BASIC_MULTILINGUAL_PLANE_MAX )
3719
1.54k
         && ( unicode_character <= LIBUNA_UTF16_CHARACTER_MAX ) )
3720
10
  {
3721
10
    *utf16_character_size += 2;
3722
10
  }
3723
1.53k
  else
3724
1.53k
  {
3725
1.53k
    *utf16_character_size += 1;
3726
1.53k
  }
3727
1.54k
  return( 1 );
3728
1.54k
}
3729
3730
/* Copies an Unicode character from an UTF-16 string
3731
 * Returns 1 if successful or -1 on error
3732
 */
3733
int libuna_unicode_character_copy_from_utf16(
3734
     libuna_unicode_character_t *unicode_character,
3735
     const libuna_utf16_character_t *utf16_string,
3736
     size_t utf16_string_size,
3737
     size_t *utf16_string_index,
3738
     libcerror_error_t **error )
3739
0
{
3740
0
  static char *function                             = "libuna_unicode_character_copy_from_utf16";
3741
0
  libuna_unicode_character_t safe_unicode_character = 0;
3742
0
  libuna_utf16_character_t utf16_surrogate          = 0;
3743
0
  size_t safe_utf16_string_index                    = 0;
3744
3745
0
  if( unicode_character == NULL )
3746
0
  {
3747
0
    libcerror_error_set(
3748
0
     error,
3749
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3750
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3751
0
     "%s: invalid Unicode character.",
3752
0
     function );
3753
3754
0
    return( -1 );
3755
0
  }
3756
0
  if( utf16_string == NULL )
3757
0
  {
3758
0
    libcerror_error_set(
3759
0
     error,
3760
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3761
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3762
0
     "%s: invalid UTF-16 string.",
3763
0
     function );
3764
3765
0
    return( -1 );
3766
0
  }
3767
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
3768
0
  {
3769
0
    libcerror_error_set(
3770
0
     error,
3771
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3772
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3773
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
3774
0
     function );
3775
3776
0
    return( -1 );
3777
0
  }
3778
0
  if( utf16_string_index == NULL )
3779
0
  {
3780
0
    libcerror_error_set(
3781
0
     error,
3782
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3783
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3784
0
     "%s: invalid UTF-16 string index.",
3785
0
     function );
3786
3787
0
    return( -1 );
3788
0
  }
3789
0
  safe_utf16_string_index = *utf16_string_index;
3790
3791
0
  if( safe_utf16_string_index >= utf16_string_size )
3792
0
  {
3793
0
    libcerror_error_set(
3794
0
     error,
3795
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3796
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3797
0
     "%s: UTF-16 string too small.",
3798
0
     function );
3799
3800
0
    return( -1 );
3801
0
  }
3802
0
  safe_unicode_character   = utf16_string[ safe_utf16_string_index ];
3803
0
  safe_utf16_string_index += 1;
3804
3805
  /* Determine if the UTF-16 character is within the high surrogate range
3806
   */
3807
0
  if( ( safe_unicode_character >= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START )
3808
0
   && ( safe_unicode_character <= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_END ) )
3809
0
  {
3810
0
    if( safe_utf16_string_index >= utf16_string_size )
3811
0
    {
3812
0
      libcerror_error_set(
3813
0
       error,
3814
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3815
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3816
0
       "%s: missing surrogate UTF-16 character bytes.",
3817
0
       function );
3818
3819
0
      return( -1 );
3820
0
    }
3821
0
    utf16_surrogate          = utf16_string[ safe_utf16_string_index ];
3822
0
    safe_utf16_string_index += 1;
3823
3824
    /* Determine if the UTF-16 character is within the low surrogate range
3825
     */
3826
0
    if( ( utf16_surrogate >= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START )
3827
0
     && ( utf16_surrogate <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
3828
0
    {
3829
0
      safe_unicode_character  -= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START;
3830
0
      safe_unicode_character <<= 10;
3831
0
      safe_unicode_character  += utf16_surrogate - LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START;
3832
0
      safe_unicode_character  += 0x010000;
3833
0
    }
3834
0
    else
3835
0
    {
3836
0
      safe_unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
3837
0
    }
3838
0
  }
3839
  /* Determine if the Unicode character is valid
3840
   */
3841
0
  else if( ( safe_unicode_character >= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START )
3842
0
        && ( safe_unicode_character <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
3843
0
  {
3844
0
    safe_unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
3845
0
  }
3846
0
  *unicode_character  = safe_unicode_character;
3847
0
  *utf16_string_index = safe_utf16_string_index;
3848
3849
0
  return( 1 );
3850
0
}
3851
3852
/* Copies an Unicode character into a UTF-16 string
3853
 * Returns 1 if successful or -1 on error
3854
 */
3855
int libuna_unicode_character_copy_to_utf16(
3856
     libuna_unicode_character_t unicode_character,
3857
     libuna_utf16_character_t *utf16_string,
3858
     size_t utf16_string_size,
3859
     size_t *utf16_string_index,
3860
     libcerror_error_t **error )
3861
0
{
3862
0
  static char *function          = "libuna_unicode_character_copy_to_utf16";
3863
0
  size_t safe_utf16_string_index = 0;
3864
3865
0
  if( utf16_string == NULL )
3866
0
  {
3867
0
    libcerror_error_set(
3868
0
     error,
3869
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3870
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3871
0
     "%s: invalid UTF-16 string.",
3872
0
     function );
3873
3874
0
    return( -1 );
3875
0
  }
3876
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
3877
0
  {
3878
0
    libcerror_error_set(
3879
0
     error,
3880
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3881
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3882
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
3883
0
     function );
3884
3885
0
    return( -1 );
3886
0
  }
3887
0
  if( utf16_string_index == NULL )
3888
0
  {
3889
0
    libcerror_error_set(
3890
0
     error,
3891
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3892
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3893
0
     "%s: invalid UTF-16 string index.",
3894
0
     function );
3895
3896
0
    return( -1 );
3897
0
  }
3898
0
  safe_utf16_string_index = *utf16_string_index;
3899
3900
0
  if( safe_utf16_string_index >= utf16_string_size )
3901
0
  {
3902
0
    libcerror_error_set(
3903
0
     error,
3904
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3905
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3906
0
     "%s: UTF-16 string too small.",
3907
0
     function );
3908
3909
0
    return( -1 );
3910
0
  }
3911
  /* Determine if the Unicode character is valid
3912
   */
3913
0
  if( ( ( unicode_character >= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START )
3914
0
    && ( unicode_character <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
3915
0
   || ( unicode_character > LIBUNA_UTF16_CHARACTER_MAX ) )
3916
0
  {
3917
0
    unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
3918
0
  }
3919
0
  if( unicode_character <= LIBUNA_UNICODE_BASIC_MULTILINGUAL_PLANE_MAX )
3920
0
  {
3921
0
    utf16_string[ safe_utf16_string_index++ ] = (libuna_utf16_character_t) unicode_character;
3922
0
  }
3923
0
  else
3924
0
  {
3925
0
    if( ( utf16_string_size < 2 )
3926
0
     || ( safe_utf16_string_index > ( utf16_string_size - 2 ) ) )
3927
0
    {
3928
0
      libcerror_error_set(
3929
0
       error,
3930
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3931
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3932
0
       "%s: UTF-16 string too small.",
3933
0
       function );
3934
3935
0
      return( -1 );
3936
0
    }
3937
0
    unicode_character                        -= 0x010000;
3938
0
    utf16_string[ safe_utf16_string_index++ ] = (libuna_utf16_character_t) ( ( unicode_character >> 10 ) + LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START );
3939
0
    utf16_string[ safe_utf16_string_index++ ] = (libuna_utf16_character_t) ( ( unicode_character & 0x03ff ) + LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START );
3940
0
  }
3941
0
  *utf16_string_index = safe_utf16_string_index;
3942
3943
0
  return( 1 );
3944
0
}
3945
3946
/* Copies an Unicode character from an UTF-16 stream
3947
 * Returns 1 if successful or -1 on error
3948
 */
3949
int libuna_unicode_character_copy_from_utf16_stream(
3950
     libuna_unicode_character_t *unicode_character,
3951
     const uint8_t *utf16_stream,
3952
     size_t utf16_stream_size,
3953
     size_t *utf16_stream_index,
3954
     int byte_order,
3955
     libcerror_error_t **error )
3956
9.66M
{
3957
9.66M
  static char *function                             = "libuna_unicode_character_copy_from_utf16_stream";
3958
9.66M
  libuna_unicode_character_t safe_unicode_character = 0;
3959
9.66M
  libuna_utf16_character_t utf16_surrogate          = 0;
3960
9.66M
  size_t safe_utf16_stream_index                    = 0;
3961
3962
9.66M
  if( unicode_character == NULL )
3963
0
  {
3964
0
    libcerror_error_set(
3965
0
     error,
3966
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3967
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3968
0
     "%s: invalid Unicode character.",
3969
0
     function );
3970
3971
0
    return( -1 );
3972
0
  }
3973
9.66M
  if( utf16_stream == NULL )
3974
0
  {
3975
0
    libcerror_error_set(
3976
0
     error,
3977
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3978
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3979
0
     "%s: invalid UTF-16 stream.",
3980
0
     function );
3981
3982
0
    return( -1 );
3983
0
  }
3984
9.66M
  if( utf16_stream_size > (size_t) SSIZE_MAX )
3985
0
  {
3986
0
    libcerror_error_set(
3987
0
     error,
3988
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3989
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3990
0
     "%s: invalid UTF-16 stream size value exceeds maximum.",
3991
0
     function );
3992
3993
0
    return( -1 );
3994
0
  }
3995
9.66M
  if( utf16_stream_index == NULL )
3996
0
  {
3997
0
    libcerror_error_set(
3998
0
     error,
3999
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4000
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4001
0
     "%s: invalid UTF-16 stream index.",
4002
0
     function );
4003
4004
0
    return( -1 );
4005
0
  }
4006
9.66M
  if( ( byte_order != LIBUNA_ENDIAN_BIG )
4007
9.66M
   && ( byte_order != LIBUNA_ENDIAN_LITTLE ) )
4008
0
  {
4009
0
    libcerror_error_set(
4010
0
     error,
4011
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4012
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
4013
0
     "%s: unsupported byte order.",
4014
0
     function );
4015
4016
0
    return( -1 );
4017
0
  }
4018
9.66M
  safe_utf16_stream_index = *utf16_stream_index;
4019
4020
9.66M
  if( ( utf16_stream_size < 2 )
4021
9.66M
   || ( safe_utf16_stream_index > ( utf16_stream_size - 2 ) ) )
4022
62
  {
4023
62
    libcerror_error_set(
4024
62
     error,
4025
62
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4026
62
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4027
62
     "%s: UTF-16 stream too small.",
4028
62
     function );
4029
4030
62
    return( -1 );
4031
62
  }
4032
9.66M
  if( byte_order == LIBUNA_ENDIAN_BIG )
4033
2.01M
  {
4034
2.01M
    safe_unicode_character   = utf16_stream[ safe_utf16_stream_index ];
4035
2.01M
    safe_unicode_character <<= 8;
4036
2.01M
    safe_unicode_character  += utf16_stream[ safe_utf16_stream_index + 1 ];
4037
2.01M
  }
4038
7.64M
  else if( byte_order == LIBUNA_ENDIAN_LITTLE )
4039
7.64M
  {
4040
7.64M
    safe_unicode_character   = utf16_stream[ safe_utf16_stream_index + 1 ];
4041
7.64M
    safe_unicode_character <<= 8;
4042
7.64M
    safe_unicode_character  += utf16_stream[ safe_utf16_stream_index ];
4043
7.64M
  }
4044
9.66M
  safe_utf16_stream_index += 2;
4045
4046
  /* Determine if the Unicode character is valid
4047
   */
4048
9.66M
  if( ( safe_unicode_character >= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START )
4049
9.66M
   && ( safe_unicode_character <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
4050
566
  {
4051
566
    libcerror_error_set(
4052
566
     error,
4053
566
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4054
566
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4055
566
     "%s: unsupported UTF-16 character.",
4056
566
     function );
4057
4058
566
    return( -1 );
4059
566
  }
4060
  /* Determine if the UTF-16 character is within the high surrogate range
4061
   */
4062
9.66M
  if( ( safe_unicode_character >= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START )
4063
9.66M
   && ( safe_unicode_character <= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_END ) )
4064
55.0k
  {
4065
55.0k
    if( safe_utf16_stream_index > ( utf16_stream_size - 2 ) )
4066
61
    {
4067
61
      libcerror_error_set(
4068
61
       error,
4069
61
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4070
61
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4071
61
       "%s: missing surrogate UTF-16 character bytes.",
4072
61
       function );
4073
4074
61
      return( -1 );
4075
61
    }
4076
54.9k
    if( byte_order == LIBUNA_ENDIAN_BIG )
4077
40.9k
    {
4078
40.9k
      utf16_surrogate   = utf16_stream[ safe_utf16_stream_index ];
4079
40.9k
      utf16_surrogate <<= 8;
4080
40.9k
      utf16_surrogate  += utf16_stream[ safe_utf16_stream_index + 1 ];
4081
40.9k
    }
4082
14.0k
    else if( byte_order == LIBUNA_ENDIAN_LITTLE )
4083
14.0k
    {
4084
14.0k
      utf16_surrogate   = utf16_stream[ safe_utf16_stream_index + 1 ];
4085
14.0k
      utf16_surrogate <<= 8;
4086
14.0k
      utf16_surrogate  += utf16_stream[ safe_utf16_stream_index ];
4087
14.0k
    }
4088
54.9k
    safe_utf16_stream_index += 2;
4089
4090
    /* Determine if the UTF-16 character is within the low surrogate range
4091
     */
4092
54.9k
    if( ( utf16_surrogate < LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START )
4093
54.9k
     || ( utf16_surrogate > LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
4094
852
    {
4095
852
      libcerror_error_set(
4096
852
       error,
4097
852
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4098
852
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4099
852
       "%s: unsupported low surrogate UTF-16 character.",
4100
852
       function );
4101
4102
852
      return( -1 );
4103
852
    }
4104
54.1k
    safe_unicode_character  -= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START;
4105
54.1k
    safe_unicode_character <<= 10;
4106
54.1k
    safe_unicode_character  += utf16_surrogate - LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START;
4107
54.1k
    safe_unicode_character  += 0x010000;
4108
54.1k
  }
4109
9.66M
  *unicode_character  = safe_unicode_character;
4110
9.66M
  *utf16_stream_index = safe_utf16_stream_index;
4111
4112
9.66M
  return( 1 );
4113
9.66M
}
4114
4115
/* Copies an Unicode character to an UTF-16 stream
4116
 * Returns 1 if successful or -1 on error
4117
 */
4118
int libuna_unicode_character_copy_to_utf16_stream(
4119
     libuna_unicode_character_t unicode_character,
4120
     uint8_t *utf16_stream,
4121
     size_t utf16_stream_size,
4122
     size_t *utf16_stream_index,
4123
     int byte_order,
4124
     libcerror_error_t **error )
4125
0
{
4126
0
  static char *function                    = "libuna_unicode_character_copy_to_utf16_stream";
4127
0
  libuna_utf16_character_t utf16_surrogate = 0;
4128
0
  size_t safe_utf16_stream_index           = 0;
4129
4130
0
  if( utf16_stream == NULL )
4131
0
  {
4132
0
    libcerror_error_set(
4133
0
     error,
4134
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4135
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4136
0
     "%s: invalid UTF-16 stream.",
4137
0
     function );
4138
4139
0
    return( -1 );
4140
0
  }
4141
0
  if( utf16_stream_size > (size_t) SSIZE_MAX )
4142
0
  {
4143
0
    libcerror_error_set(
4144
0
     error,
4145
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4146
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4147
0
     "%s: invalid UTF-16 stream size value exceeds maximum.",
4148
0
     function );
4149
4150
0
    return( -1 );
4151
0
  }
4152
0
  if( utf16_stream_index == NULL )
4153
0
  {
4154
0
    libcerror_error_set(
4155
0
     error,
4156
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4157
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4158
0
     "%s: invalid UTF-16 stream index.",
4159
0
     function );
4160
4161
0
    return( -1 );
4162
0
  }
4163
0
  if( ( byte_order != LIBUNA_ENDIAN_BIG )
4164
0
   && ( byte_order != LIBUNA_ENDIAN_LITTLE ) )
4165
0
  {
4166
0
    libcerror_error_set(
4167
0
     error,
4168
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4169
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
4170
0
     "%s: unsupported byte order.",
4171
0
     function );
4172
4173
0
    return( -1 );
4174
0
  }
4175
0
  safe_utf16_stream_index = *utf16_stream_index;
4176
4177
  /* Determine if the Unicode character is valid
4178
   */
4179
0
  if( ( ( unicode_character >= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START )
4180
0
    &&  ( unicode_character <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
4181
0
   || ( unicode_character > LIBUNA_UTF16_CHARACTER_MAX ) )
4182
0
  {
4183
0
    libcerror_error_set(
4184
0
     error,
4185
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4186
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4187
0
     "%s: unsupported Unicode character.",
4188
0
     function );
4189
4190
0
    return( -1 );
4191
0
  }
4192
0
  if( unicode_character <= LIBUNA_UNICODE_BASIC_MULTILINGUAL_PLANE_MAX )
4193
0
  {
4194
0
    if( ( utf16_stream_size < 2 )
4195
0
     || ( safe_utf16_stream_index > ( utf16_stream_size - 2 ) ) )
4196
0
    {
4197
0
      libcerror_error_set(
4198
0
       error,
4199
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4200
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4201
0
       "%s: UTF-16 stream too small.",
4202
0
       function );
4203
4204
0
      return( -1 );
4205
0
    }
4206
0
    if( byte_order == LIBUNA_ENDIAN_BIG )
4207
0
    {
4208
0
      utf16_stream[ safe_utf16_stream_index + 1 ] = (uint8_t) ( unicode_character & 0xff );
4209
0
      unicode_character                         >>= 8;
4210
0
      utf16_stream[ safe_utf16_stream_index     ] = (uint8_t) ( unicode_character & 0xff );
4211
0
    }
4212
0
    else if( byte_order == LIBUNA_ENDIAN_LITTLE )
4213
0
    {
4214
0
      utf16_stream[ safe_utf16_stream_index     ] = (uint8_t) ( unicode_character & 0xff );
4215
0
      unicode_character                         >>= 8;
4216
0
      utf16_stream[ safe_utf16_stream_index + 1 ] = (uint8_t) ( unicode_character & 0xff );
4217
0
    }
4218
0
    safe_utf16_stream_index += 2;
4219
0
  }
4220
0
  else
4221
0
  {
4222
0
    if( ( utf16_stream_size < 4 )
4223
0
     || ( safe_utf16_stream_index > ( utf16_stream_size - 4 ) ) )
4224
0
    {
4225
0
      libcerror_error_set(
4226
0
       error,
4227
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4228
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4229
0
       "%s: UTF-16 stream too small.",
4230
0
       function );
4231
4232
0
      return( -1 );
4233
0
    }
4234
0
    unicode_character -= 0x010000;
4235
4236
0
    utf16_surrogate = (libuna_utf16_character_t) ( ( unicode_character >> 10 ) + LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START );
4237
4238
0
    if( byte_order == LIBUNA_ENDIAN_BIG )
4239
0
    {
4240
0
      utf16_stream[ safe_utf16_stream_index + 1 ] = (uint8_t) ( utf16_surrogate & 0xff );
4241
0
      utf16_surrogate                           >>= 8;
4242
0
      utf16_stream[ safe_utf16_stream_index     ] = (uint8_t) ( utf16_surrogate & 0xff );
4243
0
    }
4244
0
    else if( byte_order == LIBUNA_ENDIAN_LITTLE )
4245
0
    {
4246
0
      utf16_stream[ safe_utf16_stream_index     ] = (uint8_t) ( utf16_surrogate & 0xff );
4247
0
      utf16_surrogate                           >>= 8;
4248
0
      utf16_stream[ safe_utf16_stream_index + 1 ] = (uint8_t) ( utf16_surrogate & 0xff );
4249
0
    }
4250
0
    safe_utf16_stream_index += 2;
4251
4252
0
    utf16_surrogate = (libuna_utf16_character_t) ( ( unicode_character & 0x03ff ) + LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START );
4253
4254
0
    if( byte_order == LIBUNA_ENDIAN_BIG )
4255
0
    {
4256
0
      utf16_stream[ safe_utf16_stream_index + 1 ] = (uint8_t) ( utf16_surrogate & 0xff );
4257
0
      utf16_surrogate                           >>= 8;
4258
0
      utf16_stream[ safe_utf16_stream_index     ] = (uint8_t) ( utf16_surrogate & 0xff );
4259
0
    }
4260
0
    else if( byte_order == LIBUNA_ENDIAN_LITTLE )
4261
0
    {
4262
0
      utf16_stream[ safe_utf16_stream_index     ] = (uint8_t) ( utf16_surrogate & 0xff );
4263
0
      utf16_surrogate                           >>= 8;
4264
0
      utf16_stream[ safe_utf16_stream_index + 1 ] = (uint8_t) ( utf16_surrogate & 0xff );
4265
0
    }
4266
0
    safe_utf16_stream_index += 2;
4267
0
  }
4268
0
  *utf16_stream_index = safe_utf16_stream_index;
4269
4270
0
  return( 1 );
4271
0
}
4272
4273
/* Determines the size of an UTF-32 character from an Unicode character
4274
 * Adds the size to the UTF-32 character size value
4275
 * Returns 1 if successful or -1 on error
4276
 */
4277
int libuna_unicode_character_size_to_utf32(
4278
     libuna_unicode_character_t unicode_character LIBUNA_ATTRIBUTE_UNUSED,
4279
     size_t *utf32_character_size,
4280
     libcerror_error_t **error )
4281
0
{
4282
0
  static char *function = "libuna_unicode_character_size_to_utf32";
4283
4284
0
  LIBUNA_UNREFERENCED_PARAMETER( unicode_character )
4285
4286
0
  if( utf32_character_size == NULL )
4287
0
  {
4288
0
    libcerror_error_set(
4289
0
     error,
4290
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4291
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4292
0
     "%s: invalid UTF-32 character size.",
4293
0
     function );
4294
4295
0
    return( -1 );
4296
0
  }
4297
0
  *utf32_character_size += 1;
4298
4299
0
  return( 1 );
4300
0
}
4301
4302
/* Copies an Unicode character from an UTF-32 string
4303
 * Returns 1 if successful or -1 on error
4304
 */
4305
int libuna_unicode_character_copy_from_utf32(
4306
     libuna_unicode_character_t *unicode_character,
4307
     const libuna_utf32_character_t *utf32_string,
4308
     size_t utf32_string_size,
4309
     size_t *utf32_string_index,
4310
     libcerror_error_t **error )
4311
0
{
4312
0
  static char *function                             = "libuna_unicode_character_copy_from_utf32";
4313
0
  libuna_unicode_character_t safe_unicode_character = 0;
4314
0
  size_t safe_utf32_string_index                    = 0;
4315
4316
0
  if( unicode_character == NULL )
4317
0
  {
4318
0
    libcerror_error_set(
4319
0
     error,
4320
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4321
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4322
0
     "%s: invalid Unicode character.",
4323
0
     function );
4324
4325
0
    return( -1 );
4326
0
  }
4327
0
  if( utf32_string == NULL )
4328
0
  {
4329
0
    libcerror_error_set(
4330
0
     error,
4331
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4332
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4333
0
     "%s: invalid UTF-32 string.",
4334
0
     function );
4335
4336
0
    return( -1 );
4337
0
  }
4338
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
4339
0
  {
4340
0
    libcerror_error_set(
4341
0
     error,
4342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4343
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4344
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
4345
0
     function );
4346
4347
0
    return( -1 );
4348
0
  }
4349
0
  if( utf32_string_index == NULL )
4350
0
  {
4351
0
    libcerror_error_set(
4352
0
     error,
4353
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4354
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4355
0
     "%s: invalid UTF-32 string index.",
4356
0
     function );
4357
4358
0
    return( -1 );
4359
0
  }
4360
0
  safe_utf32_string_index = *utf32_string_index;
4361
4362
0
  if( safe_utf32_string_index >= utf32_string_size )
4363
0
  {
4364
0
    libcerror_error_set(
4365
0
     error,
4366
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4367
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4368
0
     "%s: UTF-32 string too small.",
4369
0
     function );
4370
4371
0
    return( -1 );
4372
0
  }
4373
  /* Determine if the Unicode character is valid
4374
   */
4375
0
  if( ( utf32_string[ safe_utf32_string_index ] >= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START )
4376
0
   && ( utf32_string[ safe_utf32_string_index ] <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
4377
0
  {
4378
0
    safe_unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
4379
0
  }
4380
0
  else
4381
0
  {
4382
0
    safe_unicode_character = utf32_string[ safe_utf32_string_index ];
4383
0
  }
4384
0
  *unicode_character  = safe_unicode_character;
4385
0
  *utf32_string_index = safe_utf32_string_index + 1;
4386
4387
0
  return( 1 );
4388
0
}
4389
4390
/* Copies an Unicode character into a UTF-32 string
4391
 * Returns 1 if successful or -1 on error
4392
 */
4393
int libuna_unicode_character_copy_to_utf32(
4394
     libuna_unicode_character_t unicode_character,
4395
     libuna_utf32_character_t *utf32_string,
4396
     size_t utf32_string_size,
4397
     size_t *utf32_string_index,
4398
     libcerror_error_t **error )
4399
0
{
4400
0
  static char *function          = "libuna_unicode_character_copy_to_utf32";
4401
0
  size_t safe_utf32_string_index = 0;
4402
4403
0
  if( utf32_string == NULL )
4404
0
  {
4405
0
    libcerror_error_set(
4406
0
     error,
4407
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4408
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4409
0
     "%s: invalid UTF-32 string.",
4410
0
     function );
4411
4412
0
    return( -1 );
4413
0
  }
4414
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
4415
0
  {
4416
0
    libcerror_error_set(
4417
0
     error,
4418
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4419
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4420
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
4421
0
     function );
4422
4423
0
    return( -1 );
4424
0
  }
4425
0
  if( utf32_string_index == NULL )
4426
0
  {
4427
0
    libcerror_error_set(
4428
0
     error,
4429
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4430
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4431
0
     "%s: invalid UTF-32 string index.",
4432
0
     function );
4433
4434
0
    return( -1 );
4435
0
  }
4436
0
  safe_utf32_string_index = *utf32_string_index;
4437
4438
0
  if( safe_utf32_string_index >= utf32_string_size )
4439
0
  {
4440
0
    libcerror_error_set(
4441
0
     error,
4442
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4443
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4444
0
     "%s: UTF-32 string too small.",
4445
0
     function );
4446
4447
0
    return( -1 );
4448
0
  }
4449
  /* Determine if the Unicode character is valid
4450
   */
4451
0
  if( ( ( unicode_character >= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START )
4452
0
    && ( unicode_character <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
4453
0
   || ( unicode_character > LIBUNA_UTF32_CHARACTER_MAX ) )
4454
0
  {
4455
0
    utf32_string[ safe_utf32_string_index ] = (libuna_utf32_character_t) LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
4456
0
  }
4457
0
  else
4458
0
  {
4459
0
    utf32_string[ safe_utf32_string_index ] = (libuna_utf32_character_t) unicode_character;
4460
0
  }
4461
0
  *utf32_string_index = safe_utf32_string_index + 1;
4462
4463
0
  return( 1 );
4464
0
}
4465
4466
/* Copies an Unicode character from an UTF-32 stream
4467
 * Returns 1 if successful or -1 on error
4468
 */
4469
int libuna_unicode_character_copy_from_utf32_stream(
4470
     libuna_unicode_character_t *unicode_character,
4471
     const uint8_t *utf32_stream,
4472
     size_t utf32_stream_size,
4473
     size_t *utf32_stream_index,
4474
     int byte_order,
4475
     libcerror_error_t **error )
4476
0
{
4477
0
  static char *function                             = "libuna_unicode_character_copy_from_utf32_stream";
4478
0
  libuna_unicode_character_t safe_unicode_character = 0;
4479
0
  size_t safe_utf32_stream_index                    = 0;
4480
4481
0
  if( unicode_character == NULL )
4482
0
  {
4483
0
    libcerror_error_set(
4484
0
     error,
4485
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4486
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4487
0
     "%s: invalid Unicode character.",
4488
0
     function );
4489
4490
0
    return( -1 );
4491
0
  }
4492
0
  if( utf32_stream == NULL )
4493
0
  {
4494
0
    libcerror_error_set(
4495
0
     error,
4496
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4497
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4498
0
     "%s: invalid UTF-32 stream.",
4499
0
     function );
4500
4501
0
    return( -1 );
4502
0
  }
4503
0
  if( utf32_stream_size > (size_t) SSIZE_MAX )
4504
0
  {
4505
0
    libcerror_error_set(
4506
0
     error,
4507
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4508
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4509
0
     "%s: invalid UTF-32 stream size value exceeds maximum.",
4510
0
     function );
4511
4512
0
    return( -1 );
4513
0
  }
4514
0
  if( utf32_stream_index == NULL )
4515
0
  {
4516
0
    libcerror_error_set(
4517
0
     error,
4518
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4519
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4520
0
     "%s: invalid UTF-32 stream index.",
4521
0
     function );
4522
4523
0
    return( -1 );
4524
0
  }
4525
0
  safe_utf32_stream_index = *utf32_stream_index;
4526
4527
0
  if( ( utf32_stream_size < 4 )
4528
0
   || ( safe_utf32_stream_index > ( utf32_stream_size - 4 ) ) )
4529
0
  {
4530
0
    libcerror_error_set(
4531
0
     error,
4532
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4533
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4534
0
     "%s: UTF-32 stream too small.",
4535
0
     function );
4536
4537
0
    return( -1 );
4538
0
  }
4539
0
  if( ( byte_order != LIBUNA_ENDIAN_BIG )
4540
0
   && ( byte_order != LIBUNA_ENDIAN_LITTLE ) )
4541
0
  {
4542
0
    libcerror_error_set(
4543
0
     error,
4544
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4545
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
4546
0
     "%s: unsupported byte order.",
4547
0
     function );
4548
4549
0
    return( -1 );
4550
0
  }
4551
0
  if( byte_order == LIBUNA_ENDIAN_BIG )
4552
0
  {
4553
0
    safe_unicode_character   = utf32_stream[ safe_utf32_stream_index ];
4554
0
    safe_unicode_character <<= 8;
4555
0
    safe_unicode_character  += utf32_stream[ safe_utf32_stream_index + 1 ];
4556
0
    safe_unicode_character <<= 8;
4557
0
    safe_unicode_character  += utf32_stream[ safe_utf32_stream_index + 2 ];
4558
0
    safe_unicode_character <<= 8;
4559
0
    safe_unicode_character  += utf32_stream[ safe_utf32_stream_index + 3 ];
4560
0
  }
4561
0
  else if( byte_order == LIBUNA_ENDIAN_LITTLE )
4562
0
  {
4563
0
    safe_unicode_character   = utf32_stream[ safe_utf32_stream_index + 3 ];
4564
0
    safe_unicode_character <<= 8;
4565
0
    safe_unicode_character  += utf32_stream[ safe_utf32_stream_index + 2 ];
4566
0
    safe_unicode_character <<= 8;
4567
0
    safe_unicode_character  += utf32_stream[ safe_utf32_stream_index + 1 ];
4568
0
    safe_unicode_character <<= 8;
4569
0
    safe_unicode_character  += utf32_stream[ safe_utf32_stream_index ];
4570
0
  }
4571
  /* Determine if the Unicode character is valid
4572
   */
4573
0
  if( ( safe_unicode_character >= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_START )
4574
0
   && ( safe_unicode_character <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
4575
0
  {
4576
0
    safe_unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
4577
0
  }
4578
0
  *unicode_character  = safe_unicode_character;
4579
0
  *utf32_stream_index = safe_utf32_stream_index + 4;
4580
4581
0
  return( 1 );
4582
0
}
4583
4584
/* Copies an Unicode character to an UTF-32 stream
4585
 * Returns 1 if successful or -1 on error
4586
 */
4587
int libuna_unicode_character_copy_to_utf32_stream(
4588
     libuna_unicode_character_t unicode_character,
4589
     uint8_t *utf32_stream,
4590
     size_t utf32_stream_size,
4591
     size_t *utf32_stream_index,
4592
     int byte_order,
4593
     libcerror_error_t **error )
4594
0
{
4595
0
  static char *function          = "libuna_unicode_character_copy_to_utf32_stream";
4596
0
  size_t safe_utf32_stream_index = 0;
4597
4598
0
  if( utf32_stream == NULL )
4599
0
  {
4600
0
    libcerror_error_set(
4601
0
     error,
4602
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4603
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4604
0
     "%s: invalid UTF-32 stream.",
4605
0
     function );
4606
4607
0
    return( -1 );
4608
0
  }
4609
0
  if( utf32_stream_size > (size_t) SSIZE_MAX )
4610
0
  {
4611
0
    libcerror_error_set(
4612
0
     error,
4613
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4614
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4615
0
     "%s: invalid UTF-32 stream size value exceeds maximum.",
4616
0
     function );
4617
4618
0
    return( -1 );
4619
0
  }
4620
0
  if( utf32_stream_index == NULL )
4621
0
  {
4622
0
    libcerror_error_set(
4623
0
     error,
4624
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4625
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4626
0
     "%s: invalid UTF-32 stream index.",
4627
0
     function );
4628
4629
0
    return( -1 );
4630
0
  }
4631
0
  safe_utf32_stream_index = *utf32_stream_index;
4632
4633
0
  if( ( utf32_stream_size < 4 )
4634
0
   || ( safe_utf32_stream_index > ( utf32_stream_size - 4 ) ) )
4635
0
  {
4636
0
    libcerror_error_set(
4637
0
     error,
4638
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4639
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4640
0
     "%s: UTF-32 stream too small.",
4641
0
     function );
4642
4643
0
    return( -1 );
4644
0
  }
4645
0
  if( ( byte_order != LIBUNA_ENDIAN_BIG )
4646
0
   && ( byte_order != LIBUNA_ENDIAN_LITTLE ) )
4647
0
  {
4648
0
    libcerror_error_set(
4649
0
     error,
4650
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4651
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
4652
0
     "%s: unsupported byte order.",
4653
0
     function );
4654
4655
0
    return( -1 );
4656
0
  }
4657
  /* Determine if the Unicode character is valid
4658
   */
4659
0
  if( ( ( unicode_character >= LIBUNA_UNICODE_SURROGATE_HIGH_RANGE_START )
4660
0
    && ( unicode_character <= LIBUNA_UNICODE_SURROGATE_LOW_RANGE_END ) )
4661
0
   || ( unicode_character > LIBUNA_UTF32_CHARACTER_MAX ) )
4662
0
  {
4663
0
    unicode_character = LIBUNA_UNICODE_REPLACEMENT_CHARACTER;
4664
0
  }
4665
0
  if( byte_order == LIBUNA_ENDIAN_BIG )
4666
0
  {
4667
0
    utf32_stream[ safe_utf32_stream_index + 3 ] = (uint8_t) ( unicode_character & 0xff );
4668
0
    unicode_character                         >>= 8;
4669
0
    utf32_stream[ safe_utf32_stream_index + 2 ] = (uint8_t) ( unicode_character & 0xff );
4670
0
    unicode_character                         >>= 8;
4671
0
    utf32_stream[ safe_utf32_stream_index + 1 ] = (uint8_t) ( unicode_character & 0xff );
4672
0
    unicode_character                         >>= 8;
4673
0
    utf32_stream[ safe_utf32_stream_index     ] = (uint8_t) ( unicode_character & 0xff );
4674
0
  }
4675
0
  else if( byte_order == LIBUNA_ENDIAN_LITTLE )
4676
0
  {
4677
0
    utf32_stream[ safe_utf32_stream_index     ] = (uint8_t) ( unicode_character & 0xff );
4678
0
    unicode_character                         >>= 8;
4679
0
    utf32_stream[ safe_utf32_stream_index + 1 ] = (uint8_t) ( unicode_character & 0xff );
4680
0
    unicode_character                         >>= 8;
4681
0
    utf32_stream[ safe_utf32_stream_index + 2 ] = (uint8_t) ( unicode_character & 0xff );
4682
0
    unicode_character                        >>= 8;
4683
0
    utf32_stream[ safe_utf32_stream_index + 3 ] = (uint8_t) ( unicode_character & 0xff );
4684
0
  }
4685
0
  *utf32_stream_index = safe_utf32_stream_index + 4;
4686
4687
0
  return( 1 );
4688
0
}
4689