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

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