"Fossies" - the Fresh Open Source Software Archive

Member "utrac-0.3.2/src/ut_loading.c" (4 Jan 2009, 6048 Bytes) of package /linux/privat/old/utrac-0.3.2.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ut_loading.c" see the Fossies "Dox" file reference documentation.

    1 /***************************************************************************
    2  *            ut_load.c
    3  *
    4  *  Thu Dec 23 15:53:42 2004
    5  *  Copyright  2004  Alliance MCA
    6  *  Written by : Antoine Calando (antoine@alliancemca.net)
    7  ****************************************************************************/
    8 
    9 /*
   10  *  This program is free software; you can redistribute it and/or modify
   11  *  it under the terms of the GNU General Public License as published by
   12  *  the Free Software Foundation; either version 2 of the License, or
   13  *  (at your option) any later version.
   14  *
   15  *  This program is distributed in the hope that it will be useful,
   16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18  *  GNU Library General Public License for more details.
   19  *
   20  *  You should have received a copy of the GNU General Public License
   21  *  along with this program; if not, write to the Free Software
   22  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   23  */
   24  
   25 
   26 /*!
   27  * \file ut_load.c 
   28  * \brief Loading functions
   29  * \author Antoine Calando (antoine@alliancemca.net)
   30  */
   31 
   32 #include <sys/stat.h>
   33 #include <unistd.h>
   34 #include <fcntl.h>
   35 #include <stdio.h>
   36 #include <stdlib.h>
   37 
   38 #include "utrac.h"
   39 #include "ut_text.h"
   40 
   41 //#undef UT_DEBUG
   42 //#define UT_DEBUG 2
   43 #include "debug.h"
   44 
   45 
   46 /***************************************************************************/
   47 /*!
   48  * \brief Load a text in a buffer
   49  *   
   50  * \param text  UtText structure containing eventually a pointer to a user function
   51  *              which update a progress bar. File contents will be accessible via 
   52  *              UtText::data, and size in UtText::size.
   53  * \param filename  Filename (with path) of the file to load.
   54  *
   55  * \return UT_OK on succes, error code otherwise.
   56  */
   57 UtCode ut_load_file_pass (UtText *text, const char * filename) {
   58     DBG3 ("Loading file %s...", filename)
   59     
   60     int fd = open (filename, O_RDONLY);
   61     if (fd==-1) return UT_OPEN_FILE_ERROR;
   62 
   63     struct stat f_stat;
   64     if (fstat (fd, &f_stat)) return UT_FSTAT_FILE_ERROR;
   65     text->size = f_stat.st_size;
   66     
   67     if (!text->size) return UT_EMPTY_DATA_ERROR;
   68 
   69     free (text->data);
   70     //some space is needed to add an EOL (1 or 2 bytes) if it is missing and an EOF
   71     text->data = (char*) malloc (text->size + 3);
   72     if (!text->data) return UT_MALLOC_ERROR;
   73     
   74     ulong cumul=0;
   75     bool cont = true;
   76 
   77     //if progress feature is used, read() is called with UT_LOAD_STEP several times and
   78     //can overflow the buffer allocated if read() fills it more than the size of the file
   79     while (cumul<text->size && cont) {
   80         long code=read (fd, text->data+cumul, (ut_session->progress_function)?UT_LOAD_STEP:(text->size-cumul));
   81         if (code<=0) return UT_READ_FILE_ERROR;
   82         cumul += code;
   83         if (ut_session->progress_function) cont = ut_update_progress (text, cumul, false);
   84     }
   85 
   86     
   87     if (!cont) {
   88         DBG2 ("File loading canceled by user!")
   89         free (text->data);
   90         text->data = NULL;
   91         return UT_INTERRUPTED_BY_USER;
   92     }
   93 
   94     ASSERT (cumul==text->size)
   95     DBG2 ("File %s (%lu b / %lu b) loaded!", filename, cumul, text->size)
   96     
   97     *(text->data+text->size) = UT_EOF_CHAR;
   98     *(text->data+text->size+1) = UT_EOF_CHAR;
   99     *(text->data+text->size+2) = UT_EOF_CHAR;
  100 
  101     if (close(fd)) return UT_CLOSE_FILE_ERROR;
  102         
  103     return UT_OK;
  104 }
  105 
  106 /***************************************************************************/
  107 /*!
  108  * \brief Load a text from stdin
  109  *   
  110  * \param text UtText structure used to return the loaded text, which will
  111  *        be accessible via UtText::data, and size in UtText::size. Progress function not called since
  112  *        we can't know the size of the input text before it is completely loaded.
  113  *
  114  * \return UT_OK on succes, error code otherwise.
  115  *
  116  * \note EC le buffer utilisé ici est dynamique, pourquoi ajouter 3 octets à UT_STDIN_BUFFER_SIZE
  117  *       qui doit être dimensionné à un multiple d'un bloc mémoire du système.
  118  *       AC Effectivement...
  119  * \bug  EC read() peut renvoyer 0 sans indiquer une fin de fichier (errno==EAGAIN) et le test
  120  *       while (code && cont); est donc faux !
  121  *       AC read() ne peut pas renvoyer EAGAIN si le fichier n'a pas été open() en mode EAGAIN
  122  *       (norme POSIX)
  123  */
  124 UtCode ut_load_stdin_pass (UtText *text) {
  125 
  126     //some space is needed to add an EOL (1 or 2 bytes) if it is missing and an EOF
  127     free(text->data);
  128     text->data = (char*) malloc (UT_STDIN_BUFFER_SIZE);
  129     if (!text->data) return UT_MALLOC_ERROR;
  130         
  131     struct stat f_stat;
  132     if (fstat (fileno(stdin), &f_stat)) return UT_FSTAT_FILE_ERROR;
  133     text->size = f_stat.st_size;
  134     
  135     ulong bytes_read = 0, bytes_to_read = 0;
  136     ulong buffer_size = UT_STDIN_BUFFER_SIZE;
  137     bool cont = true;
  138     
  139     //if progress feature is used, read() is called with UT_LOAD_STEP several times and
  140     //can overflow the buffer allocated if read() fills it more than the size of the file
  141     long code;
  142     do {
  143         bytes_to_read = buffer_size-bytes_read;
  144         if (ut_session->progress_function && UT_LOAD_STEP < bytes_to_read ) bytes_to_read = UT_LOAD_STEP;
  145         code = read (STDIN_FILENO, text->data + bytes_read, bytes_to_read);
  146         if (code<0) {
  147             free (text->data);
  148             text->data = NULL;
  149             return UT_READ_FILE_ERROR;
  150         }
  151         bytes_read += code;
  152 
  153         if (fstat (fileno(stdin), &f_stat)) return UT_FSTAT_FILE_ERROR;
  154         text->size = f_stat.st_size;
  155         if (ut_session->progress_function) cont = ut_update_progress (text, bytes_read, false);
  156     
  157         //if buffer full, allocate new bigger buffer
  158         if (bytes_read == buffer_size) {
  159             buffer_size *= 2;
  160             text->data =  realloc (text->data, buffer_size + 3);
  161             if (!text->data) return UT_MALLOC_ERROR;
  162         }
  163         
  164         //if (ut_session->progress_function) cont = ut_update_progress (text, bytes_read, false);
  165     } while (code && cont);
  166 
  167     if (!cont) {
  168         DBG2 ("** stdin loading canceled by user! **")
  169         free (text->data);
  170         text->data = NULL;
  171         return UT_INTERRUPTED_BY_USER;
  172     }
  173 
  174     text->size = bytes_read;
  175     
  176     DBG2 ("stdin stream (%lu b) loaded!", text->size)
  177     
  178     *(text->data+text->size) = UT_EOF_CHAR;
  179     *(text->data+text->size+1) = UT_EOF_CHAR;
  180     *(text->data+text->size+2) = UT_EOF_CHAR;
  181 
  182     return UT_OK;
  183 }