MemoryFile.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /** @file
  2. This contains some useful functions for accessing files.
  3. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <assert.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <stdlib.h>
  10. #include "CommonLib.h"
  11. #include "MemoryFile.h"
  12. //
  13. // Local (static) function prototypes
  14. //
  15. STATIC
  16. VOID
  17. CheckMemoryFileState (
  18. IN EFI_HANDLE InputMemoryFile
  19. );
  20. //
  21. // Function implementations
  22. //
  23. EFI_STATUS
  24. GetMemoryFile (
  25. IN CHAR8 *InputFileName,
  26. OUT EFI_HANDLE *OutputMemoryFile
  27. )
  28. /*++
  29. Routine Description:
  30. This opens a file, reads it into memory and returns a memory file
  31. object.
  32. Arguments:
  33. InputFile Memory file image.
  34. OutputMemoryFile Handle to memory file
  35. Returns:
  36. EFI_STATUS
  37. OutputMemoryFile is valid if !EFI_ERROR
  38. --*/
  39. {
  40. EFI_STATUS Status;
  41. CHAR8 *InputFileImage;
  42. UINT32 BytesRead;
  43. MEMORY_FILE *NewMemoryFile;
  44. Status = GetFileImage (InputFileName, &InputFileImage, &BytesRead);
  45. if (EFI_ERROR (Status)) {
  46. return Status;
  47. }
  48. NewMemoryFile = malloc (sizeof (*NewMemoryFile));
  49. if (NewMemoryFile == NULL) {
  50. free (InputFileImage);
  51. return EFI_OUT_OF_RESOURCES;
  52. }
  53. NewMemoryFile->FileImage = InputFileImage;
  54. NewMemoryFile->CurrentFilePointer = InputFileImage;
  55. NewMemoryFile->Eof = InputFileImage + BytesRead;
  56. *OutputMemoryFile = (EFI_HANDLE)NewMemoryFile;
  57. CheckMemoryFileState (*OutputMemoryFile);
  58. return EFI_SUCCESS;
  59. }
  60. EFI_STATUS
  61. FreeMemoryFile (
  62. IN EFI_HANDLE InputMemoryFile
  63. )
  64. /*++
  65. Routine Description:
  66. Frees all memory associated with the input memory file.
  67. Arguments:
  68. InputMemoryFile Handle to memory file
  69. Returns:
  70. EFI_STATUS
  71. --*/
  72. {
  73. MEMORY_FILE *MemoryFile;
  74. CheckMemoryFileState (InputMemoryFile);
  75. MemoryFile = (MEMORY_FILE*)InputMemoryFile;
  76. free (MemoryFile->FileImage);
  77. //
  78. // Invalidate state of MEMORY_FILE structure to catch invalid usage.
  79. //
  80. memset (MemoryFile, 0xcc, sizeof (*MemoryFile));
  81. MemoryFile->Eof -= 1;
  82. free (MemoryFile);
  83. return EFI_SUCCESS;
  84. }
  85. CHAR8 *
  86. ReadMemoryFileLine (
  87. IN EFI_HANDLE InputMemoryFile
  88. )
  89. /*++
  90. Routine Description:
  91. This function reads a line from the memory file. The newline characters
  92. are stripped and a null terminated string is returned.
  93. If the string pointer returned is non-NULL, then the caller must free the
  94. memory associated with this string.
  95. Arguments:
  96. InputMemoryFile Handle to memory file
  97. Returns:
  98. NULL if error or EOF
  99. NULL character termincated string otherwise (MUST BE FREED BY CALLER)
  100. --*/
  101. {
  102. CHAR8 *EndOfLine;
  103. UINTN CharsToCopy;
  104. MEMORY_FILE *InputFile;
  105. UINTN BytesToEof;
  106. CHAR8 *OutputString;
  107. //
  108. // Verify input parameters are not null
  109. //
  110. CheckMemoryFileState (InputMemoryFile);
  111. InputFile = (MEMORY_FILE*)InputMemoryFile;
  112. //
  113. // Check for end of file condition
  114. //
  115. if (InputFile->CurrentFilePointer >= InputFile->Eof) {
  116. return NULL;
  117. }
  118. //
  119. // Determine the number of bytes remaining until the EOF
  120. //
  121. BytesToEof = InputFile->Eof - InputFile->CurrentFilePointer;
  122. //
  123. // Find the next newline char
  124. //
  125. EndOfLine = memchr (InputFile->CurrentFilePointer, '\n', BytesToEof);
  126. //
  127. // Determine the number of characters to copy.
  128. //
  129. if (EndOfLine == 0) {
  130. //
  131. // If no newline found, copy to the end of the file.
  132. //
  133. CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;
  134. } else {
  135. //
  136. // Newline found in the file.
  137. //
  138. CharsToCopy = EndOfLine - InputFile->CurrentFilePointer;
  139. }
  140. OutputString = malloc (CharsToCopy + 1);
  141. if (OutputString == NULL) {
  142. return NULL;
  143. }
  144. //
  145. // Copy the line.
  146. //
  147. memcpy (OutputString, InputFile->CurrentFilePointer, CharsToCopy);
  148. //
  149. // Add the null termination over the 0x0D
  150. //
  151. if (OutputString[CharsToCopy - 1] == '\r') {
  152. OutputString[CharsToCopy - 1] = '\0';
  153. } else {
  154. OutputString[CharsToCopy] = '\0';
  155. }
  156. //
  157. // Increment the current file pointer (include the 0x0A)
  158. //
  159. InputFile->CurrentFilePointer += CharsToCopy + 1;
  160. if (InputFile->CurrentFilePointer > InputFile->Eof) {
  161. InputFile->CurrentFilePointer = InputFile->Eof;
  162. }
  163. CheckMemoryFileState (InputMemoryFile);
  164. //
  165. // Return the string
  166. //
  167. return OutputString;
  168. }
  169. STATIC
  170. VOID
  171. CheckMemoryFileState (
  172. IN EFI_HANDLE InputMemoryFile
  173. )
  174. {
  175. MEMORY_FILE *MemoryFile;
  176. assert (InputMemoryFile != NULL);
  177. MemoryFile = (MEMORY_FILE*)InputMemoryFile;
  178. assert (MemoryFile->FileImage != NULL);
  179. assert (MemoryFile->CurrentFilePointer != NULL);
  180. assert (MemoryFile->Eof != NULL);
  181. assert (MemoryFile->Eof >= MemoryFile->FileImage);
  182. assert (MemoryFile->CurrentFilePointer >= MemoryFile->FileImage);
  183. assert (MemoryFile->CurrentFilePointer <= MemoryFile->Eof);
  184. }