4a849af2eb642e013345d686cc537128a8388ab4
[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   @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.\r
166 \r
167   @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.\r
168   @retval Others               The Unicode Collation (2) protocol has not been located.\r
169 \r
170 **/\r
171 EFI_STATUS\r
172 InitializeUnicodeCollationSupport (\r
173   IN EFI_HANDLE    AgentHandle\r
174   )\r
175 {\r
176 \r
177   EFI_STATUS       Status;\r
178 \r
179   Status = EFI_UNSUPPORTED;\r
180   if (FeaturePcdGet (PcdUnicodeCollation2Support)) {\r
181     Status = InitializeUnicodeCollationSupportWithConfig (AgentHandle, &mRfc3066Lang);\r
182   }\r
183 \r
184   if (FeaturePcdGet (PcdUnicodeCollationSupport) && EFI_ERROR (Status)) {\r
185     Status = InitializeUnicodeCollationSupportWithConfig (AgentHandle, &mIso639Lang);\r
186   }\r
187 \r
188   return Status;\r
189 }\r
190 \r
191 /**\r
192   Performs a case-insensitive comparison of two Null-terminated Unicode strings.\r
193 \r
194   @param  S1                   A pointer to a Null-terminated Unicode string.\r
195   @param  S2                   A pointer to a Null-terminated Unicode string.\r
196 \r
197   @retval 0                    S1 is equivalent to S2.\r
198   @retval >0                   S1 is lexically greater than S2.\r
199   @retval <0                   S1 is lexically less than S2.\r
200 **/\r
201 INTN\r
202 FatStriCmp (\r
203   IN CHAR16       *S1,\r
204   IN CHAR16       *S2\r
205   )\r
206 {\r
207   ASSERT (StrSize (S1) != 0);\r
208   ASSERT (StrSize (S2) != 0);\r
209   ASSERT (mUnicodeCollationInterface != NULL);\r
210 \r
211   return mUnicodeCollationInterface->StriColl (\r
212                                        mUnicodeCollationInterface,\r
213                                        S1,\r
214                                        S2\r
215                                        );\r
216 }\r
217 \r
218 \r
219 /**\r
220   Uppercase a string.\r
221 \r
222   @param  Str                   The string which will be upper-cased.\r
223 \r
224   @return None.\r
225 \r
226 **/\r
227 VOID\r
228 FatStrUpr (\r
229   IN OUT CHAR16   *String\r
230   )\r
231 {\r
232   ASSERT (StrSize (String) != 0);\r
233   ASSERT (mUnicodeCollationInterface != NULL);\r
234 \r
235   mUnicodeCollationInterface->StrUpr (mUnicodeCollationInterface, String);\r
236 }\r
237 \r
238 \r
239 /**\r
240   Lowercase a string\r
241 \r
242   @param  Str                   The string which will be lower-cased.\r
243 \r
244   @return None\r
245 \r
246 **/\r
247 VOID\r
248 FatStrLwr (\r
249   IN OUT CHAR16   *String\r
250   )\r
251 {\r
252   ASSERT (StrSize (String) != 0);\r
253   ASSERT (mUnicodeCollationInterface != NULL);\r
254 \r
255   mUnicodeCollationInterface->StrLwr (mUnicodeCollationInterface, String);\r
256 }\r
257 \r
258 \r
259 /**\r
260   Convert FAT string to unicode string.\r
261 \r
262   @param  FatSize               The size of FAT string.\r
263   @param  Fat                   The FAT string.\r
264   @param  String                The unicode string.\r
265 \r
266   @return None.\r
267 \r
268 **/\r
269 VOID\r
270 FatFatToStr (\r
271   IN  UINTN                            FatSize,\r
272   IN  CHAR8                            *Fat,\r
273   OUT CHAR16                           *String\r
274   )\r
275 {\r
276   ASSERT (Fat != NULL);\r
277   ASSERT (String != NULL);\r
278   ASSERT (((UINTN) String & 0x01) == 0);\r
279   ASSERT (mUnicodeCollationInterface != NULL);\r
280 \r
281   mUnicodeCollationInterface->FatToStr (mUnicodeCollationInterface, FatSize, Fat, String);\r
282 }\r
283 \r
284 \r
285 /**\r
286   Convert unicode string to Fat string.\r
287 \r
288   @param  String                The unicode string.\r
289   @param  FatSize               The size of the FAT string.\r
290   @param  Fat                   The FAT string.\r
291 \r
292   @retval TRUE                  Convert successfully.\r
293   @retval FALSE                 Convert error.\r
294 \r
295 **/\r
296 BOOLEAN\r
297 FatStrToFat (\r
298   IN  CHAR16                          *String,\r
299   IN  UINTN                           FatSize,\r
300   OUT CHAR8                           *Fat\r
301   )\r
302 {\r
303   ASSERT (Fat != NULL);\r
304   ASSERT (StrSize (String) != 0);\r
305   ASSERT (mUnicodeCollationInterface != NULL);\r
306 \r
307   return mUnicodeCollationInterface->StrToFat (\r
308                                        mUnicodeCollationInterface,\r
309                                        String,\r
310                                        FatSize,\r
311                                        Fat\r
312                                        );\r
313 }\r