Home | History | Annotate | Download | only in Common
      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
     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
     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 *
    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
    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