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