]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLib/UefiShellLib.c
Move the 2 functions associated with reading whole lines at a single time from the...
[mirror_edk2.git] / ShellPkg / Library / UefiShellLib / UefiShellLib.c
index fa86d72ce4b056cad775bf4edf5828f75ee3642c..3c1b983a6028526787ef0f07f91d97f04cf14c57 100644 (file)
@@ -3808,3 +3808,154 @@ ShellIsHexOrDecimalNumber (
   }\r
   return (FALSE);\r
 }\r
+\r
+/**\r
+  Function to read a single line from a SHELL_FILE_HANDLE. The \n is not included in the returned\r
+  buffer.  The returned buffer must be callee freed.\r
+\r
+  If the position upon start is 0, then the Ascii Boolean will be set.  This should be\r
+  maintained and not changed for all operations with the same file.\r
+\r
+  @param[in]      Handle        SHELL_FILE_HANDLE to read from.\r
+  @param[in,out]  Ascii         Boolean value for indicating whether the file is\r
+                                Ascii (TRUE) or UCS2 (FALSE).\r
+\r
+  @return                       The line of text from the file.\r
+\r
+  @sa ShellFileHandleReadLine\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+ShellFileHandleReturnLine(\r
+  IN SHELL_FILE_HANDLE            Handle,\r
+  IN OUT BOOLEAN                *Ascii\r
+  )\r
+{\r
+  CHAR16          *RetVal;\r
+  UINTN           Size;\r
+  EFI_STATUS      Status;\r
+\r
+  Size = 0;\r
+  RetVal = NULL;\r
+\r
+  Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    RetVal = AllocateZeroPool(Size);\r
+    Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
+  }\r
+  ASSERT_EFI_ERROR(Status);\r
+  if (EFI_ERROR(Status) && (RetVal != NULL)) {\r
+    FreePool(RetVal);\r
+    RetVal = NULL;\r
+  }\r
+  return (RetVal);\r
+}\r
+\r
+/**\r
+  Function to read a single line (up to but not including the \n) from a SHELL_FILE_HANDLE.\r
+\r
+  If the position upon start is 0, then the Ascii Boolean will be set.  This should be\r
+  maintained and not changed for all operations with the same file.\r
+\r
+  @param[in]      Handle        SHELL_FILE_HANDLE to read from.\r
+  @param[in,out]  Buffer        The pointer to buffer to read into.\r
+  @param[in,out]  Size          The pointer to number of bytes in Buffer.\r
+  @param[in]      Truncate      If the buffer is large enough, this has no effect.\r
+                                If the buffer is is too small and Truncate is TRUE,\r
+                                the line will be truncated.\r
+                                If the buffer is is too small and Truncate is FALSE,\r
+                                then no read will occur.\r
+\r
+  @param[in,out]  Ascii         Boolean value for indicating whether the file is\r
+                                Ascii (TRUE) or UCS2 (FALSE).\r
+\r
+  @retval EFI_SUCCESS           The operation was successful.  The line is stored in\r
+                                Buffer.\r
+  @retval EFI_INVALID_PARAMETER Handle was NULL.\r
+  @retval EFI_INVALID_PARAMETER Size was NULL.\r
+  @retval EFI_BUFFER_TOO_SMALL  Size was not large enough to store the line.\r
+                                Size was updated to the minimum space required.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFileHandleReadLine(\r
+  IN SHELL_FILE_HANDLE          Handle,\r
+  IN OUT CHAR16                 *Buffer,\r
+  IN OUT UINTN                  *Size,\r
+  IN BOOLEAN                    Truncate,\r
+  IN OUT BOOLEAN                *Ascii\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  CHAR16      CharBuffer;\r
+  UINTN       CharSize;\r
+  UINTN       CountSoFar;\r
+  UINT64      OriginalFilePosition;\r
+\r
+\r
+  if (Handle == NULL\r
+    ||Size   == NULL\r
+   ){\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+  if (Buffer == NULL) {\r
+    ASSERT(*Size == 0);\r
+  } else {\r
+    *Buffer = CHAR_NULL;\r
+  }\r
+  gEfiShellProtocol->GetFilePosition(Handle, &OriginalFilePosition);\r
+  if (OriginalFilePosition == 0) {\r
+    CharSize = sizeof(CHAR16);\r
+    Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
+    ASSERT_EFI_ERROR(Status);\r
+    if (CharBuffer == gUnicodeFileTag) {\r
+      *Ascii = FALSE;\r
+    } else {\r
+      *Ascii = TRUE;\r
+      gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
+    }\r
+  }\r
+\r
+  for (CountSoFar = 0;;CountSoFar++){\r
+    CharBuffer = 0;\r
+    if (*Ascii) {\r
+      CharSize = sizeof(CHAR8);\r
+    } else {\r
+      CharSize = sizeof(CHAR16);\r
+    }\r
+    Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
+    if (  EFI_ERROR(Status)\r
+       || CharSize == 0\r
+       || (CharBuffer == L'\n' && !(*Ascii))\r
+       || (CharBuffer ==  '\n' && *Ascii)\r
+     ){\r
+      break;\r
+    }\r
+    //\r
+    // if we have space save it...\r
+    //\r
+    if ((CountSoFar+1)*sizeof(CHAR16) < *Size){\r
+      ASSERT(Buffer != NULL);\r
+      ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;\r
+      ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  // if we ran out of space tell when...\r
+  //\r
+  if ((CountSoFar+1)*sizeof(CHAR16) > *Size){\r
+    *Size = (CountSoFar+1)*sizeof(CHAR16);\r
+    if (!Truncate) {\r
+      gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
+    } else {\r
+      DEBUG((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine"));\r
+    }\r
+    return (EFI_BUFFER_TOO_SMALL);\r
+  }\r
+  while(Buffer[StrLen(Buffer)-1] == L'\r') {\r
+    Buffer[StrLen(Buffer)-1] = CHAR_NULL;\r
+  }\r
+\r
+  return (Status);\r
+}\r