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