]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiSortLib/UefiSortLib.c
MdeModulePkg/PartitionDxe: Fixed El Torito support when the medium is not a CDROM
[mirror_edk2.git] / ShellPkg / Library / UefiSortLib / UefiSortLib.c
index 2a65f36507d09eee8ec04f6e2309903c28b8e5df..2aab9d26919eb472076d416de3c6b2ced3fb2151 100644 (file)
@@ -1,37 +1,37 @@
 /** @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_DEVICE_PATH_TO_TEXT_PROTOCOL *mDevicePathToText = NULL;\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
@@ -43,13 +43,13 @@ STATIC EFI_UNICODE_COLLATION_PROTOCOL   *mUnicodeCollation = NULL;
   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
@@ -69,9 +69,9 @@ QuickSortWorker (
   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
@@ -87,15 +87,15 @@ QuickSortWorker (
   // 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
@@ -103,7 +103,7 @@ QuickSortWorker (
 \r
       //\r
       // increment NextSwapLocation\r
-      // \r
+      //\r
       NextSwapLocation++;\r
     }\r
   }\r
@@ -115,22 +115,26 @@ QuickSortWorker (
   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
@@ -145,12 +149,12 @@ QuickSortWorker (
   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
@@ -166,7 +170,7 @@ PerformQuickSort (
   ASSERT(BufferToSort     != NULL);\r
   ASSERT(CompareFunction  != NULL);\r
 \r
-  Buffer = AllocatePool(ElementSize);\r
+  Buffer = AllocateZeroPool(ElementSize);\r
   ASSERT(Buffer != NULL);\r
 \r
   QuickSortWorker(\r
@@ -181,16 +185,17 @@ PerformQuickSort (
 }\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  CONST VOID             *Buffer1,\r
   IN  CONST VOID             *Buffer2\r
@@ -202,7 +207,7 @@ DevicePathCompare (
   CHAR16                    *TextPath2;\r
   EFI_STATUS                Status;\r
   INTN                      RetVal;\r
-   \r
+\r
   DevicePath1 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer1;\r
   DevicePath2 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer2;\r
 \r
@@ -217,15 +222,6 @@ DevicePathCompare (
   if (DevicePath2 == NULL) {\r
     return 1;\r
   }\r
-  \r
-  if (mDevicePathToText == NULL) {\r
-    Status = gBS->LocateProtocol(\r
-      &gEfiDevicePathToTextProtocolGuid,\r
-      NULL,\r
-      (VOID**)&mDevicePathToText);\r
-\r
-    ASSERT_EFI_ERROR(Status);\r
-  }\r
 \r
   if (mUnicodeCollation == NULL) {\r
     Status = gBS->LocateProtocol(\r
@@ -236,23 +232,29 @@ DevicePathCompare (
     ASSERT_EFI_ERROR(Status);\r
   }\r
 \r
-  TextPath1 = mDevicePathToText->ConvertDevicePathToText(\r
+  TextPath1 = ConvertDevicePathToText(\r
     DevicePath1,\r
     FALSE,\r
     FALSE);\r
 \r
-  TextPath2 = mDevicePathToText->ConvertDevicePathToText(\r
+  TextPath2 = ConvertDevicePathToText(\r
     DevicePath2,\r
     FALSE,\r
     FALSE);\r
-  \r
-  RetVal = mUnicodeCollation->StriColl(\r
-    mUnicodeCollation,\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
 }\r
@@ -265,7 +267,7 @@ DevicePathCompare (
 \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
@@ -291,3 +293,24 @@ StringNoCaseCompare (
 }\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