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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: indentstream.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:15:37  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: indentstream.cpp,v 1000.2 2004/06/01 19:15:37 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:  Aaron Ucko
  35.  *
  36.  */
  37. #include <ncbi_pch.hpp>
  38. #include <html/indentstream.hpp>
  39. #include <string.h>
  40. BEGIN_NCBI_SCOPE
  41. class CIndentingStreambuf : public CNcbiStreambuf
  42. {
  43. public:
  44.     CIndentingStreambuf(CNcbiStreambuf* real_buf, SIZE_TYPE indent);
  45.     ~CIndentingStreambuf(void);
  46. protected:
  47.     CNcbiStreambuf* setbuf   (CT_CHAR_TYPE* p, streamsize n);
  48.     CT_POS_TYPE     seekoff  (CT_OFF_TYPE off, IOS_BASE::seekdir way,
  49.                               IOS_BASE::openmode m);
  50.     CT_POS_TYPE     seekpos  (CT_POS_TYPE pos, IOS_BASE::openmode m);
  51.     int             sync     (void);
  52.     streamsize      showmanyc(void);
  53.     streamsize      xsgetn   (CT_CHAR_TYPE* p, streamsize n);
  54.     CT_INT_TYPE     underflow(void);
  55.     CT_INT_TYPE     uflow    (void);
  56.     CT_INT_TYPE     pbackfail(CT_INT_TYPE c = CT_EOF);
  57.     CT_INT_TYPE     overflow (CT_INT_TYPE c = CT_EOF);
  58. private:
  59.     CNcbiStreambuf*      m_Buf;
  60.     CIndentingStreambuf* m_ISB;
  61.     string               m_Indent;
  62.     char                 m_PutArea[1024];
  63.     bool                 m_OutputActive; // avoid double-indenting
  64.     bool                 m_NeedIndent;
  65. };
  66. CIndentingOstream::CIndentingOstream(CNcbiOstream& real_stream,
  67.                                      SIZE_TYPE indent)
  68.     : CNcbiOstream(new CIndentingStreambuf(real_stream.rdbuf(), indent))
  69. {
  70.     return;
  71. }
  72. CIndentingStreambuf::CIndentingStreambuf(CNcbiStreambuf* real_buf,
  73.                                          SIZE_TYPE indent)
  74.     : m_OutputActive(false)
  75. {
  76.     m_ISB = dynamic_cast<CIndentingStreambuf*>(real_buf);
  77.     if (m_ISB != 0) { // optimize
  78.         m_ISB->overflow();
  79.         m_Buf        = m_ISB->m_Buf;
  80.         m_Indent     = m_ISB->m_Indent;
  81.         m_NeedIndent = m_ISB->m_NeedIndent;
  82.     } else {
  83.         m_Buf        = real_buf;
  84.         m_NeedIndent = true;
  85.     }
  86.     m_Indent.append(indent, ' ');
  87.     setp(m_PutArea, m_PutArea + sizeof(m_PutArea));
  88. }
  89. CIndentingStreambuf::~CIndentingStreambuf()
  90. {
  91.     overflow();
  92.     if (m_ISB) {
  93.         // Make sure not to lose the information
  94.         m_ISB->m_NeedIndent = m_NeedIndent;
  95.     }
  96. }
  97. CT_INT_TYPE CIndentingStreambuf::overflow(CT_INT_TYPE c)
  98. {
  99.     if (m_NeedIndent  &&  pptr() != pbase()) {
  100.         m_Buf->sputn(m_Indent.data(), m_Indent.size());
  101.         m_NeedIndent = false;
  102.     }
  103.     if ( !m_OutputActive ) { // avoid double-indenting
  104.         m_OutputActive = true;
  105.         const char *p, *oldp = m_PutArea;
  106.         while (oldp < pptr()
  107.                &&  (p = (const char*)memchr(oldp, 'n', pptr() - oldp)) != 0) {
  108.             m_Buf->sputn(oldp, p - oldp + 1);
  109.             if (p == pptr() - 1) {
  110.                 m_NeedIndent = true; // defer
  111.             } else {
  112.                 m_Buf->sputn(m_Indent.data(), m_Indent.size());
  113.             }
  114.             oldp = p + 1;
  115.         }
  116.         m_Buf->sputn(oldp, pptr() - oldp);
  117.         m_OutputActive = false;
  118.         setp(m_PutArea, m_PutArea + sizeof(m_PutArea));
  119.     }
  120.     if ( !CT_EQ_INT_TYPE(c, CT_EOF) ) {
  121.         sputc(CT_TO_CHAR_TYPE(c));
  122.     }
  123.     return CT_NOT_EOF(CT_EOF);
  124. }
  125. int CIndentingStreambuf::sync(void)
  126. {
  127.     overflow();
  128.     return m_Buf->PUBSYNC();
  129. }
  130. // Wrappers
  131. CNcbiStreambuf* CIndentingStreambuf::setbuf(CT_CHAR_TYPE* p, streamsize n)
  132. {
  133. #ifdef NO_PUBSYNC
  134.     return m_Buf->setbuf(p, n);
  135. #else
  136.     return m_Buf->pubsetbuf(p, n);
  137. #endif
  138. }
  139. CT_POS_TYPE CIndentingStreambuf::seekoff(CT_OFF_TYPE off,
  140.                                          IOS_BASE::seekdir way,
  141.                                          IOS_BASE::openmode m)
  142. {
  143.     return m_Buf->PUBSEEKOFF(off, way, m);
  144. }
  145. CT_POS_TYPE CIndentingStreambuf::seekpos(CT_POS_TYPE pos, IOS_BASE::openmode m)
  146. {
  147.     return m_Buf->PUBSEEKPOS(pos, m);
  148. }
  149. streamsize CIndentingStreambuf::showmanyc(void)
  150. {
  151.     return m_Buf->in_avail();
  152. }
  153. streamsize CIndentingStreambuf::xsgetn(CT_CHAR_TYPE* p, streamsize n)
  154. {
  155.     return m_Buf->sgetn(p, n);
  156. }
  157. CT_INT_TYPE CIndentingStreambuf::underflow(void)
  158. {
  159.     return m_Buf->sgetc();
  160. }
  161. CT_INT_TYPE CIndentingStreambuf::uflow(void)
  162. {
  163.     return m_Buf->sbumpc();
  164. }
  165. CT_INT_TYPE CIndentingStreambuf::pbackfail(CT_INT_TYPE c)
  166. {
  167.     return (CT_EQ_INT_TYPE(c, CT_EOF) ? CT_EOF : m_Buf->sputbackc(c));
  168. }
  169. END_NCBI_SCOPE
  170. /*
  171.  * ===========================================================================
  172.  * $Log: indentstream.cpp,v $
  173.  * Revision 1000.2  2004/06/01 19:15:37  gouriano
  174.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  175.  *
  176.  * Revision 1.4  2004/05/17 20:59:50  gorelenk
  177.  * Added include of PCH ncbi_pch.hpp
  178.  *
  179.  * Revision 1.3  2003/11/03 17:03:08  ivanov
  180.  * Some formal code rearrangement. Move log to end.
  181.  *
  182.  * Revision 1.2  2003/02/24 18:10:55  ucko
  183.  * Avoid spurious indentation in some cases.
  184.  *
  185.  * Revision 1.1  2003/02/14 16:16:57  ucko
  186.  * Introduce CIndentingOstream, and the underlying CIndentingStreambuf.
  187.  *
  188.  * ===========================================================================
  189.  */