]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/MemoryFile.c
ec27619abbb09a0b440665e3fbb593cbf598e461
[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 - 2016, 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
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 free (InputFileImage);
73 return EFI_OUT_OF_RESOURCES;
74 }
75
76 NewMemoryFile->FileImage = InputFileImage;
77 NewMemoryFile->CurrentFilePointer = InputFileImage;
78 NewMemoryFile->Eof = InputFileImage + BytesRead;
79
80 *OutputMemoryFile = (EFI_HANDLE)NewMemoryFile;
81
82 CheckMemoryFileState (*OutputMemoryFile);
83
84 return EFI_SUCCESS;
85 }
86
87
88 EFI_STATUS
89 FreeMemoryFile (
90 IN EFI_HANDLE InputMemoryFile
91 )
92 /*++
93
94 Routine Description:
95
96 Frees all memory associated with the input memory file.
97
98 Arguments:
99
100 InputMemoryFile Handle to memory file
101
102 Returns:
103
104 EFI_STATUS
105
106 --*/
107 {
108 MEMORY_FILE *MemoryFile;
109
110 CheckMemoryFileState (InputMemoryFile);
111
112 MemoryFile = (MEMORY_FILE*)InputMemoryFile;
113
114 free (MemoryFile->FileImage);
115
116 //
117 // Invalidate state of MEMORY_FILE structure to catch invalid usage.
118 //
119 memset (MemoryFile, 0xcc, sizeof (*MemoryFile));
120 MemoryFile->Eof -= 1;
121
122 free (MemoryFile);
123
124 return EFI_SUCCESS;
125 }
126
127
128 CHAR8 *
129 ReadMemoryFileLine (
130 IN EFI_HANDLE InputMemoryFile
131 )
132 /*++
133
134 Routine Description:
135
136 This function reads a line from the memory file. The newline characters
137 are stripped and a null terminated string is returned.
138
139 If the string pointer returned is non-NULL, then the caller must free the
140 memory associated with this string.
141
142 Arguments:
143
144 InputMemoryFile Handle to memory file
145
146 Returns:
147
148 NULL if error or EOF
149 NULL character termincated string otherwise (MUST BE FREED BY CALLER)
150
151 --*/
152 {
153 CHAR8 *EndOfLine;
154 UINTN CharsToCopy;
155 MEMORY_FILE *InputFile;
156 UINTN BytesToEof;
157 CHAR8 *OutputString;
158
159 //
160 // Verify input parameters are not null
161 //
162 CheckMemoryFileState (InputMemoryFile);
163
164 InputFile = (MEMORY_FILE*)InputMemoryFile;
165
166 //
167 // Check for end of file condition
168 //
169 if (InputFile->CurrentFilePointer >= InputFile->Eof) {
170 return NULL;
171 }
172
173 //
174 // Determine the number of bytes remaining until the EOF
175 //
176 BytesToEof = InputFile->Eof - InputFile->CurrentFilePointer;
177
178 //
179 // Find the next newline char
180 //
181 EndOfLine = memchr (InputFile->CurrentFilePointer, '\n', BytesToEof);
182
183 //
184 // Determine the number of characters to copy.
185 //
186 if (EndOfLine == 0) {
187 //
188 // If no newline found, copy to the end of the file.
189 //
190 CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;
191 } else {
192 //
193 // Newline found in the file.
194 //
195 CharsToCopy = EndOfLine - InputFile->CurrentFilePointer;
196 }
197
198 OutputString = malloc (CharsToCopy + 1);
199 if (OutputString == NULL) {
200 return NULL;
201 }
202
203 //
204 // Copy the line.
205 //
206 memcpy (OutputString, InputFile->CurrentFilePointer, CharsToCopy);
207
208 //
209 // Add the null termination over the 0x0D
210 //
211 if (OutputString[CharsToCopy - 1] == '\r') {
212
213 OutputString[CharsToCopy - 1] = '\0';
214
215 } else {
216
217 OutputString[CharsToCopy] = '\0';
218
219 }
220
221 //
222 // Increment the current file pointer (include the 0x0A)
223 //
224 InputFile->CurrentFilePointer += CharsToCopy + 1;
225 if (InputFile->CurrentFilePointer > InputFile->Eof) {
226 InputFile->CurrentFilePointer = InputFile->Eof;
227 }
228 CheckMemoryFileState (InputMemoryFile);
229
230 //
231 // Return the string
232 //
233 return OutputString;
234 }
235
236
237 STATIC
238 VOID
239 CheckMemoryFileState (
240 IN EFI_HANDLE InputMemoryFile
241 )
242 {
243 MEMORY_FILE *MemoryFile;
244
245 assert (InputMemoryFile != NULL);
246
247 MemoryFile = (MEMORY_FILE*)InputMemoryFile;
248
249 assert (MemoryFile->FileImage != NULL);
250 assert (MemoryFile->CurrentFilePointer != NULL);
251 assert (MemoryFile->Eof != NULL);
252 assert (MemoryFile->Eof >= MemoryFile->FileImage);
253 assert (MemoryFile->CurrentFilePointer >= MemoryFile->FileImage);
254 assert (MemoryFile->CurrentFilePointer <= MemoryFile->Eof);
255 }
256
257