?login_element?

Subversion Repositories NedoOS

Rev

Rev 104 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*------------------------------------------------------------------------*/
  2. /* Unicode handling functions for FatFs R0.13c                            */
  3. /*------------------------------------------------------------------------*/
  4. /* This module will occupy a huge memory in the .const section when the    /
  5. /  FatFs is configured for LFN with DBCS. If the system has any Unicode    /
  6. /  utilitiy for the code conversion, this module should be modified to use /
  7. /  that function to avoid silly memory consumption.                        /
  8. /-------------------------------------------------------------------------*/
  9. /*
  10. / Copyright (C) 2018, ChaN, all right reserved.
  11. /
  12. / FatFs module is an open source software. Redistribution and use of FatFs in
  13. / source and binary forms, with or without modification, are permitted provided
  14. / that the following condition is met:
  15. /
  16. / 1. Redistributions of source code must retain the above copyright notice,
  17. /    this condition and the following disclaimer.
  18. /
  19. / This software is provided by the copyright holder and contributors "AS IS"
  20. / and any warranties related to this software are DISCLAIMED.
  21. / The copyright owner or contributors be NOT LIABLE for any damages caused
  22. / by use of this software.
  23. */
  24.  
  25.  
  26. #include "ff.h"
  27.  
  28. #if FF_USE_LFN  /* This module will be blanked at non-LFN configuration */
  29.  
  30. #if FF_DEFINED != 86604 /* Revision ID */
  31. #error Wrong include file (ff.h).
  32. #endif
  33.  
  34. #define MERGE2(a, b) a ## b
  35. #define CVTBL(tbl, cp) MERGE2(tbl, cp)
  36.  
  37.  
  38. /*------------------------------------------------------------------------*/
  39. /* Code Conversion Tables                                                 */
  40. /*------------------------------------------------------------------------*/
  41.  
  42. #if FF_CODE_PAGE == 932 || FF_CODE_PAGE == 0    /* Japanese */
  43. static const WCHAR uni2oem932[] = {     /* Unicode --> Shift_JIS pairs *//* Shift_JIS --> Unicode pairs */#endif
  44.  
  45. #if FF_CODE_PAGE == 936 || FF_CODE_PAGE == 0    /* Simplified Chinese */
  46. static const WCHAR uni2oem936[] = {     /* Unicode --> GBK pairs *//* GBK --> Unicode pairs */#endif
  47.  
  48. #if FF_CODE_PAGE == 949 || FF_CODE_PAGE == 0    /* Korean */
  49. static const WCHAR uni2oem949[] = {     /* Unicode --> Korean pairs *//* Korean --> Unicode pairs */#endif
  50.  
  51. #if FF_CODE_PAGE == 950 || FF_CODE_PAGE == 0    /* Traditional Chinese */
  52. static const WCHAR uni2oem950[] = {     /* Unicode --> Big5 pairs *//* Big5 --> Unicode pairs */#endif
  53.  
  54. #if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0
  55. static const WCHAR uc437[] = {  /*  CP437(U.S.) to Unicode conversion table */
  56.         0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
  57.         0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
  58.         0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
  59.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
  60.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  61.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  62.         0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
  63.         0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
  64. };
  65. #endif
  66. #if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0
  67. static const WCHAR uc720[] = {  /*  CP720(Arabic) to Unicode conversion table */
  68.         0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
  69.         0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
  70.         0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
  71.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
  72.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  73.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  74.         0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
  75.         0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
  76. };
  77. #endif
  78. #if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0
  79. static const WCHAR uc737[] = {  /*  CP737(Greek) to Unicode conversion table */
  80.         0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
  81.         0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
  82.         0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
  83.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
  84.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  85.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  86.         0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
  87.         0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
  88. };
  89. #endif
  90. #if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0
  91. static const WCHAR uc771[] = {  /*  CP771(KBL) to Unicode conversion table */
  92.         0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
  93.         0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
  94.         0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
  95.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
  96.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  97.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
  98.         0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
  99.         0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
  100. };
  101. #endif
  102. #if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0
  103. static const WCHAR uc775[] = {  /*  CP775(Baltic) to Unicode conversion table */
  104.         0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
  105.         0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
  106.         0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
  107.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
  108.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
  109.         0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  110.         0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
  111.         0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
  112. };
  113. #endif
  114. #if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0
  115. static const WCHAR uc850[] = {  /*  CP850(Latin 1) to Unicode conversion table */
  116.         0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
  117.         0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
  118.         0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
  119.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
  120.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
  121.         0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
  122.         0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
  123.         0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
  124. };
  125. #endif
  126. #if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0
  127. static const WCHAR uc852[] = {  /*  CP852(Latin 2) to Unicode conversion table */
  128.         0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
  129.         0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
  130.         0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
  131.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
  132.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
  133.         0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
  134.         0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
  135.         0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
  136. };
  137. #endif
  138. #if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0
  139. static const WCHAR uc855[] = {  /*  CP855(Cyrillic) to Unicode conversion table */
  140.         0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
  141.         0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
  142.         0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
  143.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
  144.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
  145.         0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
  146.         0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
  147.         0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
  148. };
  149. #endif
  150. #if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0
  151. static const WCHAR uc857[] = {  /*  CP857(Turkish) to Unicode conversion table */
  152.         0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
  153.         0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
  154.         0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
  155.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
  156.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
  157.         0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
  158.         0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
  159.         0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
  160. };
  161. #endif
  162. #if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0
  163. static const WCHAR uc860[] = {  /*  CP860(Portuguese) to Unicode conversion table */
  164.         0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
  165.         0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
  166.         0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
  167.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
  168.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  169.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  170.         0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
  171.         0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
  172. };
  173. #endif
  174. #if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0
  175. static const WCHAR uc861[] = {  /*  CP861(Icelandic) to Unicode conversion table */
  176.         0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
  177.         0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
  178.         0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
  179.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
  180.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  181.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  182.         0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
  183.         0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
  184. };
  185. #endif
  186. #if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0
  187. static const WCHAR uc862[] = {  /*  CP862(Hebrew) to Unicode conversion table */
  188.         0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
  189.         0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
  190.         0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
  191.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
  192.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  193.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  194.         0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
  195.         0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
  196. };
  197. #endif
  198. #if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0
  199. static const WCHAR uc863[] = {  /*  CP863(Canadian French) to Unicode conversion table */
  200.         0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
  201.         0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
  202.         0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
  203.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
  204.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  205.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  206.         0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
  207.         0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
  208. };
  209. #endif
  210. #if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0
  211. static const WCHAR uc864[] = {  /*  CP864(Arabic) to Unicode conversion table */
  212.         0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
  213.         0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
  214.         0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
  215.         0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
  216.         0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
  217.         0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
  218.         0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
  219.         0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
  220. };
  221. #endif
  222. #if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0
  223. static const WCHAR uc865[] = {  /*  CP865(Nordic) to Unicode conversion table */
  224.         0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
  225.         0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
  226.         0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
  227.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
  228.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  229.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  230.         0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
  231.         0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
  232. };
  233. #endif
  234. #if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0
  235. static const WCHAR uc866[] = {  /*  CP866(Russian) to Unicode conversion table */
  236.         0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
  237.         0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
  238.         0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
  239.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
  240.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
  241.         0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
  242.         0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
  243.         0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
  244. };
  245. #endif
  246. #if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0
  247. static const WCHAR uc869[] = {  /*  CP869(Greek 2) to Unicode conversion table */
  248.         0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
  249.         0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
  250.         0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
  251.         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
  252.         0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
  253.         0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
  254.         0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
  255.         0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
  256. };
  257. #endif
  258.  
  259.  
  260.  
  261.  
  262. /*------------------------------------------------------------------------*/
  263. /* OEM <==> Unicode conversions for static code page configuration        */
  264. /* SBCS fixed code page                                                   */
  265. /*------------------------------------------------------------------------*/
  266.  
  267. #if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
  268. WCHAR ff_uni2oem (      /* Returns OEM code character, zero on error */
  269.         DWORD   uni,    /* UTF-16 encoded character to be converted */
  270.         WORD    cp              /* Code page for the conversion */
  271. )
  272. {
  273.         WCHAR c = 0;
  274.         const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
  275.  
  276.  
  277.         if (uni < 0x80) {       /* ASCII? */
  278.                 c = (WCHAR)uni;
  279.  
  280.         } else {                        /* Non-ASCII */
  281.                 if (uni < 0x10000 && cp == FF_CODE_PAGE) {      /* Is it in BMP and valid code page? */
  282.                         for (c = 0; c < 0x80 && uni != p[c]; c++) ;
  283.                         c = (c + 0x80) & 0xFF;
  284.                 }
  285.         }
  286.  
  287.         return c;
  288. }
  289.  
  290. WCHAR ff_oem2uni (      /* Returns Unicode character, zero on error */
  291.         WCHAR   oem,    /* OEM code to be converted */
  292.         WORD    cp              /* Code page for the conversion */
  293. )
  294. {
  295.         WCHAR c = 0;
  296.         const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
  297.  
  298.  
  299.         if (oem < 0x80) {       /* ASCII? */
  300.                 c = oem;
  301.  
  302.         } else {                        /* Extended char */
  303.                 if (cp == FF_CODE_PAGE) {       /* Is it a valid code page? */
  304.                         if (oem < 0x100) c = p[oem - 0x80];
  305.                 }
  306.         }
  307.  
  308.         return c;
  309. }
  310.  
  311. #endif
  312.  
  313.  
  314.  
  315. /*------------------------------------------------------------------------*/
  316. /* OEM <==> Unicode conversions for static code page configuration        */
  317. /* DBCS fixed code page                                                   */
  318. /*------------------------------------------------------------------------*/
  319.  
  320. #if FF_CODE_PAGE >= 900
  321. WCHAR ff_uni2oem (      /* Returns OEM code character, zero on error */
  322.         DWORD   uni,    /* UTF-16 encoded character to be converted */
  323.         WORD    cp              /* Code page for the conversion */
  324. )
  325. {
  326.         const WCHAR *p;
  327.         WCHAR c = 0, uc;
  328.         UINT i = 0, n, li, hi;
  329.  
  330.  
  331.         if (uni < 0x80) {       /* ASCII? */
  332.                 c = (WCHAR)uni;
  333.  
  334.         } else {                        /* Non-ASCII */
  335.                 if (uni < 0x10000 && cp == FF_CODE_PAGE) {      /* Is it in BMP and valid code page? */
  336.                         uc = (WCHAR)uni;
  337.                         p = CVTBL(uni2oem, FF_CODE_PAGE);
  338.                         hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
  339.                         li = 0;
  340.                         for (n = 16; n; n--) {
  341.                                 i = li + (hi - li) / 2;
  342.                                 if (uc == p[i * 2]) break;
  343.                                 if (uc > p[i * 2]) {
  344.                                         li = i;
  345.                                 } else {
  346.                                         hi = i;
  347.                                 }
  348.                         }
  349.                         if (n != 0) c = p[i * 2 + 1];
  350.                 }
  351.         }
  352.  
  353.         return c;
  354. }
  355.  
  356.  
  357. WCHAR ff_oem2uni (      /* Returns Unicode character, zero on error */
  358.         WCHAR   oem,    /* OEM code to be converted */
  359.         WORD    cp              /* Code page for the conversion */
  360. )
  361. {
  362.         const WCHAR *p;
  363.         WCHAR c = 0;
  364.         UINT i = 0, n, li, hi;
  365.  
  366.  
  367.         if (oem < 0x80) {       /* ASCII? */
  368.                 c = oem;
  369.  
  370.         } else {                        /* Extended char */
  371.                 if (cp == FF_CODE_PAGE) {       /* Is it valid code page? */
  372.                         p = CVTBL(oem2uni, FF_CODE_PAGE);
  373.                         hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;
  374.                         li = 0;
  375.                         for (n = 16; n; n--) {
  376.                                 i = li + (hi - li) / 2;
  377.                                 if (oem == p[i * 2]) break;
  378.                                 if (oem > p[i * 2]) {
  379.                                         li = i;
  380.                                 } else {
  381.                                         hi = i;
  382.                                 }
  383.                         }
  384.                         if (n != 0) c = p[i * 2 + 1];
  385.                 }
  386.         }
  387.  
  388.         return c;
  389. }
  390. #endif
  391.  
  392.  
  393.  
  394. /*------------------------------------------------------------------------*/
  395. /* OEM <==> Unicode conversions for dynamic code page configuration       */
  396. /*------------------------------------------------------------------------*/
  397.  
  398. #if FF_CODE_PAGE == 0
  399.  
  400. static const WORD cp_code[]          = {  437,   720,   737,   771,   775,   850,   852,   855,   857,   860,   861,   862,   863,   864,   865,   866,   869, 0};
  401. static const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};
  402.  
  403.  
  404. WCHAR ff_uni2oem (      /* Returns OEM code character, zero on error */
  405.         DWORD   uni,    /* UTF-16 encoded character to be converted */
  406.         WORD    cp              /* Code page for the conversion */
  407. )
  408. {
  409.         const WCHAR *p;
  410.         WCHAR c = 0, uc;
  411.         UINT i, n, li, hi;
  412.  
  413.  
  414.         if (uni < 0x80) {       /* ASCII? */
  415.                 c = (WCHAR)uni;
  416.  
  417.         } else {                        /* Non-ASCII */
  418.                 if (uni < 0x10000) { /* Is it in BMP? */
  419.                         uc = (WCHAR)uni;
  420.                         p = 0;
  421.                         if (cp < 900) { /* SBCS */
  422.                                 for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ;         /* Get conversion table */
  423.                                 p = cp_table[i];
  424.                                 if (p) {        /* Is it valid code page ? */
  425.                                         for (c = 0; c < 0x80 && uc != p[c]; c++) ;      /* Find OEM code in the table */
  426.                                         c = (c + 0x80) & 0xFF;
  427.                                 }
  428.                         } else {        /* DBCS */
  429.                                 switch (cp) {   /* Get conversion table */
  430.                                 case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;
  431.                                 case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;
  432.                                 case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;
  433.                                 case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;
  434.                                 }
  435.                                 if (p) {        /* Is it valid code page? */
  436.                                         li = 0;
  437.                                         for (n = 16; n; n--) {  /* Find OEM code */
  438.                                                 i = li + (hi - li) / 2;
  439.                                                 if (uc == p[i * 2]) break;
  440.                                                 if (uc > p[i * 2]) {
  441.                                                         li = i;
  442.                                                 } else {
  443.                                                         hi = i;
  444.                                                 }
  445.                                         }
  446.                                         if (n != 0) c = p[i * 2 + 1];
  447.                                 }
  448.                         }
  449.                 }
  450.         }
  451.  
  452.         return c;
  453. }
  454.  
  455.  
  456. WCHAR ff_oem2uni (      /* Returns Unicode character, zero on error */
  457.         WCHAR   oem,    /* OEM code to be converted (DBC if >=0x100) */
  458.         WORD    cp              /* Code page for the conversion */
  459. )
  460. {
  461.         const WCHAR *p;
  462.         WCHAR c = 0;
  463.         UINT i, n, li, hi;
  464.  
  465.  
  466.         if (oem < 0x80) {       /* ASCII? */
  467.                 c = oem;
  468.  
  469.         } else {                        /* Extended char */
  470.                 p = 0;
  471.                 if (cp < 900) { /* SBCS */
  472.                         for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ;         /* Get table */
  473.                         p = cp_table[i];
  474.                         if (p) {        /* Is it a valid CP ? */
  475.                                 if (oem < 0x100) c = p[oem - 0x80];
  476.                         }
  477.                 } else {        /* DBCS */
  478.                         switch (cp) {
  479.                         case 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break;
  480.                         case 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break;
  481.                         case 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break;
  482.                         case 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break;
  483.                         }
  484.                         if (p) {
  485.                                 li = 0;
  486.                                 for (n = 16; n; n--) {
  487.                                         i = li + (hi - li) / 2;
  488.                                         if (oem == p[i * 2]) break;
  489.                                         if (oem > p[i * 2]) {
  490.                                                 li = i;
  491.                                         } else {
  492.                                                 hi = i;
  493.                                         }
  494.                                 }
  495.                                 if (n != 0) c = p[i * 2 + 1];
  496.                         }
  497.                 }
  498.         }
  499.  
  500.         return c;
  501. }
  502. #endif
  503.  
  504.  
  505.  
  506. /*------------------------------------------------------------------------*/
  507. /* Unicode up-case conversion                                             */
  508. /*------------------------------------------------------------------------*/
  509.  
  510. DWORD ff_wtoupper (     /* Returns up-converted code point */
  511.         DWORD uni               /* Unicode code point to be up-converted */
  512. )
  513. {
  514.         const WORD *p;
  515.         WORD uc, bc, nc, cmd;
  516.         static const WORD cvt1[] = {    /* Compressed up conversion table for U+0000 - U+0FFF */
  517.                 /* Basic Latin */
  518.                 0x0061,0x031A,
  519.                 /* Latin-1 Supplement */
  520.                 0x00E0,0x0317,
  521.                 0x00F8,0x0307,
  522.                 0x00FF,0x0001,0x0178,
  523.                 /* Latin Extended-A */
  524.                 0x0100,0x0130,
  525.                 0x0132,0x0106,
  526.                 0x0139,0x0110,
  527.                 0x014A,0x012E,
  528.                 0x0179,0x0106,
  529.                 /* Latin Extended-B */
  530.                 0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
  531.                 0x01CD,0x0110,
  532.                 0x01DD,0x0001,0x018E,
  533.                 0x01DE,0x0112,
  534.                 0x01F3,0x0003,0x01F1,0x01F4,0x01F4,
  535.                 0x01F8,0x0128,
  536.                 0x0222,0x0112,
  537.                 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241,
  538.                 0x0246,0x010A,
  539.                 /* IPA Extensions */
  540.                 0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
  541.                 /* Greek, Coptic */
  542.                 0x037B,0x0003,0x03FD,0x03FE,0x03FF,
  543.                 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A,
  544.                 0x03B1,0x0311,
  545.                 0x03C2,0x0002,0x03A3,0x03A3,
  546.                 0x03C4,0x0308,
  547.                 0x03CC,0x0003,0x038C,0x038E,0x038F,
  548.                 0x03D8,0x0118,
  549.                 0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
  550.                 /* Cyrillic */
  551.                 0x0430,0x0320,
  552.                 0x0450,0x0710,
  553.                 0x0460,0x0122,
  554.                 0x048A,0x0136,
  555.                 0x04C1,0x010E,
  556.                 0x04CF,0x0001,0x04C0,
  557.                 0x04D0,0x0144,
  558.                 /* Armenian */
  559.                 0x0561,0x0426,
  560.  
  561.                 0x0000  /* EOT */
  562.         };
  563.         static const WORD cvt2[] = {    /* Compressed up conversion table for U+1000 - U+FFFF */
  564.                 /* Phonetic Extensions */
  565.                 0x1D7D,0x0001,0x2C63,
  566.                 /* Latin Extended Additional */
  567.                 0x1E00,0x0196,
  568.                 0x1EA0,0x015A,
  569.                 /* Greek Extended */
  570.                 0x1F00,0x0608,
  571.                 0x1F10,0x0606,
  572.                 0x1F20,0x0608,
  573.                 0x1F30,0x0608,
  574.                 0x1F40,0x0606,
  575.                 0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F,
  576.                 0x1F60,0x0608,
  577.                 0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
  578.                 0x1F80,0x0608,
  579.                 0x1F90,0x0608,
  580.                 0x1FA0,0x0608,
  581.                 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
  582.                 0x1FCC,0x0001,0x1FC3,
  583.                 0x1FD0,0x0602,
  584.                 0x1FE0,0x0602,
  585.                 0x1FE5,0x0001,0x1FEC,
  586.                 0x1FF3,0x0001,0x1FFC,
  587.                 /* Letterlike Symbols */
  588.                 0x214E,0x0001,0x2132,
  589.                 /* Number forms */
  590.                 0x2170,0x0210,
  591.                 0x2184,0x0001,0x2183,
  592.                 /* Enclosed Alphanumerics */
  593.                 0x24D0,0x051A,
  594.                 0x2C30,0x042F,
  595.                 /* Latin Extended-C */
  596.                 0x2C60,0x0102,
  597.                 0x2C67,0x0106, 0x2C75,0x0102,
  598.                 /* Coptic */
  599.                 0x2C80,0x0164,
  600.                 /* Georgian Supplement */
  601.                 0x2D00,0x0826,
  602.                 /* Full-width */
  603.                 0xFF41,0x031A,
  604.  
  605.                 0x0000  /* EOT */
  606.         };
  607.  
  608.  
  609.         if (uni < 0x10000) {    /* Is it in BMP? */
  610.                 uc = (WORD)uni;
  611.                 p = uc < 0x1000 ? cvt1 : cvt2;
  612.                 for (;;) {
  613.                         bc = *p++;                                                              /* Get the block base */
  614.                         if (bc == 0 || uc < bc) break;                  /* Not matched? */
  615.                         nc = *p++; cmd = nc >> 8; nc &= 0xFF;   /* Get processing command and block size */
  616.                         if (uc < bc + nc) {     /* In the block? */
  617.                                 switch (cmd) {
  618.                                 case 0: uc = p[uc - bc]; break;         /* Table conversion */
  619.                                 case 1: uc -= (uc - bc) & 1; break;     /* Case pairs */
  620.                                 case 2: uc -= 16; break;                        /* Shift -16 */
  621.                                 case 3: uc -= 32; break;                        /* Shift -32 */
  622.                                 case 4: uc -= 48; break;                        /* Shift -48 */
  623.                                 case 5: uc -= 26; break;                        /* Shift -26 */
  624.                                 case 6: uc += 8; break;                         /* Shift +8 */
  625.                                 case 7: uc -= 80; break;                        /* Shift -80 */
  626.                                 case 8: uc -= 0x1C60; break;            /* Shift -0x1C60 */
  627.                                 }
  628.                                 break;
  629.                         }
  630.                         if (cmd == 0) p += nc;  /* Skip table if needed */
  631.                 }
  632.                 uni = uc;
  633.         }
  634.  
  635.         return uni;
  636. }
  637.  
  638.  
  639. #endif /* #if FF_USE_LFN */
  640.