root/lib/lang/fileutil.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _load_file
  2. load_file_to_length
  3. load_file
  4. process_file
  5. load_int_value_file
  6. save_int_value_file

   1 #include "stdlib.h"
   2 #include "stddef.h"
   3 #include "string.h"
   4 #include "fileutil.h"
   5 
   6 // PURPOSE:
   7 // Universal file loader: alloc space in uncached memory and load file
   8 // Allocates 1 extra byte and terminates loaded data with a 0 if 'add0' == 1
   9 // If non-zero value passed in *st_size, then at most *st_size bytes read
  10 // RETURN:
  11 //  pointer to loaded file (0 if fail)
  12 //      stat() size stored in st_size (-1 if no file)
  13 //              read() size stored in rv_size (-1 if no file)
  14 //          
  15 //-------------------------------------------------------------------
  16 static char* _load_file(const char* name, int* rv_size, int* st_size, int add0)
  17 {
  18         int fd;
  19         int ssize = -1;     // stat() size
  20     int rsize = -1;     // # of bytes actually read
  21         char* buf = 0;      // memory buffer to return
  22 
  23     if (add0 != 0) add0 = 1; // Sanity check
  24 
  25         // get file stats
  26         struct stat st;
  27     if (stat(name,&st) == 0)
  28     {
  29         // get file size & check size is valid
  30                 ssize = st.st_size;
  31                 if ((st_size != 0) && (*st_size > 0) && (ssize > *st_size))       // Limit size read to the size requested
  32                     ssize = *st_size;
  33             if (ssize > 0)
  34         {
  35             // open file & check file is valid
  36                 fd = open( name, O_RDONLY, 0777 );
  37                 if (fd >= 0)
  38             {
  39                 // allocate uncached buffer to read into & check valid
  40                 char *ubuf = umalloc(512);
  41                     if (ubuf != 0)
  42                 {
  43                     // allocate output buffer and check valid
  44                     // add 1 to file size if terminating 0 is required
  45                     buf = malloc(ssize+add0);
  46                     if (buf != 0)
  47                     {
  48                         // loop over file reading in 512 bytes chunks
  49                         int lsize = 0;
  50                         rsize = 0;
  51                         while (lsize < ssize)
  52                         {
  53                             int len = ssize - lsize;
  54                             if (len > 512) len = 512;
  55                             rsize += read(fd, ubuf, len);
  56                             memcpy(buf+lsize,ubuf,len);
  57                             lsize += len;
  58                         }
  59                         if (add0) buf[ssize] = 0;
  60                     }
  61                     ufree(ubuf);
  62                     }
  63                     close(fd);
  64             }
  65         }
  66     }
  67 
  68     // save stat() size and read() size
  69     if (rv_size) *rv_size = rsize;
  70     if (st_size) *st_size = ssize;
  71 
  72         return buf;
  73 }
  74 
  75 // Use _load_file to read length bytes from a file into memory
  76 // Set length = 0 to read entire file
  77 // Returns:
  78 //      read() size in *rv_size
  79 //      memory buffer allocated (caller must free buffer)
  80 //-------------------------------------------------------------------
  81 char* load_file_to_length(const char* name, int* rv_size, int add0, int length)
  82 {
  83         int rsize, ssize = length;
  84 
  85         char* buf = _load_file(name, &rsize, &ssize, add0);
  86 
  87     if (rv_size) *rv_size = rsize;
  88 
  89         if (rsize != ssize)
  90     {
  91         if (buf) free(buf);
  92         buf = 0;
  93         if (rv_size) *rv_size = -1;
  94     }
  95 
  96         return buf;
  97 }
  98 
  99 // Use _load_file to read a file into memory
 100 // Returns:
 101 //      read() size in *rv_size
 102 //      memory buffer allocated (caller must free buffer)
 103 //-------------------------------------------------------------------
 104 char* load_file(const char* name, int* rv_size, int add0)
 105 {
 106     return load_file_to_length(name, rv_size, add0, 0);
 107 }
 108 
 109 // PURPOSE:
 110 // Universal file processor
 111 // Load file, process by callback, unalloc/close file
 112 // RETURN:
 113 //       Transfer return value from callback
 114 // NOTE:
 115 //       Call callback even if fail to load/malloc (size=-1 if no file, size=0 if empty) 
 116 //-------------------------------------------------------------------
 117 int process_file(const char *filename, callback_process_file callback, int add0)
 118 {
 119     int size;
 120 
 121     char *buf = load_file(filename, &size, add0);
 122 
 123         size = callback(buf, size);
 124 
 125         if (buf)
 126                 free(buf);
 127 
 128         return size;
 129 }
 130 
 131 //-------------------------------------------------------------------
 132 
 133 // PURPOSE: Load content to *value_p if file exist and contain number
 134 // RETURN: 0-file_not_exist_or_failed (value is not changed), 1-ok
 135 
 136 int load_int_value_file( const char* filename, int* value_p )
 137 {
 138         char *buf;
 139 
 140         buf = load_file(filename, 0, 1);
 141         if (!buf)
 142            return 0;
 143         
 144         if (value_p)    
 145                 *value_p = strtol(buf, NULL, 10 /*dec*/);
 146         free(buf);
 147 
 148         return 1;
 149 }
 150 
 151 // PURPOSE: Save integer "value" to text file with name "filename"
 152 
 153 void save_int_value_file( const char* filename, int value )
 154 {
 155         char* buf = umalloc(20);
 156         if ( !buf )
 157                 return;
 158 
 159         sprintf(buf,"%d", value);
 160 
 161         int fd = open( filename, O_WRONLY|O_CREAT|O_TRUNC, 0777);
 162         if (fd>=0) 
 163         {
 164                 write(fd, buf, strlen(buf)+1);
 165                 close(fd);
 166         } 
 167         ufree(buf);
 168 }
 169 
 170 //-------------------------------------------------------------------

/* [<][>][^][v][top][bottom][index][help] */