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