Coverage Report

Created: 2024-02-25 07:19

/src/libphdi/libclocale/libclocale_codepage.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Codepage functions
3
 *
4
 * Copyright (C) 2010-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 <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
0
{
133
0
  static char *function    = "libclocale_codepage_copy_from_string";
134
0
  size_t string_index      = 0;
135
0
  uint32_t supported_flags = 0;
136
0
  int codepage_set         = 0;
137
138
0
  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
0
  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
0
  if( string_length > (size_t) SSIZE_MAX )
161
0
  {
162
0
    libcerror_error_set(
163
0
     error,
164
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
165
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
166
0
     "%s: invalid string length value exceeds maximum.",
167
0
     function );
168
169
0
    return( -1 );
170
0
  }
171
0
  supported_flags = LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859
172
0
                  | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8
173
0
                  | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS;
174
175
0
  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
0
  *codepage = -1;
188
189
0
  if( string_length == 5 )
190
0
  {
191
0
    if( narrow_string_compare_no_case(
192
0
         string,
193
0
         "ascii",
194
0
         5 ) == 0 )
195
0
    {
196
0
      *codepage = LIBCLOCALE_CODEPAGE_ASCII;
197
198
0
      string_index = 5;
199
0
    }
200
0
  }
201
0
  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
0
  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
0
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS ) != 0 )
269
0
  {
270
    /* Supported string formats:
271
     * cp1252, ms1252, windows1252, windows-1252, windows_1252
272
     */
273
0
    if( string_length >= 7 )
274
0
    {
275
0
      if( narrow_string_compare_no_case(
276
0
           string,
277
0
           "windows",
278
0
           7 ) == 0 )
279
0
      {
280
0
        string_index = 7;
281
282
0
        codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
283
284
0
        if( string_index < string_length )
285
0
        {
286
0
          if( ( string[ string_index ] == '-' )
287
0
           || ( string[ string_index ] == '_' ) )
288
0
          {
289
0
            string_index++;
290
0
          }
291
0
        }
292
0
      }
293
0
    }
294
0
    else if( string_length >= 2 )
295
0
    {
296
0
      if( narrow_string_compare_no_case(
297
0
           string,
298
0
           "cp",
299
0
           2 ) == 0 )
300
0
      {
301
0
        string_index = 2;
302
303
0
        codepage_set = LIBCLOCALE_CODEPAGE_SET_GENERIC;
304
0
      }
305
0
      else if( narrow_string_compare_no_case(
306
0
                string,
307
0
                "ms",
308
0
                2 ) == 0 )
309
0
      {
310
0
        string_index = 2;
311
312
0
        codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
313
0
      }
314
0
    }
315
0
  }
316
0
  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
0
  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
0
  if( ( codepage_set == LIBCLOCALE_CODEPAGE_SET_GENERIC )
422
0
   || ( codepage_set == LIBCLOCALE_CODEPAGE_SET_WINDOWS ) )
423
0
  {
424
0
    if( ( string_index + 3 ) == string_length )
425
0
    {
426
0
      switch( string[ string_index ] )
427
0
      {
428
0
        case '8':
429
0
          if( ( string[ string_index + 1 ] == '7' )
430
0
           && ( string[ string_index + 2 ] == '4' ) )
431
0
          {
432
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_874;
433
0
          }
434
0
          break;
435
436
0
        case '9':
437
0
          if( ( string[ string_index + 1 ] == '3' )
438
0
           && ( string[ string_index + 2 ] == '2' ) )
439
0
          {
440
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_932;
441
0
          }
442
0
          else if( ( string[ string_index + 1 ] == '3' )
443
0
                && ( string[ string_index + 2 ] == '6' ) )
444
0
          {
445
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_936;
446
0
          }
447
0
          else if( ( string[ string_index + 1 ] == '4' )
448
0
                && ( string[ string_index + 2 ] == '9' ) )
449
0
          {
450
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_949;
451
0
          }
452
0
          else if( ( string[ string_index + 1 ] == '5' )
453
0
                && ( string[ string_index + 2 ] == '0' ) )
454
0
          {
455
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_950;
456
0
          }
457
0
          break;
458
459
0
        default:
460
0
          break;
461
0
      }
462
0
    }
463
0
    else if( ( string_index + 4 ) == string_length )
464
0
    {
465
0
      if( ( string[ string_index     ] == '1' )
466
0
       && ( string[ string_index + 1 ] == '2' )
467
0
       && ( string[ string_index + 2 ] == '5' ) )
468
0
      {
469
0
        switch( string[ string_index + 3 ] )
470
0
        {
471
0
          case '0':
472
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1250;
473
0
            break;
474
475
0
          case '1':
476
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1251;
477
0
            break;
478
479
0
          case '2':
480
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1252;
481
0
            break;
482
483
0
          case '3':
484
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1253;
485
0
            break;
486
487
0
          case '4':
488
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1254;
489
0
            break;
490
491
0
          case '5':
492
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1255;
493
0
            break;
494
495
0
          case '6':
496
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1256;
497
0
            break;
498
499
0
          case '7':
500
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1257;
501
0
            break;
502
503
0
          case '8':
504
0
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1258;
505
0
            break;
506
507
0
          default:
508
0
            break;
509
0
        }
510
0
      }
511
0
    }
512
0
  }
513
0
  if( *codepage != -1 )
514
0
  {
515
0
    return( 1 );
516
0
  }
517
0
  return( 0 );
518
0
}
519
520
#if defined( HAVE_WIDE_CHARACTER_TYPE )
521
522
/* Copies the codepage from a string
523
 * Returns 1 if successful, 0 if unsupported value or -1 on error
524
 */
525
int libclocale_codepage_copy_from_string_wide(
526
     int *codepage,
527
     const wchar_t *string,
528
     size_t string_length,
529
     uint32_t feature_flags,
530
     libcerror_error_t **error )
531
{
532
  static char *function    = "libclocale_codepage_copy_from_string_wide";
533
  size_t string_index      = 0;
534
  uint32_t supported_flags = 0;
535
  int codepage_set         = 0;
536
537
  if( codepage == NULL )
538
  {
539
    libcerror_error_set(
540
     error,
541
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
542
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
543
     "%s: invalid codepage.",
544
     function );
545
546
    return( -1 );
547
  }
548
  if( string == NULL )
549
  {
550
    libcerror_error_set(
551
     error,
552
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
553
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
554
     "%s: invalid string.",
555
     function );
556
557
    return( -1 );
558
  }
559
  if( string_length > (size_t) SSIZE_MAX )
560
  {
561
    libcerror_error_set(
562
     error,
563
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
564
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
565
     "%s: invalid string length value exceeds maximum.",
566
     function );
567
568
    return( -1 );
569
  }
570
  supported_flags = LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859
571
                  | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8
572
                  | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS;
573
574
  if( ( feature_flags & ~( supported_flags ) ) != 0 )
575
  {
576
    libcerror_error_set(
577
     error,
578
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
579
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
580
     "%s: unsupported feature flags value: 0x%08" PRIx32 ".",
581
     function,
582
     feature_flags );
583
584
    return( -1 );
585
  }
586
  *codepage = -1;
587
588
  if( string_length == 5 )
589
  {
590
    if( wide_string_compare_no_case(
591
         string,
592
         L"ascii",
593
         5 ) == 0 )
594
    {
595
      *codepage = LIBCLOCALE_CODEPAGE_ASCII;
596
597
      string_index = 5;
598
    }
599
  }
600
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859 ) != 0 )
601
  {
602
    /* Supported string formats:
603
     * iso8859-1, iso8859_1, iso-8859-1, iso-8859_1, iso_8859-1, iso_8859_1
604
     */
605
    if( string_length >= 8 )
606
    {
607
      if( wide_string_compare_no_case(
608
           string,
609
           L"iso",
610
           3 ) == 0 )
611
      {
612
        string_index = 3;
613
614
        if( ( string[ string_index ] == (wchar_t) '-' )
615
         || ( string[ string_index ] == (wchar_t) '_' ) )
616
        {
617
          string_index++;
618
        }
619
        if( ( string[ string_index     ] == (wchar_t) '8' )
620
         && ( string[ string_index + 1 ] == (wchar_t) '8' )
621
         && ( string[ string_index + 2 ] == (wchar_t) '5' )
622
         && ( string[ string_index + 3 ] == (wchar_t) '9' ) )
623
        {
624
          string_index += 4;
625
626
          if( string_index < string_length )
627
          {
628
            if( ( string[ string_index ] == (wchar_t) '-' )
629
             || ( string[ string_index ] == (wchar_t) '_' ) )
630
            {
631
              string_index++;
632
633
              codepage_set = LIBCLOCALE_CODEPAGE_SET_ISO_8859;
634
            }
635
          }
636
        }
637
      }
638
    }
639
  }
640
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8 ) != 0 )
641
  {
642
    /* Supported string formats:
643
     * koi8, koi8-r, koi8_r
644
     */
645
    if( string_length >= 4 )
646
    {
647
      if( wide_string_compare_no_case(
648
           string,
649
           L"koi8",
650
           4 ) == 0 )
651
      {
652
        string_index = 4;
653
654
        codepage_set = LIBCLOCALE_CODEPAGE_SET_KOI8;
655
656
        if( string_index < string_length )
657
        {
658
          if( ( string[ string_index ] == (wchar_t) '-' )
659
           || ( string[ string_index ] == (wchar_t) '_' ) )
660
          {
661
            string_index++;
662
          }
663
        }
664
      }
665
    }
666
  }
667
  if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS ) != 0 )
668
  {
669
    /* Supported string formats:
670
     * cp1252, ms1252, windows1252, windows-1252, windows_1252
671
     */
672
    if( string_length >= 7 )
673
    {
674
      if( wide_string_compare_no_case(
675
           string,
676
           L"windows",
677
           7 ) == 0 )
678
      {
679
        string_index = 7;
680
681
        codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
682
683
        if( string_index < string_length )
684
        {
685
          if( ( string[ string_index ] == (wchar_t) '-' )
686
           || ( string[ string_index ] == (wchar_t) '_' ) )
687
          {
688
            string_index++;
689
          }
690
        }
691
      }
692
    }
693
    else if( string_length >= 2 )
694
    {
695
      if( wide_string_compare_no_case(
696
           string,
697
           L"cp",
698
           2 ) == 0 )
699
      {
700
        string_index = 2;
701
702
        codepage_set = LIBCLOCALE_CODEPAGE_SET_GENERIC;
703
      }
704
      else if( wide_string_compare_no_case(
705
                string,
706
                L"ms",
707
                2 ) == 0 )
708
      {
709
        string_index = 2;
710
711
        codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
712
      }
713
    }
714
  }
715
  if( codepage_set == LIBCLOCALE_CODEPAGE_SET_ISO_8859 )
716
  {
717
    if( ( string_index + 1 ) == string_length )
718
    {
719
      switch( string[ string_index ] )
720
      {
721
        case '1':
722
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_1;
723
          break;
724
725
        case '2':
726
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_2;
727
          break;
728
729
        case '3':
730
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_3;
731
          break;
732
733
        case '4':
734
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_4;
735
          break;
736
737
        case '5':
738
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_5;
739
          break;
740
741
        case '6':
742
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_6;
743
          break;
744
745
        case '7':
746
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_7;
747
          break;
748
749
        case '8':
750
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_8;
751
          break;
752
753
        case '9':
754
          *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_9;
755
          break;
756
757
        default:
758
          break;
759
      }
760
    }
761
    else if( ( string_index + 2 ) == string_length )
762
    {
763
      if( string[ string_index ] == (wchar_t) '1' )
764
      {
765
        string_index++;
766
767
        switch( string[ string_index ] )
768
        {
769
          case '0':
770
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_10;
771
            break;
772
773
          case '1':
774
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_11;
775
            break;
776
777
          case '3':
778
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_13;
779
            break;
780
781
          case '4':
782
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_14;
783
            break;
784
785
          case '5':
786
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_15;
787
            break;
788
789
          case '6':
790
            *codepage = LIBCLOCALE_CODEPAGE_ISO_8859_16;
791
            break;
792
793
          default:
794
            break;
795
        }
796
      }
797
    }
798
  }
799
  if( codepage_set == LIBCLOCALE_CODEPAGE_SET_KOI8 )
800
  {
801
    if( ( string_index + 1 ) == string_length )
802
    {
803
      switch( string[ string_index ] )
804
      {
805
        case 'r':
806
        case 'R':
807
          *codepage = LIBCLOCALE_CODEPAGE_KOI8_R;
808
          break;
809
810
        case 'u':
811
        case 'U':
812
          *codepage = LIBCLOCALE_CODEPAGE_KOI8_U;
813
          break;
814
815
        default:
816
          break;
817
      }
818
    }
819
  }
820
  if( ( codepage_set == LIBCLOCALE_CODEPAGE_SET_GENERIC )
821
   || ( codepage_set == LIBCLOCALE_CODEPAGE_SET_WINDOWS ) )
822
  {
823
    if( ( string_index + 3 ) == string_length )
824
    {
825
      switch( string[ string_index ] )
826
      {
827
        case '8':
828
          if( ( string[ string_index + 1 ] == (wchar_t) '7' )
829
           && ( string[ string_index + 2 ] == (wchar_t) '4' ) )
830
          {
831
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_874;
832
          }
833
          break;
834
835
        case '9':
836
          if( ( string[ string_index + 1 ] == (wchar_t) '3' )
837
           && ( string[ string_index + 2 ] == (wchar_t) '2' ) )
838
          {
839
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_932;
840
          }
841
          else if( ( string[ string_index + 1 ] == (wchar_t) '3' )
842
                && ( string[ string_index + 2 ] == (wchar_t) '6' ) )
843
          {
844
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_936;
845
          }
846
          else if( ( string[ string_index + 1 ] == (wchar_t) '4' )
847
                && ( string[ string_index + 2 ] == (wchar_t) '9' ) )
848
          {
849
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_949;
850
          }
851
          else if( ( string[ string_index + 1 ] == (wchar_t) '5' )
852
                && ( string[ string_index + 2 ] == (wchar_t) '0' ) )
853
          {
854
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_950;
855
          }
856
          break;
857
858
        default:
859
          break;
860
      }
861
    }
862
    else if( ( string_index + 4 ) == string_length )
863
    {
864
      if( ( string[ string_index     ] == (wchar_t) '1' )
865
       && ( string[ string_index + 1 ] == (wchar_t) '2' )
866
       && ( string[ string_index + 2 ] == (wchar_t) '5' ) )
867
      {
868
        switch( string[ string_index + 3 ] )
869
        {
870
          case '0':
871
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1250;
872
            break;
873
874
          case '1':
875
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1251;
876
            break;
877
878
          case '2':
879
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1252;
880
            break;
881
882
          case '3':
883
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1253;
884
            break;
885
886
          case '4':
887
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1254;
888
            break;
889
890
          case '5':
891
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1255;
892
            break;
893
894
          case '6':
895
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1256;
896
            break;
897
898
          case '7':
899
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1257;
900
            break;
901
902
          case '8':
903
            *codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1258;
904
            break;
905
906
          default:
907
            break;
908
        }
909
      }
910
    }
911
  }
912
  if( *codepage != -1 )
913
  {
914
    return( 1 );
915
  }
916
  return( 0 );
917
}
918
919
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
920