blob: 624434aba91b3e23dc1deba3e91b42e4cb0bee86 [file] [log] [blame]
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2//
3// This file is part of GNU uCommon C++.
4//
5// GNU uCommon C++ is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published
7// by the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GNU uCommon C++ is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * Adaption of C runtime FILE processing.
20 * @file ucommon/file.h
21 */
22
23#ifndef _UCOMMON_FILE_H_
24#define _UCOMMON_FILE_H_
25
26#ifndef _UCOMMON_CONFIG_H_
27#include <ucommon/platform.h>
28#endif
29
30#ifndef _UCOMMON_PROTOCOLS_H_
31#include <ucommon/protocols.h>
32#endif
33
34#ifndef _UCOMMON_THREAD_H_
35#include <ucommon/thread.h>
36#endif
37
38#ifndef _UCOMMON_STRING_H_
39#include <ucommon/string.h>
40#endif
41
42#ifndef _UCOMMON_MEMORY_H_
43#include <ucommon/memory.h>
44#endif
45
46#ifndef _UCOMMON_FSYS_H_
47#include <ucommon/fsys.h>
48#endif
49
50#include <stdio.h>
51
52NAMESPACE_UCOMMON
53
54/**
55 * Access standard files through character protocol. This can also be
56 * used as an alternative means to access files that manages file pointers.
57 * @author David Sugar <dyfet@gnutelephony.org>
58 */
59class __EXPORT file : public CharacterProtocol
60{
61private:
62 FILE *fp;
63#ifdef _MSWINDOWS_
64 HANDLE pid;
65#else
66 pid_t pid;
67#endif
68 char *tmp;
69
70 int _putch(int code);
71
72 int _getch(void);
73
74public:
75 typedef ::fpos_t bookmark_t;
76
77 static file cin, cout, cerr;
78
79 /**
80 * Construct a file from an existing FILE pointer.
81 * @param file to use.
82 */
83 file(FILE *file);
84
85 /**
86 * Construct an open file based on a path and mode.
87 * @param path of file to open.
88 * @param mode of file.
89 * @param size of buffer, 0 = none, 1 = line mode, 2 = default
90 */
91 file(const char *path, const char *mode, size_t size = 2);
92
93 /**
94 * Construct an open file based on a pipe.
95 * @param path of file to pipe.
96 * @param argv of executable.
97 * @param mode of file.
98 * @param envp to give executable.
99 */
100 file(const char *path, char **argv, const char *mode, char **envp = NULL);
101
102 /**
103 * Construct an unopened file.
104 */
105 file();
106
107 /**
108 * Destroy object and close associated file.
109 */
110 ~file();
111
112 /**
113 * Test if file is opened.
114 * @return true if opened.
115 */
116 inline operator bool()
117 {return fp != NULL;}
118
119 /**
120 * Test if file is not opened.
121 * @return true if not opened.
122 */
123 inline bool operator !()
124 {return fp == NULL;}
125
126 inline operator FILE *()
127 {return fp;}
128
129 /**
130 * Open file path. If a file is already opened, it is closed.
131 * @param path of file to open.
132 * @param mode of file to open.
133 * @param size of buffering, 0 = none, 1 = line mode.
134 */
135 void open(const char *path, const char *mode, size_t size = 2);
136
137 /**
138 * Open an executable path.
139 * @param path of executable.
140 * @param argv to pass to executable.
141 * @param mode of pipe (only "r" and "w" are valid).
142 */
143 void open(const char *path, char **argv, const char *mode, char **envp = NULL);
144
145 /**
146 * Close an open file.
147 * @return process exit code if pipe.
148 */
149 int close(void);
150
151 /**
152 * Clear error state.
153 */
154 inline void clear(void)
155 {if(fp) clearerr(fp);}
156
157 /**
158 * Check if file is good, no error or eof...
159 * @return bool if file stream is good.
160 */
161 bool good(void);
162
163 /**
164 * Cancel pipe and close file.
165 * @return process exit code if pipe.
166 */
167 int cancel(void);
168
169 inline size_t put(const void *data, size_t size)
170 { return fp == NULL ? 0 : fwrite(data, 1, size, fp);}
171
172 inline size_t get(void *data, size_t size)
173 { return fp == NULL ? 0 : fread(data, 1, size, fp);}
174
175 inline int put(char value)
176 { return fp == NULL ? EOF : fputc(value, fp);}
177
178 inline int get(void)
179 { return fp == NULL ? EOF : fgetc(fp);}
180
181 inline int push(char value)
182 { return fp == NULL ? EOF : ungetc(value, fp);}
183
184 inline int puts(const char *data)
185 { return fp == NULL ? 0 : fputs(data, fp);}
186
187 inline char *gets(char *data, size_t size)
188 { return fp == NULL ? NULL : fgets(data, size, fp);}
189
190 template<typename T> inline size_t read(T* data, size_t count)
191 { return fp == NULL ? 0 : fread(data, sizeof(T), count, fp);}
192
193 template<typename T> inline size_t write(const T* data, size_t count)
194 { return fp == NULL ? 0 : fwrite(data, sizeof(T), count, fp);}
195
196 template<typename T> inline size_t read(T& data)
197 { return fp == NULL ? 0 : fread(data, sizeof(T), 1, fp);}
198
199 template<typename T> inline size_t write(const T& data)
200 { return fp == NULL ? 0 : fwrite(data, sizeof(T), 1, fp);}
201
202 inline void get(bookmark_t& pos)
203 { if(fp) fsetpos(fp, &pos);}
204
205 inline void set(bookmark_t& pos)
206 { if(fp) fgetpos(fp, &pos);}
207
208 int err(void) const;
209
210 bool eof(void) const;
211
212 template<typename T> inline void offset(long pos)
213 {if(fp) fseek(fp, sizeof(const T) * pos, SEEK_CUR);}
214
215 inline void seek(long offset)
216 {if(fp) fseek(fp, offset, SEEK_SET);}
217
218 inline void move(long offset)
219 {if(fp) fseek(fp, offset, SEEK_CUR);}
220
221 inline void append(void)
222 {if (fp) fseek(fp, 0l, SEEK_END);}
223
224 inline void rewind(void)
225 {if(fp) ::rewind(fp);}
226
227 inline void flush(void)
228 {if(fp) ::fflush(fp);}
229
230 size_t printf(const char *format, ...) __PRINTF(2, 3);
231
232 size_t scanf(const char *format, ...) __SCANF(2, 3);
233
234 bool is_tty(void) const;
235};
236
237/**
238 * Convience type for file.
239 */
240typedef file file_t;
241
242END_NAMESPACE
243
244#endif
245