]> git.proxmox.com Git - mirror_edk2.git/blob - FatPkg/EnhancedFatDxe/UnicodeCollation.c
Add EDK II Prime FatPkg New Feature: Support both Unicode Collation and Unicode Colla...
[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 <Uefi.h>
17
18 #include <Guid/GlobalVariable.h>
19 #include <Protocol/UnicodeCollation.h>
20
21 #include <Library/BaseLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/PcdLib.h>
25 #include <Library/MemoryAllocationLib.h>
26 #include <Library/UefiBootServicesTableLib.h>
27 #include <Library/UefiRuntimeServicesTableLib.h>
28
29 STATIC EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollationInterface = NULL;
30
31 typedef
32 BOOLEAN
33 (* SEARCH_LANG_CODE) (
34 IN CONST CHAR8 *Languages,
35 IN CONST CHAR8 *MatchLangCode
36 );
37
38 struct _UNICODE_INTERFACE {
39 CHAR16 *VariableName;
40 CHAR8 *DefaultLangCode;
41 SEARCH_LANG_CODE SearchLangCode;
42 EFI_GUID *UnicodeProtocolGuid;
43 };
44
45 typedef struct _UNICODE_INTERFACE UNICODE_INTERFACE;
46
47 STATIC
48 BOOLEAN
49 SearchIso639LangCode (
50 IN CONST CHAR8 *Languages,
51 IN CONST CHAR8 *MatchLangCode
52 )
53 {
54 CONST CHAR8 *LangCode;
55
56 for (LangCode = Languages; *LangCode != '\0'; LangCode += 3) {
57 if (CompareMem (LangCode, MatchLangCode, 3) == 0) {
58 return TRUE;
59 }
60 }
61
62 return FALSE;
63 }
64
65 STATIC
66 BOOLEAN
67 SearchRfc3066LangCode (
68 IN CONST CHAR8 *Languages,
69 IN CONST CHAR8 *MatchLangCode
70 )
71 {
72 CHAR8 *SubStr;
73 CHAR8 Terminal;
74
75 SubStr = AsciiStrStr (Languages, MatchLangCode);
76 if (SubStr == NULL) {
77 return FALSE;
78 }
79
80 if (SubStr != Languages && *(SubStr - 1) != ';') {
81 return FALSE;
82 }
83
84 Terminal = *(SubStr + AsciiStrLen (MatchLangCode));
85 if (Terminal != '\0' && Terminal != ';') {
86 return FALSE;
87 }
88
89 return TRUE;
90 }
91
92 GLOBAL_REMOVE_IF_UNREFERENCED UNICODE_INTERFACE mIso639Lang = {
93 L"Lang",
94 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang),
95 SearchIso639LangCode,
96 &gEfiUnicodeCollationProtocolGuid,
97 };
98
99 GLOBAL_REMOVE_IF_UNREFERENCED UNICODE_INTERFACE mRfc3066Lang = {
100 L"PlatformLang",
101 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),
102 SearchRfc3066LangCode,
103 &gEfiUnicodeCollation2ProtocolGuid,
104 };
105
106 STATIC
107 EFI_STATUS
108 InitializeUnicodeCollationSupportWithConfig (
109 IN EFI_HANDLE AgentHandle,
110 IN UNICODE_INTERFACE *UnicodeInterface
111 )
112 {
113 EFI_STATUS Status;
114 CHAR8 Buffer[100];
115 UINTN BufferSize;
116 UINTN Index;
117 CHAR8 *LangCode;
118 UINTN NoHandles;
119 EFI_HANDLE *Handles;
120 EFI_UNICODE_COLLATION_PROTOCOL *Uci;
121
122 LangCode = Buffer;
123 BufferSize = sizeof (Buffer);
124 Status = gRT->GetVariable (
125 UnicodeInterface->VariableName,
126 &gEfiGlobalVariableGuid,
127 NULL,
128 &BufferSize,
129 Buffer
130 );
131 if (EFI_ERROR (Status)) {
132 LangCode = UnicodeInterface->DefaultLangCode;
133 }
134
135 Status = gBS->LocateHandleBuffer (
136 ByProtocol,
137 UnicodeInterface->UnicodeProtocolGuid,
138 NULL,
139 &NoHandles,
140 &Handles
141 );
142 if (EFI_ERROR (Status)) {
143 return Status;
144 }
145
146 for (Index = 0; Index < NoHandles; Index++) {
147 //
148 // Open Unicode Collation Protocol
149 //
150 Status = gBS->OpenProtocol (
151 Handles[Index],
152 UnicodeInterface->UnicodeProtocolGuid,
153 (VOID **) &Uci,
154 AgentHandle,
155 NULL,
156 EFI_OPEN_PROTOCOL_GET_PROTOCOL
157 );
158 if (EFI_ERROR (Status)) {
159 continue;
160 }
161
162 if (UnicodeInterface->SearchLangCode (Uci->SupportedLanguages, LangCode)) {
163 mUnicodeCollationInterface = Uci;
164 break;
165 }
166 }
167
168 FreePool (Handles);
169
170 return (mUnicodeCollationInterface != NULL)? EFI_SUCCESS : EFI_NOT_FOUND;
171 }
172
173 /**
174 Initialize Unicode Collation support.
175
176 @param AgentHandle The handle used to open Unicode Collation (2) protocol.
177
178 @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located.
179 @retval Others The Unicode Collation (2) protocol has not been located.
180
181 **/
182 EFI_STATUS
183 InitializeUnicodeCollationSupport (
184 IN EFI_HANDLE AgentHandle
185 )
186 {
187
188 EFI_STATUS Status;
189
190 Status = EFI_UNSUPPORTED;
191 if (FeaturePcdGet (PcdUnicodeCollation2Support)) {
192 Status = InitializeUnicodeCollationSupportWithConfig (AgentHandle, &mRfc3066Lang);
193 }
194
195 if (FeaturePcdGet (PcdUnicodeCollationSupport) && EFI_ERROR (Status)) {
196 Status = InitializeUnicodeCollationSupportWithConfig (AgentHandle, &mIso639Lang);
197 }
198
199 return Status;
200 }
201
202 /**
203 Performs a case-insensitive comparison of two Null-terminated Unicode strings.
204
205 @param S1 A pointer to a Null-terminated Unicode string.
206 @param S2 A pointer to a Null-terminated Unicode string.
207
208 @retval 0 S1 is equivalent to S2.
209 @retval >0 S1 is lexically greater than S2.
210 @retval <0 S1 is lexically less than S2.
211 **/
212 INTN
213 FatStriCmp (
214 IN CHAR16 *S1,
215 IN CHAR16 *S2
216 )
217 {
218 ASSERT (StrSize (S1) != 0);
219 ASSERT (StrSize (S2) != 0);
220 ASSERT (mUnicodeCollationInterface != NULL);
221
222 return mUnicodeCollationInterface->StriColl (
223 mUnicodeCollationInterface,
224 S1,
225 S2
226 );
227 }
228
229
230 /**
231 Uppercase a string.
232
233 @param Str The string which will be upper-cased.
234
235 @return None.
236
237 **/
238 VOID
239 FatStrUpr (
240 IN OUT CHAR16 *String
241 )
242 {
243 ASSERT (StrSize (String) != 0);
244 ASSERT (mUnicodeCollationInterface != NULL);
245
246 mUnicodeCollationInterface->StrUpr (mUnicodeCollationInterface, String);
247 }
248
249
250 /**
251 Lowercase a string
252
253 @param Str The string which will be lower-cased.
254
255 @return None
256
257 **/
258 VOID
259 FatStrLwr (
260 IN OUT CHAR16 *String
261 )
262 {
263 ASSERT (StrSize (String) != 0);
264 ASSERT (mUnicodeCollationInterface != NULL);
265
266 mUnicodeCollationInterface->StrLwr (mUnicodeCollationInterface, String);
267 }
268
269
270 /**
271 Convert FAT string to unicode string.
272
273 @param FatSize The size of FAT string.
274 @param Fat The FAT string.
275 @param String The unicode string.
276
277 @return None.
278
279 **/
280 VOID
281 FatFatToStr (
282 IN UINTN FatSize,
283 IN CHAR8 *Fat,
284 OUT CHAR16 *String
285 )
286 {
287 ASSERT (Fat != NULL);
288 ASSERT (String != NULL);
289 ASSERT (((UINTN) String & 0x01) != 0);
290 ASSERT (mUnicodeCollationInterface != NULL);
291
292 mUnicodeCollationInterface->FatToStr (mUnicodeCollationInterface, FatSize, Fat, String);
293 }
294
295
296 /**
297 Convert unicode string to Fat string.
298
299 @param String The unicode string.
300 @param FatSize The size of the FAT string.
301 @param Fat The FAT string.
302
303 @retval TRUE Convert successfully.
304 @retval FALSE Convert error.
305
306 **/
307 BOOLEAN
308 FatStrToFat (
309 IN CHAR16 *String,
310 IN UINTN FatSize,
311 OUT CHAR8 *Fat
312 )
313 {
314 ASSERT (Fat != NULL);
315 ASSERT (StrSize (String) != 0);
316 ASSERT (mUnicodeCollationInterface != NULL);
317
318 return mUnicodeCollationInterface->StrToFat (
319 mUnicodeCollationInterface,
320 String,
321 FatSize,
322 Fat
323 );
324 }