diff options
Diffstat (limited to 'src/stable/file.cpp')
-rw-r--r-- | src/stable/file.cpp | 298 |
1 files changed, 149 insertions, 149 deletions
diff --git a/src/stable/file.cpp b/src/stable/file.cpp index 14e4f3c..7ae2484 100644 --- a/src/stable/file.cpp +++ b/src/stable/file.cpp | |||
@@ -19,298 +19,298 @@ | |||
19 | namespace Bu { subExceptionDef( FileException ) } | 19 | namespace Bu { subExceptionDef( FileException ) } |
20 | 20 | ||
21 | Bu::File::File( const Bu::String &sName, int iFlags ) : | 21 | Bu::File::File( const Bu::String &sName, int iFlags ) : |
22 | fd( -1 ), | 22 | fd( -1 ), |
23 | bEos( true ) | 23 | bEos( true ) |
24 | { | 24 | { |
25 | #ifdef USE_64BIT_IO | 25 | #ifdef USE_64BIT_IO |
26 | fd = ::open64( sName.getStr(), getPosixFlags( iFlags ), 0666 ); | 26 | fd = ::open64( sName.getStr(), getPosixFlags( iFlags ), 0666 ); |
27 | #else | 27 | #else |
28 | fd = ::open( sName.getStr(), getPosixFlags( iFlags ), 0666 ); | 28 | fd = ::open( sName.getStr(), getPosixFlags( iFlags ), 0666 ); |
29 | #endif | 29 | #endif |
30 | if( fd < 0 ) | 30 | if( fd < 0 ) |
31 | { | 31 | { |
32 | throw Bu::FileException( errno, "%s: %s", | 32 | throw Bu::FileException( errno, "%s: %s", |
33 | strerror(errno), sName.getStr() ); | 33 | strerror(errno), sName.getStr() ); |
34 | } | 34 | } |
35 | bEos = false; | 35 | bEos = false; |
36 | } | 36 | } |
37 | 37 | ||
38 | Bu::File::File( int fd ) : | 38 | Bu::File::File( int fd ) : |
39 | fd( fd ) | 39 | fd( fd ) |
40 | { | 40 | { |
41 | bEos = false; | 41 | bEos = false; |
42 | } | 42 | } |
43 | 43 | ||
44 | Bu::File::~File() | 44 | Bu::File::~File() |
45 | { | 45 | { |
46 | close(); | 46 | close(); |
47 | } | 47 | } |
48 | 48 | ||
49 | void Bu::File::close() | 49 | void Bu::File::close() |
50 | { | 50 | { |
51 | if( fd >= 0 ) | 51 | if( fd >= 0 ) |
52 | { | 52 | { |
53 | if( ::close( fd ) ) | 53 | if( ::close( fd ) ) |
54 | { | 54 | { |
55 | throw Bu::FileException( errno, "%s", | 55 | throw Bu::FileException( errno, "%s", |
56 | strerror(errno) ); | 56 | strerror(errno) ); |
57 | } | 57 | } |
58 | fd = -1; | 58 | fd = -1; |
59 | bEos = true; | 59 | bEos = true; |
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | Bu::size Bu::File::read( void *pBuf, Bu::size nBytes ) | 63 | Bu::size Bu::File::read( void *pBuf, Bu::size nBytes ) |
64 | { | 64 | { |
65 | if( fd < 0 ) | 65 | if( fd < 0 ) |
66 | throw FileException("File not open."); | 66 | throw FileException("File not open."); |
67 | 67 | ||
68 | Bu::size iRead = ::read( fd, pBuf, nBytes ); | 68 | Bu::size iRead = ::read( fd, pBuf, nBytes ); |
69 | if( iRead == 0 ) | 69 | if( iRead == 0 ) |
70 | bEos = true; | 70 | bEos = true; |
71 | else if( iRead == -1 && errno == EAGAIN ) | 71 | else if( iRead == -1 && errno == EAGAIN ) |
72 | return 0; | 72 | return 0; |
73 | else if( iRead < 0 ) | 73 | else if( iRead < 0 ) |
74 | throw FileException( errno, "%s", strerror( errno ) ); | 74 | throw FileException( errno, "%s", strerror( errno ) ); |
75 | return iRead; | 75 | return iRead; |
76 | } | 76 | } |
77 | 77 | ||
78 | Bu::size Bu::File::write( const void *pBuf, Bu::size nBytes ) | 78 | Bu::size Bu::File::write( const void *pBuf, Bu::size nBytes ) |
79 | { | 79 | { |
80 | if( fd < 0 ) | 80 | if( fd < 0 ) |
81 | throw FileException("File not open."); | 81 | throw FileException("File not open."); |
82 | 82 | ||
83 | Bu::size iWrote = ::write( fd, pBuf, nBytes ); | 83 | Bu::size iWrote = ::write( fd, pBuf, nBytes ); |
84 | if( iWrote < 0 ) | 84 | if( iWrote < 0 ) |
85 | throw FileException( errno, "%s", strerror( errno ) ); | 85 | throw FileException( errno, "%s", strerror( errno ) ); |
86 | return iWrote; | 86 | return iWrote; |
87 | } | 87 | } |
88 | 88 | ||
89 | Bu::size Bu::File::tell() | 89 | Bu::size Bu::File::tell() |
90 | { | 90 | { |
91 | if( fd < 0 ) | 91 | if( fd < 0 ) |
92 | throw FileException("File not open."); | 92 | throw FileException("File not open."); |
93 | 93 | ||
94 | #ifdef USE_64BIT_IO | 94 | #ifdef USE_64BIT_IO |
95 | return lseek64( fd, 0, SEEK_CUR ); | 95 | return lseek64( fd, 0, SEEK_CUR ); |
96 | #else | 96 | #else |
97 | return lseek( fd, 0, SEEK_CUR ); | 97 | return lseek( fd, 0, SEEK_CUR ); |
98 | #endif | 98 | #endif |
99 | } | 99 | } |
100 | 100 | ||
101 | void Bu::File::seek( Bu::size offset ) | 101 | void Bu::File::seek( Bu::size offset ) |
102 | { | 102 | { |
103 | if( fd < 0 ) | 103 | if( fd < 0 ) |
104 | throw FileException("File not open."); | 104 | throw FileException("File not open."); |
105 | 105 | ||
106 | #ifdef USE_64BIT_IO | 106 | #ifdef USE_64BIT_IO |
107 | lseek64( fd, offset, SEEK_CUR ); | 107 | lseek64( fd, offset, SEEK_CUR ); |
108 | #else | 108 | #else |
109 | lseek( fd, offset, SEEK_CUR ); | 109 | lseek( fd, offset, SEEK_CUR ); |
110 | #endif | 110 | #endif |
111 | bEos = false; | 111 | bEos = false; |
112 | } | 112 | } |
113 | 113 | ||
114 | void Bu::File::setPos( Bu::size pos ) | 114 | void Bu::File::setPos( Bu::size pos ) |
115 | { | 115 | { |
116 | if( fd < 0 ) | 116 | if( fd < 0 ) |
117 | throw FileException("File not open."); | 117 | throw FileException("File not open."); |
118 | 118 | ||
119 | #ifdef USE_64BIT_IO | 119 | #ifdef USE_64BIT_IO |
120 | lseek64( fd, pos, SEEK_SET ); | 120 | lseek64( fd, pos, SEEK_SET ); |
121 | #else | 121 | #else |
122 | lseek( fd, pos, SEEK_SET ); | 122 | lseek( fd, pos, SEEK_SET ); |
123 | #endif | 123 | #endif |
124 | bEos = false; | 124 | bEos = false; |
125 | } | 125 | } |
126 | 126 | ||
127 | void Bu::File::setPosEnd( Bu::size pos ) | 127 | void Bu::File::setPosEnd( Bu::size pos ) |
128 | { | 128 | { |
129 | if( fd < 0 ) | 129 | if( fd < 0 ) |
130 | throw FileException("File not open."); | 130 | throw FileException("File not open."); |
131 | 131 | ||
132 | lseek64( fd, pos, SEEK_END ); | 132 | lseek64( fd, pos, SEEK_END ); |
133 | bEos = false; | 133 | bEos = false; |
134 | } | 134 | } |
135 | 135 | ||
136 | bool Bu::File::isEos() | 136 | bool Bu::File::isEos() |
137 | { | 137 | { |
138 | return bEos; | 138 | return bEos; |
139 | } | 139 | } |
140 | 140 | ||
141 | bool Bu::File::canRead() | 141 | bool Bu::File::canRead() |
142 | { | 142 | { |
143 | #ifdef WIN32 | 143 | #ifdef WIN32 |
144 | return true; | 144 | return true; |
145 | #else | 145 | #else |
146 | int iMode = fcntl( fd, F_GETFL, 0 )&O_ACCMODE; | 146 | int iMode = fcntl( fd, F_GETFL, 0 )&O_ACCMODE; |
147 | if( iMode == O_RDONLY || iMode == O_RDWR ) | 147 | if( iMode == O_RDONLY || iMode == O_RDWR ) |
148 | return true; | 148 | return true; |
149 | return false; | 149 | return false; |
150 | #endif | 150 | #endif |
151 | } | 151 | } |
152 | 152 | ||
153 | bool Bu::File::canWrite() | 153 | bool Bu::File::canWrite() |
154 | { | 154 | { |
155 | #ifdef WIN32 | 155 | #ifdef WIN32 |
156 | return true; | 156 | return true; |
157 | #else | 157 | #else |
158 | int iMode = fcntl( fd, F_GETFL, 0 )&O_ACCMODE; | 158 | int iMode = fcntl( fd, F_GETFL, 0 )&O_ACCMODE; |
159 | if( iMode == O_WRONLY || iMode == O_RDWR ) | 159 | if( iMode == O_WRONLY || iMode == O_RDWR ) |
160 | return true; | 160 | return true; |
161 | return false; | 161 | return false; |
162 | #endif | 162 | #endif |
163 | } | 163 | } |
164 | 164 | ||
165 | bool Bu::File::isReadable() | 165 | bool Bu::File::isReadable() |
166 | { | 166 | { |
167 | return true; | 167 | return true; |
168 | } | 168 | } |
169 | 169 | ||
170 | bool Bu::File::isWritable() | 170 | bool Bu::File::isWritable() |
171 | { | 171 | { |
172 | return true; | 172 | return true; |
173 | } | 173 | } |
174 | 174 | ||
175 | bool Bu::File::isSeekable() | 175 | bool Bu::File::isSeekable() |
176 | { | 176 | { |
177 | return true; | 177 | return true; |
178 | } | 178 | } |
179 | 179 | ||
180 | bool Bu::File::isBlocking() | 180 | bool Bu::File::isBlocking() |
181 | { | 181 | { |
182 | return true; | 182 | return true; |
183 | } | 183 | } |
184 | 184 | ||
185 | void Bu::File::setBlocking( bool bBlocking ) | 185 | void Bu::File::setBlocking( bool bBlocking ) |
186 | { | 186 | { |
187 | #ifdef WIN32 | 187 | #ifdef WIN32 |
188 | fprintf(stderr, "STUB: Bu::File::setBlocking\n"); | 188 | fprintf(stderr, "STUB: Bu::File::setBlocking\n"); |
189 | #else | 189 | #else |
190 | if( bBlocking ) | 190 | if( bBlocking ) |
191 | fcntl( | 191 | fcntl( |
192 | fd, | 192 | fd, |
193 | F_SETFL, fcntl( fd, F_GETFL, 0 )&(~O_NONBLOCK) | 193 | F_SETFL, fcntl( fd, F_GETFL, 0 )&(~O_NONBLOCK) |
194 | ); | 194 | ); |
195 | else | 195 | else |
196 | fcntl( | 196 | fcntl( |
197 | fd, | 197 | fd, |
198 | F_SETFL, fcntl( fd, F_GETFL, 0 )|O_NONBLOCK | 198 | F_SETFL, fcntl( fd, F_GETFL, 0 )|O_NONBLOCK |
199 | ); | 199 | ); |
200 | #endif | 200 | #endif |
201 | } | 201 | } |
202 | 202 | ||
203 | Bu::File Bu::File::tempFile( Bu::String &sName ) | 203 | Bu::File Bu::File::tempFile( Bu::String &sName ) |
204 | { | 204 | { |
205 | int iXes; | 205 | int iXes; |
206 | for( iXes = sName.getSize()-1; iXes >= 0; iXes-- ) | 206 | for( iXes = sName.getSize()-1; iXes >= 0; iXes-- ) |
207 | { | 207 | { |
208 | if( sName[iXes] != 'X' ) | 208 | if( sName[iXes] != 'X' ) |
209 | break; | 209 | break; |
210 | } | 210 | } |
211 | iXes++; | 211 | iXes++; |
212 | if( iXes == sName.getSize() ) | 212 | if( iXes == sName.getSize() ) |
213 | throw Bu::ExceptionBase("Invalid temporary filename template."); | 213 | throw Bu::ExceptionBase("Invalid temporary filename template."); |
214 | for( int iter = 0; iter < 1000; iter++ ) | 214 | for( int iter = 0; iter < 1000; iter++ ) |
215 | { | 215 | { |
216 | for( int j = iXes; j < sName.getSize(); j++ ) | 216 | for( int j = iXes; j < sName.getSize(); j++ ) |
217 | { | 217 | { |
218 | uint32_t iX = Bu::Random::rand(); | 218 | uint32_t iX = Bu::Random::rand(); |
219 | sName[j] = ('A'+(iX%26)) | ((iX&0x1000)?(0x20):(0)); | 219 | sName[j] = ('A'+(iX%26)) | ((iX&0x1000)?(0x20):(0)); |
220 | } | 220 | } |
221 | 221 | ||
222 | try | 222 | try |
223 | { | 223 | { |
224 | return Bu::File( sName, Bu::File::Read|Bu::File::Write | 224 | return Bu::File( sName, Bu::File::Read|Bu::File::Write |
225 | |Bu::File::Create|Bu::File::Exclusive ); | 225 | |Bu::File::Create|Bu::File::Exclusive ); |
226 | } catch(...) { } | 226 | } catch(...) { } |
227 | } | 227 | } |
228 | throw Bu::FileException("Failed to create unique temporary file after 1000" | 228 | throw Bu::FileException("Failed to create unique temporary file after 1000" |
229 | " iterations."); | 229 | " iterations."); |
230 | } | 230 | } |
231 | 231 | ||
232 | void Bu::File::setSize( Bu::size iSize ) | 232 | void Bu::File::setSize( Bu::size iSize ) |
233 | { | 233 | { |
234 | #ifdef WIN32 | 234 | #ifdef WIN32 |
235 | chsize( fd, iSize ); | 235 | chsize( fd, iSize ); |
236 | #else | 236 | #else |
237 | ftruncate( fd, iSize ); | 237 | ftruncate( fd, iSize ); |
238 | #endif | 238 | #endif |
239 | } | 239 | } |
240 | 240 | ||
241 | Bu::size Bu::File::getSize() const | 241 | Bu::size Bu::File::getSize() const |
242 | { | 242 | { |
243 | struct stat st; | 243 | struct stat st; |
244 | fstat( fd, &st ); | 244 | fstat( fd, &st ); |
245 | return st.st_size; | 245 | return st.st_size; |
246 | } | 246 | } |
247 | 247 | ||
248 | Bu::size Bu::File::getBlockSize() const | 248 | Bu::size Bu::File::getBlockSize() const |
249 | { | 249 | { |
250 | #ifdef WIN32 | 250 | #ifdef WIN32 |
251 | return 4096; | 251 | return 4096; |
252 | #else | 252 | #else |
253 | struct stat st; | 253 | struct stat st; |
254 | fstat( fd, &st ); | 254 | fstat( fd, &st ); |
255 | return st.st_blksize; | 255 | return st.st_blksize; |
256 | #endif | 256 | #endif |
257 | } | 257 | } |
258 | 258 | ||
259 | Bu::String Bu::File::getLocation() const | 259 | Bu::String Bu::File::getLocation() const |
260 | { | 260 | { |
261 | return "to be implemented"; | 261 | return "to be implemented"; |
262 | } | 262 | } |
263 | 263 | ||
264 | #ifndef WIN32 | 264 | #ifndef WIN32 |
265 | void Bu::File::chmod( mode_t t ) | 265 | void Bu::File::chmod( mode_t t ) |
266 | { | 266 | { |
267 | fchmod( fd, t ); | 267 | fchmod( fd, t ); |
268 | } | 268 | } |
269 | #endif | 269 | #endif |
270 | 270 | ||
271 | void Bu::File::flush() | 271 | void Bu::File::flush() |
272 | { | 272 | { |
273 | // There is no flushing with direct I/O... | 273 | // There is no flushing with direct I/O... |
274 | //fflush( fh ); | 274 | //fflush( fh ); |
275 | } | 275 | } |
276 | 276 | ||
277 | bool Bu::File::isOpen() | 277 | bool Bu::File::isOpen() |
278 | { | 278 | { |
279 | return (fd > -1); | 279 | return (fd > -1); |
280 | } | 280 | } |
281 | 281 | ||
282 | int Bu::File::getPosixFlags( int iFlags ) | 282 | int Bu::File::getPosixFlags( int iFlags ) |
283 | { | 283 | { |
284 | int iRet = 0; | 284 | int iRet = 0; |
285 | switch( (iFlags&ReadWrite) ) | 285 | switch( (iFlags&ReadWrite) ) |
286 | { | 286 | { |
287 | // According to posix, O_RDWR is not necesarilly O_RDONLY|O_WRONLY, so | 287 | // According to posix, O_RDWR is not necesarilly O_RDONLY|O_WRONLY, so |
288 | // lets be proper and use the right value in the right place. | 288 | // lets be proper and use the right value in the right place. |
289 | case Read: iRet = O_RDONLY; break; | 289 | case Read: iRet = O_RDONLY; break; |
290 | case Write: iRet = O_WRONLY; break; | 290 | case Write: iRet = O_WRONLY; break; |
291 | case ReadWrite: iRet = O_RDWR; break; | 291 | case ReadWrite: iRet = O_RDWR; break; |
292 | default: | 292 | default: |
293 | throw FileException( | 293 | throw FileException( |
294 | "You must specify Read, Write, or both when opening a file."); | 294 | "You must specify Read, Write, or both when opening a file."); |
295 | } | 295 | } |
296 | 296 | ||
297 | if( (iFlags&Create) ) | 297 | if( (iFlags&Create) ) |
298 | iRet |= O_CREAT; | 298 | iRet |= O_CREAT; |
299 | if( (iFlags&Append) ) | 299 | if( (iFlags&Append) ) |
300 | iRet |= O_APPEND; | 300 | iRet |= O_APPEND; |
301 | if( (iFlags&Truncate) ) | 301 | if( (iFlags&Truncate) ) |
302 | iRet |= O_TRUNC; | 302 | iRet |= O_TRUNC; |
303 | #ifndef WIN32 | 303 | #ifndef WIN32 |
304 | if( (iFlags&NonBlock) ) | 304 | if( (iFlags&NonBlock) ) |
305 | iRet |= O_NONBLOCK; | 305 | iRet |= O_NONBLOCK; |
306 | #endif | 306 | #endif |
307 | if( (iFlags&Exclusive) == Exclusive ) | 307 | if( (iFlags&Exclusive) == Exclusive ) |
308 | iRet |= O_EXCL; | 308 | iRet |= O_EXCL; |
309 | 309 | ||
310 | #ifdef O_BINARY | 310 | #ifdef O_BINARY |
311 | iRet |= O_BINARY; | 311 | iRet |= O_BINARY; |
312 | #endif | 312 | #endif |
313 | 313 | ||
314 | return iRet; | 314 | return iRet; |
315 | } | 315 | } |
316 | 316 | ||