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