]>
Commit | Line | Data |
---|---|---|
f42be642 | 1 | /** @file\r |
61e33430 | 2 | Driver to implement English version of Unicode Collation Protocol.\r |
adbcbf8f | 3 | \r |
d1102dba | 4 | Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r |
9d510e61 | 5 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
adbcbf8f | 6 | \r |
f42be642 | 7 | **/\r |
adbcbf8f | 8 | \r |
adbcbf8f | 9 | #include "UnicodeCollationEng.h"\r |
10 | \r | |
1436aea4 MK |
11 | CHAR8 mEngUpperMap[MAP_TABLE_SIZE];\r |
12 | CHAR8 mEngLowerMap[MAP_TABLE_SIZE];\r | |
13 | CHAR8 mEngInfoMap[MAP_TABLE_SIZE];\r | |
adbcbf8f | 14 | \r |
1436aea4 | 15 | CHAR8 mOtherChars[] = {\r |
adbcbf8f | 16 | '0',\r |
17 | '1',\r | |
18 | '2',\r | |
19 | '3',\r | |
20 | '4',\r | |
21 | '5',\r | |
22 | '6',\r | |
23 | '7',\r | |
24 | '8',\r | |
25 | '9',\r | |
26 | '\\',\r | |
27 | '.',\r | |
28 | '_',\r | |
29 | '^',\r | |
30 | '$',\r | |
31 | '~',\r | |
32 | '!',\r | |
33 | '#',\r | |
34 | '%',\r | |
35 | '&',\r | |
36 | '-',\r | |
37 | '{',\r | |
38 | '}',\r | |
39 | '(',\r | |
40 | ')',\r | |
41 | '@',\r | |
42 | '`',\r | |
43 | '\'',\r | |
44 | '\0'\r | |
45 | };\r | |
46 | \r | |
ff61847d | 47 | EFI_HANDLE mHandle = NULL;\r |
adbcbf8f | 48 | \r |
2d9a7522 | 49 | //\r |
50 | // EFI Unicode Collation Protocol supporting ISO 639-2 language code\r | |
51 | //\r | |
52 | GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_COLLATION_PROTOCOL UnicodeEng = {\r | |
adbcbf8f | 53 | EngStriColl,\r |
54 | EngMetaiMatch,\r | |
55 | EngStrLwr,\r | |
56 | EngStrUpr,\r | |
57 | EngFatToStr,\r | |
58 | EngStrToFat,\r | |
59 | "eng"\r | |
60 | };\r | |
61 | \r | |
62 | //\r | |
0254efc0 | 63 | // EFI Unicode Collation2 Protocol supporting RFC 4646 language code\r |
adbcbf8f | 64 | //\r |
2d9a7522 | 65 | GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_COLLATION_PROTOCOL Unicode2Eng = {\r |
66 | EngStriColl,\r | |
67 | EngMetaiMatch,\r | |
68 | EngStrLwr,\r | |
69 | EngStrUpr,\r | |
70 | EngFatToStr,\r | |
71 | EngStrToFat,\r | |
72 | "en"\r | |
73 | };\r | |
74 | \r | |
61e33430 | 75 | /**\r |
76 | The user Entry Point for English module.\r | |
d1102dba | 77 | \r |
61e33430 | 78 | This function initializes unicode character mapping and then installs Unicode\r |
d1102dba | 79 | Collation & Unicode Collation 2 Protocols based on the feature flags.\r |
61e33430 | 80 | \r |
d1102dba | 81 | @param ImageHandle The firmware allocated handle for the EFI image.\r |
61e33430 | 82 | @param SystemTable A pointer to the EFI System Table.\r |
d1102dba | 83 | \r |
61e33430 | 84 | @retval EFI_SUCCESS The entry point is executed successfully.\r |
85 | @retval other Some error occurs when executing this entry point.\r | |
86 | \r | |
87 | **/\r | |
adbcbf8f | 88 | EFI_STATUS\r |
2d9a7522 | 89 | EFIAPI\r |
adbcbf8f | 90 | InitializeUnicodeCollationEng (\r |
1436aea4 MK |
91 | IN EFI_HANDLE ImageHandle,\r |
92 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
adbcbf8f | 93 | )\r |
adbcbf8f | 94 | {\r |
2d9a7522 | 95 | EFI_STATUS Status;\r |
adbcbf8f | 96 | UINTN Index;\r |
97 | UINTN Index2;\r | |
98 | \r | |
99 | //\r | |
100 | // Initialize mapping tables for the supported languages\r | |
101 | //\r | |
48557c65 | 102 | for (Index = 0; Index < MAP_TABLE_SIZE; Index++) {\r |
1436aea4 MK |
103 | mEngUpperMap[Index] = (CHAR8)Index;\r |
104 | mEngLowerMap[Index] = (CHAR8)Index;\r | |
adbcbf8f | 105 | mEngInfoMap[Index] = 0;\r |
106 | \r | |
1436aea4 MK |
107 | if (((Index >= 'a') && (Index <= 'z')) || ((Index >= 0xe0) && (Index <= 0xf6)) || ((Index >= 0xf8) && (Index <= 0xfe))) {\r |
108 | Index2 = Index - 0x20;\r | |
109 | mEngUpperMap[Index] = (CHAR8)Index2;\r | |
110 | mEngLowerMap[Index2] = (CHAR8)Index;\r | |
adbcbf8f | 111 | \r |
1436aea4 | 112 | mEngInfoMap[Index] |= CHAR_FAT_VALID;\r |
adbcbf8f | 113 | mEngInfoMap[Index2] |= CHAR_FAT_VALID;\r |
114 | }\r | |
115 | }\r | |
116 | \r | |
ea7cb08c | 117 | for (Index = 0; mOtherChars[Index] != 0; Index++) {\r |
1436aea4 | 118 | Index2 = mOtherChars[Index];\r |
adbcbf8f | 119 | mEngInfoMap[Index2] |= CHAR_FAT_VALID;\r |
120 | }\r | |
2d9a7522 | 121 | \r |
122 | if (FeaturePcdGet (PcdUnicodeCollation2Support)) {\r | |
123 | if (FeaturePcdGet (PcdUnicodeCollationSupport)) {\r | |
124 | Status = gBS->InstallMultipleProtocolInterfaces (\r | |
125 | &mHandle,\r | |
126 | &gEfiUnicodeCollationProtocolGuid,\r | |
127 | &UnicodeEng,\r | |
128 | &gEfiUnicodeCollation2ProtocolGuid,\r | |
129 | &Unicode2Eng,\r | |
130 | NULL\r | |
131 | );\r | |
132 | ASSERT_EFI_ERROR (Status);\r | |
133 | } else {\r | |
134 | Status = gBS->InstallMultipleProtocolInterfaces (\r | |
135 | &mHandle,\r | |
136 | &gEfiUnicodeCollation2ProtocolGuid,\r | |
137 | &Unicode2Eng,\r | |
138 | NULL\r | |
139 | );\r | |
140 | ASSERT_EFI_ERROR (Status);\r | |
141 | }\r | |
142 | } else {\r | |
143 | if (FeaturePcdGet (PcdUnicodeCollationSupport)) {\r | |
144 | Status = gBS->InstallMultipleProtocolInterfaces (\r | |
145 | &mHandle,\r | |
146 | &gEfiUnicodeCollationProtocolGuid,\r | |
147 | &UnicodeEng,\r | |
148 | NULL\r | |
149 | );\r | |
150 | ASSERT_EFI_ERROR (Status);\r | |
151 | } else {\r | |
152 | //\r | |
153 | // This module must support to produce at least one of Unicode Collation Protocol\r | |
154 | // and Unicode Collation 2 Protocol.\r | |
155 | //\r | |
156 | ASSERT (FALSE);\r | |
157 | Status = EFI_UNSUPPORTED;\r | |
158 | }\r | |
159 | }\r | |
160 | \r | |
161 | return Status;\r | |
adbcbf8f | 162 | }\r |
163 | \r | |
61e33430 | 164 | /**\r |
4f077902 | 165 | Performs a case-insensitive comparison of two Null-terminated strings.\r |
61e33430 | 166 | \r |
167 | @param This Protocol instance pointer.\r | |
4f077902 SZ |
168 | @param Str1 A pointer to a Null-terminated string.\r |
169 | @param Str2 A pointer to a Null-terminated string.\r | |
61e33430 | 170 | \r |
171 | @retval 0 Str1 is equivalent to Str2\r | |
172 | @retval > 0 Str1 is lexically greater than Str2\r | |
173 | @retval < 0 Str1 is lexically less than Str2\r | |
174 | \r | |
175 | **/\r | |
adbcbf8f | 176 | INTN\r |
177 | EFIAPI\r | |
178 | EngStriColl (\r | |
1436aea4 MK |
179 | IN EFI_UNICODE_COLLATION_PROTOCOL *This,\r |
180 | IN CHAR16 *Str1,\r | |
181 | IN CHAR16 *Str2\r | |
adbcbf8f | 182 | )\r |
adbcbf8f | 183 | {\r |
ea7cb08c | 184 | while (*Str1 != 0) {\r |
185 | if (TO_UPPER (*Str1) != TO_UPPER (*Str2)) {\r | |
adbcbf8f | 186 | break;\r |
187 | }\r | |
188 | \r | |
61e33430 | 189 | Str1 += 1;\r |
190 | Str2 += 1;\r | |
adbcbf8f | 191 | }\r |
192 | \r | |
ea7cb08c | 193 | return TO_UPPER (*Str1) - TO_UPPER (*Str2);\r |
adbcbf8f | 194 | }\r |
195 | \r | |
61e33430 | 196 | /**\r |
d1102dba | 197 | Converts all the characters in a Null-terminated string to\r |
4f077902 | 198 | lower case characters.\r |
61e33430 | 199 | \r |
200 | @param This Protocol instance pointer.\r | |
4f077902 | 201 | @param Str A pointer to a Null-terminated string.\r |
61e33430 | 202 | \r |
203 | **/\r | |
adbcbf8f | 204 | VOID\r |
205 | EFIAPI\r | |
206 | EngStrLwr (\r | |
1436aea4 MK |
207 | IN EFI_UNICODE_COLLATION_PROTOCOL *This,\r |
208 | IN OUT CHAR16 *Str\r | |
adbcbf8f | 209 | )\r |
adbcbf8f | 210 | {\r |
ea7cb08c | 211 | while (*Str != 0) {\r |
212 | *Str = TO_LOWER (*Str);\r | |
adbcbf8f | 213 | Str += 1;\r |
214 | }\r | |
215 | }\r | |
216 | \r | |
61e33430 | 217 | /**\r |
4f077902 SZ |
218 | Converts all the characters in a Null-terminated string to upper\r |
219 | case characters.\r | |
61e33430 | 220 | \r |
221 | @param This Protocol instance pointer.\r | |
4f077902 | 222 | @param Str A pointer to a Null-terminated string.\r |
61e33430 | 223 | \r |
224 | **/\r | |
adbcbf8f | 225 | VOID\r |
226 | EFIAPI\r | |
227 | EngStrUpr (\r | |
1436aea4 MK |
228 | IN EFI_UNICODE_COLLATION_PROTOCOL *This,\r |
229 | IN OUT CHAR16 *Str\r | |
adbcbf8f | 230 | )\r |
adbcbf8f | 231 | {\r |
ea7cb08c | 232 | while (*Str != 0) {\r |
233 | *Str = TO_UPPER (*Str);\r | |
adbcbf8f | 234 | Str += 1;\r |
235 | }\r | |
236 | }\r | |
237 | \r | |
61e33430 | 238 | /**\r |
4f077902 SZ |
239 | Performs a case-insensitive comparison of a Null-terminated\r |
240 | pattern string and a Null-terminated string.\r | |
61e33430 | 241 | \r |
242 | @param This Protocol instance pointer.\r | |
4f077902 SZ |
243 | @param String A pointer to a Null-terminated string.\r |
244 | @param Pattern A pointer to a Null-terminated pattern string.\r | |
61e33430 | 245 | \r |
246 | @retval TRUE Pattern was found in String.\r | |
247 | @retval FALSE Pattern was not found in String.\r | |
248 | \r | |
249 | **/\r | |
adbcbf8f | 250 | BOOLEAN\r |
251 | EFIAPI\r | |
252 | EngMetaiMatch (\r | |
1436aea4 MK |
253 | IN EFI_UNICODE_COLLATION_PROTOCOL *This,\r |
254 | IN CHAR16 *String,\r | |
255 | IN CHAR16 *Pattern\r | |
adbcbf8f | 256 | )\r |
adbcbf8f | 257 | {\r |
258 | CHAR16 CharC;\r | |
259 | CHAR16 CharP;\r | |
260 | CHAR16 Index3;\r | |
261 | \r | |
1436aea4 MK |
262 | for ( ; ;) {\r |
263 | CharP = *Pattern;\r | |
adbcbf8f | 264 | Pattern += 1;\r |
265 | \r | |
266 | switch (CharP) {\r | |
1436aea4 MK |
267 | case 0:\r |
268 | //\r | |
269 | // End of pattern. If end of string, TRUE match\r | |
270 | //\r | |
271 | if (*String != 0) {\r | |
272 | return FALSE;\r | |
273 | } else {\r | |
adbcbf8f | 274 | return TRUE;\r |
275 | }\r | |
276 | \r | |
1436aea4 MK |
277 | case '*':\r |
278 | //\r | |
279 | // Match zero or more chars\r | |
280 | //\r | |
281 | while (*String != 0) {\r | |
282 | if (EngMetaiMatch (This, String, Pattern)) {\r | |
283 | return TRUE;\r | |
284 | }\r | |
adbcbf8f | 285 | \r |
1436aea4 MK |
286 | String += 1;\r |
287 | }\r | |
adbcbf8f | 288 | \r |
1436aea4 | 289 | return EngMetaiMatch (This, String, Pattern);\r |
adbcbf8f | 290 | \r |
1436aea4 | 291 | case '?':\r |
adbcbf8f | 292 | //\r |
1436aea4 | 293 | // Match any one char\r |
adbcbf8f | 294 | //\r |
1436aea4 | 295 | if (*String == 0) {\r |
adbcbf8f | 296 | return FALSE;\r |
297 | }\r | |
298 | \r | |
1436aea4 MK |
299 | String += 1;\r |
300 | break;\r | |
301 | \r | |
302 | case '[':\r | |
303 | //\r | |
304 | // Match char set\r | |
305 | //\r | |
306 | CharC = *String;\r | |
307 | if (CharC == 0) {\r | |
adbcbf8f | 308 | //\r |
1436aea4 | 309 | // syntax problem\r |
adbcbf8f | 310 | //\r |
1436aea4 MK |
311 | return FALSE;\r |
312 | }\r | |
313 | \r | |
314 | Index3 = 0;\r | |
315 | CharP = *Pattern++;\r | |
316 | while (CharP != 0) {\r | |
317 | if (CharP == ']') {\r | |
318 | return FALSE;\r | |
319 | }\r | |
320 | \r | |
321 | if (CharP == '-') {\r | |
adbcbf8f | 322 | //\r |
1436aea4 | 323 | // if range of chars, get high range\r |
adbcbf8f | 324 | //\r |
1436aea4 MK |
325 | CharP = *Pattern;\r |
326 | if ((CharP == 0) || (CharP == ']')) {\r | |
327 | //\r | |
328 | // syntax problem\r | |
329 | //\r | |
330 | return FALSE;\r | |
331 | }\r | |
332 | \r | |
333 | if ((TO_UPPER (CharC) >= TO_UPPER (Index3)) && (TO_UPPER (CharC) <= TO_UPPER (CharP))) {\r | |
334 | //\r | |
335 | // if in range, it's a match\r | |
336 | //\r | |
337 | break;\r | |
338 | }\r | |
adbcbf8f | 339 | }\r |
340 | \r | |
1436aea4 MK |
341 | Index3 = CharP;\r |
342 | if (TO_UPPER (CharC) == TO_UPPER (CharP)) {\r | |
adbcbf8f | 343 | //\r |
1436aea4 | 344 | // if char matches\r |
adbcbf8f | 345 | //\r |
346 | break;\r | |
347 | }\r | |
adbcbf8f | 348 | \r |
1436aea4 | 349 | CharP = *Pattern++;\r |
adbcbf8f | 350 | }\r |
351 | \r | |
1436aea4 MK |
352 | //\r |
353 | // skip to end of match char set\r | |
354 | //\r | |
355 | while ((CharP != 0) && (CharP != ']')) {\r | |
356 | CharP = *Pattern;\r | |
357 | Pattern += 1;\r | |
358 | }\r | |
adbcbf8f | 359 | \r |
1436aea4 MK |
360 | String += 1;\r |
361 | break;\r | |
adbcbf8f | 362 | \r |
1436aea4 MK |
363 | default:\r |
364 | CharC = *String;\r | |
365 | if (TO_UPPER (CharC) != TO_UPPER (CharP)) {\r | |
366 | return FALSE;\r | |
367 | }\r | |
adbcbf8f | 368 | \r |
1436aea4 MK |
369 | String += 1;\r |
370 | break;\r | |
adbcbf8f | 371 | }\r |
372 | }\r | |
373 | }\r | |
374 | \r | |
61e33430 | 375 | /**\r |
4f077902 | 376 | Converts an 8.3 FAT file name in an OEM character set to a Null-terminated string.\r |
61e33430 | 377 | \r |
378 | @param This Protocol instance pointer.\r | |
379 | @param FatSize The size of the string Fat in bytes.\r | |
380 | @param Fat A pointer to a Null-terminated string that contains an 8.3 file\r | |
4f077902 SZ |
381 | name using an 8-bit OEM character set.\r |
382 | @param String A pointer to a Null-terminated string. The string must\r | |
383 | be preallocated to hold FatSize characters.\r | |
61e33430 | 384 | \r |
385 | **/\r | |
adbcbf8f | 386 | VOID\r |
387 | EFIAPI\r | |
388 | EngFatToStr (\r | |
1436aea4 MK |
389 | IN EFI_UNICODE_COLLATION_PROTOCOL *This,\r |
390 | IN UINTN FatSize,\r | |
391 | IN CHAR8 *Fat,\r | |
392 | OUT CHAR16 *String\r | |
adbcbf8f | 393 | )\r |
adbcbf8f | 394 | {\r |
395 | //\r | |
396 | // No DBCS issues, just expand and add null terminate to end of string\r | |
397 | //\r | |
ea7cb08c | 398 | while ((*Fat != 0) && (FatSize != 0)) {\r |
1436aea4 MK |
399 | *String = *Fat;\r |
400 | String += 1;\r | |
401 | Fat += 1;\r | |
adbcbf8f | 402 | FatSize -= 1;\r |
403 | }\r | |
404 | \r | |
405 | *String = 0;\r | |
406 | }\r | |
407 | \r | |
61e33430 | 408 | /**\r |
d1102dba LG |
409 | Converts a Null-terminated string to legal characters in a FAT\r |
410 | filename using an OEM character set.\r | |
61e33430 | 411 | \r |
412 | @param This Protocol instance pointer.\r | |
4f077902 SZ |
413 | @param String A pointer to a Null-terminated string. The string must\r |
414 | be preallocated to hold FatSize characters.\r | |
61e33430 | 415 | @param FatSize The size of the string Fat in bytes.\r |
416 | @param Fat A pointer to a Null-terminated string that contains an 8.3 file\r | |
417 | name using an OEM character set.\r | |
418 | \r | |
419 | @retval TRUE Fat is a Long File Name\r | |
420 | @retval FALSE Fat is an 8.3 file name\r | |
421 | \r | |
422 | **/\r | |
adbcbf8f | 423 | BOOLEAN\r |
424 | EFIAPI\r | |
425 | EngStrToFat (\r | |
1436aea4 MK |
426 | IN EFI_UNICODE_COLLATION_PROTOCOL *This,\r |
427 | IN CHAR16 *String,\r | |
428 | IN UINTN FatSize,\r | |
429 | OUT CHAR8 *Fat\r | |
adbcbf8f | 430 | )\r |
adbcbf8f | 431 | {\r |
1436aea4 | 432 | BOOLEAN SpecialCharExist;\r |
adbcbf8f | 433 | \r |
434 | SpecialCharExist = FALSE;\r | |
ea7cb08c | 435 | while ((*String != 0) && (FatSize != 0)) {\r |
adbcbf8f | 436 | //\r |
437 | // Skip '.' or ' ' when making a fat name\r | |
438 | //\r | |
1436aea4 | 439 | if ((*String != '.') && (*String != ' ')) {\r |
adbcbf8f | 440 | //\r |
441 | // If this is a valid fat char, move it.\r | |
48557c65 | 442 | // Otherwise, move a '_' and flag the fact that the name needs a long file name.\r |
adbcbf8f | 443 | //\r |
1436aea4 | 444 | if ((*String < MAP_TABLE_SIZE) && ((mEngInfoMap[*String] & CHAR_FAT_VALID) != 0)) {\r |
adbcbf8f | 445 | *Fat = mEngUpperMap[*String];\r |
446 | } else {\r | |
1436aea4 MK |
447 | *Fat = '_';\r |
448 | SpecialCharExist = TRUE;\r | |
adbcbf8f | 449 | }\r |
450 | \r | |
1436aea4 | 451 | Fat += 1;\r |
adbcbf8f | 452 | FatSize -= 1;\r |
453 | }\r | |
454 | \r | |
455 | String += 1;\r | |
456 | }\r | |
1436aea4 | 457 | \r |
adbcbf8f | 458 | //\r |
459 | // Do not terminate that fat string\r | |
460 | //\r | |
461 | return SpecialCharExist;\r | |
462 | }\r |