Coverage Report

Created: 2024-02-25 07:20

/src/libvhdi/libuna/libuna_codepage_mac_symbol.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * MacSymbol codepage functions
3
 *
4
 * Copyright (C) 2008-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <types.h>
24
25
#include "libuna_codepage_mac_symbol.h"
26
#include "libuna_libcerror.h"
27
#include "libuna_types.h"
28
29
/* Extended ASCII to Unicode character lookup table for the MacSymbol codepage
30
 * Unknown are filled with the Unicode replacement character 0xfffd
31
 */
32
const uint16_t libuna_codepage_mac_symbol_byte_stream_to_unicode_base_0x20[ 224 ] = {
33
  0x0020, 0x0021, 0x2200, 0x0023, 0x2203, 0x0025, 0x0026, 0x220d,
34
  0x0028, 0x0029, 0x2217, 0x002b, 0x002c, 0x2212, 0x002e, 0x002f,
35
  0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
36
  0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
37
  0x2245, 0x0391, 0x0392, 0x03a7, 0x0394, 0x0395, 0x03a6, 0x0393,
38
  0x0397, 0x0399, 0x03d1, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f,
39
  0x03a0, 0x0398, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03c2, 0x03a9,
40
  0x039e, 0x03a8, 0x0396, 0x005b, 0x2234, 0x005d, 0x22a5, 0x005f,
41
  0xf8e5, 0x03b1, 0x03b2, 0x03c7, 0x03b4, 0x03b5, 0x03c6, 0x03b3,
42
  0x03b7, 0x03b9, 0x03d5, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03bf,
43
  0x03c0, 0x03b8, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03d6, 0x03c9,
44
  0x03be, 0x03c8, 0x03b6, 0x007b, 0x007c, 0x007d, 0x223c, 0x007f,
45
  0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
46
  0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
47
  0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
48
  0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
49
  0x20ac, 0x03d2, 0x2032, 0x2264, 0x2044, 0x221e, 0x0192, 0x2663,
50
  0x2666, 0x2665, 0x2660, 0x2194, 0x2190, 0x2191, 0x2192, 0x2193,
51
  0x00b0, 0x00b1, 0x2033, 0x2265, 0x00d7, 0x221d, 0x2202, 0x2022,
52
  0x00f7, 0x2260, 0x2261, 0x2248, 0x2026, 0x23d0, 0x23af, 0x21b5,
53
  0x2135, 0x2111, 0x211c, 0x2118, 0x2297, 0x2295, 0x2205, 0x2229,
54
  0x222a, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, 0x2209,
55
  0x2220, 0x2207, 0x00ae, 0x00a9, 0x2122, 0x220f, 0x221a, 0x22c5,
56
  0x00ac, 0x2227, 0x2228, 0x21d4, 0x21d0, 0x21d1, 0x21d2, 0x21d3,
57
  0x25ca, 0x3008, 0x00ae, 0x00a9, 0x2122, 0x2211, 0x239b, 0x239c,
58
  0x239d, 0x23a1, 0x23a2, 0x23a3, 0x23a7, 0x23a8, 0x23a9, 0x23aa,
59
  0xf8ff, 0x3009, 0x222b, 0x2320, 0x23ae, 0x2321, 0x239e, 0x239f,
60
  0x23a0, 0x23a4, 0x23a5, 0x23a6, 0x23ab, 0x23ac, 0x23ad, 0xfffd
61
};
62
63
/* Unicode to ASCII character lookup tables for the MacSymbol codepage
64
 * Unknown are filled with the ASCII replacement character 0x1a
65
 */
66
const uint8_t libuna_codepage_mac_symbol_unicode_to_byte_stream_base_0x0390[ 72 ] = {
67
  0x1a, 0x41, 0x42, 0x47, 0x44, 0x45, 0x5a, 0x48,
68
  0x51, 0x49, 0x4b, 0x4c, 0x4d, 0x4e, 0x58, 0x4f,
69
  0x50, 0x52, 0x1a, 0x53, 0x54, 0x55, 0x46, 0x43,
70
  0x59, 0x57, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
71
  0x1a, 0x61, 0x62, 0x67, 0x64, 0x65, 0x7a, 0x68,
72
  0x71, 0x69, 0x6b, 0x6c, 0x6d, 0x6e, 0x78, 0x6f,
73
  0x70, 0x72, 0x56, 0x73, 0x74, 0x75, 0x66, 0x63,
74
  0x79, 0x77, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
75
  0x1a, 0x4a, 0xa1, 0x1a, 0x1a, 0x6a, 0x76, 0x1a
76
};
77
78
const uint8_t libuna_codepage_mac_symbol_unicode_to_byte_stream_base_0x2200[ 80 ] = {
79
  0x22, 0x1a, 0xb6, 0x24, 0x1a, 0xc6, 0x1a, 0xd1,
80
  0xce, 0xcf, 0x1a, 0x1a, 0x1a, 0x27, 0x1a, 0xd5,
81
  0x1a, 0xe5, 0x2d, 0x1a, 0x1a, 0x1a, 0x1a, 0x2a,
82
  0x1a, 0x1a, 0xd6, 0x1a, 0x1a, 0xb5, 0xa5, 0x1a,
83
  0xd0, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0xd9,
84
  0xda, 0xc7, 0xc8, 0xf2, 0x1a, 0x1a, 0x1a, 0x1a,
85
  0x1a, 0x1a, 0x1a, 0x1a, 0x5c, 0x1a, 0x1a, 0x1a,
86
  0x1a, 0x1a, 0x1a, 0x1a, 0x7e, 0x1a, 0x1a, 0x1a,
87
  0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x40, 0x1a, 0x1a,
88
  0xbb, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a
89
};
90
91
const uint8_t libuna_codepage_mac_symbol_unicode_to_byte_stream_base_0x2280[ 40 ] = {
92
  0x1a, 0x1a, 0xcc, 0xc9, 0xcb, 0x1a, 0xcd, 0xca,
93
  0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
94
  0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0xc5, 0x1a, 0xc4,
95
  0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
96
  0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x5e, 0x1a, 0x1a
97
};
98
99
const uint8_t libuna_codepage_mac_symbol_unicode_to_byte_stream_base_0x2398[ 24 ] = {
100
  0x1a, 0x1a, 0x1a, 0xe6, 0xe7, 0xe8, 0xf6, 0xf7,
101
  0xf8, 0xe9, 0xea, 0xeb, 0xf9, 0xfa, 0xfb, 0xec,
102
  0xed, 0xee, 0xef, 0xfc, 0xfd, 0xfe, 0xf4, 0xbe
103
};
104
105
/* Determines the size of a MacSymbol encoded byte stream from an Unicode character
106
 * Adds the size to the byte stream character size value
107
 * Returns 1 if successful, 0 if the byte stream character is valid but not supported since it requires special handling or -1 on error
108
 */
109
int libuna_codepage_mac_symbol_unicode_character_size_to_byte_stream(
110
     libuna_unicode_character_t unicode_character,
111
     size_t *byte_stream_character_size,
112
     libcerror_error_t **error )
113
0
{
114
0
  static char *function = "libuna_codepage_mac_symbol_unicode_character_size_to_byte_stream";
115
0
  int result            = 0;
116
117
0
  if( byte_stream_character_size == NULL )
118
0
  {
119
0
    libcerror_error_set(
120
0
     error,
121
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123
0
     "%s: invalid byte stream character size.",
124
0
     function );
125
126
0
    return( -1 );
127
0
  }
128
0
  switch( unicode_character )
129
0
  {
130
0
    case 0x000000aeUL:
131
0
    case 0x000000a9UL:
132
0
    case 0x00002122UL:
133
0
      result = 0;
134
0
      break;
135
136
0
    default:
137
0
      *byte_stream_character_size += 1;
138
139
0
      result = 1;
140
0
      break;
141
0
  }
142
0
  return( result );
143
0
}
144
145
/* Copies an Unicode character from a MacSymbol encoded byte stream
146
 * Returns 1 if successful or -1 on error
147
 */
148
int libuna_codepage_mac_symbol_copy_from_byte_stream(
149
     libuna_unicode_character_t *unicode_character,
150
     const uint8_t *byte_stream,
151
     size_t byte_stream_size,
152
     size_t *byte_stream_index,
153
     libcerror_error_t **error )
154
0
{
155
0
  static char *function                             = "libuna_codepage_mac_symbol_copy_from_byte_stream";
156
0
  libuna_unicode_character_t safe_unicode_character = 0xfffd;
157
0
  size_t safe_byte_stream_index                     = 0;
158
0
  uint8_t byte_stream_character                     = 0;
159
160
0
  if( unicode_character == NULL )
161
0
  {
162
0
    libcerror_error_set(
163
0
     error,
164
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
165
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
166
0
     "%s: invalid Unicode character.",
167
0
     function );
168
169
0
    return( -1 );
170
0
  }
171
0
  if( byte_stream == NULL )
172
0
  {
173
0
    libcerror_error_set(
174
0
     error,
175
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
176
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
177
0
     "%s: invalid byte stream.",
178
0
     function );
179
180
0
    return( -1 );
181
0
  }
182
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
183
0
  {
184
0
    libcerror_error_set(
185
0
     error,
186
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
187
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
188
0
     "%s: invalid byte stream size value exceeds maximum.",
189
0
     function );
190
191
0
    return( -1 );
192
0
  }
193
0
  if( byte_stream_index == NULL )
194
0
  {
195
0
    libcerror_error_set(
196
0
     error,
197
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
198
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
199
0
     "%s: invalid byte stream index.",
200
0
     function );
201
202
0
    return( -1 );
203
0
  }
204
0
  safe_byte_stream_index = *byte_stream_index;
205
206
0
  if( safe_byte_stream_index >= byte_stream_size )
207
0
  {
208
0
    libcerror_error_set(
209
0
     error,
210
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
211
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
212
0
     "%s: byte stream too small.",
213
0
     function );
214
215
0
    return( -1 );
216
0
  }
217
0
  byte_stream_character = byte_stream[ safe_byte_stream_index++ ];
218
219
0
  if( byte_stream_character < 0x20 )
220
0
  {
221
0
    safe_unicode_character = byte_stream_character;
222
0
  }
223
0
  else
224
0
  {
225
0
    byte_stream_character -= 0x20;
226
227
0
    safe_unicode_character = libuna_codepage_mac_symbol_byte_stream_to_unicode_base_0x20[ byte_stream_character ];
228
0
  }
229
0
  *unicode_character = safe_unicode_character;
230
0
  *byte_stream_index = safe_byte_stream_index;
231
232
0
  return( 1 );
233
0
}
234
235
/* Copies an Unicode character to a MacSymbol encoded byte stream
236
 * Returns 1 if successful or -1 on error
237
 */
238
int libuna_codepage_mac_symbol_copy_to_byte_stream(
239
     libuna_unicode_character_t unicode_character,
240
     uint8_t *byte_stream,
241
     size_t byte_stream_size,
242
     size_t *byte_stream_index,
243
     libcerror_error_t **error )
244
0
{
245
0
  static char *function         = "libuna_codepage_mac_symbol_copy_to_byte_stream";
246
0
  size_t safe_byte_stream_index = 0;
247
0
  uint16_t byte_stream_value    = 0x001a;
248
249
0
  if( byte_stream == NULL )
250
0
  {
251
0
    libcerror_error_set(
252
0
     error,
253
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
254
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
255
0
     "%s: invalid byte stream.",
256
0
     function );
257
258
0
    return( -1 );
259
0
  }
260
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
261
0
  {
262
0
    libcerror_error_set(
263
0
     error,
264
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
265
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
266
0
     "%s: invalid byte stream size value exceeds maximum.",
267
0
     function );
268
269
0
    return( -1 );
270
0
  }
271
0
  if( byte_stream_index == NULL )
272
0
  {
273
0
    libcerror_error_set(
274
0
     error,
275
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
276
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
277
0
     "%s: invalid byte stream index.",
278
0
     function );
279
280
0
    return( -1 );
281
0
  }
282
0
  safe_byte_stream_index = *byte_stream_index;
283
284
0
  if( safe_byte_stream_index >= byte_stream_size )
285
0
  {
286
0
    libcerror_error_set(
287
0
     error,
288
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
289
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
290
0
     "%s: byte stream too small.",
291
0
     function );
292
293
0
    return( -1 );
294
0
  }
295
0
  if( ( unicode_character <= 0x0021 )
296
0
   || ( unicode_character == 0x0023 )
297
0
   || ( unicode_character == 0x0025 )
298
0
   || ( unicode_character == 0x0026 )
299
0
   || ( unicode_character == 0x0028 )
300
0
   || ( unicode_character == 0x0029 )
301
0
   || ( unicode_character == 0x002b )
302
0
   || ( unicode_character == 0x002c )
303
0
   || ( ( unicode_character >= 0x002e )
304
0
    &&  ( unicode_character <= 0x003f ) )
305
0
   || ( unicode_character == 0x005b )
306
0
   || ( unicode_character == 0x005d )
307
0
   || ( unicode_character == 0x005f )
308
0
   || ( unicode_character == 0x007b )
309
0
   || ( unicode_character == 0x007c )
310
0
   || ( unicode_character == 0x007d )
311
0
   || ( unicode_character == 0x007f )
312
0
   || ( unicode_character == 0x00b0 )
313
0
   || ( unicode_character == 0x00b1 ) )
314
0
  {
315
0
    byte_stream_value = (uint16_t) unicode_character;
316
0
  }
317
0
  else if( ( unicode_character >= 0x0390 )
318
0
        && ( unicode_character < 0x03d8 ) )
319
0
  {
320
0
    unicode_character -= 0x0390;
321
322
0
    byte_stream_value = libuna_codepage_mac_symbol_unicode_to_byte_stream_base_0x0390[ unicode_character ];
323
0
  }
324
0
  else if( ( unicode_character >= 0x2200 )
325
0
        && ( unicode_character < 0x2250 ) )
326
0
  {
327
0
    unicode_character -= 0x2200;
328
329
0
    byte_stream_value = libuna_codepage_mac_symbol_unicode_to_byte_stream_base_0x2200[ unicode_character ];
330
0
  }
331
0
  else if( ( unicode_character >= 0x2280 )
332
0
        && ( unicode_character < 0x22a8 ) )
333
0
  {
334
0
    unicode_character -= 0x2280;
335
336
0
    byte_stream_value = libuna_codepage_mac_symbol_unicode_to_byte_stream_base_0x2280[ unicode_character ];
337
0
  }
338
0
  else if( ( unicode_character >= 0x2398 )
339
0
        && ( unicode_character < 0x23b0 ) )
340
0
  {
341
0
    unicode_character -= 0x2398;
342
343
0
    byte_stream_value = libuna_codepage_mac_symbol_unicode_to_byte_stream_base_0x2398[ unicode_character ];
344
0
  }
345
0
  else switch( unicode_character )
346
0
  {
347
0
    case 0x00a9:
348
0
      byte_stream_value = 0xd3;
349
0
      break;
350
351
0
    case 0x00ac:
352
0
      byte_stream_value = 0xd8;
353
0
      break;
354
355
0
    case 0x00ae:
356
0
      byte_stream_value = 0xd2;
357
0
      break;
358
359
0
    case 0x00d7:
360
0
      byte_stream_value = 0xb4;
361
0
      break;
362
363
0
    case 0x00f7:
364
0
      byte_stream_value = 0xb8;
365
0
      break;
366
367
0
    case 0x0192:
368
0
      byte_stream_value = 0xa6;
369
0
      break;
370
371
0
    case 0x2022:
372
0
      byte_stream_value = 0xb7;
373
0
      break;
374
375
0
    case 0x2026:
376
0
      byte_stream_value = 0xbc;
377
0
      break;
378
379
0
    case 0x2032:
380
0
      byte_stream_value = 0xa2;
381
0
      break;
382
383
0
    case 0x2033:
384
0
      byte_stream_value = 0xb2;
385
0
      break;
386
387
0
    case 0x2044:
388
0
      byte_stream_value = 0xa4;
389
0
      break;
390
391
0
    case 0x20ac:
392
0
      byte_stream_value = 0xa0;
393
0
      break;
394
395
0
    case 0x2111:
396
0
      byte_stream_value = 0xc1;
397
0
      break;
398
399
0
    case 0x2118:
400
0
      byte_stream_value = 0xc3;
401
0
      break;
402
403
0
    case 0x211c:
404
0
      byte_stream_value = 0xc2;
405
0
      break;
406
407
0
    case 0x2122:
408
0
      byte_stream_value = 0xd4;
409
0
      break;
410
411
0
    case 0x2135:
412
0
      byte_stream_value = 0xc0;
413
0
      break;
414
415
0
    case 0x2190:
416
0
      byte_stream_value = 0xac;
417
0
      break;
418
419
0
    case 0x2191:
420
0
      byte_stream_value = 0xad;
421
0
      break;
422
423
0
    case 0x2192:
424
0
      byte_stream_value = 0xae;
425
0
      break;
426
427
0
    case 0x2193:
428
0
      byte_stream_value = 0xaf;
429
0
      break;
430
431
0
    case 0x2194:
432
0
      byte_stream_value = 0xab;
433
0
      break;
434
435
0
    case 0x21b5:
436
0
      byte_stream_value = 0xbf;
437
0
      break;
438
439
0
    case 0x21d0:
440
0
      byte_stream_value = 0xdc;
441
0
      break;
442
443
0
    case 0x21d1:
444
0
      byte_stream_value = 0xdd;
445
0
      break;
446
447
0
    case 0x21d2:
448
0
      byte_stream_value = 0xde;
449
0
      break;
450
451
0
    case 0x21d3:
452
0
      byte_stream_value = 0xdf;
453
0
      break;
454
455
0
    case 0x21d4:
456
0
      byte_stream_value = 0xdb;
457
0
      break;
458
459
0
    case 0x2260:
460
0
      byte_stream_value = 0xb9;
461
0
      break;
462
463
0
    case 0x2261:
464
0
      byte_stream_value = 0xba;
465
0
      break;
466
467
0
    case 0x2264:
468
0
      byte_stream_value = 0xa3;
469
0
      break;
470
471
0
    case 0x2265:
472
0
      byte_stream_value = 0xb3;
473
0
      break;
474
475
0
    case 0x22c5:
476
0
      byte_stream_value = 0xd7;
477
0
      break;
478
479
0
    case 0x2320:
480
0
      byte_stream_value = 0xf3;
481
0
      break;
482
483
0
    case 0x2321:
484
0
      byte_stream_value = 0xf5;
485
0
      break;
486
487
0
    case 0x23d0:
488
0
      byte_stream_value = 0xbd;
489
0
      break;
490
491
0
    case 0x25ca:
492
0
      byte_stream_value = 0xe0;
493
0
      break;
494
495
0
    case 0x2660:
496
0
      byte_stream_value = 0xaa;
497
0
      break;
498
499
0
    case 0x2663:
500
0
      byte_stream_value = 0xa7;
501
0
      break;
502
503
0
    case 0x2665:
504
0
      byte_stream_value = 0xa9;
505
0
      break;
506
507
0
    case 0x2666:
508
0
      byte_stream_value = 0xa8;
509
0
      break;
510
511
0
    case 0x3008:
512
0
      byte_stream_value = 0xe1;
513
0
      break;
514
515
0
    case 0x3009:
516
0
      byte_stream_value = 0xf1;
517
0
      break;
518
519
0
    case 0xf8e5:
520
0
      byte_stream_value = 0x60;
521
0
      break;
522
523
0
    case 0xf8ff:
524
0
      byte_stream_value = 0xf0;
525
0
      break;
526
527
0
    default:
528
0
      byte_stream_value = 0x1a;
529
0
      break;
530
0
  }
531
0
  byte_stream[ safe_byte_stream_index++ ] = (uint8_t) ( byte_stream_value & 0x00ff );
532
533
0
  *byte_stream_index = safe_byte_stream_index;
534
535
0
  return( 1 );
536
0
}
537