]> git.ipfire.org Git - thirdparty/sarg.git/blob - fileobject.c
Add support to decompress xz files
[thirdparty/sarg.git] / fileobject.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2015
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 *
25 */
26 /*!\file
27 \brief Encapsulate a file object
28
29 The file can be a standard file of the C library or a gzip file or
30 a bzip file.
31 */
32
33 #include "include/conf.h"
34 #include "include/stringbuffer.h"
35 #include "include/fileobject.h"
36
37 //! Message describing the last open error.
38 static char LastOpenErrorString[2048]="";
39 //! Message describing the last close error.
40 static char LastCloseErrorString[2048]="";
41
42 /*!
43 * Read a file using the standard C api.
44 *
45 * \param Data The file object.
46 * \param Buffer The boffer to store the data read.
47 * \param Size How many bytes to read.
48 *
49 * \return The number of bytes read.
50 */
51 static int Standard_Read(void *Data,void *Buffer,int Size)
52 {
53 return(fread(Buffer,1,Size,(FILE *)Data));
54 }
55
56 /*!
57 * Check if end of file is reached.
58 *
59 * \param Data The file object.
60 *
61 * \return \c True if end of file is reached.
62 */
63 static int Standard_Eof(void *Data)
64 {
65 return(feof((FILE *)Data));
66 }
67
68 /*!
69 * Return to the beginnig of the file.
70 *
71 * \param Data The file object.
72 */
73 static void Standard_Rewind(void *Data)
74 {
75 rewind((FILE *)Data);
76 }
77
78 /*!
79 * Close a file using the standard C api.
80 *
81 * \param Data File to close.
82 *
83 * \return EOF on error.
84 */
85 static int Standard_Close(void *Data)
86 {
87 int RetCode=0;
88
89 if (fclose((FILE *)Data)==EOF)
90 {
91 FileObject_SetLastCloseError(strerror(errno));
92 RetCode=-1;
93 }
94 return(RetCode);
95 }
96
97 /*!
98 * Open a file for reading using the standard C api.
99 *
100 * \param FileName The file to open.
101 *
102 * \return The object to pass to other function in this module.
103 */
104 FileObject *FileObject_Open(const char *FileName)
105 {
106 FileObject *File;
107
108 LastOpenErrorString[0]='\0';
109 File=malloc(sizeof(*File));
110 if (!File)
111 {
112 FileObject_SetLastOpenError(_("Not enough memory"));
113 return(NULL);
114 }
115 File->Data=MY_FOPEN(FileName,"r");
116 if (!File->Data)
117 {
118 free(File);
119 FileObject_SetLastOpenError(strerror(errno));
120 return(NULL);
121 }
122 File->Read=Standard_Read;
123 File->Eof=Standard_Eof;
124 File->Rewind=Standard_Rewind;
125 File->Close=Standard_Close;
126 return(File);
127 }
128
129 /*!
130 * Open a file for reading using the standard C api.
131 *
132 * \param FileName The file to open.
133 *
134 * \return The object to pass to other function in this module.
135 */
136 FileObject *FileObject_FdOpen(int fd)
137 {
138 FileObject *File;
139
140 LastOpenErrorString[0]='\0';
141 File=malloc(sizeof(*File));
142 if (!File)
143 {
144 FileObject_SetLastOpenError(_("Not enough memory"));
145 return(NULL);
146 }
147 File->Data=fdopen(fd,"r");
148 if (!File->Data)
149 {
150 free(File);
151 FileObject_SetLastOpenError(strerror(errno));
152 return(NULL);
153 }
154 File->Read=Standard_Read;
155 File->Eof=Standard_Eof;
156 File->Rewind=Standard_Rewind;
157 File->Close=Standard_Close;
158 return(File);
159 }
160
161 /*!
162 * Read the content of the file using the function identified
163 * by the file object.
164 *
165 * \param File The file object to read.
166 * \param Buffer The buffer to write the data into.
167 * \param Size The maximum number of bytes to read.
168 *
169 * \return The number of bytes read or -1.
170 */
171 int FileObject_Read(FileObject *File,void *Buffer,int Size)
172 {
173 return(File->Read(File->Data,Buffer,Size));
174 }
175
176 /*!
177 * Check if the end of file is reached.
178 *
179 * \param File The file object.
180 *
181 * \return \c True if end of file is reached.
182 */
183 int FileObject_Eof(FileObject *File)
184 {
185 return(File->Eof(File->Data));
186 }
187
188 /*!
189 * Return to the beginning of the file.
190 *
191 * \param File The file object.
192 */
193 void FileObject_Rewind(FileObject *File)
194 {
195 File->Rewind(File->Data);
196 }
197
198 /*!
199 * Close the file opened. The memory is freed. The object
200 * cannot be reused after this function returns.
201 *
202 * \param File The file object to close.
203 *
204 * \return Zero on success or -1 on failure.
205 */
206 int FileObject_Close(FileObject *File)
207 {
208 LastCloseErrorString[0]='\0';
209 int RetCode=File->Close(File->Data);
210 free(File);
211 return(RetCode);
212 }
213
214 /*!
215 * Set the message returned by the last open error.
216 *
217 * \param Message The message explaining what error occurred
218 * when the file was opened.
219 */
220 void FileObject_SetLastOpenError(const char *Message)
221 {
222 if (Message)
223 {
224 strncpy(LastOpenErrorString,Message,sizeof(LastOpenErrorString)-1);
225 LastOpenErrorString[sizeof(LastOpenErrorString)-1]='\0';
226 }
227 else
228 LastOpenErrorString[0]='\0';
229 }
230
231 /*!
232 * Get a message explaining the last open error.
233 *
234 * \return The string to display to the user.
235 */
236 const char *FileObject_GetLastOpenError(void)
237 {
238 return(LastOpenErrorString);
239 }
240
241 /*!
242 * Set the message returned by the last close error.
243 *
244 * \param Message The message explaining what error occurred
245 * when the file was closed.
246 */
247 void FileObject_SetLastCloseError(const char *Message)
248 {
249 if (Message)
250 {
251 strncpy(LastCloseErrorString,Message,sizeof(LastCloseErrorString)-1);
252 LastCloseErrorString[sizeof(LastCloseErrorString)-1]='\0';
253 }
254 else
255 LastCloseErrorString[0]='\0';
256 }
257
258 /*!
259 * Get a message explaining the last close error.
260 *
261 * \return The string to display to the user.
262 */
263 const char *FileObject_GetLastCloseError(void)
264 {
265 return(LastCloseErrorString);
266 }