]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/UefiSortLib/UefiSortLib.c
MdeModulePkg/SortLib: Add QuickSort function on BaseLib
[mirror_edk2.git] / MdeModulePkg / Library / UefiSortLib / UefiSortLib.c
CommitLineData
a4ee2a4f 1/** @file\r
2 Library used for sorting routines.\r
3\r
99325a8b 4 Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved. <BR>\r
9d510e61 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a4ee2a4f 6\r
7**/\r
8\r
9#include <Uefi.h>\r
10\r
11#include <Protocol/UnicodeCollation.h>\r
12#include <Protocol/DevicePath.h>\r
a4ee2a4f 13\r
14#include <Library/UefiBootServicesTableLib.h>\r
15#include <Library/BaseLib.h>\r
16#include <Library/BaseMemoryLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
1e6e84c7 19#include <Library/SortLib.h>\r
863986b3 20#include <Library/DevicePathLib.h>\r
a4ee2a4f 21\r
11d2decf 22STATIC EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r
23\r
ae591c14
DM
24#define USL_FREE_NON_NULL(Pointer) \\r
25{ \\r
26 if ((Pointer) != NULL) { \\r
27 FreePool((Pointer)); \\r
28 (Pointer) = NULL; \\r
29 } \\r
30}\r
11d2decf 31\r
a4ee2a4f 32/**\r
33 Function to perform a Quick Sort alogrithm on a buffer of comparable elements.\r
34\r
35 Each element must be equal sized.\r
36\r
37 if BufferToSort is NULL, then ASSERT.\r
38 if CompareFunction is NULL, then ASSERT.\r
39\r
40 if Count is < 2 then perform no action.\r
41 if Size is < 1 then perform no action.\r
42\r
4ff7e37b
ED
43 @param[in, out] BufferToSort on call a Buffer of (possibly sorted) elements\r
44 on return a buffer of sorted elements\r
45 @param[in] Count the number of elements in the buffer to sort\r
46 @param[in] ElementSize Size of an element in bytes\r
47 @param[in] CompareFunction The function to call to perform the comparison\r
48 of any 2 elements\r
a4ee2a4f 49**/\r
50VOID\r
51EFIAPI\r
52PerformQuickSort (\r
53 IN OUT VOID *BufferToSort,\r
54 IN CONST UINTN Count,\r
55 IN CONST UINTN ElementSize,\r
56 IN SORT_COMPARE CompareFunction\r
125c2cf4 57 )\r
58{\r
a4ee2a4f 59 VOID *Buffer;\r
60\r
61 ASSERT(BufferToSort != NULL);\r
62 ASSERT(CompareFunction != NULL);\r
63\r
9586a351 64 Buffer = AllocateZeroPool(ElementSize);\r
a4ee2a4f 65 ASSERT(Buffer != NULL);\r
66\r
99325a8b 67 QuickSort (\r
a4ee2a4f 68 BufferToSort,\r
69 Count,\r
70 ElementSize,\r
71 CompareFunction,\r
99325a8b
IK
72 Buffer\r
73 );\r
a4ee2a4f 74\r
75 FreePool(Buffer);\r
76 return;\r
77}\r
78\r
79/**\r
da70d025 80 Function to compare 2 device paths for use in QuickSort.\r
a4ee2a4f 81\r
82 @param[in] Buffer1 pointer to Device Path poiner to compare\r
83 @param[in] Buffer2 pointer to second DevicePath pointer to compare\r
84\r
85 @retval 0 Buffer1 equal to Buffer2\r
ae591c14
DM
86 @retval <0 Buffer1 is less than Buffer2\r
87 @retval >0 Buffer1 is greater than Buffer2\r
a4ee2a4f 88**/\r
89INTN\r
e26d7b59 90EFIAPI\r
a4ee2a4f 91DevicePathCompare (\r
b3011f40 92 IN CONST VOID *Buffer1,\r
93 IN CONST VOID *Buffer2\r
125c2cf4 94 )\r
95{\r
a4ee2a4f 96 EFI_DEVICE_PATH_PROTOCOL *DevicePath1;\r
97 EFI_DEVICE_PATH_PROTOCOL *DevicePath2;\r
98 CHAR16 *TextPath1;\r
99 CHAR16 *TextPath2;\r
100 EFI_STATUS Status;\r
101 INTN RetVal;\r
1e6e84c7 102\r
a4ee2a4f 103 DevicePath1 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer1;\r
104 DevicePath2 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer2;\r
105\r
106 if (DevicePath1 == NULL) {\r
107 if (DevicePath2 == NULL) {\r
108 return 0;\r
109 }\r
110\r
111 return -1;\r
112 }\r
113\r
114 if (DevicePath2 == NULL) {\r
115 return 1;\r
116 }\r
1e6e84c7 117\r
11d2decf 118 if (mUnicodeCollation == NULL) {\r
a4ee2a4f 119 Status = gBS->LocateProtocol(\r
120 &gEfiUnicodeCollation2ProtocolGuid,\r
121 NULL,\r
11d2decf 122 (VOID**)&mUnicodeCollation);\r
a4ee2a4f 123\r
124 ASSERT_EFI_ERROR(Status);\r
125 }\r
126\r
863986b3 127 TextPath1 = ConvertDevicePathToText(\r
a4ee2a4f 128 DevicePath1,\r
129 FALSE,\r
130 FALSE);\r
131\r
863986b3 132 TextPath2 = ConvertDevicePathToText(\r
a4ee2a4f 133 DevicePath2,\r
134 FALSE,\r
135 FALSE);\r
1e6e84c7 136\r
eca218a7 137 if (TextPath1 == NULL) {\r
138 RetVal = -1;\r
139 } else if (TextPath2 == NULL) {\r
140 RetVal = 1;\r
141 } else {\r
142 RetVal = mUnicodeCollation->StriColl(\r
143 mUnicodeCollation,\r
144 TextPath1,\r
145 TextPath2);\r
146 }\r
a4ee2a4f 147\r
ae591c14
DM
148 USL_FREE_NON_NULL(TextPath1);\r
149 USL_FREE_NON_NULL(TextPath2);\r
a4ee2a4f 150\r
151 return (RetVal);\r
11d2decf 152}\r
153\r
154/**\r
155 Function to compare 2 strings without regard to case of the characters.\r
156\r
157 @param[in] Buffer1 Pointer to String to compare.\r
158 @param[in] Buffer2 Pointer to second String to compare.\r
159\r
160 @retval 0 Buffer1 equal to Buffer2.\r
ae591c14
DM
161 @retval <0 Buffer1 is less than Buffer2.\r
162 @retval >0 Buffer1 is greater than Buffer2.\r
11d2decf 163**/\r
164INTN\r
165EFIAPI\r
166StringNoCaseCompare (\r
b3011f40 167 IN CONST VOID *Buffer1,\r
168 IN CONST VOID *Buffer2\r
11d2decf 169 )\r
170{\r
171 EFI_STATUS Status;\r
172 if (mUnicodeCollation == NULL) {\r
173 Status = gBS->LocateProtocol(\r
174 &gEfiUnicodeCollation2ProtocolGuid,\r
175 NULL,\r
176 (VOID**)&mUnicodeCollation);\r
177\r
178 ASSERT_EFI_ERROR(Status);\r
179 }\r
180\r
181 return (mUnicodeCollation->StriColl(\r
182 mUnicodeCollation,\r
183 *(CHAR16**)Buffer1,\r
184 *(CHAR16**)Buffer2));\r
185}\r
186\r
187\r
a405b86d 188/**\r
189 Function to compare 2 strings.\r
190\r
191 @param[in] Buffer1 Pointer to String to compare (CHAR16**).\r
192 @param[in] Buffer2 Pointer to second String to compare (CHAR16**).\r
193\r
194 @retval 0 Buffer1 equal to Buffer2.\r
ae591c14
DM
195 @retval <0 Buffer1 is less than Buffer2.\r
196 @retval >0 Buffer1 is greater than Buffer2.\r
a405b86d 197**/\r
198INTN\r
199EFIAPI\r
200StringCompare (\r
201 IN CONST VOID *Buffer1,\r
202 IN CONST VOID *Buffer2\r
203 )\r
204{\r
205 return (StrCmp(\r
206 *(CHAR16**)Buffer1,\r
207 *(CHAR16**)Buffer2));\r
208}\r