/** @file\r
Library used for sorting routines.\r
\r
-Copyright (c) 2009, Intel Corporation<BR>\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved. <BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
**/\r
\r
#include <Uefi.h>\r
+#include <ShellBase.h>\r
\r
#include <Protocol/UnicodeCollation.h>\r
#include <Protocol/DevicePath.h>\r
-#include <Protocol/DevicePathToText.h>\r
\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/BaseLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
-#include <Library/SortLib.h> \r
+#include <Library/SortLib.h>\r
+#include <Library/DevicePathLib.h>\r
+\r
+STATIC EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r
+\r
\r
/**\r
- Worker function for QuickSorting. This function is identical to PerformQuickSort, \r
- except that is uses the pre-allocated buffer so the in place sorting does not need to \r
+ Worker function for QuickSorting. This function is identical to PerformQuickSort,\r
+ except that is uses the pre-allocated buffer so the in place sorting does not need to\r
allocate and free buffers constantly.\r
\r
Each element must be equal sized.\r
if Count is < 2 then perform no action.\r
if Size is < 1 then perform no action.\r
\r
- @param[in,out] BufferToSort on call a Buffer of (possibly sorted) elements\r
- on return a buffer of sorted elements\r
- @param[in] Count the number of elements in the buffer to sort\r
- @param[in] ElementSize Size of an element in bytes\r
- @param[in] CompareFunction The function to call to perform the comparison \r
- of any 2 elements\r
- @param[in] Buffer Buffer of size ElementSize for use in swapping\r
+ @param[in, out] BufferToSort on call a Buffer of (possibly sorted) elements\r
+ on return a buffer of sorted elements\r
+ @param[in] Count the number of elements in the buffer to sort\r
+ @param[in] ElementSize Size of an element in bytes\r
+ @param[in] CompareFunction The function to call to perform the comparison\r
+ of any 2 elements\r
+ @param[in] Buffer Buffer of size ElementSize for use in swapping\r
**/\r
VOID\r
EFIAPI\r
ASSERT(CompareFunction != NULL);\r
ASSERT(Buffer != NULL);\r
\r
- if ( Count < 2 \r
+ if ( Count < 2\r
|| ElementSize < 1\r
- ){\r
+ ){\r
return;\r
}\r
\r
// and everything "right" are above it\r
//\r
for ( LoopCount = 0\r
- ; LoopCount < Count -1 \r
+ ; LoopCount < Count -1\r
; LoopCount++\r
- ){\r
+ ){\r
//\r
// if the element is less than the pivot\r
//\r
if (CompareFunction((VOID*)((UINT8*)BufferToSort+((LoopCount)*ElementSize)),Pivot) <= 0){\r
//\r
- // swap \r
+ // swap\r
//\r
CopyMem (Buffer, (UINT8*)BufferToSort+(NextSwapLocation*ElementSize), ElementSize);\r
CopyMem ((UINT8*)BufferToSort+(NextSwapLocation*ElementSize), (UINT8*)BufferToSort+((LoopCount)*ElementSize), ElementSize);\r
\r
//\r
// increment NextSwapLocation\r
- // \r
+ //\r
NextSwapLocation++;\r
}\r
}\r
CopyMem ((UINT8*)BufferToSort+(NextSwapLocation*ElementSize), Buffer, ElementSize);\r
\r
//\r
- // Now recurse on 2 paritial lists. neither of these will have the 'pivot' element \r
+ // Now recurse on 2 paritial lists. neither of these will have the 'pivot' element\r
// IE list is sorted left half, pivot element, sorted right half...\r
//\r
- QuickSortWorker(\r
- BufferToSort, \r
- NextSwapLocation, \r
- ElementSize, \r
- CompareFunction,\r
- Buffer);\r
+ if (NextSwapLocation >= 2) {\r
+ QuickSortWorker(\r
+ BufferToSort,\r
+ NextSwapLocation,\r
+ ElementSize,\r
+ CompareFunction,\r
+ Buffer);\r
+ }\r
\r
- QuickSortWorker(\r
- (UINT8 *)BufferToSort + (NextSwapLocation+1) * ElementSize,\r
- Count - NextSwapLocation - 1, \r
- ElementSize, \r
- CompareFunction,\r
- Buffer);\r
+ if ((Count - NextSwapLocation - 1) >= 2) {\r
+ QuickSortWorker(\r
+ (UINT8 *)BufferToSort + (NextSwapLocation+1) * ElementSize,\r
+ Count - NextSwapLocation - 1,\r
+ ElementSize,\r
+ CompareFunction,\r
+ Buffer);\r
+ }\r
\r
return;\r
}\r
if Count is < 2 then perform no action.\r
if Size is < 1 then perform no action.\r
\r
- @param[in,out] BufferToSort on call a Buffer of (possibly sorted) elements\r
- on return a buffer of sorted elements\r
- @param[in] Count the number of elements in the buffer to sort\r
- @param[in] ElementSize Size of an element in bytes\r
- @param[in] CompareFunction The function to call to perform the comparison \r
- of any 2 elements\r
+ @param[in, out] BufferToSort on call a Buffer of (possibly sorted) elements\r
+ on return a buffer of sorted elements\r
+ @param[in] Count the number of elements in the buffer to sort\r
+ @param[in] ElementSize Size of an element in bytes\r
+ @param[in] CompareFunction The function to call to perform the comparison\r
+ of any 2 elements\r
**/\r
VOID\r
EFIAPI\r
ASSERT(BufferToSort != NULL);\r
ASSERT(CompareFunction != NULL);\r
\r
- Buffer = AllocatePool(ElementSize);\r
+ Buffer = AllocateZeroPool(ElementSize);\r
ASSERT(Buffer != NULL);\r
\r
QuickSortWorker(\r
}\r
\r
/**\r
- function to compare 2 device paths for use in QuickSort\r
+ Function to compare 2 device paths for use in QuickSort.\r
\r
@param[in] Buffer1 pointer to Device Path poiner to compare\r
@param[in] Buffer2 pointer to second DevicePath pointer to compare\r
\r
@retval 0 Buffer1 equal to Buffer2\r
@return < 0 Buffer1 is less than Buffer2\r
- @return > 0 Buffer1 is greater than Buffer2 \r
+ @return > 0 Buffer1 is greater than Buffer2\r
**/\r
INTN\r
+EFIAPI\r
DevicePathCompare (\r
- IN VOID *Buffer1,\r
- IN VOID *Buffer2\r
+ IN CONST VOID *Buffer1,\r
+ IN CONST VOID *Buffer2\r
)\r
{\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath1;\r
CHAR16 *TextPath2;\r
EFI_STATUS Status;\r
INTN RetVal;\r
- \r
- STATIC EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToText = NULL;\r
- STATIC EFI_UNICODE_COLLATION_PROTOCOL *UnicodeCollation = NULL;\r
\r
DevicePath1 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer1;\r
DevicePath2 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer2;\r
if (DevicePath2 == NULL) {\r
return 1;\r
}\r
- \r
- if (DevicePathToText == NULL) {\r
- Status = gBS->LocateProtocol(\r
- &gEfiDevicePathToTextProtocolGuid,\r
- NULL,\r
- (VOID**)&DevicePathToText);\r
-\r
- ASSERT_EFI_ERROR(Status);\r
- }\r
\r
- if (UnicodeCollation == NULL) {\r
+ if (mUnicodeCollation == NULL) {\r
Status = gBS->LocateProtocol(\r
&gEfiUnicodeCollation2ProtocolGuid,\r
NULL,\r
- (VOID**)&UnicodeCollation);\r
+ (VOID**)&mUnicodeCollation);\r
\r
ASSERT_EFI_ERROR(Status);\r
}\r
\r
- TextPath1 = DevicePathToText->ConvertDevicePathToText(\r
+ TextPath1 = ConvertDevicePathToText(\r
DevicePath1,\r
FALSE,\r
FALSE);\r
\r
- TextPath2 = DevicePathToText->ConvertDevicePathToText(\r
+ TextPath2 = ConvertDevicePathToText(\r
DevicePath2,\r
FALSE,\r
FALSE);\r
- \r
- RetVal = UnicodeCollation->StriColl(\r
- UnicodeCollation,\r
- TextPath1,\r
- TextPath2);\r
\r
- FreePool(TextPath1);\r
- FreePool(TextPath2);\r
+ if (TextPath1 == NULL) {\r
+ RetVal = -1;\r
+ } else if (TextPath2 == NULL) {\r
+ RetVal = 1;\r
+ } else {\r
+ RetVal = mUnicodeCollation->StriColl(\r
+ mUnicodeCollation,\r
+ TextPath1,\r
+ TextPath2);\r
+ }\r
+\r
+ SHELL_FREE_NON_NULL(TextPath1);\r
+ SHELL_FREE_NON_NULL(TextPath2);\r
\r
return (RetVal);\r
-}
\ No newline at end of file
+}\r
+\r
+/**\r
+ Function to compare 2 strings without regard to case of the characters.\r
+\r
+ @param[in] Buffer1 Pointer to String to compare.\r
+ @param[in] Buffer2 Pointer to second String to compare.\r
+\r
+ @retval 0 Buffer1 equal to Buffer2.\r
+ @return < 0 Buffer1 is less than Buffer2.\r
+ @return > 0 Buffer1 is greater than Buffer2.\r
+**/\r
+INTN\r
+EFIAPI\r
+StringNoCaseCompare (\r
+ IN CONST VOID *Buffer1,\r
+ IN CONST VOID *Buffer2\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ if (mUnicodeCollation == NULL) {\r
+ Status = gBS->LocateProtocol(\r
+ &gEfiUnicodeCollation2ProtocolGuid,\r
+ NULL,\r
+ (VOID**)&mUnicodeCollation);\r
+\r
+ ASSERT_EFI_ERROR(Status);\r
+ }\r
+\r
+ return (mUnicodeCollation->StriColl(\r
+ mUnicodeCollation,\r
+ *(CHAR16**)Buffer1,\r
+ *(CHAR16**)Buffer2));\r
+}\r
+\r
+\r
+/**\r
+ Function to compare 2 strings.\r
+\r
+ @param[in] Buffer1 Pointer to String to compare (CHAR16**).\r
+ @param[in] Buffer2 Pointer to second String to compare (CHAR16**).\r
+\r
+ @retval 0 Buffer1 equal to Buffer2.\r
+ @return < 0 Buffer1 is less than Buffer2.\r
+ @return > 0 Buffer1 is greater than Buffer2.\r
+**/\r
+INTN\r
+EFIAPI\r
+StringCompare (\r
+ IN CONST VOID *Buffer1,\r
+ IN CONST VOID *Buffer2\r
+ )\r
+{\r
+ return (StrCmp(\r
+ *(CHAR16**)Buffer1,\r
+ *(CHAR16**)Buffer2));\r
+}\r