"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 }