Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfstream_stdio.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 00019 #if defined (__SUNPPRO_CC) && !defined (_STLP_NO_NEW_C_HEADERS) 00020 # include <time.h> 00021 // For sunpro, it chokes if time.h is included through stat.h 00022 #endif 00023 00024 #include <fstream> 00025 00026 #ifdef __CYGWIN__ 00027 # define __int64 long long 00028 #endif 00029 00030 #include <cstdio> 00031 #if !defined(__ISCPP__) 00032 extern "C" { 00033 # include <sys/stat.h> 00034 } 00035 #endif 00036 00037 #if defined( __MSL__ ) 00038 # include <unix.h> 00039 #endif 00040 00041 #if defined(__ISCPP__) 00042 # include <c_locale_is/filestat.h> 00043 #endif 00044 00045 #if defined(__BEOS__) && defined(__INTEL__) 00046 # include <fcntl.h> 00047 # include <sys/stat.h> // For _fstat 00048 #endif 00049 00050 #if defined (_STLP_MSVC) || defined (__MINGW32__) 00051 # include <fcntl.h> 00052 # define S_IREAD _S_IREAD 00053 # define S_IWRITE _S_IWRITE 00054 # define S_IFREG _S_IFREG 00055 // map permission masks 00056 # ifndef S_IRUSR 00057 # define S_IRUSR _S_IREAD 00058 # define S_IWUSR _S_IWRITE 00059 # endif 00060 # ifndef S_IRGRP 00061 # define S_IRGRP _S_IREAD 00062 # define S_IWGRP _S_IWRITE 00063 # endif 00064 # ifndef S_IROTH 00065 # define S_IROTH _S_IREAD 00066 # define S_IWOTH _S_IWRITE 00067 # endif 00068 00069 # ifndef O_RDONLY 00070 # define O_RDONLY _O_RDONLY 00071 # define O_WRONLY _O_WRONLY 00072 # define O_RDWR _O_RDWR 00073 # define O_APPEND _O_APPEND 00074 # define O_CREAT _O_CREAT 00075 # define O_TRUNC _O_TRUNC 00076 # define O_TEXT _O_TEXT 00077 # define O_BINARY _O_BINARY 00078 # endif 00079 00080 # ifndef O_ACCMODE 00081 # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) 00082 # endif 00083 #endif 00084 00085 const _STLP_fd INVALID_STLP_FD = -1; 00086 00087 00088 # ifdef __MSL__ 00089 # define _O_TEXT 0x0 00090 # if !defined( O_TEXT ) 00091 # define O_TEXT _O_TEXT 00092 # endif 00093 # define _S_IFREG S_IFREG 00094 # define S_IREAD S_IRUSR 00095 # define S_IWRITE S_IWUSR 00096 # define S_IEXEC S_IXUSR 00097 # define _S_IWRITE S_IWRITE 00098 # define _S_IREAD S_IREAD 00099 # define _open open 00100 # define _close close 00101 # define _read read 00102 # define _write write 00103 # endif 00104 00105 _STLP_BEGIN_NAMESPACE 00106 00107 // Compare with streamoff definition in stl/char_traits.h! 00108 00109 #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \ 00110 (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE)) 00111 # define FOPEN fopen 00112 # define FSEEK fseek 00113 # define FSTAT fstat 00114 # define STAT stat 00115 # define FTELL ftell 00116 #else 00117 # define FOPEN fopen64 00118 # define FSEEK fseeko64 00119 # define FSTAT fstat64 00120 # define STAT stat64 00121 # define FTELL ftello64 00122 #endif 00123 00124 _STLP_MOVE_TO_PRIV_NAMESPACE 00125 00126 // Helper functions for _Filebuf_base. 00127 00128 static bool __is_regular_file(_STLP_fd fd) { 00129 struct STAT buf; 00130 return FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0 ; 00131 } 00132 00133 // Number of characters in the file. 00134 static streamoff __file_size(_STLP_fd fd) { 00135 streamoff ret = 0; 00136 00137 struct STAT buf; 00138 if (FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0) 00139 ret = buf.st_size > 0 ? buf.st_size : 0; 00140 00141 return ret; 00142 } 00143 00144 _STLP_MOVE_TO_STD_NAMESPACE 00145 00146 // All version of Unix have mmap and lseek system calls. Some also have 00147 // longer versions of those system calls to accommodate 64-bit offsets. 00148 // If we're on a Unix system, define some macros to encapsulate those 00149 // differences. 00150 00151 size_t _Filebuf_base::_M_page_size = 4096; 00152 00153 _Filebuf_base::_Filebuf_base() 00154 : _M_file_id(INVALID_STLP_FD), 00155 _M_openmode(0), 00156 _M_is_open(false), 00157 _M_should_close(false) 00158 {} 00159 00160 void _Filebuf_base::_S_initialize() 00161 { 00162 00163 } 00164 00165 // Return the size of the file. This is a wrapper for stat. 00166 // Returns zero if the size cannot be determined or is ill-defined. 00167 streamoff _Filebuf_base::_M_file_size() 00168 { 00169 return _STLP_PRIV __file_size(_M_file_id); 00170 } 00171 00172 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode, 00173 long permission) 00174 { 00175 _STLP_fd file_no; 00176 00177 if (_M_is_open) 00178 return false; 00179 00180 // use FILE-based i/o 00181 const char* flags; 00182 00183 switch (openmode & (~ios_base::ate)) { 00184 case ios_base::out: 00185 case ios_base::out | ios_base::trunc: 00186 flags = "w"; 00187 break; 00188 00189 case ios_base::out | ios_base::binary: 00190 case ios_base::out | ios_base::trunc | ios_base::binary: 00191 flags = "wb"; 00192 break; 00193 00194 case ios_base::out | ios_base::app: 00195 flags = "a"; 00196 break; 00197 00198 case ios_base::out | ios_base::app | ios_base::binary: 00199 flags = "ab"; 00200 break; 00201 00202 case ios_base::in: 00203 flags = "r"; 00204 break; 00205 00206 case ios_base::in | ios_base::binary: 00207 flags = "rb"; 00208 break; 00209 00210 case ios_base::in | ios_base::out: 00211 flags = "r+"; 00212 break; 00213 00214 case ios_base::in | ios_base::out | ios_base::binary: 00215 flags = "r+b"; 00216 break; 00217 00218 case ios_base::in | ios_base::out | ios_base::trunc: 00219 flags = "w+"; 00220 break; 00221 00222 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: 00223 flags = "w+b"; 00224 break; 00225 00226 default: // The above are the only combinations of 00227 return false; // flags allowed by the C++ standard. 00228 } 00229 00230 // fbp : TODO : set permissions ! 00231 (void)permission; // currently unused //*TY 02/26/2000 - added to suppress warning message 00232 _M_file = FOPEN(name, flags); 00233 00234 if (_M_file) { 00235 file_no = fileno(_M_file); 00236 } else { 00237 return false; 00238 } 00239 00240 // unset buffering immediately 00241 setbuf(_M_file, 0); 00242 00243 _M_is_open = true; 00244 00245 if (openmode & ios_base::ate) { 00246 if (FSEEK(_M_file, 0, SEEK_END) != 0) 00247 _M_is_open = false; 00248 } 00249 00250 _M_file_id = file_no; 00251 _M_should_close = _M_is_open; 00252 _M_openmode = openmode; 00253 00254 if (_M_is_open) 00255 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 00256 00257 return (_M_is_open != 0); 00258 } 00259 00260 00261 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) 00262 { 00263 // This doesn't really grant everyone in the world read/write 00264 // access. On Unix, file-creation system calls always clear 00265 // bits that are set in the umask from the permissions flag. 00266 return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP | 00267 S_IWGRP | S_IROTH | S_IWOTH); 00268 } 00269 00270 // Associated the filebuf with a file descriptor pointing to an already- 00271 // open file. Mode is set to be consistent with the way that the file 00272 // was opened. 00273 bool _Filebuf_base::_M_open( int file_no, ios_base::openmode ) 00274 { 00275 if (_M_is_open || file_no < 0) 00276 return false; 00277 00278 struct STAT buf; 00279 if (FSTAT(file_no, &buf) != 0) 00280 return false; 00281 int mode = buf.st_mode; 00282 00283 switch ( mode & (S_IWRITE | S_IREAD) ) { 00284 case S_IREAD: 00285 _M_openmode = ios_base::in; 00286 break; 00287 case S_IWRITE: 00288 _M_openmode = ios_base::out; 00289 break; 00290 case (S_IWRITE | S_IREAD): 00291 _M_openmode = ios_base::in | ios_base::out; 00292 break; 00293 default: 00294 return false; 00295 } 00296 _M_file_id = file_no; 00297 _M_is_open = true; 00298 _M_should_close = false; 00299 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 00300 return true; 00301 } 00302 00303 bool _Filebuf_base::_M_close() 00304 { 00305 if (!_M_is_open) 00306 return false; 00307 00308 bool ok = _M_should_close ? (fclose(_M_file) == 0) : true; 00309 00310 _M_is_open = _M_should_close = false; 00311 _M_openmode = 0; 00312 return ok; 00313 } 00314 00315 // Read up to n characters into a buffer. Return value is number of 00316 // characters read. 00317 ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) { 00318 return fread(buf, 1, n, _M_file); 00319 } 00320 00321 // Write n characters from a buffer. Return value: true if we managed 00322 // to write the entire buffer, false if we didn't. 00323 bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) 00324 { 00325 for (;;) { 00326 ptrdiff_t written = fwrite(buf, 1, n, _M_file); 00327 00328 if (n == written) { 00329 return true; 00330 } 00331 00332 if (written > 0 && written < n) { 00333 n -= written; 00334 buf += written; 00335 } else { 00336 return false; 00337 } 00338 } 00339 } 00340 00341 // Wrapper for lseek or the like. 00342 streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) 00343 { 00344 int whence; 00345 00346 switch ( dir ) { 00347 case ios_base::beg: 00348 if (offset < 0 /* || offset > _M_file_size() */ ) 00349 return streamoff(-1); 00350 whence = SEEK_SET; 00351 break; 00352 case ios_base::cur: 00353 whence = SEEK_CUR; 00354 break; 00355 case ios_base::end: 00356 if (/* offset > 0 || */ -offset > _M_file_size() ) 00357 return streamoff(-1); 00358 whence = SEEK_END; 00359 break; 00360 default: 00361 return streamoff(-1); 00362 } 00363 00364 if ( FSEEK(_M_file, offset, whence) == 0 ) { 00365 return FTELL(_M_file); 00366 } 00367 00368 return streamoff(-1); 00369 } 00370 00371 00372 // Attempts to memory-map len bytes of the current file, starting 00373 // at position offset. Precondition: offset is a multiple of the 00374 // page size. Postcondition: return value is a null pointer if the 00375 // memory mapping failed. Otherwise the return value is a pointer to 00376 // the memory-mapped file and the file position is set to offset. 00377 void *_Filebuf_base::_M_mmap(streamoff, streamoff ) 00378 { 00379 return 0; 00380 } 00381 00382 void _Filebuf_base::_M_unmap(void*, streamoff) 00383 { 00384 // precondition : there is a valid mapping at the moment 00385 } 00386 00387 _STLP_END_NAMESPACE Generated on Sun May 27 2012 04:35:11 for ReactOS by
1.7.6.1
|