/** @file | |
Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR> | |
This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
Module Name: | |
MemoryFile.c | |
Abstract: | |
This contains some useful functions for accessing files. | |
**/ | |
#include <assert.h> | |
#include <string.h> | |
#include <ctype.h> | |
#include <stdlib.h> | |
#include "CommonLib.h" | |
#include "MemoryFile.h" | |
// | |
// Local (static) function prototypes | |
// | |
STATIC | |
VOID | |
CheckMemoryFileState ( | |
IN EFI_HANDLE InputMemoryFile | |
); | |
// | |
// Function implementations | |
// | |
EFI_STATUS | |
GetMemoryFile ( | |
IN CHAR8 *InputFileName, | |
OUT EFI_HANDLE *OutputMemoryFile | |
) | |
/*++ | |
Routine Description: | |
This opens a file, reads it into memory and returns a memory file | |
object. | |
Arguments: | |
InputFile Memory file image. | |
OutputMemoryFile Handle to memory file | |
Returns: | |
EFI_STATUS | |
OutputMemoryFile is valid if !EFI_ERROR | |
--*/ | |
{ | |
EFI_STATUS Status; | |
CHAR8 *InputFileImage; | |
UINT32 BytesRead; | |
MEMORY_FILE *NewMemoryFile; | |
Status = GetFileImage (InputFileName, &InputFileImage, &BytesRead); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
NewMemoryFile = malloc (sizeof (*NewMemoryFile)); | |
if (NewMemoryFile == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
NewMemoryFile->FileImage = InputFileImage; | |
NewMemoryFile->CurrentFilePointer = InputFileImage; | |
NewMemoryFile->Eof = InputFileImage + BytesRead; | |
*OutputMemoryFile = (EFI_HANDLE)NewMemoryFile; | |
CheckMemoryFileState (*OutputMemoryFile); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
FreeMemoryFile ( | |
IN EFI_HANDLE InputMemoryFile | |
) | |
/*++ | |
Routine Description: | |
Frees all memory associated with the input memory file. | |
Arguments: | |
InputMemoryFile Handle to memory file | |
Returns: | |
EFI_STATUS | |
--*/ | |
{ | |
MEMORY_FILE *MemoryFile; | |
CheckMemoryFileState (InputMemoryFile); | |
MemoryFile = (MEMORY_FILE*)InputMemoryFile; | |
free (MemoryFile->FileImage); | |
// | |
// Invalidate state of MEMORY_FILE structure to catch invalid usage. | |
// | |
memset (MemoryFile, 0xcc, sizeof (*MemoryFile)); | |
MemoryFile->Eof -= 1; | |
free (MemoryFile); | |
return EFI_SUCCESS; | |
} | |
CHAR8 * | |
ReadMemoryFileLine ( | |
IN EFI_HANDLE InputMemoryFile | |
) | |
/*++ | |
Routine Description: | |
This function reads a line from the memory file. The newline characters | |
are stripped and a null terminated string is returned. | |
If the string pointer returned is non-NULL, then the caller must free the | |
memory associated with this string. | |
Arguments: | |
InputMemoryFile Handle to memory file | |
Returns: | |
NULL if error or EOF | |
NULL character termincated string otherwise (MUST BE FREED BY CALLER) | |
--*/ | |
{ | |
CHAR8 *EndOfLine; | |
UINTN CharsToCopy; | |
MEMORY_FILE *InputFile; | |
UINTN BytesToEof; | |
CHAR8 *OutputString; | |
// | |
// Verify input parameters are not null | |
// | |
CheckMemoryFileState (InputMemoryFile); | |
InputFile = (MEMORY_FILE*)InputMemoryFile; | |
// | |
// Check for end of file condition | |
// | |
if (InputFile->CurrentFilePointer >= InputFile->Eof) { | |
return NULL; | |
} | |
// | |
// Determine the number of bytes remaining until the EOF | |
// | |
BytesToEof = InputFile->Eof - InputFile->CurrentFilePointer; | |
// | |
// Find the next newline char | |
// | |
EndOfLine = memchr (InputFile->CurrentFilePointer, '\n', BytesToEof); | |
// | |
// Determine the number of characters to copy. | |
// | |
if (EndOfLine == 0) { | |
// | |
// If no newline found, copy to the end of the file. | |
// | |
CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer; | |
} else { | |
// | |
// Newline found in the file. | |
// | |
CharsToCopy = EndOfLine - InputFile->CurrentFilePointer; | |
} | |
OutputString = malloc (CharsToCopy); | |
if (OutputString == NULL) { | |
return NULL; | |
} | |
// | |
// Copy the line. | |
// | |
memcpy (OutputString, InputFile->CurrentFilePointer, CharsToCopy); | |
// | |
// Add the null termination over the 0x0D | |
// | |
if (OutputString[CharsToCopy - 1] == '\r') { | |
OutputString[CharsToCopy - 1] = '\0'; | |
} else { | |
OutputString[CharsToCopy] = '\0'; | |
} | |
// | |
// Increment the current file pointer (include the 0x0A) | |
// | |
InputFile->CurrentFilePointer += CharsToCopy + 1; | |
CheckMemoryFileState (InputMemoryFile); | |
// | |
// Return the string | |
// | |
return OutputString; | |
} | |
STATIC | |
VOID | |
CheckMemoryFileState ( | |
IN EFI_HANDLE InputMemoryFile | |
) | |
{ | |
MEMORY_FILE *MemoryFile; | |
assert (InputMemoryFile != NULL); | |
MemoryFile = (MEMORY_FILE*)InputMemoryFile; | |
assert (MemoryFile->FileImage != NULL); | |
assert (MemoryFile->CurrentFilePointer != NULL); | |
assert (MemoryFile->Eof != NULL); | |
assert (MemoryFile->Eof >= MemoryFile->FileImage); | |
assert (MemoryFile->CurrentFilePointer >= MemoryFile->FileImage); | |
assert (MemoryFile->CurrentFilePointer <= MemoryFile->Eof); | |
} | |