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