1 /** @file
2 This contains some useful functions for accessing files.
3
4 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <assert.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <stdlib.h>
19 #include "CommonLib.h"
20 #include "MemoryFile.h"
21
22
23 //
24 // Local (static) function prototypes
25 //
26 STATIC
27 VOID
28 CheckMemoryFileState (
29 IN EFI_HANDLE InputMemoryFile
30 );
31
32 //
33 // Function implementations
34 //
35
36 EFI_STATUS
GetMemoryFile(IN CHAR8 * InputFileName,OUT EFI_HANDLE * OutputMemoryFile)37 GetMemoryFile (
38 IN CHAR8 *InputFileName,
39 OUT EFI_HANDLE *OutputMemoryFile
40 )
41 /*++
42
43 Routine Description:
44
45 This opens a file, reads it into memory and returns a memory file
46 object.
47
48 Arguments:
49
50 InputFile Memory file image.
51 OutputMemoryFile Handle to memory file
52
53 Returns:
54
55 EFI_STATUS
56 OutputMemoryFile is valid if !EFI_ERROR
57
58 --*/
59 {
60 EFI_STATUS Status;
61 CHAR8 *InputFileImage;
62 UINT32 BytesRead;
63 MEMORY_FILE *NewMemoryFile;
64
65 Status = GetFileImage (InputFileName, &InputFileImage, &BytesRead);
66 if (EFI_ERROR (Status)) {
67 return Status;
68 }
69
70 NewMemoryFile = malloc (sizeof (*NewMemoryFile));
71 if (NewMemoryFile == NULL) {
72 return EFI_OUT_OF_RESOURCES;
73 }
74
75 NewMemoryFile->FileImage = InputFileImage;
76 NewMemoryFile->CurrentFilePointer = InputFileImage;
77 NewMemoryFile->Eof = InputFileImage + BytesRead;
78
79 *OutputMemoryFile = (EFI_HANDLE)NewMemoryFile;
80
81 CheckMemoryFileState (*OutputMemoryFile);
82
83 return EFI_SUCCESS;
84 }
85
86
87 EFI_STATUS
FreeMemoryFile(IN EFI_HANDLE InputMemoryFile)88 FreeMemoryFile (
89 IN EFI_HANDLE InputMemoryFile
90 )
91 /*++
92
93 Routine Description:
94
95 Frees all memory associated with the input memory file.
96
97 Arguments:
98
99 InputMemoryFile Handle to memory file
100
101 Returns:
102
103 EFI_STATUS
104
105 --*/
106 {
107 MEMORY_FILE *MemoryFile;
108
109 CheckMemoryFileState (InputMemoryFile);
110
111 MemoryFile = (MEMORY_FILE*)InputMemoryFile;
112
113 free (MemoryFile->FileImage);
114
115 //
116 // Invalidate state of MEMORY_FILE structure to catch invalid usage.
117 //
118 memset (MemoryFile, 0xcc, sizeof (*MemoryFile));
119 MemoryFile->Eof -= 1;
120
121 free (MemoryFile);
122
123 return EFI_SUCCESS;
124 }
125
126
127 CHAR8 *
ReadMemoryFileLine(IN EFI_HANDLE InputMemoryFile)128 ReadMemoryFileLine (
129 IN EFI_HANDLE InputMemoryFile
130 )
131 /*++
132
133 Routine Description:
134
135 This function reads a line from the memory file. The newline characters
136 are stripped and a null terminated string is returned.
137
138 If the string pointer returned is non-NULL, then the caller must free the
139 memory associated with this string.
140
141 Arguments:
142
143 InputMemoryFile Handle to memory file
144
145 Returns:
146
147 NULL if error or EOF
148 NULL character termincated string otherwise (MUST BE FREED BY CALLER)
149
150 --*/
151 {
152 CHAR8 *EndOfLine;
153 UINTN CharsToCopy;
154 MEMORY_FILE *InputFile;
155 UINTN BytesToEof;
156 CHAR8 *OutputString;
157
158 //
159 // Verify input parameters are not null
160 //
161 CheckMemoryFileState (InputMemoryFile);
162
163 InputFile = (MEMORY_FILE*)InputMemoryFile;
164
165 //
166 // Check for end of file condition
167 //
168 if (InputFile->CurrentFilePointer >= InputFile->Eof) {
169 return NULL;
170 }
171
172 //
173 // Determine the number of bytes remaining until the EOF
174 //
175 BytesToEof = InputFile->Eof - InputFile->CurrentFilePointer;
176
177 //
178 // Find the next newline char
179 //
180 EndOfLine = memchr (InputFile->CurrentFilePointer, '\n', BytesToEof);
181
182 //
183 // Determine the number of characters to copy.
184 //
185 if (EndOfLine == 0) {
186 //
187 // If no newline found, copy to the end of the file.
188 //
189 CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;
190 } else {
191 //
192 // Newline found in the file.
193 //
194 CharsToCopy = EndOfLine - InputFile->CurrentFilePointer;
195 }
196
197 OutputString = malloc (CharsToCopy + 1);
198 if (OutputString == NULL) {
199 return NULL;
200 }
201
202 //
203 // Copy the line.
204 //
205 memcpy (OutputString, InputFile->CurrentFilePointer, CharsToCopy);
206
207 //
208 // Add the null termination over the 0x0D
209 //
210 if (OutputString[CharsToCopy - 1] == '\r') {
211
212 OutputString[CharsToCopy - 1] = '\0';
213
214 } else {
215
216 OutputString[CharsToCopy] = '\0';
217
218 }
219
220 //
221 // Increment the current file pointer (include the 0x0A)
222 //
223 InputFile->CurrentFilePointer += CharsToCopy + 1;
224 CheckMemoryFileState (InputMemoryFile);
225
226 //
227 // Return the string
228 //
229 return OutputString;
230 }
231
232
233 STATIC
234 VOID
CheckMemoryFileState(IN EFI_HANDLE InputMemoryFile)235 CheckMemoryFileState (
236 IN EFI_HANDLE InputMemoryFile
237 )
238 {
239 MEMORY_FILE *MemoryFile;
240
241 assert (InputMemoryFile != NULL);
242
243 MemoryFile = (MEMORY_FILE*)InputMemoryFile;
244
245 assert (MemoryFile->FileImage != NULL);
246 assert (MemoryFile->CurrentFilePointer != NULL);
247 assert (MemoryFile->Eof != NULL);
248 assert (MemoryFile->Eof >= MemoryFile->FileImage);
249 assert (MemoryFile->CurrentFilePointer >= MemoryFile->FileImage);
250 assert (MemoryFile->CurrentFilePointer <= MemoryFile->Eof);
251 }
252
253
254