1 /*
2  * Codepage functions
3  *
4  * Copyright (C) 2010-2021, 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  */
libclocale_codepage_get(int * codepage,libcerror_error_t ** error)44 int libclocale_codepage_get(
45      int *codepage,
46      libcerror_error_t **error )
47 {
48 	static char *function = "libclocale_codepage_get";
49 
50 	if( codepage == NULL )
51 	{
52 		libcerror_error_set(
53 		 error,
54 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56 		 "%s: invalid codepage.",
57 		 function );
58 
59 		return( -1 );
60 	}
61 	*codepage = libclocale_codepage;
62 
63 	return( 1 );
64 }
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  */
libclocale_codepage_set(int codepage,libcerror_error_t ** error)70 int libclocale_codepage_set(
71      int codepage,
72      libcerror_error_t **error )
73 {
74 	static char *function = "libclocale_codepage_set";
75 
76 	if( ( codepage != LIBCLOCALE_CODEPAGE_ASCII )
77 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_1 )
78 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_2 )
79 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_3 )
80 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_4 )
81 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_5 )
82 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_6 )
83 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_7 )
84 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_8 )
85 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_9 )
86 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_10 )
87 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_11 )
88 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_13 )
89 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_14 )
90 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_15 )
91 	 && ( codepage != LIBCLOCALE_CODEPAGE_ISO_8859_16 )
92 	 && ( codepage != LIBCLOCALE_CODEPAGE_KOI8_R )
93 	 && ( codepage != LIBCLOCALE_CODEPAGE_KOI8_U )
94 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_874 )
95 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_932 )
96 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_936 )
97 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_949 )
98 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_950 )
99 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1250 )
100 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1251 )
101 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1252 )
102 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1253 )
103 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1254 )
104 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1256 )
105 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1257 )
106 	 && ( codepage != LIBCLOCALE_CODEPAGE_WINDOWS_1258 )
107 	 && ( codepage != 0 ) )
108 	{
109 		libcerror_error_set(
110 		 error,
111 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
112 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
113 		 "%s: unsupported codepage.",
114 		 function );
115 
116 		return( -1 );
117 	}
118 	libclocale_codepage = codepage;
119 
120 	return( 1 );
121 }
122 
123 /* Copies the codepage from a string
124  * Returns 1 if successful, 0 if unsupported value or -1 on error
125  */
libclocale_codepage_copy_from_string(int * codepage,const char * string,size_t string_length,uint32_t feature_flags,libcerror_error_t ** error)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 {
133 	static char *function    = "libclocale_codepage_copy_from_string";
134 	size_t string_index      = 0;
135 	uint32_t supported_flags = 0;
136 	int codepage_set         = 0;
137 
138 	if( codepage == NULL )
139 	{
140 		libcerror_error_set(
141 		 error,
142 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
143 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
144 		 "%s: invalid codepage.",
145 		 function );
146 
147 		return( -1 );
148 	}
149 	if( string == NULL )
150 	{
151 		libcerror_error_set(
152 		 error,
153 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
154 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
155 		 "%s: invalid string.",
156 		 function );
157 
158 		return( -1 );
159 	}
160 	if( string_length > (size_t) SSIZE_MAX )
161 	{
162 		libcerror_error_set(
163 		 error,
164 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
165 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
166 		 "%s: invalid string length value exceeds maximum.",
167 		 function );
168 
169 		return( -1 );
170 	}
171 	supported_flags = LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859
172 	                | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8
173 	                | LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS;
174 
175 	if( ( feature_flags & ~( supported_flags ) ) != 0 )
176 	{
177 		libcerror_error_set(
178 		 error,
179 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
180 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
181 		 "%s: unsupported feature flags value: 0x%08" PRIx32 ".",
182 		 function,
183 		 feature_flags );
184 
185 		return( -1 );
186 	}
187 	*codepage = -1;
188 
189 	if( string_length == 5 )
190 	{
191 		if( narrow_string_compare_no_case(
192 		     string,
193 		     "ascii",
194 		     5 ) == 0 )
195 		{
196 			*codepage = LIBCLOCALE_CODEPAGE_ASCII;
197 
198 			string_index = 5;
199 		}
200 	}
201 	if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_ISO_8859 ) != 0 )
202 	{
203 		/* Supported string formats:
204 		 * iso8859-1, iso8859_1, iso-8859-1, iso-8859_1, iso_8859-1, iso_8859_1
205 		 */
206 		if( string_length >= 8 )
207 		{
208 			if( narrow_string_compare_no_case(
209 			     string,
210 			     "iso",
211 			     3 ) == 0 )
212 			{
213 				string_index = 3;
214 
215 				if( ( string[ string_index ] == '-' )
216 				 || ( string[ string_index ] == '_' ) )
217 				{
218 					string_index++;
219 				}
220 				if( ( string[ string_index     ] == '8' )
221 				 && ( string[ string_index + 1 ] == '8' )
222 				 && ( string[ string_index + 2 ] == '5' )
223 				 && ( string[ string_index + 3 ] == '9' ) )
224 				{
225 					string_index += 4;
226 
227 					if( string_index < string_length )
228 					{
229 						if( ( string[ string_index ] == '-' )
230 						 || ( string[ string_index ] == '_' ) )
231 						{
232 							string_index++;
233 
234 							codepage_set = LIBCLOCALE_CODEPAGE_SET_ISO_8859;
235 						}
236 					}
237 				}
238 			}
239 		}
240 	}
241 	if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_KOI8 ) != 0 )
242 	{
243 		/* Supported string formats:
244 		 * koi8, koi8-r, koi8_r
245 		 */
246 		if( string_length >= 4 )
247 		{
248 			if( narrow_string_compare_no_case(
249 			     string,
250 			     "koi8",
251 			     4 ) == 0 )
252 			{
253 				string_index = 4;
254 
255 				codepage_set = LIBCLOCALE_CODEPAGE_SET_KOI8;
256 
257 				if( string_index < string_length )
258 				{
259 					if( ( string[ string_index ] == '-' )
260 					 || ( string[ string_index ] == '_' ) )
261 					{
262 						string_index++;
263 					}
264 				}
265 			}
266 		}
267 	}
268 	if( ( feature_flags & LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS ) != 0 )
269 	{
270 		/* Supported string formats:
271 		 * cp1252, ms1252, windows1252, windows-1252, windows_1252
272 		 */
273 		if( string_length >= 7 )
274 		{
275 			if( narrow_string_compare_no_case(
276 			     string,
277 			     "windows",
278 			     7 ) == 0 )
279 			{
280 				string_index = 7;
281 
282 				codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
283 
284 				if( string_index < string_length )
285 				{
286 					if( ( string[ string_index ] == '-' )
287 					 || ( string[ string_index ] == '_' ) )
288 					{
289 						string_index++;
290 					}
291 				}
292 			}
293 		}
294 		else if( string_length >= 2 )
295 		{
296 			if( narrow_string_compare_no_case(
297 			     string,
298 			     "cp",
299 			     2 ) == 0 )
300 			{
301 				string_index = 2;
302 
303 				codepage_set = LIBCLOCALE_CODEPAGE_SET_GENERIC;
304 			}
305 			else if( narrow_string_compare_no_case(
306 			          string,
307 			          "ms",
308 			          2 ) == 0 )
309 			{
310 				string_index = 2;
311 
312 				codepage_set = LIBCLOCALE_CODEPAGE_SET_WINDOWS;
313 			}
314 		}
315 	}
316 	if( codepage_set == LIBCLOCALE_CODEPAGE_SET_ISO_8859 )
317 	{
318 		if( ( string_index + 1 ) == string_length )
319 		{
320 			switch( string[ string_index ] )
321 			{
322 				case '1':
323 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_1;
324 					break;
325 
326 				case '2':
327 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_2;
328 					break;
329 
330 				case '3':
331 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_3;
332 					break;
333 
334 				case '4':
335 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_4;
336 					break;
337 
338 				case '5':
339 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_5;
340 					break;
341 
342 				case '6':
343 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_6;
344 					break;
345 
346 				case '7':
347 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_7;
348 					break;
349 
350 				case '8':
351 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_8;
352 					break;
353 
354 				case '9':
355 					*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_9;
356 					break;
357 
358 				default:
359 					break;
360 			}
361 		}
362 		else if( ( string_index + 2 ) == string_length )
363 		{
364 			if( string[ string_index ] == '1' )
365 			{
366 				string_index++;
367 
368 				switch( string[ string_index ] )
369 				{
370 					case '0':
371 						*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_10;
372 						break;
373 
374 					case '1':
375 						*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_11;
376 						break;
377 
378 					case '3':
379 						*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_13;
380 						break;
381 
382 					case '4':
383 						*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_14;
384 						break;
385 
386 					case '5':
387 						*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_15;
388 						break;
389 
390 					case '6':
391 						*codepage = LIBCLOCALE_CODEPAGE_ISO_8859_16;
392 						break;
393 
394 					default:
395 						break;
396 				}
397 			}
398 		}
399 	}
400 	if( codepage_set == LIBCLOCALE_CODEPAGE_SET_KOI8 )
401 	{
402 		if( ( string_index + 1 ) == string_length )
403 		{
404 			switch( string[ string_index ] )
405 			{
406 				case 'r':
407 				case 'R':
408 					*codepage = LIBCLOCALE_CODEPAGE_KOI8_R;
409 					break;
410 
411 				case 'u':
412 				case 'U':
413 					*codepage = LIBCLOCALE_CODEPAGE_KOI8_U;
414 					break;
415 
416 				default:
417 					break;
418 			}
419 		}
420 	}
421 	if( ( codepage_set == LIBCLOCALE_CODEPAGE_SET_GENERIC )
422 	 || ( codepage_set == LIBCLOCALE_CODEPAGE_SET_WINDOWS ) )
423 	{
424 		if( ( string_index + 3 ) == string_length )
425 		{
426 			switch( string[ string_index ] )
427 			{
428 				case '8':
429 					if( ( string[ string_index + 1 ] == '7' )
430 					 && ( string[ string_index + 2 ] == '4' ) )
431 					{
432 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_874;
433 					}
434 					break;
435 
436 				case '9':
437 					if( ( string[ string_index + 1 ] == '3' )
438 					 && ( string[ string_index + 2 ] == '2' ) )
439 					{
440 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_932;
441 					}
442 					else if( ( string[ string_index + 1 ] == '3' )
443 					      && ( string[ string_index + 2 ] == '6' ) )
444 					{
445 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_936;
446 					}
447 					else if( ( string[ string_index + 1 ] == '4' )
448 					      && ( string[ string_index + 2 ] == '9' ) )
449 					{
450 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_949;
451 					}
452 					else if( ( string[ string_index + 1 ] == '5' )
453 					      && ( string[ string_index + 2 ] == '0' ) )
454 					{
455 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_950;
456 					}
457 					break;
458 
459 				default:
460 					break;
461 			}
462 		}
463 		else if( ( string_index + 4 ) == string_length )
464 		{
465 			if( ( string[ string_index     ] == '1' )
466 			 && ( string[ string_index + 1 ] == '2' )
467 			 && ( string[ string_index + 2 ] == '5' ) )
468 			{
469 				switch( string[ string_index + 3 ] )
470 				{
471 					case '0':
472 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1250;
473 						break;
474 
475 					case '1':
476 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1251;
477 						break;
478 
479 					case '2':
480 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1252;
481 						break;
482 
483 					case '3':
484 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1253;
485 						break;
486 
487 					case '4':
488 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1254;
489 						break;
490 
491 					case '5':
492 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1255;
493 						break;
494 
495 					case '6':
496 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1256;
497 						break;
498 
499 					case '7':
500 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1257;
501 						break;
502 
503 					case '8':
504 						*codepage = LIBCLOCALE_CODEPAGE_WINDOWS_1258;
505 						break;
506 
507 					default:
508 						break;
509 				}
510 			}
511 		}
512 	}
513 	if( *codepage != -1 )
514 	{
515 		return( 1 );
516 	}
517 	return( 0 );
518 }
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  */
libclocale_codepage_copy_from_string_wide(int * codepage,const wchar_t * string,size_t string_length,uint32_t feature_flags,libcerror_error_t ** error)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 
921