1 #ifndef CORELIB___NCBISTRE__HPP
2 #define CORELIB___NCBISTRE__HPP
3
4 /* $Id: ncbistre.hpp 633662 2021-06-23 13:15:42Z ivanov $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Denis Vakatov, Anton Lavrentiev
30 *
31 *
32 */
33
34 /// @file ncbistre.hpp
35 /// NCBI C++ stream class wrappers for triggering between "new" and
36 /// "old" C++ stream libraries.
37
38
39 #include <corelib/ncbictype.hpp>
40
41 /// Determine which iostream library to use, include appropriate
42 /// headers, and #define specific preprocessor variables.
43 /// The default is the new(template-based, std::) one.
44
45 #if !defined(HAVE_IOSTREAM) && !defined(NCBI_USE_OLD_IOSTREAM)
46 # define NCBI_USE_OLD_IOSTREAM
47 #endif
48
49 #if defined(HAVE_IOSTREAM_H) && defined(NCBI_USE_OLD_IOSTREAM)
50 # include <iostream.h>
51 # include <fstream.h>
52 # if defined(HAVE_STRSTREA_H)
53 # include <strstrea.h>
54 # else
55 # include <strstream.h>
56 # endif
57 # include <iomanip.h>
58 # define IO_PREFIX
59 # define IOS_BASE ::ios
60 # define IOS_PREFIX ::ios
61 # define PUBSYNC sync
62 # define PUBSEEKPOS seekpos
63 # define PUBSEEKOFF seekoff
64
65 #elif defined(HAVE_IOSTREAM)
66 # if defined(NCBI_USE_OLD_IOSTREAM)
67 # undef NCBI_USE_OLD_IOSTREAM
68 # endif
69 # if defined(NCBI_COMPILER_GCC) || \
70 (defined(NCBI_COMPILER_ANY_CLANG) && defined(__GLIBCXX__))
71 // Don't bug us about including <strstream>.
72 # define _CPP_BACKWARD_BACKWARD_WARNING_H 1
73 # define _BACKWARD_BACKWARD_WARNING_H 1
74 # endif
75 # include <iostream>
76 # include <fstream>
77 # if defined(NCBI_COMPILER_ICC) && defined(__GNUC__) && !defined(__INTEL_CXXLIB_ICC)
78 # define _BACKWARD_BACKWARD_WARNING_H 1
79 # include <backward/strstream>
80 # else
81 #if 1
82 # include <strstream>
83 #else
84 #define NCBI_SHUN_OSTRSTREAM 1
85 #endif
86 # include <sstream>
87 # endif
88 # include <iomanip>
89 # define IO_PREFIX NCBI_NS_STD
90 # define IOS_BASE IO_PREFIX::ios_base
91 # define IOS_PREFIX IO_PREFIX::ios
92
93 # ifdef NO_PUBSYNC
94 # define PUBSYNC sync
95 # define PUBSETBUF setbuf
96 # define PUBSEEKOFF seekoff
97 # define PUBSEEKPOS seekpos
98 # else
99 # define PUBSYNC pubsync
100 # define PUBSETBUF pubsetbuf
101 # define PUBSEEKOFF pubseekoff
102 # define PUBSEEKPOS pubseekpos
103 # endif
104
105 # ifdef _LIBCPP_VERSION
106 # define NCBI_SHUN_OSTRSTREAM 1
107 # include <sstream>
108 # endif
109
110 #else
111 # error "Neither <iostream> nor <iostream.h> can be found!"
112 #endif
113
114 // Obsolete
115 #define SEEKOFF PUBSEEKOFF
116
117 #include <stddef.h>
118
119
120 // (BEGIN_NCBI_SCOPE must be followed by END_NCBI_SCOPE later in this file)
121 BEGIN_NCBI_SCOPE
122
123 /** @addtogroup Stream
124 *
125 * @{
126 */
127
128 // I/O classes
129
130 /// Portable alias for streampos.
131 typedef IO_PREFIX::streampos CNcbiStreampos;
132
133 /// Portable alias for streamoff.
134 typedef IO_PREFIX::streamoff CNcbiStreamoff;
135
136 /// Portable alias for ios.
137 typedef IO_PREFIX::ios CNcbiIos;
138
139 /// Portable alias for streambuf.
140 typedef IO_PREFIX::streambuf CNcbiStreambuf;
141
142 /// Portable alias for istream.
143 typedef IO_PREFIX::istream CNcbiIstream;
144
145 /// Portable alias for ostream.
146 typedef IO_PREFIX::ostream CNcbiOstream;
147
148 /// Portable alias for iostream.
149 typedef IO_PREFIX::iostream CNcbiIostream;
150
151 #ifndef NCBI_SHUN_OSTRSTREAM
152 /// Portable alias for strstreambuf.
153 //typedef IO_PREFIX::strstreambuf CNcbiStrstreambuf;
154
155 /// Portable alias for istrstream.
156 //typedef IO_PREFIX::istrstream CNcbiIstrstream;
157
158 /// Portable alias for ostrstream.
159 //typedef IO_PREFIX::ostrstream CNcbiOstrstream;
160
161 /// Portable alias for strstream.
162 //typedef IO_PREFIX::strstream CNcbiStrstream;
163 # define NCBI_STRSTREAM_INIT(p, l) (p), (l)
164
165 class CNcbiIstrstream : public IO_PREFIX::istrstream
166 {
167 public:
168 typedef IO_PREFIX::istrstream _Mybase;
169
CNcbiIstrstream(const string & _Str)170 explicit CNcbiIstrstream(const string& _Str)
171 : _Mybase(_Str.data(), _Str.size()) {
172 }
173 // [[deprecated("(const char*) constructor: review, maybe using string argument is better")]]
CNcbiIstrstream(const char * _Ptr)174 explicit CNcbiIstrstream(const char *_Ptr)
175 : _Mybase(_Ptr) {
176 }
177
178 [[deprecated("(char*) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbiIstrstream(char * _Ptr)179 explicit CNcbiIstrstream(char *_Ptr)
180 : _Mybase(_Ptr) {
181 }
182 #if !defined(NCBI_COMPILER_MSVC) || (NCBI_COMPILER_VERSION > 1916)
183 template<class T>
184 using enable_if_integral = typename std::enable_if<std::is_integral<T>::value>;
185
186 template< typename TInteger, typename = typename enable_if_integral<TInteger>::type >
187 [[deprecated("(char*, Tinteger) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbiIstrstream(char * _Ptr,TInteger _Count)188 CNcbiIstrstream(char *_Ptr, TInteger _Count)
189 : _Mybase(_Ptr, _Count) {
190 }
191 template< typename TInteger, typename = typename enable_if_integral<TInteger>::type >
192 // [[deprecated("(const char*, Tinteger) constructor is deprecated, consider using string argument instead")]]
CNcbiIstrstream(const char * _Ptr,TInteger _Count)193 CNcbiIstrstream(const char *_Ptr, TInteger _Count)
194 : _Mybase(_Ptr, _Count) {
195 }
196 #else
197 [[deprecated("(char*, streamsize) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbiIstrstream(char * _Ptr,streamsize _Count)198 CNcbiIstrstream(char *_Ptr, streamsize _Count)
199 : _Mybase(_Ptr, (int)_Count) {
200 }
201 [[deprecated("(char*, size_t) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbiIstrstream(char * _Ptr,size_t _Count)202 CNcbiIstrstream(char *_Ptr, size_t _Count)
203 : _Mybase(_Ptr, (int)_Count) {
204 }
205 [[deprecated("(char*, int) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbiIstrstream(char * _Ptr,int _Count)206 CNcbiIstrstream(char *_Ptr, int _Count)
207 : _Mybase(_Ptr, _Count) {
208 }
209 // [[deprecated("(const char*, streamsize) constructor is deprecated, consider using string argument instead")]]
CNcbiIstrstream(const char * _Ptr,streamsize _Count)210 CNcbiIstrstream(const char *_Ptr, streamsize _Count)
211 : _Mybase(_Ptr, _Count) {
212 }
213 // [[deprecated("(const char*, size_t) constructor is deprecated, consider using string argument instead")]]
CNcbiIstrstream(const char * _Ptr,size_t _Count)214 CNcbiIstrstream(const char *_Ptr, size_t _Count)
215 : _Mybase(_Ptr, _Count) {
216 }
217 // [[deprecated("(const char*, int) constructor is deprecated, consider using string argument instead")]]
CNcbiIstrstream(const char * _Ptr,int _Count)218 CNcbiIstrstream(const char *_Ptr, int _Count)
219 : _Mybase(_Ptr, _Count) {
220 }
221 #endif
222
223 #if 0
224 CNcbiIstrstream(CNcbiIstrstream&& _Right)
225 : _Mybase(std::move(_Right)) {
226 }
227 CNcbiIstrstream& operator=(CNcbiIstrstream&& _Right) {
228 _Mybase::operator=(std::move(_Right));
229 return (*this);
230 }
231 #endif
232 };
233
234 template<typename _Base, IOS_BASE::openmode _DefMode>
235 class CNcbistrstream_Base : public _Base
236 {
237 public:
238 typedef _Base _Mybase;
CNcbistrstream_Base(void)239 CNcbistrstream_Base(void)
240 : _Mybase() {
241 }
242 #if 0
243 CNcbistrstream_Base(const string& _Str, IOS_BASE::openmode _Mode = _DefMode)
244 : _Mybase( const_cast<char*>(_Str.data()), _Str.size(), _Mode) {
245 }
246 #endif
247 #if !defined(NCBI_COMPILER_MSVC) || (NCBI_COMPILER_VERSION > 1916)
248 template<class T>
249 using enable_if_integral = typename std::enable_if<std::is_integral<T>::value>;
250
251 template< typename TInteger, typename = typename enable_if_integral<TInteger>::type >
252 [[deprecated("(char*, Tinteger, ios::openmode) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbistrstream_Base(char * _Ptr,TInteger _Count,IOS_BASE::openmode _Mode=_DefMode)253 CNcbistrstream_Base(char *_Ptr, TInteger _Count, IOS_BASE::openmode _Mode = _DefMode)
254 : _Mybase(_Ptr, _Count, _Mode) {
255 }
256 #else
257 [[deprecated("(char*, streamsize, ios::openmode) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbistrstream_Base(char * _Ptr,streamsize _Count,IOS_BASE::openmode _Mode=_DefMode)258 CNcbistrstream_Base(char *_Ptr, streamsize _Count, IOS_BASE::openmode _Mode = _DefMode)
259 : _Mybase(_Ptr, _Count, _Mode) {
260 }
261 [[deprecated("(char*, size_t, ios::openmode) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbistrstream_Base(char * _Ptr,size_t _Count,IOS_BASE::openmode _Mode=_DefMode)262 CNcbistrstream_Base(char *_Ptr, size_t _Count, IOS_BASE::openmode _Mode = _DefMode)
263 : _Mybase(_Ptr, _Count, _Mode) {
264 }
265 [[deprecated("(char*, int, ios::openmode) constructor is deprecated, WILL BE REMOVED SOON")]]
CNcbistrstream_Base(char * _Ptr,int _Count,IOS_BASE::openmode _Mode=_DefMode)266 CNcbistrstream_Base(char *_Ptr, int _Count, IOS_BASE::openmode _Mode = _DefMode)
267 : _Mybase(_Ptr, _Count, _Mode) {
268 }
269 #endif
270
271 #if 0
272 CNcbistrstream_Base(CNcbistrstream_Base&& _Right)
273 : _Mybase(std::move(_Right)) {
274 }
275 CNcbistrstream_Base& operator=(CNcbistrstream_Base&& _Right) {
276 _Mybase::operator=(std::move(_Right));
277 return (*this);
278 }
279 #endif
280 };
281 using CNcbiOstrstream = CNcbistrstream_Base<IO_PREFIX::ostrstream, IOS_BASE::out>;
282 using CNcbiStrstream = CNcbistrstream_Base<IO_PREFIX::strstream, IOS_BASE::in | IOS_BASE::out>;
283 #if defined(NCBI_COMPILER_MSVC)
284 template class NCBI_XNCBI_EXPORT CNcbistrstream_Base<IO_PREFIX::ostrstream, IOS_BASE::out>;
285 template class NCBI_XNCBI_EXPORT CNcbistrstream_Base<IO_PREFIX::strstream, IOS_BASE::in | IOS_BASE::out>;
286 #endif
287
288 #else
289 #if 1
290 //typedef IO_PREFIX::stringbuf CNcbiStrstreambuf;
291 typedef IO_PREFIX::istringstream CNcbiIstrstream;
292 typedef IO_PREFIX::ostringstream CNcbiOstrstream;
293 typedef IO_PREFIX::stringstream CNcbiStrstream;
294 # define NCBI_STRSTREAM_INIT(p, l) string(p, l)
295 #else
296 # define NCBI_STRSTREAM_INIT(p, l) (p), (l)
297 template<typename _Base, IOS_BASE::openmode _DefMode>
298 class CNcbistrstream_Base : public _Base
299 {
300 public:
301 typedef _Base _Mybase;
CNcbistrstream_Base(IOS_BASE::openmode _Mode=_DefMode)302 explicit CNcbistrstream_Base(IOS_BASE::openmode _Mode = _DefMode)
303 : _Mybase(_Mode) {
304 }
CNcbistrstream_Base(const string & _Str,IOS_BASE::openmode _Mode=_DefMode)305 explicit CNcbistrstream_Base(const string& _Str, IOS_BASE::openmode _Mode = _DefMode)
306 : _Mybase(_Str, _Mode) {
307 }
308
309 #if !defined(NCBI_COMPILER_MSVC) || (NCBI_COMPILER_VERSION > 1916)
310 template<class T>
311 using enable_if_integral = typename std::enable_if<std::is_integral<T>::value>;
312
313 template< typename TInteger, typename = typename enable_if_integral<TInteger>::type >
314 [[deprecated("(const char*, Tinteger, ios::openmode) constructor is deprecated, use string argument instead")]]
CNcbistrstream_Base(const char * _Ptr,TInteger _Count,IOS_BASE::openmode _Mode=_DefMode)315 CNcbistrstream_Base(const char *_Ptr, TInteger _Count, IOS_BASE::openmode _Mode = _DefMode)
316 : _Mybase(string(_Ptr, _Count), _Mode) {
317 }
318 #else
319 [[deprecated("(const char*, streamsize, ios::openmode) constructor is deprecated, use string argument instead")]]
CNcbistrstream_Base(const char * s,streamsize n,IOS_BASE::openmode _Mode=_DefMode)320 CNcbistrstream_Base(const char* s, streamsize n, IOS_BASE::openmode _Mode = _DefMode)
321 : _Mybase(string(s,n), _Mode) {
322 }
323 [[deprecated("(const char*, size_t, ios::openmode) constructor is deprecated, use string argument instead")]]
CNcbistrstream_Base(const char * s,size_t n,IOS_BASE::openmode _Mode=_DefMode)324 CNcbistrstream_Base(const char* s, size_t n, IOS_BASE::openmode _Mode = _DefMode)
325 : _Mybase(string(s,n), _Mode) {
326 }
327 [[deprecated("(const char*, int, ios::openmode) constructor is deprecated, use string argument instead")]]
CNcbistrstream_Base(const char * s,int n,IOS_BASE::openmode _Mode=_DefMode)328 CNcbistrstream_Base(const char* s, int n, IOS_BASE::openmode _Mode = _DefMode)
329 : _Mybase(string(s,n), _Mode) {
330 }
331 #endif
332
333 template< typename TInteger>
334 CNcbistrstream_Base(char* s, TInteger n) = delete;
335 template< typename TInteger>
336 CNcbistrstream_Base(char* s, TInteger n, IOS_BASE::openmode _Mode) = delete;
337
338 #if 0
339 CNcbistrstream_Base(CNcbistrstream_Base&& _Right)
340 : _Mybase(std::move(_Right)) {
341 }
342 CNcbistrstream_Base& operator=(CNcbistrstream_Base&& _Right) {
343 _Mybase::operator=(std::move(_Right));
344 return (*this);
345 }
346 #endif
347 };
348 using CNcbiIstrstream = CNcbistrstream_Base<IO_PREFIX::istringstream, IOS_BASE::in>;
349 using CNcbiOstrstream = CNcbistrstream_Base<IO_PREFIX::ostringstream, IOS_BASE::out>;
350 using CNcbiStrstream = CNcbistrstream_Base<IO_PREFIX::stringstream, IOS_BASE::in | IOS_BASE::out>;
351 #if defined(NCBI_COMPILER_MSVC)
352 template class NCBI_XNCBI_EXPORT CNcbistrstream_Base<IO_PREFIX::istringstream, IOS_BASE::in>;
353 template class NCBI_XNCBI_EXPORT CNcbistrstream_Base<IO_PREFIX::ostringstream, IOS_BASE::out>;
354 template class NCBI_XNCBI_EXPORT CNcbistrstream_Base<IO_PREFIX::stringstream, IOS_BASE::in | IOS_BASE::out>;
355 #endif
356 #endif
357 #endif
358
359 /// Portable alias for filebuf.
360 typedef IO_PREFIX::filebuf CNcbiFilebuf;
361
362
363 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE)
364 // this is helper method for fstream classes only
365 // do not use it elsewhere
366 NCBI_XNCBI_EXPORT
367 wstring ncbi_Utf8ToWstring(const char *utf8);
368
369 class CNcbiIfstream : public IO_PREFIX::ifstream
370 {
371 public:
CNcbiIfstream()372 CNcbiIfstream( ) {
373 }
CNcbiIfstream(const char * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in,int _Prot=(int)IOS_BASE::_Openprot)374 explicit CNcbiIfstream(
375 const char *_Filename,
376 IOS_BASE::openmode _Mode = IOS_BASE::in,
377 int _Prot = (int)IOS_BASE::_Openprot
378 ) : IO_PREFIX::ifstream(
379 ncbi_Utf8ToWstring(_Filename).c_str(), _Mode, _Prot) {
380 }
CNcbiIfstream(const string & _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in,int _Prot=(int)IOS_BASE::_Openprot)381 explicit CNcbiIfstream(
382 const string& _Filename,
383 IOS_BASE::openmode _Mode = IOS_BASE::in,
384 int _Prot = (int)IOS_BASE::_Openprot
385 ) : CNcbiIfstream(_Filename.c_str(), _Mode, _Prot) {
386 }
CNcbiIfstream(const wchar_t * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in,int _Prot=(int)IOS_BASE::_Openprot)387 explicit CNcbiIfstream(
388 const wchar_t *_Filename,
389 IOS_BASE::openmode _Mode = IOS_BASE::in,
390 int _Prot = (int)IOS_BASE::_Openprot
391 ) : IO_PREFIX::ifstream(_Filename,_Mode,_Prot) {
392 }
CNcbiIfstream(const wstring & _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in,int _Prot=(int)IOS_BASE::_Openprot)393 explicit CNcbiIfstream(
394 const wstring& _Filename,
395 IOS_BASE::openmode _Mode = IOS_BASE::in,
396 int _Prot = (int)IOS_BASE::_Openprot
397 ) : CNcbiIfstream(_Filename.c_str(),_Mode,_Prot) {
398 }
399
open(const char * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in,int _Prot=(int)IOS_BASE::_Openprot)400 void open(
401 const char *_Filename,
402 IOS_BASE::openmode _Mode = IOS_BASE::in,
403 int _Prot = (int)IOS_BASE::_Openprot) {
404 IO_PREFIX::ifstream::open(
405 ncbi_Utf8ToWstring(_Filename).c_str(), _Mode, _Prot);
406 }
open(const string & _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in,int _Prot=(int)IOS_BASE::_Openprot)407 void open(
408 const string& _Filename,
409 IOS_BASE::openmode _Mode = IOS_BASE::in,
410 int _Prot = (int)IOS_BASE::_Openprot) {
411 CNcbiIfstream::open(_Filename.c_str(), _Mode, _Prot);
412 }
open(const wchar_t * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in,int _Prot=(int)ios_base::_Openprot)413 void open(const wchar_t *_Filename,
414 IOS_BASE::openmode _Mode = IOS_BASE::in,
415 int _Prot = (int)ios_base::_Openprot) {
416 IO_PREFIX::ifstream::open(_Filename,_Mode,_Prot);
417 }
open(const wstring & _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in,int _Prot=(int)ios_base::_Openprot)418 void open(const wstring& _Filename,
419 IOS_BASE::openmode _Mode = IOS_BASE::in,
420 int _Prot = (int)ios_base::_Openprot) {
421 CNcbiIfstream::open(_Filename.c_str(), _Mode, _Prot);
422 }
423 };
424 #else
425 /// Portable alias for ifstream.
426 typedef IO_PREFIX::ifstream CNcbiIfstream;
427 #endif
428
429 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE)
430 class CNcbiOfstream : public IO_PREFIX::ofstream
431 {
432 public:
CNcbiOfstream()433 CNcbiOfstream( ) {
434 }
CNcbiOfstream(const char * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)435 explicit CNcbiOfstream(
436 const char *_Filename,
437 IOS_BASE::openmode _Mode = IOS_BASE::out,
438 int _Prot = (int)IOS_BASE::_Openprot
439 ) : IO_PREFIX::ofstream(
440 ncbi_Utf8ToWstring(_Filename).c_str(), _Mode, _Prot) {
441 }
CNcbiOfstream(const string & _Filename,IOS_BASE::openmode _Mode=IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)442 explicit CNcbiOfstream(
443 const string& _Filename,
444 IOS_BASE::openmode _Mode = IOS_BASE::out,
445 int _Prot = (int)IOS_BASE::_Openprot
446 ) : CNcbiOfstream(_Filename.c_str(), _Mode, _Prot) {
447 }
CNcbiOfstream(const wchar_t * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)448 explicit CNcbiOfstream(
449 const wchar_t *_Filename,
450 IOS_BASE::openmode _Mode = IOS_BASE::out,
451 int _Prot = (int)IOS_BASE::_Openprot
452 ) : IO_PREFIX::ofstream(_Filename,_Mode,_Prot) {
453 }
CNcbiOfstream(const wstring & _Filename,IOS_BASE::openmode _Mode=IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)454 explicit CNcbiOfstream(
455 const wstring& _Filename,
456 IOS_BASE::openmode _Mode = IOS_BASE::out,
457 int _Prot = (int)IOS_BASE::_Openprot
458 ) : CNcbiOfstream(_Filename.c_str(),_Mode,_Prot) {
459 }
460
open(const char * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)461 void open(
462 const char *_Filename,
463 IOS_BASE::openmode _Mode = IOS_BASE::out,
464 int _Prot = (int)IOS_BASE::_Openprot) {
465 IO_PREFIX::ofstream::open(
466 ncbi_Utf8ToWstring(_Filename).c_str(), _Mode, _Prot);
467 }
open(const string & _Filename,IOS_BASE::openmode _Mode=IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)468 void open(
469 const string& _Filename,
470 IOS_BASE::openmode _Mode = IOS_BASE::out,
471 int _Prot = (int)IOS_BASE::_Openprot) {
472 CNcbiOfstream::open(_Filename.c_str(), _Mode, _Prot);
473 }
open(const wchar_t * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)474 void open(const wchar_t *_Filename,
475 IOS_BASE::openmode _Mode = IOS_BASE::out,
476 int _Prot = (int)IOS_BASE::_Openprot) {
477 IO_PREFIX::ofstream::open(_Filename,_Mode,_Prot);
478 }
open(const wstring & _Filename,IOS_BASE::openmode _Mode=IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)479 void open(const wstring& _Filename,
480 IOS_BASE::openmode _Mode = IOS_BASE::out,
481 int _Prot = (int)IOS_BASE::_Openprot) {
482 CNcbiOfstream::open(_Filename.c_str(), _Mode, _Prot);
483 }
484 };
485 #else
486 /// Portable alias for ofstream.
487 typedef IO_PREFIX::ofstream CNcbiOfstream;
488 #endif
489
490 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE)
491 class CNcbiFstream : public IO_PREFIX::fstream
492 {
493 public:
CNcbiFstream()494 CNcbiFstream( ) {
495 }
CNcbiFstream(const char * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in|IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)496 explicit CNcbiFstream(
497 const char *_Filename,
498 IOS_BASE::openmode _Mode = IOS_BASE::in | IOS_BASE::out,
499 int _Prot = (int)IOS_BASE::_Openprot
500 ) : IO_PREFIX::fstream(
501 ncbi_Utf8ToWstring(_Filename).c_str(), _Mode, _Prot) {
502 }
CNcbiFstream(const wchar_t * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in|IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)503 explicit CNcbiFstream(
504 const wchar_t *_Filename,
505 IOS_BASE::openmode _Mode = IOS_BASE::in | IOS_BASE::out,
506 int _Prot = (int)IOS_BASE::_Openprot
507 ) : IO_PREFIX::fstream(_Filename,_Mode,_Prot) {
508 }
509
open(const char * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in|IOS_BASE::out,int _Prot=(int)IOS_BASE::_Openprot)510 void open(
511 const char *_Filename,
512 IOS_BASE::openmode _Mode = IOS_BASE::in | IOS_BASE::out,
513 int _Prot = (int)IOS_BASE::_Openprot) {
514 IO_PREFIX::fstream::open(
515 ncbi_Utf8ToWstring(_Filename).c_str(), _Mode, _Prot);
516 }
open(const wchar_t * _Filename,IOS_BASE::openmode _Mode=IOS_BASE::in|IOS_BASE::out,int _Prot=(int)ios_base::_Openprot)517 void open(const wchar_t *_Filename,
518 IOS_BASE::openmode _Mode = IOS_BASE::in | IOS_BASE::out,
519 int _Prot = (int)ios_base::_Openprot) {
520 IO_PREFIX::fstream::open(_Filename,_Mode,_Prot);
521 }
522 };
523 #else
524 /// Portable alias for fstream.
525 typedef IO_PREFIX::fstream CNcbiFstream;
526 #endif
527
528 // Standard I/O streams
529 #define NcbiCin IO_PREFIX::cin
530 #define NcbiCout IO_PREFIX::cout
531 #define NcbiCerr IO_PREFIX::cerr
532 #define NcbiClog IO_PREFIX::clog
533
534 // I/O manipulators (the list may be incomplete)
535 #define NcbiEndl IO_PREFIX::endl
536 #define NcbiEnds IO_PREFIX::ends
537 #define NcbiFlush IO_PREFIX::flush
538
539 #define NcbiDec IO_PREFIX::dec
540 #define NcbiHex IO_PREFIX::hex
541 #define NcbiOct IO_PREFIX::oct
542 #define NcbiWs IO_PREFIX::ws
543
544 #define NcbiFixed IO_PREFIX::fixed
545 #define NcbiScientific IO_PREFIX::scientific
546
547 #define NcbiSetbase IO_PREFIX::setbase
548 #define NcbiResetiosflags IO_PREFIX::resetiosflags
549 #define NcbiSetiosflags IO_PREFIX::setiosflags
550 #define NcbiSetfill IO_PREFIX::setfill
551 #define NcbiSetprecision IO_PREFIX::setprecision
552 #define NcbiSetw IO_PREFIX::setw
553
554 // I/O state
555 #define NcbiGoodbit IOS_PREFIX::goodbit
556 #define NcbiEofbit IOS_PREFIX::eofbit
557 #define NcbiFailbit IOS_PREFIX::failbit
558 #define NcbiBadbit IOS_PREFIX::badbit
559 #define NcbiHardfail IOS_PREFIX::hardfail
560
561
562 /// Platform-specific EndOfLine
563 NCBI_XNCBI_EXPORT
564 extern const char* Endl(void);
565
566 /// Read from "is" to "str" up to the delimiter symbol "delim" (or EOF)
567 NCBI_XNCBI_EXPORT
568 extern CNcbiIstream& NcbiGetline(CNcbiIstream& is, string& str, char delim,
569 string::size_type* count = NULL);
570
571 /// Read from "is" to "str" up to any symbol contained within "delims" (or EOF)
572 /// @note
573 /// Special case -- if two different delimiters are back to back and in the
574 /// same order as in delims, treat them as a single delimiter. E.g. "\r\n"
575 /// will handle mixed DOS/MAC/UNIX line endings such as "\r", "\n" and "\r\n".
576 NCBI_XNCBI_EXPORT
577 extern CNcbiIstream& NcbiGetline(CNcbiIstream& is, string& str,
578 const string& delims,
579 string::size_type* count = NULL);
580
581 /// Read from "is" to "str" the next line
582 /// (taking into account platform specifics of End-of-Line)
583 NCBI_XNCBI_EXPORT
584 extern CNcbiIstream& NcbiGetlineEOL(CNcbiIstream& is, string& str,
585 string::size_type* count = NULL);
586
587
588 /// Copy the entire contents of stream "is" to stream "os".
589 /// @return
590 /// "true" if the operation was successful, i.e. "is" had been read entirely
591 /// with all of its _available_ contents (including none) written to "os";
592 /// "false" if either extraction from "is" or insertion into "os" failed.
593 ///
594 /// The call may throw exceptions only if they are enabled on the respective
595 /// stream(s).
596 ///
597 /// @note The call is an extension to the standard
598 /// ostream& ostream::operator<<(streambuf*),
599 /// which severely lacks error checking (esp. for partial write failures).
600 ///
601 /// @note Input ("is") stream state is not always asserted accurately: in
602 /// particular, upon successful completion "is.eof()" may not necessarily be
603 /// true; or, in case of fatal read errors "is" may not have its "is.bad()"
604 /// state set (however, the return code should still be "false" to properly
605 /// indicate the copy failure in this case).
606 ///
607 /// @attention This call (as well as the mentioned STL counterpart) provides
608 /// only the mechanism of delivering data to the destination stream(buf) "os";
609 /// and a successful return result does not generally guarantee that the data
610 /// have yet reached the physical destination. Other "os"-specific API must be
611 /// performed to assure the data integrity at the receiving device: such as
612 /// checking for errors after doing a "close()" (if "os" is an ofstream, for
613 /// example). For instance, uploading into the Toolkit FTP stream must be
614 /// finalized with a read for the byte count delivered; otherwise, it may not
615 /// work correctly.
616 /// @sa
617 /// CConn_IOStream
618 NCBI_XNCBI_EXPORT
619 extern bool NcbiStreamCopy(CNcbiOstream& os, CNcbiIstream& is);
620
621
622 /// Same as NcbiStreamCopy() but throws an CCoreException when copy fails.
623 /// @sa
624 /// NcbiStreamCopy, CCoreException
625 NCBI_XNCBI_EXPORT
626 extern void NcbiStreamCopyThrow(CNcbiOstream& os, CNcbiIstream& is);
627
628
629 /// Input the entire contents of an istream into a string (NULL causes drain).
630 /// "is" gets its failbit set if nothing was extracted from it; and gets its
631 /// eofbit (w/o failbit) set if the stream has reached an EOF condition.
632 ///
633 /// @param pos
634 /// Where in "*s" to begin saving data (ignored when "s" == NULL).
635 /// @return
636 /// Size of copied data if the operation was successful (i.e. "is" had
637 /// reached EOF), 0 otherwise.
638 /// @note
639 /// If "s" != NULL, then "s->size() >= pos" always upon return.
640 /// @sa
641 /// NcbiStreamCopy
642 NCBI_XNCBI_EXPORT
643 extern size_t NcbiStreamToString(string* s, CNcbiIstream& is, size_t pos = 0);
644
645
646 /// Compare stream contents in binary form.
647 ///
648 /// @param is1
649 /// First stream to compare.
650 /// @param is2
651 /// Second stream to compare.
652 /// @return
653 /// TRUE if streams content is equal; FALSE otherwise.
654 NCBI_XNCBI_EXPORT
655 extern bool NcbiStreamCompare(CNcbiIstream& is1, CNcbiIstream& is2);
656
657 /// Mode to compare streams in text form.
658 enum ECompareTextMode {
659 /// Skip end-of-line characters ('\r' and '\n')
660 eCompareText_IgnoreEol,
661 ///< Skip white spaces (in terms of isspace(), including end-of-line)
662 eCompareText_IgnoreWhiteSpace
663 };
664
665 /// Compare stream contents in text form.
666 ///
667 /// @param is1
668 /// First stream to compare.
669 /// @param is2
670 /// Second stream to compare.
671 /// @param mode
672 /// Type of white space characters to ignore.
673 /// @param buf_size
674 /// Size of buffer to read stream.
675 /// Zero value means using default buffer size.
676 /// @return
677 /// TRUE if streams content is equal; FALSE otherwise.
678 NCBI_XNCBI_EXPORT
679 extern bool NcbiStreamCompareText(CNcbiIstream& is1, CNcbiIstream& is2,
680 ECompareTextMode mode, size_t buf_size = 0);
681
682 /// Compare stream content with string in text form.
683 ///
684 /// @param is
685 /// Stream to compare.
686 /// @param str
687 /// String to compare.
688 /// @param mode
689 /// Type of white space characters to ignore.
690 /// @param buf_size
691 /// Size of buffer to read stream.
692 /// Zero value means using default buffer size.
693 /// @return
694 /// TRUE if stream and string content is equal; FALSE otherwise.
695 NCBI_XNCBI_EXPORT
696 extern bool NcbiStreamCompareText(CNcbiIstream& is, const string& str,
697 ECompareTextMode mode, size_t buf_size = 0);
698
699
700 # define CT_INT_TYPE NCBI_NS_STD::char_traits<char>::int_type
701 # define CT_CHAR_TYPE NCBI_NS_STD::char_traits<char>::char_type
702 # define CT_POS_TYPE NCBI_NS_STD::char_traits<char>::pos_type
703 # define CT_OFF_TYPE NCBI_NS_STD::char_traits<char>::off_type
704 # define CT_EOF NCBI_NS_STD::char_traits<char>::eof()
705 # define CT_NOT_EOF NCBI_NS_STD::char_traits<char>::not_eof
706 # define CT_TO_INT_TYPE NCBI_NS_STD::char_traits<char>::to_int_type
707 # define CT_TO_CHAR_TYPE NCBI_NS_STD::char_traits<char>::to_char_type
708 # define CT_EQ_INT_TYPE NCBI_NS_STD::char_traits<char>::eq_int_type
709
710
711 #ifdef NCBI_COMPILER_MIPSPRO
712 /// Special workaround for MIPSPro 1-byte look-ahead issues
713 class CMIPSPRO_ReadsomeTolerantStreambuf : public CNcbiStreambuf
714 {
715 public:
716 /// NB: Do not use these two ugly, weird, ad-hoc methods, ever!!!
MIPSPRO_ReadsomeBegin(void)717 void MIPSPRO_ReadsomeBegin(void)
718 {
719 if (!m_MIPSPRO_ReadsomeGptrSetLevel++)
720 m_MIPSPRO_ReadsomeGptr = gptr();
721 }
MIPSPRO_ReadsomeEnd(void)722 void MIPSPRO_ReadsomeEnd (void)
723 {
724 --m_MIPSPRO_ReadsomeGptrSetLevel;
725 }
726 protected:
CMIPSPRO_ReadsomeTolerantStreambuf()727 CMIPSPRO_ReadsomeTolerantStreambuf() : m_MIPSPRO_ReadsomeGptrSetLevel(0) {}
728
729 const CT_CHAR_TYPE* m_MIPSPRO_ReadsomeGptr;
730 unsigned int m_MIPSPRO_ReadsomeGptrSetLevel;
731 };
732 #endif // NCBI_COMPILER_MIPSPRO
733
734
735 /// Convert stream position to 64-bit int
736 ///
737 /// On most systems stream position is a structure,
738 /// this function converts it to plain numeric value.
739 ///
740 /// @sa NcbiInt8ToStreampos
741 ///
742 inline
NcbiStreamposToInt8(CT_POS_TYPE stream_pos)743 Int8 NcbiStreamposToInt8(CT_POS_TYPE stream_pos)
744 {
745 return (CT_OFF_TYPE)(stream_pos - (CT_POS_TYPE)((CT_OFF_TYPE)0));
746 }
747
748
749 /// Convert plain numeric stream position (offset) into
750 /// stream position usable with STL stream library.
751 ///
752 /// @sa NcbiStreamposToInt8
753 inline
NcbiInt8ToStreampos(Int8 pos)754 CT_POS_TYPE NcbiInt8ToStreampos(Int8 pos)
755 {
756 return (CT_POS_TYPE)((CT_OFF_TYPE) 0) + (CT_OFF_TYPE)(pos);
757 }
758
759
760 /// CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string
761 /// Sample usage:
762 /*
763 string GetString(void)
764 {
765 CNcbiOstrstream out;
766 out << "some text";
767 return CNcbiOstrstreamToString(out);
768 }
769 */
770 /// Note: there is no need to terminate with '\0' char ("ends");
771 /// there is no need to explicitly "unfreeze" the "out" stream.
772
773 class NCBI_XNCBI_EXPORT CNcbiOstrstreamToString
774 {
775 CNcbiOstrstreamToString(const CNcbiOstrstreamToString&);
776 CNcbiOstrstreamToString& operator= (const CNcbiOstrstreamToString&);
777 public:
CNcbiOstrstreamToString(CNcbiOstrstream & out)778 CNcbiOstrstreamToString(CNcbiOstrstream& out)
779 : m_Out(out)
780 {
781 }
782 operator string(void) const;
783 private:
784 friend NCBI_XNCBI_EXPORT CNcbiOstream& operator<<(CNcbiOstream& out, const CNcbiOstrstreamToString& s);
785
786 CNcbiOstrstream& m_Out;
787 };
788
789 NCBI_XNCBI_EXPORT
790 CNcbiOstream& operator<<(CNcbiOstream& out, const CNcbiOstrstreamToString& s);
791
792 inline
GetOssSize(CNcbiOstrstream & oss)793 Int8 GetOssSize(CNcbiOstrstream& oss)
794 {
795 #ifdef NCBI_SHUN_OSTRSTREAM
796 return NcbiStreamposToInt8(oss.tellp());
797 #else
798 return oss.pcount();
799 #endif
800 }
801
802 inline
IsOssEmpty(CNcbiOstrstream & oss)803 bool IsOssEmpty(CNcbiOstrstream& oss)
804 {
805 return GetOssSize(oss) == 0;
806 }
807
808 /// Utility class for automatic conversion of strings to all uppercase letters.
809 /// Sample usage:
810 /// out << "Original: \"" << str << '"' << endl;
811 /// out << "Uppercase: \"" << Upcase(str) << '"' << endl;
812
813 class NCBI_XNCBI_EXPORT CUpcaseStringConverter
814 {
815 public:
CUpcaseStringConverter(const string & s)816 explicit CUpcaseStringConverter(const string& s) : m_String(s) { }
817 const string& m_String;
818 };
819
820 class NCBI_XNCBI_EXPORT CUpcaseCharPtrConverter
821 {
822 public:
CUpcaseCharPtrConverter(const char * s)823 explicit CUpcaseCharPtrConverter(const char* s) : m_String(s) { }
824 const char* m_String;
825 };
826
827
828 /// Utility class for automatic conversion of strings to all lowercase letters.
829 /// Sample usage:
830 /// out << "Original: \"" << str << '"' << endl;
831 /// out << "Lowercase: \"" << Locase(str) << '"' << endl;
832
833 class NCBI_XNCBI_EXPORT CLocaseStringConverter
834 {
835 public:
CLocaseStringConverter(const string & s)836 explicit CLocaseStringConverter(const string& s) : m_String(s) { }
837 const string& m_String;
838 };
839
840 class NCBI_XNCBI_EXPORT CLocaseCharPtrConverter
841 {
842 public:
CLocaseCharPtrConverter(const char * s)843 explicit CLocaseCharPtrConverter(const char* s) : m_String(s) { }
844 const char* m_String;
845 };
846
847
848 /// Utility class for automatic conversion of strings (that may contain
849 /// non-graphical characters) to a safe "printable" form.
850 /// The safe printable form utilizes '\'-quoted special sequences, as well
851 /// as either contracted or full 3-digit octal representation of non-printable
852 /// characters, always making sure there is no ambiguity in the string
853 /// interpretation (so that if the printed form is used back in a C program,
854 /// it will be equivalent to the original string).
855 /// Sample usage:
856 /// out << "Printable: \"" << Printable(str) << '"' << endl;
857
858 class NCBI_XNCBI_EXPORT CPrintableStringConverter
859 {
860 public:
CPrintableStringConverter(const string & s)861 explicit CPrintableStringConverter(const string& s) : m_String(s) { }
862 const string& m_String;
863 };
864
865 class NCBI_XNCBI_EXPORT CPrintableCharPtrConverter
866 {
867 public:
CPrintableCharPtrConverter(const char * s)868 explicit CPrintableCharPtrConverter(const char* s) : m_String(s) { }
869 const char* m_String;
870 };
871
872
873 /* @} */
874
875
876 /// Convert one single character to a "printable" form.
877 /// A "printable" form is one of well-known C-style backslash-quoted sequences
878 /// ('\0', '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\'', '\"'),
879 /// or '\xXX' for other non-printable characters (per isprint()), or a
880 /// graphical representation of 'c' as an ASCII character.
881 /// @note *DO NOT USE* to convert strings! Because of the '\xXX' notation,
882 /// such conversions can result in ambiguity (e.g. "\xAAA" is a valid
883 /// _single_-character string per the standard).
884 NCBI_DEPRECATED
885 NCBI_XNCBI_EXPORT extern string Printable(char c);
886
887
888 inline
Upcase(char c)889 char Upcase(char c)
890 {
891 return static_cast<char>(toupper((unsigned char) c));
892 }
893
894 inline
Upcase(const string & s)895 CUpcaseStringConverter Upcase(const string& s)
896 {
897 return CUpcaseStringConverter(s);
898 }
899
900 inline
Upcase(const char * s)901 CUpcaseCharPtrConverter Upcase(const char* s)
902 {
903 return CUpcaseCharPtrConverter(s);
904 }
905
906 inline
Locase(char c)907 char Locase(char c)
908 {
909 return static_cast<char>(tolower((unsigned char) c));
910 }
911
912 inline
Locase(const string & s)913 CLocaseStringConverter Locase(const string& s)
914 {
915 return CLocaseStringConverter(s);
916 }
917
918 inline
Locase(const char * s)919 CLocaseCharPtrConverter Locase(const char* s)
920 {
921 return CLocaseCharPtrConverter(s);
922 }
923
924 inline
Printable(const string & s)925 CPrintableStringConverter Printable(const string& s)
926 {
927 return CPrintableStringConverter(s);
928 }
929
930 inline
Printable(const char * s)931 CPrintableCharPtrConverter Printable(const char* s)
932 {
933 return CPrintableCharPtrConverter(s);
934 }
935
936 NCBI_XNCBI_EXPORT
937 CNcbiOstream& operator<<(CNcbiOstream& out, CUpcaseStringConverter s);
938
939 NCBI_XNCBI_EXPORT
940 CNcbiOstream& operator<<(CNcbiOstream& out, CUpcaseCharPtrConverter s);
941
942 NCBI_XNCBI_EXPORT
943 CNcbiOstream& operator<<(CNcbiOstream& out, CLocaseStringConverter s);
944
945 NCBI_XNCBI_EXPORT
946 CNcbiOstream& operator<<(CNcbiOstream& out, CLocaseCharPtrConverter s);
947
948 NCBI_XNCBI_EXPORT
949 CNcbiOstream& operator<<(CNcbiOstream& out, CPrintableStringConverter s);
950
951 NCBI_XNCBI_EXPORT
952 CNcbiOstream& operator<<(CNcbiOstream& out, CPrintableCharPtrConverter s);
953
954
955 /////////////////////////////////////////////////////////////////////////////
956 ///
957 /// Helper functions to read plain-text data streams.
958 /// It understands Byte Order Mark (BOM) and converts the input if needed.
959 ///
960 /// See clause 13.6 in
961 /// http://www.unicode.org/unicode/uni2book/ch13.pdf
962 /// and also
963 /// http://unicode.org/faq/utf_bom.html#BOM
964 ///
965 /// @sa ReadIntoUtf8, GetTextEncodingForm
966 enum EEncodingForm {
967 /// Stream has no BOM.
968 eEncodingForm_Unknown,
969 /// Stream has no BOM.
970 eEncodingForm_ISO8859_1,
971 /// Stream has no BOM.
972 eEncodingForm_Windows_1252,
973 /// Stream has UTF8 BOM.
974 eEncodingForm_Utf8,
975 /// Stream has UTF16 BOM. Byte order is native for this OS
976 eEncodingForm_Utf16Native,
977 /// Stream has UTF16 BOM. Byte order is nonnative for this OS
978 eEncodingForm_Utf16Foreign
979 };
980
981
982 /// How to read the text if the encoding form is not known (i.e. passed
983 /// "eEncodingForm_Unknown" and the stream does not have BOM too)
984 ///
985 /// @sa ReadIntoUtf8
986 enum EReadUnknownNoBOM {
987 /// Read the text "as is" (raw octal data). The read data can then
988 /// be accessed using the regular std::string API (rather than the
989 /// CStringUTF8 one).
990 eNoBOM_RawRead,
991
992 /// Try to guess the text's encoding form.
993 ///
994 /// @note
995 /// In this case the encoding is a guesswork, which is not necessarily
996 /// correct. If the guess is wrong then the data may be distorted on
997 /// read. Use CStringUTF8::IsValid() to verify that guess. If it
998 /// does not verify, then the read data can be accessed using the
999 /// regular std::string API (rather than the CStringUTF8 one).
1000 eNoBOM_GuessEncoding
1001 };
1002
1003
1004 /// Read all input data from stream and try convert it into UTF8 string.
1005 ///
1006 /// @param input
1007 /// Input text stream
1008 /// @param result
1009 /// UTF8 string (but it can be a raw octet string if the encoding is unknown)
1010 /// @param what_if_no_bom
1011 /// What to do if the 'encoding_form' is passed "eEncodingForm_Unknown" and
1012 /// the BOM is not detected in the stream
1013 /// @return
1014 /// The encoding as detected based on the BOM
1015 /// ("eEncodingForm_Unknown" if there was no BOM).
1016 NCBI_XNCBI_EXPORT
1017 EEncodingForm ReadIntoUtf8(
1018 CNcbiIstream& input,
1019 CStringUTF8* result,
1020 EEncodingForm encoding_form = eEncodingForm_Unknown,
1021 EReadUnknownNoBOM what_if_no_bom = eNoBOM_GuessEncoding
1022 );
1023
1024
1025 /// Whether to discard BOM or to keep it in the input stream
1026 ///
1027 /// @sa GetTextEncodingForm
1028 enum EBOMDiscard {
1029 eBOM_Discard, ///< Discard the read BOM bytes
1030 eBOM_Keep ///< Push the read BOM bytes back into the input stream
1031 };
1032
1033
1034 /// Detect if the stream has BOM.
1035 ///
1036 /// @param input
1037 /// Input stream
1038 /// @param discard_bom
1039 /// Whether to discard the read BOM bytes or to push them back to the stream
1040 ///
1041 /// NOTE: If the function needs to push back more than one char then it uses
1042 /// CStreamUtils::Pushback().
1043 /// @sa CStreamUtils::Pushback()
1044 NCBI_XNCBI_EXPORT
1045 EEncodingForm GetTextEncodingForm(CNcbiIstream& input, EBOMDiscard discard_bom);
1046
1047
1048 /// Byte Order Mark helper class to use in serialization
1049 ///
1050 /// @sa GetTextEncodingForm
1051 class CByteOrderMark
1052 {
1053 public:
CByteOrderMark(void)1054 CByteOrderMark(void)
1055 : m_EncodingForm(eEncodingForm_Unknown) {
1056 }
1057
CByteOrderMark(EEncodingForm encodingForm)1058 CByteOrderMark(EEncodingForm encodingForm)
1059 : m_EncodingForm(encodingForm) {
1060 }
1061
GetEncodingForm(void) const1062 EEncodingForm GetEncodingForm(void) const {
1063 return m_EncodingForm;
1064 }
SetEncodingForm(EEncodingForm encodingForm)1065 void SetEncodingForm(EEncodingForm encodingForm) {
1066 m_EncodingForm = encodingForm;
1067 }
1068 private:
1069 EEncodingForm m_EncodingForm;
1070 };
1071
1072
1073 /// Write Byte Order Mark into output stream
1074 NCBI_XNCBI_EXPORT CNcbiOstream& operator<< (CNcbiOstream& str, const CByteOrderMark& bom);
1075
1076
1077 /// Read Byte Order Mark, if present, from input stream
1078 ///
1079 /// @note
1080 /// If BOM is found, stream position advances,
1081 /// otherwise, stream position remains unchanged
1082 ///
1083 /// @sa GetTextEncodingForm
1084 inline
operator >>(CNcbiIstream & str,CByteOrderMark & bom)1085 CNcbiIstream& operator>> (CNcbiIstream& str, CByteOrderMark& bom) {
1086 bom.SetEncodingForm( GetTextEncodingForm(str, eBOM_Discard));
1087 return str;
1088 }
1089
1090 #include <corelib/ncbi_base64.h>
1091
1092
1093 END_NCBI_SCOPE
1094
1095
1096 // Provide formatted I/O of standard C++ "string" by "old-fashioned" IOSTREAMs
1097 // NOTE: these must have been inside the _NCBI_SCOPE and without the
1098 // "ncbi::" and "std::" prefixes, but there is some bug in SunPro 5.0...
1099 #if defined(NCBI_USE_OLD_IOSTREAM)
1100 extern NCBI_NS_NCBI::CNcbiOstream&
1101 operator<<(NCBI_NS_NCBI::CNcbiOstream& os, const NCBI_NS_STD::string& str);
1102 extern NCBI_NS_NCBI::CNcbiIstream&
1103 operator>>(NCBI_NS_NCBI::CNcbiIstream& is, NCBI_NS_STD::string& str);
1104 #endif // NCBI_USE_OLD_IOSTREAM
1105
1106
1107 #endif /* NCBISTRE__HPP */
1108