ncbistre.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:14k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbistre.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:09:24  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.31
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: ncbistre.cpp,v 1000.1 2004/06/01 19:09:24 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Denis Vakatov
  35.  *
  36.  * File Description:
  37.  *   NCBI C++ stream class wrappers
  38.  *   Triggering between "new" and "old" C++ stream libraries
  39.  *
  40.  */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/ncbistd.hpp>
  43. #include <corelib/ncbistre.hpp>
  44. #include <ctype.h>
  45. BEGIN_NCBI_SCOPE
  46. #if defined(NCBI_USE_OLD_IOSTREAM)  ||  defined(NCBI_OS_DARWIN)
  47. static CNcbiIstream& s_NcbiGetline(CNcbiIstream& is, string& str,
  48.                                    char delim, char delim2)
  49. {
  50.     CT_INT_TYPE ch;
  51.     char        buf[1024];
  52.     SIZE_TYPE   pos = 0;
  53.     IOS_BASE::fmtflags f = is.flags();
  54.     is.unsetf(IOS_BASE::skipws);
  55. #ifdef NO_PUBSYNC
  56.     if ( !is.ipfx(1) ) {
  57.         is.flags(f);
  58.         return is;
  59.     }
  60. #else
  61.     CNcbiIstream::sentry s(is);
  62.     if ( !s ) {
  63.         is.clear(NcbiFailbit | is.rdstate());
  64.         is.flags(f);
  65.         return is;
  66.     }
  67. #endif
  68.     str.erase();
  69.     SIZE_TYPE end = str.max_size();
  70.     SIZE_TYPE i = 0;
  71.     for (ch = is.rdbuf()->sbumpc();  !CT_EQ_INT_TYPE(ch, CT_EOF);
  72.          ch = is.rdbuf()->sbumpc()) {
  73.         i++;
  74.         if (CT_TO_CHAR_TYPE(ch) == delim  ||  CT_TO_CHAR_TYPE(ch) == delim2)
  75.             break;
  76.         if (i == end) {
  77.             is.clear(NcbiFailbit | is.rdstate());      
  78.             break;
  79.         }
  80.         buf[pos++] = CT_TO_CHAR_TYPE(ch);
  81.         if (pos == sizeof(buf)) {
  82.             str.append(buf, pos);
  83.             pos = 0;
  84.         }
  85.     }
  86.     str.append(buf, pos);
  87.     if (ch == EOF) 
  88.         is.clear(NcbiEofbit | is.rdstate());      
  89.     if ( !i )
  90.         is.clear(NcbiFailbit | is.rdstate());      
  91. #ifdef NO_PUBSYNC
  92.     is.isfx();
  93. #endif
  94.     is.flags(f);
  95.     return is;
  96. }
  97. #endif  /* NCBI_USE_OLD_IOSTREAM || NCBI_OS_DARWIN */
  98. #ifdef NCBI_COMPILER_GCC
  99. #  if NCBI_COMPILER_VERSION < 300
  100. #    define NCBI_COMPILER_GCC29x
  101. #  endif
  102. #endif
  103. extern CNcbiIstream& NcbiGetline(CNcbiIstream& is, string& str, char delim)
  104. {
  105. #if defined(NCBI_USE_OLD_IOSTREAM)
  106.     return s_NcbiGetline(is, str, delim, delim);
  107. #elif defined(NCBI_COMPILER_GCC29x)
  108.     // The code below is normally somewhat faster than this call,
  109.     // which typically appends one character at a time to str;
  110.     // however, it blows up when built with some GCC versions.
  111.     return getline(is, str, delim);
  112. #else
  113.     char buf[1024];
  114.     str.erase();
  115.     while (is.good()) {
  116.         CT_INT_TYPE nextc = is.get();
  117.         if (CT_EQ_INT_TYPE(nextc, CT_EOF) 
  118.             ||  CT_EQ_INT_TYPE(nextc, CT_TO_INT_TYPE(delim))) {
  119.             break;
  120.         }
  121.         is.putback(nextc);
  122.         is.get(buf, sizeof(buf), delim);
  123.         str.append(buf, is.gcount());
  124.     }
  125.     if ( str.empty()  &&  is.eof() ) {
  126.         is.setstate(NcbiFailbit);
  127.     }
  128.     return is;
  129. #endif
  130. }
  131. // Platform-specific EndOfLine
  132. const char* Endl(void)
  133. {
  134. #if   defined(NCBI_OS_MAC)
  135.     static const char s_Endl[] = "r";
  136. #elif defined(NCBI_OS_MSWIN)
  137.     static const char s_Endl[] = "rn";
  138. #else /* assume UNIX-like EOLs */
  139.     static const char s_Endl[] = "n";
  140. #endif
  141.     return s_Endl;
  142. }
  143. // Get the next line taking into account platform specifics of End-of-Line
  144. CNcbiIstream& NcbiGetlineEOL(CNcbiIstream& is, string& str)
  145. {
  146. #if   defined(NCBI_OS_MAC)
  147.     NcbiGetline(is, str, 'r');
  148. #elif defined(NCBI_OS_MSWIN)
  149.     NcbiGetline(is, str, 'n');
  150.     if (!str.empty()  &&  str[str.length()-1] == 'r')
  151.         str.resize(str.length() - 1);
  152. #elif defined(NCBI_OS_DARWIN)
  153.     s_NcbiGetline(is, str, 'r', 'n');
  154. #else /* assume UNIX-like EOLs */
  155.     NcbiGetline(is, str, 'n');
  156. #endif
  157.     // special case -- an empty line
  158.     if (is.fail()  &&  !is.eof()  &&  !is.gcount()  &&  str.empty())
  159.         is.clear(is.rdstate() & ~NcbiFailbit);
  160.     return is;
  161. }
  162. CNcbiOstrstreamToString::operator string(void) const
  163. {
  164.     SIZE_TYPE length = m_Out.pcount();
  165.     if ( length == 0 )
  166.         return string();
  167.     const char* str = m_Out.str();
  168.     m_Out.freeze(false);
  169.     return string(str, length);
  170. }
  171. CNcbiOstream& operator<<(CNcbiOstream& out, CUpcaseStringConverter s)
  172. {
  173.     ITERATE ( string, c, s.m_String ) {
  174.         out.put(char(toupper(*c)));
  175.     }
  176.     return out;
  177. }
  178. CNcbiOstream& operator<<(CNcbiOstream& out, CLocaseStringConverter s)
  179. {
  180.     ITERATE ( string, c, s.m_String ) {
  181.         out.put(char(tolower(*c)));
  182.     }
  183.     return out;
  184. }
  185. CNcbiOstream& operator<<(CNcbiOstream& out, CUpcaseCharPtrConverter s)
  186. {
  187.     for ( const char* c = s.m_String; *c; ++c ) {
  188.         out.put(char(toupper(*c)));
  189.     }
  190.     return out;
  191. }
  192. CNcbiOstream& operator<<(CNcbiOstream& out, CLocaseCharPtrConverter s)
  193. {
  194.     for ( const char* c = s.m_String; *c; ++c ) {
  195.         out.put(char(tolower(*c)));
  196.     }
  197.     return out;
  198. }
  199. #ifdef NCBI_OS_MSWIN
  200. CNcbiOstream& operator<<(CNcbiOstream& out, __int64 val)
  201. {
  202.     return (out << NStr::Int8ToString(val));
  203. }
  204. #endif
  205. static const char s_Hex[] = "0123456789ABCDEF";
  206. string Printable(char c)
  207. {
  208.     string s;
  209.     switch ( c ) {
  210.     case '':  s = "\0";   break;
  211.     case '\':  s = "\\";  break;
  212.     case 'n':  s = "\n";   break;
  213.     case 't':  s = "\t";   break;
  214.     case 'r':  s = "\r";   break;
  215.     case 'v':  s = "\v";   break;
  216.     default:
  217.         {
  218.             if ( isprint(c) ) {
  219.                 s = c;
  220.             } else {
  221.                 s = "\x";
  222.                 s += s_Hex[(unsigned char) c / 16];
  223.                 s += s_Hex[(unsigned char) c % 16];
  224.             }
  225.         }
  226.     }
  227.     return s;
  228. }
  229. inline
  230. void WritePrintable(CNcbiOstream& out, char c)
  231. {
  232.     switch ( c ) {
  233.     case '':  out.write("\0",  2);  break;
  234.     case '\':  out.write("\\", 2);  break;
  235.     case 'n':  out.write("\n",  2);  break;
  236.     case 't':  out.write("\t",  2);  break;
  237.     case 'r':  out.write("\r",  2);  break;
  238.     case 'v':  out.write("\v",  2);  break;
  239.     default:
  240.         {
  241.             if ( isprint(c) ) {
  242.                 out.put(c);
  243.             } else {
  244.                 out.write("\x", 2);
  245.                 out.put(s_Hex[(unsigned char) c / 16]);
  246.                 out.put(s_Hex[(unsigned char) c % 16]);
  247.             }
  248.         }
  249.     }
  250. }
  251. CNcbiOstream& operator<<(CNcbiOstream& out, CPrintableStringConverter s)
  252. {
  253.     ITERATE ( string, c, s.m_String ) {
  254.         WritePrintable(out, *c);
  255.     }
  256.     return out;
  257. }
  258. CNcbiOstream& operator<<(CNcbiOstream& out, CPrintableCharPtrConverter s)
  259. {
  260.     for ( const char* c = s.m_String; *c; ++c ) {
  261.         WritePrintable(out, *c);
  262.     }
  263.     return out;
  264. }
  265. #if defined(NCBI_COMPILER_WORKSHOP)
  266. // We have to use two #if's here because KAI C++ cannot handle #if foo == bar
  267. #  if (NCBI_COMPILER_VERSION == 530)
  268. // The version that ships with the compiler is buggy.
  269. // Here's a working (and simpler!) one.
  270. template<>
  271. istream& istream::read(char *s, streamsize n)
  272. {
  273.     sentry ipfx(*this, 1);
  274.     try {
  275.         if (rdbuf()->sgetc() == traits_type::eof()) {
  276.             // Workaround for bug in sgetn.  *SIGH*.
  277.             __chcount = 0;
  278.             setstate(eofbit);
  279.             return *this;
  280.         }
  281.         __chcount = rdbuf()->sgetn(s, n);
  282.         if (__chcount == 0) {
  283.             setstate(eofbit);
  284.         } else if (__chcount < n) {
  285.             setstate(eofbit | failbit);
  286.         } else if (!ipfx) {
  287.             setstate(failbit);
  288.         } 
  289.     } catch (...) {
  290.         setstate(failbit);
  291.         throw;
  292.     }
  293.     return *this;
  294. }
  295. #  endif  /* NCBI_COMPILER_VERSION == 530 */
  296. #endif  /* NCBI_COMPILER_WORKSHOP */
  297. END_NCBI_SCOPE
  298. // See in the header why it is outside of NCBI scope (SunPro bug workaround...)
  299. #if defined(NCBI_USE_OLD_IOSTREAM)
  300. extern NCBI_NS_NCBI::CNcbiOstream& operator<<(NCBI_NS_NCBI::CNcbiOstream& os,
  301.                                               const NCBI_NS_STD::string& str)
  302. {
  303.     return str.empty() ? os : os << str.c_str();
  304. }
  305. extern NCBI_NS_NCBI::CNcbiIstream& operator>>(NCBI_NS_NCBI::CNcbiIstream& is,
  306.                                               NCBI_NS_STD::string& str)
  307. {
  308.     int ch;
  309.     if ( !is.ipfx() )
  310.         return is;
  311.     str.erase();
  312.     SIZE_TYPE end = str.max_size();
  313.     if ( is.width() )
  314.         end = (int)end < is.width() ? end : is.width(); 
  315.     SIZE_TYPE i = 0;
  316.     for (ch = is.rdbuf()->sbumpc();  ch != EOF  &&  !isspace(ch);
  317.          ch = is.rdbuf()->sbumpc()) {
  318.         str.append(1, (char)ch);
  319.         i++;
  320.         if (i == end)
  321.             break;
  322.     }
  323.     if (ch == EOF) 
  324.         is.clear(NcbiEofbit | is.rdstate());      
  325.     if ( !i )
  326.         is.clear(NcbiFailbit | is.rdstate());      
  327.     is.width(0);
  328.     return is;
  329. }
  330. #endif  /* NCBI_USE_OLD_IOSTREAM */
  331. /*
  332.  * ===========================================================================
  333.  * $Log: ncbistre.cpp,v $
  334.  * Revision 1000.1  2004/06/01 19:09:24  gouriano
  335.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.31
  336.  *
  337.  * Revision 1.31  2004/05/14 13:59:27  gorelenk
  338.  * Added include of ncbi_pch.hpp
  339.  *
  340.  * Revision 1.30  2003/09/05 16:01:37  ivanov
  341.  * Added forgotten eof() check before set FAILBIT in the NcbiGetline()
  342.  *
  343.  * Revision 1.29  2003/09/05 15:56:00  ivanov
  344.  * Fix for R2.8 -- only set FAILBIT if no symbols have been read
  345.  *
  346.  * Revision 1.28  2003/09/05 15:22:26  ivanov
  347.  * Fixed NcbiGetline() to correct handle last line in the input stream
  348.  *
  349.  * Revision 1.27  2003/08/27 18:58:22  ucko
  350.  * NcbiGetline: revert to std::getline for GCC 2.9x, since the custom
  351.  * version blows up mysteriously (at least in debug builds).
  352.  *
  353.  * Revision 1.26  2003/08/25 21:14:58  ucko
  354.  * [s_]NcbiGetline: take care to append characters to str in bulk rather
  355.  * than one at a time, which can be pretty inefficient.
  356.  *
  357.  * Revision 1.25  2003/08/19 17:06:12  ucko
  358.  * Actually conditionalize the Windows-specific operator<<....
  359.  *
  360.  * Revision 1.24  2003/08/19 15:41:55  dicuccio
  361.  * Added conditionally compiled prototype for operator<<(ostream&, __int64)
  362.  *
  363.  * Revision 1.23  2003/05/18 04:28:18  vakatov
  364.  * Fix warning about "s_NcbiGetline()" being defined but not used sometimes
  365.  *
  366.  * Revision 1.22  2003/03/31 21:34:01  ucko
  367.  * s_NCBIGetline: avoid eating initial whitespace, and use portability macros.
  368.  *
  369.  * Revision 1.21  2003/03/27 23:10:43  vakatov
  370.  * Identation
  371.  *
  372.  * Revision 1.20  2003/03/26 21:18:54  kans
  373.  * s_NcbiGetline takes two delimiters, NcbiGetlineEOL calls this if
  374.  * NCBI_OS_DARWIN to handle both kinds of newlines
  375.  *
  376.  * Revision 1.19  2003/03/10 18:57:08  kuznets
  377.  * iterate->ITERATE
  378.  *
  379.  * Revision 1.18  2002/10/17 22:10:33  vakatov
  380.  * C&P typo fixed
  381.  *
  382.  * Revision 1.17  2002/10/17 22:07:27  vakatov
  383.  * + Endl() -- platform-specific EndOfLine
  384.  *
  385.  * Revision 1.16  2002/08/01 18:42:17  ivanov
  386.  * + NcbiGetlineEOL() -- moved from ncbireg and renamed
  387.  *
  388.  * Revision 1.15  2002/04/11 21:08:03  ivanov
  389.  * CVS log moved to end of the file
  390.  *
  391.  * Revision 1.14  2001/10/15 19:48:23  vakatov
  392.  * Use two #if's instead of "#if ... && ..." as KAI cannot handle #if x == y
  393.  *
  394.  * Revision 1.13  2001/09/06 19:35:14  ucko
  395.  * WorkShop 5.3's implementation of istream::read is broken; provide one
  396.  * that works.
  397.  *
  398.  * Revision 1.12  2001/04/11 20:14:31  vakatov
  399.  * Printable() -- added the forgotten "break"s.
  400.  * Printable(), WritePrintable() -- cast "char" to "unsigned char".
  401.  *
  402.  * Revision 1.11  2001/03/26 20:26:59  vakatov
  403.  * Added "Printable" symbol conversions (by A.Grichenko)
  404.  *
  405.  * Revision 1.10  2000/12/24 00:03:20  vakatov
  406.  * Include ncbistd.hpp instead of ncbiutil.hpp
  407.  *
  408.  * Revision 1.9  2000/12/15 15:36:41  vasilche
  409.  * Added header corelib/ncbistr.hpp for all string utility functions.
  410.  * Optimized string utility functions.
  411.  * Added assignment operator to CRef<> and CConstRef<>.
  412.  * Add Upcase() and Locase() methods for automatic conversion.
  413.  *
  414.  * Revision 1.8  2000/12/12 14:39:50  vasilche
  415.  * Added class Locase for printing strings to ostream with automatic conversion
  416.  *
  417.  * Revision 1.7  2000/12/12 14:20:36  vasilche
  418.  * Added operator bool to CArgValue.
  419.  * Various NStr::Compare() methods made faster.
  420.  * Added class Upcase for printing strings to ostream with automatic conversion
  421.  *
  422.  * Revision 1.6  1999/12/28 18:55:43  vasilche
  423.  * Reduced size of compiled object files:
  424.  * 1. avoid inline or implicit virtual methods (especially destructors).
  425.  * 2. avoid std::string's methods usage in inline methods.
  426.  * 3. avoid string literals ("xxx") in inline methods.
  427.  *
  428.  * Revision 1.5  1999/05/06 23:02:40  vakatov
  429.  * Use the new(template-based, std::) stream library by default
  430.  *
  431.  * Revision 1.4  1998/12/30 23:15:11  vakatov
  432.  * [NCBI_USE_NEW_IOSTREAM] NcbiGetline() -- use "smart" getline()
  433.  *
  434.  * Revision 1.3  1998/12/28 17:56:40  vakatov
  435.  * New CVS and development tree structure for the NCBI C++ projects
  436.  *
  437.  * Revision 1.2  1998/12/03 18:56:14  vakatov
  438.  * minor fixes
  439.  *
  440.  * Revision 1.1  1998/12/03 16:40:26  vakatov
  441.  * Initial revision
  442.  * Aux. function "Getline()" to read from "istream" to a "string"
  443.  * Adopted standard I/O "string" <--> "istream" for old-fashioned streams
  444.  *
  445.  * ===========================================================================
  446.  */