[FORMATTING] No code changes.
[reactos.git] / irc / ArchBlackmann / File.cpp
1 // File.cpp
2 // (C) 2002-2004 Royce Mitchell III
3 // Dually licensed under BSD & LGPL
4
5 #ifdef _MSC_VER
6 #pragma warning ( disable : 4786 )
7 #endif//_MSC_VER
8
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include "File.h"
12
13 #ifndef nelem
14 #define nelem(x) ( sizeof(x) / sizeof(x[0]) )
15 #endif//nelem
16
17 typedef File::filesize_t filesize_t;
18 typedef File::fileoff_t fileoff_t;
19
20
21 fileoff_t File::seek ( fileoff_t offset )
22 {
23 #ifdef WIN32
24 if ( _f->_flag & _IOWRT ) // is there pending output?
25 fflush ( _f );
26
27 // reset "buffered input" variables
28 _f->_cnt = 0;
29 _f->_ptr = _f->_base;
30
31 // make sure we're going forward
32 if ( _f->_flag & _IORW )
33 _f->_flag &= ~(_IOREAD|_IOWRT);
34
35 return _lseeki64 ( _fileno(_f), offset, SEEK_SET );
36 #else//UNIX
37 return lseek64 ( fileno(_f), offset, SEEK_SET );
38 #endif
39 }
40
41 std::string File::getline ( bool strip_crlf /*= false*/ )
42 {
43 std::string s = "";
44 char buf[256];
45 for ( ;; )
46 {
47 *buf = 0;
48 fgets ( buf, nelem(buf)-1, _f );
49 if ( !*buf )
50 break;
51 s += buf;
52 if ( strchr ( "\r\n", buf[strlen(buf)-1] ) )
53 break;
54 }
55 if ( strip_crlf && s.size() )
56 {
57 char* p = strpbrk ( &s[0], "\r\n" );
58 if ( p )
59 {
60 *p = '\0';
61 s.resize ( p-&s[0] );
62 }
63 }
64 return s;
65 }
66
67 std::wstring File::wgetline ( bool strip_crlf /*= false*/ )
68 {
69 std::wstring s = L"";
70 wchar_t buf[256];
71 for ( ;; )
72 {
73 *buf = 0;
74 fgetws ( buf, nelem(buf)-1, _f );
75 if ( !*buf )
76 break;
77 s += buf;
78 if ( wcschr ( L"\r\n", buf[wcslen(buf)-1] ) )
79 break;
80 }
81 if ( strip_crlf && s.size() )
82 {
83 wchar_t* p = wcspbrk ( &s[0], L"\r\n" );
84 if ( p )
85 {
86 *p = L'\0';
87 s.resize ( (p-&s[0])/sizeof(wchar_t) );
88 }
89 }
90 return s;
91 }
92
93 // this function searches for the next end-of-line and puts all data it
94 // finds until then in the 'line' parameter.
95 //
96 // call continuously until the function returns false ( no more data )
97 bool File::next_line ( std::string& line, bool strip_crlf )
98 {
99 line = getline(strip_crlf);
100 // indicate that we're done *if*:
101 // 1) there's no more data, *and*
102 // 2) we're at the end of the file
103 return line.size()>0 || !eof();
104 }
105
106 bool File::next_line ( std::wstring& line, bool strip_crlf )
107 {
108 line = wgetline ( strip_crlf );
109 return line.size()>0 || !eof();
110 }
111
112 /*
113 example usage:
114
115 bool mycallback ( const std::string& line, int line_number, long lparam )
116 {
117 std::cout << line << std::endl;
118 return true; // continue enumeration
119 }
120
121 File f ( "file.txt", "rb" ); // open file for binary read-only ( i.e. "rb" )
122 f.enum_lines ( mycallback, 0, true );
123 */
124
125 /*bool File::enum_lines ( bool (*callback)(const std::string& line, int line_number, long lparam), long lparam, bool strip_crlf )
126 {
127 int line_number = 0;
128 for ( ;; )
129 {
130 std::string s = getline(strip_crlf);
131 line_number++;
132 if ( !s.size() )
133 {
134 if ( eof() )
135 return true;
136 else
137 continue;
138 }
139 if ( !(*callback) ( s, line_number, lparam ) )
140 return false;
141 }
142 }*/
143
144 filesize_t File::length() const
145 {
146 #ifdef WIN32
147 return _filelengthi64 ( _fileno(_f) );
148 #elif defined(UNIX)
149 struct stat64 file_stat;
150 verify(fstat64(fileno(_f), &file_stat) == 0);
151 return file_stat.st_size;
152 #endif
153 }
154
155 void File::close()
156 {
157 if ( _f )
158 {
159 fclose(_f);
160 _f = 0;
161 }
162 }
163
164 void File::printf ( const char* fmt, ... )
165 {
166 va_list arg;
167 int done;
168
169 va_start(arg, fmt);
170 assert(_f);
171 done = vfprintf ( _f, fmt, arg );
172 va_end(arg);
173 }
174
175 /*static*/ bool File::LoadIntoString ( std::string& s, const std::string& filename )
176 {
177 File in ( filename, "rb" );
178 if ( !in.isopened() )
179 return false;
180 filesize_t flen = in.length();
181 size_t len = size_t(flen);
182 if ( len != flen )
183 return false; // file too big...
184 s.resize ( len + 1 );
185 if ( !in.read ( &s[0], len ) )
186 return false;
187 s[len] = '\0';
188 s.resize ( len );
189 return true;
190 }
191
192 /*static*/ bool File::LoadIntoString ( std::string& s, const std::wstring& filename )
193 {
194 File in ( filename, L"rb" );
195 if ( !in.isopened() )
196 return false;
197 filesize_t flen = in.length();
198 size_t len = size_t(flen);
199 if ( len != flen )
200 return false; // file too big...
201 s.resize ( len + 1 );
202 if ( !in.read ( &s[0], len ) )
203 return false;
204 s[len] = '\0';
205 s.resize ( len );
206 return true;
207 }
208
209 /*static*/ bool File::SaveFromString ( const std::string& filename, const std::string& s, bool binary )
210 {
211 File out ( filename, binary ? "wb" : "w" );
212 if ( !out.isopened() )
213 return false;
214 out.write ( s.c_str(), s.size() );
215 return true;
216 }
217
218 /*static*/ bool File::SaveFromString ( const std::wstring& filename, const std::string& s, bool binary )
219 {
220 File out ( filename, binary ? L"wb" : L"w" );
221 if ( !out.isopened() )
222 return false;
223 out.write ( s.c_str(), s.size() );
224 return true;
225 }
226
227 /*static*/ bool File::SaveFromBuffer ( const std::string& filename, const char* buf, size_t buflen, bool binary )
228 {
229 File out ( filename, binary ? "wb" : "w" );
230 if ( !out.isopened() )
231 return false;
232 out.write ( buf, buflen );
233 return true;
234 }
235
236 /*static*/ bool File::SaveFromBuffer ( const std::wstring& filename, const char* buf, size_t buflen, bool binary )
237 {
238 File out ( filename, binary ? L"wb" : L"w" );
239 if ( !out.isopened() )
240 return false;
241 out.write ( buf, buflen );
242 return true;
243 }
244
245 /*static*/ std::string File::TempFileName ( const std::string& prefix )
246 {
247 #ifdef WIN32
248 std::string s ( _tempnam ( ".", prefix.c_str() ) );
249 return s;
250 #else
251 // FIXME
252 return string("");
253 #endif
254 }
255
256 /*static*/ std::wstring File::TempFileName ( const std::wstring& prefix )
257 {
258 #ifdef WIN32
259 std::wstring s ( _wtempnam ( L".", prefix.c_str() ) );
260 return s;
261 #else
262 // FIXME
263 return std::wstring(L"");
264 #endif
265 }