]> git.proxmox.com Git - mirror_edk2.git/blob - FatPkg/EnhancedFatDxe/UnicodeCollation.c
Fix a spec conformance issue that "Attributes" should only be checked when OpenMode...
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / UnicodeCollation.c
1 /** @file
2 Unicode Collation Library that hides the trival difference of Unicode Collation
3 and Unicode collation 2 Protocol.
4
5 Copyright (c) 2007, Intel Corporation<BR>
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "Fat.h"
17
18 STATIC EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollationInterface = NULL;
19
20 typedef
21 BOOLEAN
22 (* SEARCH_LANG_CODE) (
23 IN CONST CHAR8 *Languages,
24 IN CONST CHAR8 *MatchLangCode
25 );
26
27 struct _UNICODE_INTERFACE {
28 CHAR16 *VariableName;
29 CHAR8 *DefaultLangCode;
30 SEARCH_LANG_CODE SearchLangCode;
31 EFI_GUID *UnicodeProtocolGuid;
32 };
33
34 typedef struct _UNICODE_INTERFACE UNICODE_INTERFACE;
35
36 STATIC
37 BOOLEAN
38 SearchIso639LangCode (
39 IN CONST CHAR8 *Languages,
40 IN CONST CHAR8 *MatchLangCode
41 )
42 {
43 CONST CHAR8 *LangCode;
44
45 for (LangCode = Languages; *LangCode != '\0'; LangCode += 3) {
46 if (CompareMem (LangCode, MatchLangCode, 3) == 0) {
47 return TRUE;
48 }
49 }
50
51 return FALSE;
52 }
53
54 STATIC
55 BOOLEAN
56 SearchRfc3066LangCode (
57 IN CONST CHAR8 *Languages,
58 IN CONST CHAR8 *MatchLangCode
59 )
60 {
61 CHAR8 *SubStr;
62 CHAR8 Terminal;
63
64 SubStr = AsciiStrStr (Languages, MatchLangCode);
65 if (SubStr == NULL) {
66 return FALSE;
67 }
68
69 if (SubStr != Languages && *(SubStr - 1) != ';') {
70 return FALSE;
71 }
72
73 Terminal = *(SubStr + AsciiStrLen (MatchLangCode));
74 if (Terminal != '\0' && Terminal != ';') {
75 return FALSE;
76 }
77
78 return TRUE;
79 }
80
81 GLOBAL_REMOVE_IF_UNREFERENCED UNICODE_INTERFACE mIso639Lang = {
82 L"Lang",
83 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang),
84 SearchIso639LangCode,
85 &gEfiUnicodeCollationProtocolGuid,
86 };
87
88 GLOBAL_REMOVE_IF_UNREFERENCED UNICODE_INTERFACE mRfc3066Lang = {
89 L"PlatformLang",
90 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),
91 SearchRfc3066LangCode,
92 &gEfiUnicodeCollation2ProtocolGuid,
93 };
94
95 STATIC
96 EFI_STATUS
97 InitializeUnicodeCollationSupportWithConfig (
98 IN EFI_HANDLE AgentHandle,
99 IN UNICODE_INTERFACE *UnicodeInterface
100 )
101 {
102 EFI_STATUS Status;
103 CHAR8 Buffer[100];
104 UINTN BufferSize;
105 UINTN Index;
106 CHAR8 *LangCode;
107 UINTN NoHandles;
108 EFI_HANDLE *Handles;
109 EFI_UNICODE_COLLATION_PROTOCOL *Uci;
110
111 LangCode = Buffer;
112 BufferSize = sizeof (Buffer);
113 Status = gRT->GetVariable (
114 UnicodeInterface->VariableName,
115 &gEfiGlobalVariableGuid,
116 NULL,
117 &BufferSize,
118 Buffer
119 );
120 if (EFI_ERROR (Status)) {
121 LangCode = UnicodeInterface->DefaultLangCode;
122 }
123
124 Status = gBS->LocateHandleBuffer (
125 ByProtocol,
126 UnicodeInterface->UnicodeProtocolGuid,
127 NULL,
128 &NoHandles,
129 &Handles
130 );
131 if (EFI_ERROR (Status)) {
132 return Status;
133 }
134
135 for (Index = 0; Index < NoHandles; Index++) {
136 //
137 // Open Unicode Collation Protocol
138 //
139 Status = gBS->OpenProtocol (
140 Handles[Index],
141 UnicodeInterface->UnicodeProtocolGuid,
142 (VOID **) &Uci,
143 AgentHandle,
144 NULL,
145 EFI_OPEN_PROTOCOL_GET_PROTOCOL
146 );
147 if (EFI_ERROR (Status)) {
148 continue;
149 }
150
151 if (UnicodeInterface->SearchLangCode (Uci->SupportedLanguages, LangCode)) {
152 mUnicodeCollationInterface = Uci;
153 break;
154 }
155 }
156
157 FreePool (Handles);
158
159 return (mUnicodeCollationInterface != NULL)? EFI_SUCCESS : EFI_NOT_FOUND;
160 }
161
162 /**
163 Initialize Unicode Collation support.
164
165 This function searches Initialized Unicode Collation support based on PCDs:
166 PcdUnicodeCollation2Support and PcdUnicodeCollationSupport.
167 It first tries to locate Unicode Collation 2 protocol and matches it with current
168 platform language code. If for any reason the first attempt fails, it then tries to
169 use Unicode Collation Protocol.
170
171 @param AgentHandle The handle used to open Unicode Collation (2) protocol.
172
173 @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located.
174 @retval Others The Unicode Collation (2) protocol has not been located.
175
176 **/
177 EFI_STATUS
178 InitializeUnicodeCollationSupport (
179 IN EFI_HANDLE AgentHandle
180 )
181 {
182
183 EFI_STATUS Status;
184
185 Status = EFI_UNSUPPORTED;
186
187 //
188 // First try to use RFC 3066 Unicode Collation 2 Protocol.
189 //
190 if (FeaturePcdGet (PcdUnicodeCollation2Support)) {
191 Status = InitializeUnicodeCollationSupportWithConfig (AgentHandle, &mRfc3066Lang);
192 }
193
194 //
195 // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back
196 // on the ISO 639-2 Unicode Collation Protocol.
197 //
198 if (FeaturePcdGet (PcdUnicodeCollationSupport) && EFI_ERROR (Status)) {
199 Status = InitializeUnicodeCollationSupportWithConfig (AgentHandle, &mIso639Lang);
200 }
201
202 return Status;
203 }
204
205 /**
206 Performs a case-insensitive comparison of two Null-terminated Unicode strings.
207
208 @param S1 A pointer to a Null-terminated Unicode string.
209 @param S2 A pointer to a Null-terminated Unicode string.
210
211 @retval 0 S1 is equivalent to S2.
212 @retval >0 S1 is lexically greater than S2.
213 @retval <0 S1 is lexically less than S2.
214 **/
215 INTN
216 FatStriCmp (
217 IN CHAR16 *S1,
218 IN CHAR16 *S2
219 )
220 {
221 ASSERT (StrSize (S1) != 0);
222 ASSERT (StrSize (S2) != 0);
223 ASSERT (mUnicodeCollationInterface != NULL);
224
225 return mUnicodeCollationInterface->StriColl (
226 mUnicodeCollationInterface,
227 S1,
228 S2
229 );
230 }
231
232
233 /**
234 Uppercase a string.
235
236 @param Str The string which will be upper-cased.
237
238 @return None.
239
240 **/
241 VOID
242 FatStrUpr (
243 IN OUT CHAR16 *String
244 )
245 {
246 ASSERT (StrSize (String) != 0);
247 ASSERT (mUnicodeCollationInterface != NULL);
248
249 mUnicodeCollationInterface->StrUpr (mUnicodeCollationInterface, String);
250 }
251
252
253 /**
254 Lowercase a string
255
256 @param Str The string which will be lower-cased.
257
258 @return None
259
260 **/
261 VOID
262 FatStrLwr (
263 IN OUT CHAR16 *String
264 )
265 {
266 ASSERT (StrSize (String) != 0);
267 ASSERT (mUnicodeCollationInterface != NULL);
268
269 mUnicodeCollationInterface->StrLwr (mUnicodeCollationInterface, String);
270 }
271
272
273 /**
274 Convert FAT string to unicode string.
275
276 @param FatSize The size of FAT string.
277 @param Fat The FAT string.
278 @param String The unicode string.
279
280 @return None.
281
282 **/
283 VOID
284 FatFatToStr (
285 IN UINTN FatSize,
286 IN CHAR8 *Fat,
287 OUT CHAR16 *String
288 )
289 {
290 ASSERT (Fat != NULL);
291 ASSERT (String != NULL);
292 ASSERT (((UINTN) String & 0x01) == 0);
293 ASSERT (mUnicodeCollationInterface != NULL);
294
295 mUnicodeCollationInterface->FatToStr (mUnicodeCollationInterface, FatSize, Fat, String);
296 }
297
298
299 /**
300 Convert unicode string to Fat string.
301
302 @param String The unicode string.
303 @param FatSize The size of the FAT string.
304 @param Fat The FAT string.
305
306 @retval TRUE Convert successfully.
307 @retval FALSE Convert error.
308
309 **/
310 BOOLEAN
311 FatStrToFat (
312 IN CHAR16 *String,
313 IN UINTN FatSize,
314 OUT CHAR8 *Fat
315 )
316 {
317 ASSERT (Fat != NULL);
318 ASSERT (StrSize (String) != 0);
319 ASSERT (mUnicodeCollationInterface != NULL);
320
321 return mUnicodeCollationInterface->StrToFat (
322 mUnicodeCollationInterface,
323 String,
324 FatSize,
325 Fat
326 );
327 }