Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeniostream.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 #include "stlport_prefix.h" 00019 00020 #include <memory> 00021 #include <istream> 00022 #include <fstream> 00023 #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__) 00024 # define _STLP_USE_NOT_INIT_SEGMENT 00025 # include <iostream> 00026 #endif 00027 00028 #include "stdio_streambuf.h" 00029 #include "aligned_buffer.h" 00030 #include "_stdio_file.h" 00031 #include "c_locale.h" 00032 00033 // boris : note this is repeated in <iostream> 00034 #ifndef _STLP_USE_NAMESPACES 00035 // in case of SGI iostreams, we have to rename our streams not to clash with those 00036 // provided in native lib 00037 # define cin _STLP_cin 00038 # define cout _STLP_cout 00039 # define cerr _STLP_cerr 00040 # define clog _STLP_clog 00041 #endif 00042 00043 _STLP_BEGIN_NAMESPACE 00044 00045 // This file handles iostream initialization. It is inherently 00046 // nonportable, since the C++ language definition provides no mechanism 00047 // for controlling order of initialization of nonlocal objects. 00048 // Initialization has three parts, which must be performed in the following 00049 // order: 00050 // (1) Initialize the locale system 00051 // (2) Call the constructors for the eight global stream objects. 00052 // (3) Create streambufs for the global stream objects, and initialize 00053 // the stream objects by calling the init() member function. 00054 00055 00056 #if defined (_STLP_USE_NOT_INIT_SEGMENT) 00057 00058 // Definitions of the eight global I/O objects that are declared in 00059 // <iostream>. For some compilers we use pragmas to put the global I/O 00060 // objects into an initialization segment that will not 00061 // be executed. We then explicitly invoke the constructors 00062 // with placement new in ios_base::_S_initialize() 00063 00064 # if defined (__MWERKS__) 00065 # pragma suppress_init_code on 00066 # else 00067 # pragma init_seg("STLPORT_NO_INIT") 00068 # endif 00069 00070 _STLP_DECLSPEC istream cin(0); 00071 _STLP_DECLSPEC ostream cout(0); 00072 _STLP_DECLSPEC ostream cerr(0); 00073 _STLP_DECLSPEC ostream clog(0); 00074 00075 # ifndef _STLP_NO_WCHAR_T 00076 _STLP_DECLSPEC wistream wcin(0); 00077 _STLP_DECLSPEC wostream wcout(0); 00078 _STLP_DECLSPEC wostream wcerr(0); 00079 _STLP_DECLSPEC wostream wclog(0); 00080 # endif 00081 00082 # if defined (__MWERKS__) 00083 # pragma suppress_init_code off 00084 # endif 00085 00086 #else 00087 00088 // Definitions of the eight global I/O objects that are declared in 00089 // <iostream>. Disgusting hack: we deliberately define them with the 00090 // wrong types so that the constructors don't get run automatically. 00091 // We need special tricks to make sure that these objects are struct- 00092 // aligned rather than byte-aligned. 00093 00094 // This is not portable. Declaring a variable with different types in 00095 // two translations units is "undefined", according to the C++ standard. 00096 // Most compilers, however, silently accept this instead of diagnosing 00097 // it as an error. 00098 00099 # ifndef __DMC__ 00100 _STLP_DECLSPEC _Stl_aligned_buffer<istream> cin; 00101 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cout; 00102 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cerr; 00103 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> clog; 00104 # else 00105 _Stl_aligned_buffer<istream> cin; 00106 _Stl_aligned_buffer<ostream> cout; 00107 _Stl_aligned_buffer<ostream> cerr; 00108 _Stl_aligned_buffer<ostream> clog; 00109 00110 # pragma alias("?cin@std@@3V?$basic_istream@std@DV?$char_traits@std@D@1@@1@A", "?cin@std@@3T?$_Stl_aligned_buffer@std@V?$basic_istream@std@DV?$char_traits@std@D@1@@1@@1@A") 00111 # pragma alias("?cout@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?cout@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A") 00112 # pragma alias("?cerr@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?cerr@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A") 00113 # pragma alias("?clog@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?clog@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A") 00114 # endif 00115 00116 # ifndef _STLP_NO_WCHAR_T 00117 00118 # ifndef __DMC__ 00119 _STLP_DECLSPEC _Stl_aligned_buffer<wistream> wcin; 00120 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcout; 00121 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcerr; 00122 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wclog; 00123 # else 00124 _Stl_aligned_buffer<wistream> wcin; 00125 _Stl_aligned_buffer<wostream> wcout; 00126 _Stl_aligned_buffer<wostream> wcerr; 00127 _Stl_aligned_buffer<wostream> wclog; 00128 00129 # pragma alias("?wcin@std@@3V?$basic_istream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcin@std@@3T?$_Stl_aligned_buffer@std@V?$basic_istream@std@_YV?$char_traits@std@_Y@1@@1@@1@A") 00130 # pragma alias("?wcout@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcout@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A") 00131 # pragma alias("?wcerr@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcerr@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A") 00132 # pragma alias("?wclog@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wclog@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A") 00133 # endif 00134 # endif 00135 #endif /* STL_MSVC || __MWERKS__ */ 00136 00137 // Member functions from class ios_base and ios_base::Init 00138 00139 long ios_base::Init::_S_count = 0; 00140 // by default, those are synced 00141 bool ios_base::_S_is_synced = true; 00142 00143 ios_base::Init::Init() { 00144 if (_S_count++ == 0) { 00145 _Locale_init(); 00146 ios_base::_S_initialize(); 00147 _Filebuf_base::_S_initialize(); 00148 } 00149 } 00150 00151 ios_base::Init::~Init() { 00152 if (--_S_count == 0) { 00153 ios_base::_S_uninitialize(); 00154 _Locale_final(); 00155 } 00156 } 00157 00158 static int _Stl_extract_open_param(FILE* f) 00159 { return _FILE_fd(f); } 00160 00161 #ifdef _STLP_REDIRECT_STDSTREAMS 00162 static const char* _Stl_extract_open_param(const char* name) 00163 { return name; } 00164 #endif 00165 00166 template <class _Tp> 00167 static filebuf* 00168 _Stl_create_filebuf(_Tp x, ios_base::openmode mode ) { 00169 auto_ptr<filebuf> result(new basic_filebuf<char, char_traits<char> >()); 00170 result->open(_Stl_extract_open_param(x), mode); 00171 00172 if (result->is_open()) 00173 return result.release(); 00174 00175 return 0; 00176 } 00177 00178 #if !defined (_STLP_NO_WCHAR_T) 00179 static wfilebuf* 00180 _Stl_create_wfilebuf(FILE* f, ios_base::openmode mode) { 00181 auto_ptr<wfilebuf> result(new basic_filebuf<wchar_t, char_traits<wchar_t> >()); 00182 result->_M_open(_FILE_fd(f), mode); 00183 00184 if (result->is_open()) 00185 return result.release(); 00186 00187 return 0; 00188 } 00189 #endif 00190 00191 void _STLP_CALL ios_base::_S_initialize() { 00192 #if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE) 00193 using _STLP_PRIV stdio_istreambuf; 00194 using _STLP_PRIV stdio_ostreambuf; 00195 #endif 00196 00197 auto_ptr<streambuf> cin_buf; 00198 auto_ptr<streambuf> cout_buf; 00199 auto_ptr<streambuf> cerr_buf; 00200 auto_ptr<streambuf> clog_buf; 00201 00202 if (_S_is_synced) 00203 cin_buf.reset(new stdio_istreambuf(stdin)); 00204 else 00205 cin_buf.reset(_Stl_create_filebuf(stdin, ios_base::in)); 00206 00207 if (_S_is_synced) { 00208 #ifdef _STLP_REDIRECT_STDSTREAMS 00209 cout_buf.reset(_Stl_create_filebuf("/stdout.txt", ios::out)); 00210 cerr_buf.reset(_Stl_create_filebuf("/stderr.txt", ios::out)); 00211 clog_buf.reset(_Stl_create_filebuf("/stdlog.txt", ios::out)); 00212 #else 00213 cout_buf.reset(new stdio_ostreambuf(stdout)); 00214 cerr_buf.reset(new stdio_ostreambuf(stderr)); 00215 clog_buf.reset(new stdio_ostreambuf(stderr)); 00216 #endif 00217 } 00218 else { 00219 cout_buf.reset(_Stl_create_filebuf(stdout, ios_base::out)); 00220 cerr_buf.reset(_Stl_create_filebuf(stderr, ios_base::out)); 00221 clog_buf.reset(_Stl_create_filebuf(stderr, ios_base::out)); 00222 } 00223 00224 istream* ptr_cin = new(&cin) istream(cin_buf.get()); cin_buf.release(); 00225 ostream* ptr_cout = new(&cout) ostream(cout_buf.get()); cout_buf.release(); 00226 ostream* ptr_cerr = new(&cerr) ostream(cerr_buf.get()); cerr_buf.release(); 00227 /*ostream* ptr_clog = */ new(&clog) ostream(clog_buf.get()); clog_buf.release(); 00228 ptr_cin->tie(ptr_cout); 00229 ptr_cerr->setf(ios_base::unitbuf); 00230 00231 #ifndef _STLP_NO_WCHAR_T 00232 auto_ptr<wfilebuf> win(_Stl_create_wfilebuf(stdin, ios_base::in)); 00233 auto_ptr<wfilebuf> wout(_Stl_create_wfilebuf(stdout, ios_base::out)); 00234 auto_ptr<wfilebuf> werr(_Stl_create_wfilebuf(stderr, ios_base::out)); 00235 auto_ptr<wfilebuf> wlog(_Stl_create_wfilebuf(stderr, ios_base::out)); 00236 00237 // Run constructors for the four wide stream objects. 00238 wistream* ptr_wcin = new(&wcin) wistream(win.get()); win.release(); 00239 wostream* ptr_wcout = new(&wcout) wostream(wout.get()); wout.release(); 00240 wostream* ptr_wcerr = new(&wcerr) wostream(werr.get()); werr.release(); 00241 /*wostream* ptr_wclog = */ new(&wclog) wostream(wlog.get()); wlog.release(); 00242 00243 ptr_wcin->tie(ptr_wcout); 00244 ptr_wcerr->setf(ios_base::unitbuf); 00245 #endif 00246 } 00247 00248 void _STLP_CALL ios_base::_S_uninitialize() { 00249 // Note that destroying output streambufs flushes the buffers. 00250 istream* ptr_cin = &cin; 00251 ostream* ptr_cout = &cout; 00252 ostream* ptr_cerr = &cerr; 00253 ostream* ptr_clog = &clog; 00254 00255 // We don't want any exceptions being thrown here 00256 ptr_cin->exceptions(0); 00257 ptr_cout->exceptions(0); 00258 ptr_cerr->exceptions(0); 00259 ptr_clog->exceptions(0); 00260 00261 delete ptr_cin->rdbuf(0); 00262 delete ptr_cout->rdbuf(0); 00263 delete ptr_cerr->rdbuf(0); 00264 delete ptr_clog->rdbuf(0); 00265 00266 _Destroy(ptr_cin); 00267 _Destroy(ptr_cout); 00268 _Destroy(ptr_cerr); 00269 _Destroy(ptr_clog); 00270 00271 #ifndef _STLP_NO_WCHAR_T 00272 wistream* ptr_wcin = &wcin; 00273 wostream* ptr_wcout = &wcout; 00274 wostream* ptr_wcerr = &wcerr; 00275 wostream* ptr_wclog = &wclog; 00276 00277 // We don't want any exceptions being thrown here 00278 ptr_wcin->exceptions(0); 00279 ptr_wcout->exceptions(0); 00280 ptr_wcerr->exceptions(0); 00281 ptr_wclog->exceptions(0); 00282 00283 delete ptr_wcin->rdbuf(0); 00284 delete ptr_wcout->rdbuf(0); 00285 delete ptr_wcerr->rdbuf(0); 00286 delete ptr_wclog->rdbuf(0); 00287 00288 _Destroy(ptr_wcin); 00289 _Destroy(ptr_wcout); 00290 _Destroy(ptr_wcerr); 00291 _Destroy(ptr_wclog); 00292 #endif 00293 } 00294 00295 00296 bool _STLP_CALL ios_base::sync_with_stdio(bool sync) { 00297 # if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE) 00298 using _STLP_PRIV stdio_istreambuf; 00299 using _STLP_PRIV stdio_ostreambuf; 00300 # endif 00301 00302 if (sync == _S_is_synced) return sync; 00303 00304 // if by any chance we got there before std streams initialization, 00305 // just set the sync flag and exit 00306 if (Init::_S_count == 0) { 00307 _S_is_synced = sync; 00308 return sync; 00309 } 00310 00311 auto_ptr<streambuf> cin_buf; 00312 auto_ptr<streambuf> cout_buf; 00313 auto_ptr<streambuf> cerr_buf; 00314 auto_ptr<streambuf> clog_buf; 00315 00316 if (sync) 00317 cin_buf.reset(new stdio_istreambuf(stdin)); 00318 else 00319 cin_buf.reset(_Stl_create_filebuf(stdin, ios_base::in)); 00320 00321 if (sync) { 00322 #ifdef _STLP_REDIRECT_STDSTREAMS 00323 cout_buf.reset(_Stl_create_filebuf("/stdout.txt", ios::out)); 00324 cerr_buf.reset(_Stl_create_filebuf("/stderr.txt", ios::out)); 00325 clog_buf.reset(_Stl_create_filebuf("/stdlog.txt", ios::out)); 00326 #else 00327 cout_buf.reset(new stdio_ostreambuf(stdout)); 00328 cerr_buf.reset(new stdio_ostreambuf(stderr)); 00329 clog_buf.reset(new stdio_ostreambuf(stderr)); 00330 #endif 00331 } 00332 else { 00333 cout_buf.reset(_Stl_create_filebuf(stdout, ios_base::out)); 00334 cerr_buf.reset(_Stl_create_filebuf(stderr, ios_base::out)); 00335 clog_buf.reset(_Stl_create_filebuf(stderr, ios_base::out)); 00336 } 00337 00338 if (cin_buf.get() != 0 && cout_buf.get() != 0 && cerr_buf.get() != 0 && clog_buf.get() != 0) { 00339 // When streambuf passed to rdbuf is not null, rdbuf is exception safe: 00340 delete (&cin)->rdbuf(cin_buf.release()); 00341 delete (&cout)->rdbuf(cout_buf.release()); 00342 delete (&cerr)->rdbuf(cerr_buf.release()); 00343 delete (&clog)->rdbuf(clog_buf.release()); 00344 _S_is_synced = sync; 00345 } 00346 00347 return _S_is_synced; 00348 } 00349 00350 _STLP_END_NAMESPACE 00351 00352 // Local Variables: 00353 // mode:C++ 00354 // End: Generated on Mon May 28 2012 04:34:58 for ReactOS by
1.7.6.1
|