Coverage Report

Created: 2026-05-24 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvmdk/libclocale/libclocale_codepage.c
Line
Count
Source
1
/*
2
 * Codepage functions
3
 *
4
 * Copyright (C) 2010-2026, 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 <narrow_string.h>
24
#include <wide_string.h>
25
#include <types.h>
26
27
#include "libclocale_codepage.h"
28
#include "libclocale_definitions.h"
29
#include "libclocale_libcerror.h"
30
#include "libclocale_wide_string.h"
31
32
/* If the codepage is not set strings are formatted using UTF-8
33
 */
34
#if defined( WINAPI )
35
int libclocale_codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1252;
36
#else
37
int libclocale_codepage = 0;
38
#endif
39
40
/* Retrieves the narrow system string codepage
41
 * A value of 0 represents no codepage, UTF-8 encoding is used instead
42
 * Returns 1 if successful or -1 on error
43
 */
44
int libclocale_codepage_get(
45
     int *codepage,
46
     libcerror_error_t **error )
47
0
{
48
0
  static char *function = "libclocale_codepage_get";
49
50
0
  if( codepage == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid codepage.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
0
  *codepage = libclocale_codepage;
62
63
0
  return( 1 );
64
0
}
65
66
/* Sets the narrow system string codepage
67
 * A value of 0 represents no codepage, UTF-8 encoding is used instead
68
 * Returns 1 if successful or -1 on error
69
 */
70
int libclocale_codepage_set(
71
     int codepage,
72
     libcerror_error_t **error )
73
0
{
74
0
  static char *function = "libclocale_codepage_set";
75
76
0
  if( ( codepage != LIBCLOCALE_CODEPAGE_ASCII )
77
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_1 )
78
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_2 )
79
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_3 )
80
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_4 )
81
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_5 )
82
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_6 )
83
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_7 )
84
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_8 )
85
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_9 )
86
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_10 )
87
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_11 )
88
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_13 )
89
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_14 )
90
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_15 )
91
0
   && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_16 )
92
0
   && ( codepage != LIBCLOCALE_CODEPAGE_KOI8_R )
93
0
   && ( codepage != LIBCLOCALE_CODEPAGE_KOI8_U )
94
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_874 )
95
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_932 )
96
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_936 )
97
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_949 )
98
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_950 )
99
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1250 )
100
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1251 )
101
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1252 )
102
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1253 )
103
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1254 )
104
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1256 )
105
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1257 )
106
0
   && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1258 )
107
0
   && ( codepage != 0 ) )
108
0
  {
109
0
    libcerror_error_set(
110
0
     error,
111
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
112
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
113
0
     "%s: unsupported codepage.",
114
0
     function );
115
116
0
    return( -1 );
117
0
  }
118
0
  libclocale_codepage = codepage;
119
120
0
  return( 1 );
121
0
}
122
123
/* Copies the codepage from a string
124
 * Returns 1 if successful, 0 if unsupported value or -1 on error
125
 */
126
int libclocale_codepage_copy_from_string(
127
     int *codepage,
128
     const char *string,
129
     size_t string_length,
130
     uint32_t feature_flags,
131
     libcerror_error_t **error )
132
3.32k
{
133
3.32k
  static char *function    = "libclocale_codepage_copy_from_string";
134
3.32k
  size_t string_index      = 0;
135
3.32k
  uint32_t supported_flags = 0;
136
3.32k
  int codepage_set         = 0;
137
138
3.32k
  if( codepage == NULL )
139
0
  {
140
0
    libcerror_error_set(
141
0
     error,
142
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
143
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
144
0
     "%s: invalid codepage.",
145
0
     function );
146
147
0
    return( -1 );
148
0
  }
149
3.32k
  if( string == NULL )
150
0
  {
151
0
    libcerror_error_set(
152
0
     error,
153
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
154
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
155
0
     "%s: invalid string.",
156
0
     function );
157
158
0
    return( -1 );
159
0
  }
160
3.32k
  if( string_length > (size_t) SSIZE_MAX )
161
1
  {
162
1
    libcerror_error_set(
163
1
     error,
164
1
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
165
1
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
166
1
     "%s: invalid string length value exceeds maximum.",
167
1
     function );
168
169
1
    return( -1 );
170
1
  }
171
3.32k
  supported_flags = LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859
172
3.32k
                  | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8
173
3.32k
                  | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS;
174
175
3.32k
  if( ( feature_flags & ~( supported_flags ) ) != 0 )
176
0
  {
177
0
    libcerror_error_set(
178
0
     error,
179
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
180
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
181
0
     "%s: unsupported feature flags value: 0x%08" PRIx32 ".",
182
0
     function,
183
0
     feature_flags );
184
185
0
    return( -1 );
186
0
  }
187
3.32k
  *codepage = -1;
188
189
3.32k
  if( string_length == 5 )
190
2.06k
  {
191
2.06k
    if( narrow_string_compare_no_case(
192
2.06k
         string,
193
2.06k
         "ascii",
194
2.06k
         5 ) == 0 )
195
566
    {
196
566
      *codepage = LIBCLOCALE_CODEPAGE_ASCII;
197
198
566
      string_index = 5;
199
566
    }
200
2.06k
  }
201
3.32k
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859 ) != 0 )
202
0
  {
203
    /* Supported string formats:
204
     * iso8859-1, iso8859_1, iso-8859-1, iso-8859_1, iso_8859-1, iso_8859_1
205
     */
206
0
    if( string_length >= 8 )
207
0
    {
208
0
      if( narrow_string_compare_no_case(
209
0
           string,
210
0
           "iso",
211
0
           3 ) == 0 )
212
0
      {
213
0
        string_index = 3;
214
215
0
        if( ( string[ string_index ] == '-' )
216
0
         || ( string[ string_index ] == '_' ) )
217
0
        {
218
0
          string_index++;
219
0
        }
220
0
        if( ( string[ string_index     ] == '8' )
221
0
         && ( string[ string_index + 1 ] == '8' )
222
0
         && ( string[ string_index + 2 ] == '5' )
223
0
         && ( string[ string_index + 3 ] == '9' ) )
224
0
        {
225
0
          string_index += 4;
226
227
0
          if( string_index < string_length )
228
0
          {
229
0
            if( ( string[ string_index ] == '-' )
230
0
             || ( string[ string_index ] == '_' ) )
231
0
            {
232
0
              string_index++;
233
234
0
              codepage_set = LIBCLOCALE_CODEPAGE_SET_ISO_8859;
235
0
            }
236
0
          }
237
0
        }
238
0
      }
239
0
    }
240
0
  }
241
3.32k
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8 ) != 0 )
242
0
  {
243
    /* Supported string formats:
244
     * koi8, koi8-r, koi8_r
245
     */
246
0
    if( string_length >= 4 )
247
0
    {
248
0
      if( narrow_string_compare_no_case(
249
0
           string,
250
0
           "koi8",
251
0
           4 ) == 0 )
252
0
      {
253
0
        string_index = 4;
254
255
0
        codepage_set = LIBCLOCALE_CODEPAGE_SET_KOI8;
256
257
0
        if( string_index < string_length )
258
0
        {
259
0
          if( ( string[ string_index ] == '-' )
260
0
           || ( string[ string_index ] == '_' ) )
261
0
          {
262
0
            string_index++;
263
0
          }
264
0
        }
265
0
      }
266
0
    }
267
0
  }
268
3.32k
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS ) != 0 )
269
3.32k
  {
270
    /* Supported string formats:
271
     * cp1252, ms1252, windows1252, windows-1252, windows_1252, windows-949-2000, windows_949_2000
272
     */
273
3.32k
    if( string_length >= 7 )
274
845
    {
275
845
      if( narrow_string_compare_no_case(
276
845
           string,
277
845
           "windows",
278
845
           7 ) == 0 )
279
692
      {
280
692
        string_index = 7;
281
282
692
        codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
283
284
692
        if( string_index < string_length )
285
691
        {
286
691
          if( ( string[ string_index ] == '-' )
287
443
           || ( string[ string_index ] == '_' ) )
288
459
          {
289
459
            string_index++;
290
459
          }
291
691
        }
292
692
      }
293
845
    }
294
2.48k
    else if( string_length >= 2 )
295
2.46k
    {
296
2.46k
      if( narrow_string_compare_no_case(
297
2.46k
           string,
298
2.46k
           "cp",
299
2.46k
           2 ) == 0 )
300
219
      {
301
219
        string_index = 2;
302
303
219
        codepage_set = LIBCLOCALE_CODEPAGE_SET_GENERIC;
304
219
      }
305
2.24k
      else if( narrow_string_compare_no_case(
306
2.24k
                string,
307
2.24k
                "ms",
308
2.24k
                2 ) == 0 )
309
1.48k
      {
310
1.48k
        string_index = 2;
311
312
1.48k
        codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
313
1.48k
      }
314
2.46k
    }
315
3.32k
  }
316
3.32k
  if( codepage_set == LIBCLOCALE_CODEPAGE_SET_ISO_8859 )
317
0
  {
318
0
    if( ( string_index + 1 ) == string_length )
319
0
    {
320
0
      switch( string[ string_index ] )
321
0
      {
322
0
        case '1':
323
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_1;
324
0
          break;
325
326
0
        case '2':
327
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_2;
328
0
          break;
329
330
0
        case '3':
331
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_3;
332
0
          break;
333
334
0
        case '4':
335
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_4;
336
0
          break;
337
338
0
        case '5':
339
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_5;
340
0
          break;
341
342
0
        case '6':
343
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_6;
344
0
          break;
345
346
0
        case '7':
347
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_7;
348
0
          break;
349
350
0
        case '8':
351
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_8;
352
0
          break;
353
354
0
        case '9':
355
0
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_9;
356
0
          break;
357
358
0
        default:
359
0
          break;
360
0
      }
361
0
    }
362
0
    else if( ( string_index + 2 ) == string_length )
363
0
    {
364
0
      if( string[ string_index ] == '1' )
365
0
      {
366
0
        string_index++;
367
368
0
        switch( string[ string_index ] )
369
0
        {
370
0
          case '0':
371
0
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_10;
372
0
            break;
373
374
0
          case '1':
375
0
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_11;
376
0
            break;
377
378
0
          case '3':
379
0
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_13;
380
0
            break;
381
382
0
          case '4':
383
0
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_14;
384
0
            break;
385
386
0
          case '5':
387
0
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_15;
388
0
            break;
389
390
0
          case '6':
391
0
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_16;
392
0
            break;
393
394
0
          default:
395
0
            break;
396
0
        }
397
0
      }
398
0
    }
399
0
  }
400
3.32k
  if( codepage_set == LIBCLOCALE_CODEPAGE_SET_KOI8 )
401
0
  {
402
0
    if( ( string_index + 1 ) == string_length )
403
0
    {
404
0
      switch( string[ string_index ] )
405
0
      {
406
0
        case 'r':
407
0
        case 'R':
408
0
          *codepage = LIBCLOCALE_CODEPAGE_KOI8_R;
409
0
          break;
410
411
0
        case 'u':
412
0
        case 'U':
413
0
          *codepage = LIBCLOCALE_CODEPAGE_KOI8_U;
414
0
          break;
415
416
0
        default:
417
0
          break;
418
0
      }
419
0
    }
420
0
  }
421
3.32k
  if( ( codepage_set == LIBCLOCALE_CODEPAGE_SET_GENERIC )
422
3.10k
   || ( codepage_set == LIBCLOCALE_CODEPAGE_SET_WINDOWS ) )
423
2.39k
  {
424
2.39k
    if( ( string_index + 3 ) == string_length )
425
1.96k
    {
426
1.96k
      switch( string[ string_index ] )
427
1.96k
      {
428
289
        case '8':
429
289
          if( ( string[ string_index + 1 ] == '7' )
430
288
           && ( string[ string_index + 2 ] == '4' ) )
431
278
          {
432
278
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_874;
433
278
          }
434
289
          break;
435
436
1.67k
        case '9':
437
1.67k
          if( ( string[ string_index + 1 ] == '3' )
438
1.24k
           && ( string[ string_index + 2 ] == '2' ) )
439
384
          {
440
384
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_932;
441
384
          }
442
1.28k
          else if( ( string[ string_index + 1 ] == '3' )
443
862
                && ( string[ string_index + 2 ] == '6' ) )
444
850
          {
445
850
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_936;
446
850
          }
447
438
          else if( ( string[ string_index + 1 ] == '4' )
448
202
                && ( string[ string_index + 2 ] == '9' ) )
449
194
          {
450
194
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_949;
451
194
          }
452
244
          else if( ( string[ string_index + 1 ] == '5' )
453
214
                && ( string[ string_index + 2 ] == '0' ) )
454
204
          {
455
204
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_950;
456
204
          }
457
1.67k
          break;
458
459
1
        default:
460
1
          break;
461
1.96k
      }
462
1.96k
    }
463
437
    else if( ( string_index + 4 ) == string_length )
464
284
    {
465
284
      if( ( string[ string_index     ] == '1' )
466
282
       && ( string[ string_index + 1 ] == '2' )
467
273
       && ( string[ string_index + 2 ] == '5' ) )
468
263
      {
469
263
        switch( string[ string_index + 3 ] )
470
263
        {
471
146
          case '0':
472
146
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1250;
473
146
            break;
474
475
12
          case '1':
476
12
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1251;
477
12
            break;
478
479
67
          case '2':
480
67
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1252;
481
67
            break;
482
483
6
          case '3':
484
6
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1253;
485
6
            break;
486
487
4
          case '4':
488
4
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1254;
489
4
            break;
490
491
3
          case '5':
492
3
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1255;
493
3
            break;
494
495
9
          case '6':
496
9
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1256;
497
9
            break;
498
499
9
          case '7':
500
9
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1257;
501
9
            break;
502
503
1
          case '8':
504
1
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1258;
505
1
            break;
506
507
6
          default:
508
6
            break;
509
263
        }
510
263
      }
511
284
    }
512
153
    else if( ( string_index + 8 ) == string_length )
513
0
    {
514
0
      if( ( string[ string_index     ] == '9' )
515
0
       && ( string[ string_index + 1 ] == '4' )
516
0
       && ( string[ string_index + 2 ] == '9' )
517
0
       && ( ( string[ string_index + 3 ] == '-' )
518
0
        ||  ( string[ string_index + 3 ] == '_' ) )
519
0
       && ( string[ string_index + 4 ] == '2' )
520
0
       && ( string[ string_index + 5 ] == '0' )
521
0
       && ( string[ string_index + 6 ] == '0' )
522
0
       && ( string[ string_index + 7 ] == '0' ) )
523
0
      {
524
0
        *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_949;
525
0
      }
526
0
    }
527
2.39k
  }
528
3.32k
  if( *codepage != -1 )
529
2.73k
  {
530
2.73k
    return( 1 );
531
2.73k
  }
532
592
  return( 0 );
533
3.32k
}
534
535
#if defined( HAVE_WIDE_CHARACTER_TYPE )
536
537
/* Copies the codepage from a string
538
 * Returns 1 if successful, 0 if unsupported value or -1 on error
539
 */
540
int libclocale_codepage_copy_from_string_wide(
541
     int *codepage,
542
     const wchar_t *string,
543
     size_t string_length,
544
     uint32_t feature_flags,
545
     libcerror_error_t **error )
546
{
547
  static char *function    = "libclocale_codepage_copy_from_string_wide";
548
  size_t string_index      = 0;
549
  uint32_t supported_flags = 0;
550
  int codepage_set         = 0;
551
552
  if( codepage == NULL )
553
  {
554
    libcerror_error_set(
555
     error,
556
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
557
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
558
     "%s: invalid codepage.",
559
     function );
560
561
    return( -1 );
562
  }
563
  if( string == NULL )
564
  {
565
    libcerror_error_set(
566
     error,
567
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
568
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
569
     "%s: invalid string.",
570
     function );
571
572
    return( -1 );
573
  }
574
  if( string_length > (size_t) SSIZE_MAX )
575
  {
576
    libcerror_error_set(
577
     error,
578
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
579
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
580
     "%s: invalid string length value exceeds maximum.",
581
     function );
582
583
    return( -1 );
584
  }
585
  supported_flags = LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859
586
                  | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8
587
                  | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS;
588
589
  if( ( feature_flags & ~( supported_flags ) ) != 0 )
590
  {
591
    libcerror_error_set(
592
     error,
593
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
594
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
595
     "%s: unsupported feature flags value: 0x%08" PRIx32 ".",
596
     function,
597
     feature_flags );
598
599
    return( -1 );
600
  }
601
  *codepage = -1;
602
603
  if( string_length == 5 )
604
  {
605
    if( wide_string_compare_no_case(
606
         string,
607
         L"ascii",
608
         5 ) == 0 )
609
    {
610
      *codepage = LIBCLOCALE_CODEPAGE_ASCII;
611
612
      string_index = 5;
613
    }
614
  }
615
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859 ) != 0 )
616
  {
617
    /* Supported string formats:
618
     * iso8859-1, iso8859_1, iso-8859-1, iso-8859_1, iso_8859-1, iso_8859_1
619
     */
620
    if( string_length >= 8 )
621
    {
622
      if( wide_string_compare_no_case(
623
           string,
624
           L"iso",
625
           3 ) == 0 )
626
      {
627
        string_index = 3;
628
629
        if( ( string[ string_index ] == (wchar_t) '-' )
630
         || ( string[ string_index ] == (wchar_t) '_' ) )
631
        {
632
          string_index++;
633
        }
634
        if( ( string[ string_index     ] == (wchar_t) '8' )
635
         && ( string[ string_index + 1 ] == (wchar_t) '8' )
636
         && ( string[ string_index + 2 ] == (wchar_t) '5' )
637
         && ( string[ string_index + 3 ] == (wchar_t) '9' ) )
638
        {
639
          string_index += 4;
640
641
          if( string_index < string_length )
642
          {
643
            if( ( string[ string_index ] == (wchar_t) '-' )
644
             || ( string[ string_index ] == (wchar_t) '_' ) )
645
            {
646
              string_index++;
647
648
              codepage_set = LIBCLOCALE_CODEPAGE_SET_ISO_8859;
649
            }
650
          }
651
        }
652
      }
653
    }
654
  }
655
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8 ) != 0 )
656
  {
657
    /* Supported string formats:
658
     * koi8, koi8-r, koi8_r
659
     */
660
    if( string_length >= 4 )
661
    {
662
      if( wide_string_compare_no_case(
663
           string,
664
           L"koi8",
665
           4 ) == 0 )
666
      {
667
        string_index = 4;
668
669
        codepage_set = LIBCLOCALE_CODEPAGE_SET_KOI8;
670
671
        if( string_index < string_length )
672
        {
673
          if( ( string[ string_index ] == (wchar_t) '-' )
674
           || ( string[ string_index ] == (wchar_t) '_' ) )
675
          {
676
            string_index++;
677
          }
678
        }
679
      }
680
    }
681
  }
682
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS ) != 0 )
683
  {
684
    /* Supported string formats:
685
     * cp1252, ms1252, windows1252, windows-1252, windows_1252, windows-949-2000, windows_949_2000
686
     */
687
    if( string_length >= 7 )
688
    {
689
      if( wide_string_compare_no_case(
690
           string,
691
           L"windows",
692
           7 ) == 0 )
693
      {
694
        string_index = 7;
695
696
        codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
697
698
        if( string_index < string_length )
699
        {
700
          if( ( string[ string_index ] == (wchar_t) '-' )
701
           || ( string[ string_index ] == (wchar_t) '_' ) )
702
          {
703
            string_index++;
704
          }
705
        }
706
      }
707
    }
708
    else if( string_length >= 2 )
709
    {
710
      if( wide_string_compare_no_case(
711
           string,
712
           L"cp",
713
           2 ) == 0 )
714
      {
715
        string_index = 2;
716
717
        codepage_set = LIBCLOCALE_CODEPAGE_SET_GENERIC;
718
      }
719
      else if( wide_string_compare_no_case(
720
                string,
721
                L"ms",
722
                2 ) == 0 )
723
      {
724
        string_index = 2;
725
726
        codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
727
      }
728
    }
729
  }
730
  if( codepage_set == LIBCLOCALE_CODEPAGE_SET_ISO_8859 )
731
  {
732
    if( ( string_index + 1 ) == string_length )
733
    {
734
      switch( string[ string_index ] )
735
      {
736
        case '1':
737
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_1;
738
          break;
739
740
        case '2':
741
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_2;
742
          break;
743
744
        case '3':
745
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_3;
746
          break;
747
748
        case '4':
749
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_4;
750
          break;
751
752
        case '5':
753
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_5;
754
          break;
755
756
        case '6':
757
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_6;
758
          break;
759
760
        case '7':
761
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_7;
762
          break;
763
764
        case '8':
765
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_8;
766
          break;
767
768
        case '9':
769
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_9;
770
          break;
771
772
        default:
773
          break;
774
      }
775
    }
776
    else if( ( string_index + 2 ) == string_length )
777
    {
778
      if( string[ string_index ] == (wchar_t) '1' )
779
      {
780
        string_index++;
781
782
        switch( string[ string_index ] )
783
        {
784
          case '0':
785
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_10;
786
            break;
787
788
          case '1':
789
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_11;
790
            break;
791
792
          case '3':
793
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_13;
794
            break;
795
796
          case '4':
797
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_14;
798
            break;
799
800
          case '5':
801
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_15;
802
            break;
803
804
          case '6':
805
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_16;
806
            break;
807
808
          default:
809
            break;
810
        }
811
      }
812
    }
813
  }
814
  if( codepage_set == LIBCLOCALE_CODEPAGE_SET_KOI8 )
815
  {
816
    if( ( string_index + 1 ) == string_length )
817
    {
818
      switch( string[ string_index ] )
819
      {
820
        case 'r':
821
        case 'R':
822
          *codepage = LIBCLOCALE_CODEPAGE_KOI8_R;
823
          break;
824
825
        case 'u':
826
        case 'U':
827
          *codepage = LIBCLOCALE_CODEPAGE_KOI8_U;
828
          break;
829
830
        default:
831
          break;
832
      }
833
    }
834
  }
835
  if( ( codepage_set == LIBCLOCALE_CODEPAGE_SET_GENERIC )
836
   || ( codepage_set == LIBCLOCALE_CODEPAGE_SET_WINDOWS ) )
837
  {
838
    if( ( string_index + 3 ) == string_length )
839
    {
840
      switch( string[ string_index ] )
841
      {
842
        case '8':
843
          if( ( string[ string_index + 1 ] == (wchar_t) '7' )
844
           && ( string[ string_index + 2 ] == (wchar_t) '4' ) )
845
          {
846
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_874;
847
          }
848
          break;
849
850
        case '9':
851
          if( ( string[ string_index + 1 ] == (wchar_t) '3' )
852
           && ( string[ string_index + 2 ] == (wchar_t) '2' ) )
853
          {
854
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_932;
855
          }
856
          else if( ( string[ string_index + 1 ] == (wchar_t) '3' )
857
                && ( string[ string_index + 2 ] == (wchar_t) '6' ) )
858
          {
859
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_936;
860
          }
861
          else if( ( string[ string_index + 1 ] == (wchar_t) '4' )
862
                && ( string[ string_index + 2 ] == (wchar_t) '9' ) )
863
          {
864
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_949;
865
          }
866
          else if( ( string[ string_index + 1 ] == (wchar_t) '5' )
867
                && ( string[ string_index + 2 ] == (wchar_t) '0' ) )
868
          {
869
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_950;
870
          }
871
          break;
872
873
        default:
874
          break;
875
      }
876
    }
877
    else if( ( string_index + 4 ) == string_length )
878
    {
879
      if( ( string[ string_index     ] == (wchar_t) '1' )
880
       && ( string[ string_index + 1 ] == (wchar_t) '2' )
881
       && ( string[ string_index + 2 ] == (wchar_t) '5' ) )
882
      {
883
        switch( string[ string_index + 3 ] )
884
        {
885
          case '0':
886
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1250;
887
            break;
888
889
          case '1':
890
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1251;
891
            break;
892
893
          case '2':
894
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1252;
895
            break;
896
897
          case '3':
898
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1253;
899
            break;
900
901
          case '4':
902
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1254;
903
            break;
904
905
          case '5':
906
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1255;
907
            break;
908
909
          case '6':
910
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1256;
911
            break;
912
913
          case '7':
914
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1257;
915
            break;
916
917
          case '8':
918
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1258;
919
            break;
920
921
          default:
922
            break;
923
        }
924
      }
925
    }
926
    else if( ( string_index + 8 ) == string_length )
927
    {
928
      if( ( string[ string_index     ] == (wchar_t) '9' )
929
       && ( string[ string_index + 1 ] == (wchar_t) '4' )
930
       && ( string[ string_index + 2 ] == (wchar_t) '9' )
931
       && ( ( string[ string_index + 3 ] == (wchar_t) '-' )
932
        ||  ( string[ string_index + 3 ] == (wchar_t) '_' ) )
933
       && ( string[ string_index + 4 ] == (wchar_t) '2' )
934
       && ( string[ string_index + 5 ] == (wchar_t) '0' )
935
       && ( string[ string_index + 6 ] == (wchar_t) '0' )
936
       && ( string[ string_index + 7 ] == (wchar_t) '0' ) )
937
      {
938
        *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_949;
939
      }
940
    }
941
  }
942
  if( *codepage != -1 )
943
  {
944
    return( 1 );
945
  }
946
  return( 0 );
947
}
948
949
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
950