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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bytestreambuf.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:18:12  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: bytestreambuf.cpp,v 1000.1 2004/06/01 19:18:12 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: Michael Kholodov
  35. *
  36. * File Description: streambuf implementation for BLOBs
  37. *
  38. * ---------------------------------------------------------------------------
  39. * $Log: bytestreambuf.cpp,v $
  40. * Revision 1000.1  2004/06/01 19:18:12  gouriano
  41. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  42. *
  43. * Revision 1.9  2004/05/17 21:10:28  gorelenk
  44. * Added include of PCH ncbi_pch.hpp
  45. *
  46. * Revision 1.8  2002/07/12 13:34:11  kholodov
  47. * Fixed: incorrect length reported for NULL BLOB
  48. *
  49. * Revision 1.7  2002/06/21 14:41:32  kholodov
  50. * Fixed: reset total bytes written for debug output
  51. *
  52. * Revision 1.6  2002/05/16 22:09:19  kholodov
  53. * Fixed: incorrect start of BLOB column
  54. *
  55. * Revision 1.5  2002/05/14 19:51:47  kholodov
  56. * Fixed: incorrect column no handling for detecting end of column
  57. *
  58. * Revision 1.4  2002/05/13 19:11:53  kholodov
  59. * Modified: added proper handling of EOFs while reading column data using CDB_Result::CurrentItemNo().
  60. *
  61. * Revision 1.3  2002/04/03 20:06:25  ucko
  62. * Always return >= 1 from showmanyc() to avoid spurious "EOF"s.
  63. * Pass status messages to _TRACE rather than writing them to cout.
  64. * #if out buggy code in destructor.
  65. *
  66. * Revision 1.2  2002/02/14 00:59:40  vakatov
  67. * Clean-up: warning elimination, fool-proofing, fine-tuning, identation, etc.
  68. *
  69. * Revision 1.1  2002/01/30 14:51:21  kholodov
  70. * User DBAPI implementation, first commit
  71. *
  72. *
  73. *
  74. * ===========================================================================
  75. */
  76. #include <ncbi_pch.hpp>
  77. #include <exception>
  78. #include <algorithm>
  79. #include "bytestreambuf.hpp"
  80. #include <dbapi/driver/exception.hpp>
  81. #include <dbapi/driver/interfaces.hpp>
  82. #include <dbapi/driver/public.hpp>
  83. BEGIN_NCBI_SCOPE
  84. static const streamsize DEF_BUFSIZE = 2048;
  85. CByteStreamBuf::CByteStreamBuf(streamsize bufsize)
  86.     : m_buf(0), 
  87.     m_size(bufsize > 0 ? bufsize : DEF_BUFSIZE), 
  88.     m_len(0), m_rs(0), m_cmd(0), m_column(-1)
  89.     m_buf = new CT_CHAR_TYPE[m_size * 2]; // read and write buffer in one
  90.     setg(0, 0, 0); // call underflow on the first read
  91.     setp(getPBuf(), getPBuf() + m_size);
  92.     _TRACE("I/O buffer size: " << m_size);
  93. }
  94. CByteStreamBuf::~CByteStreamBuf()
  95. {
  96. #if 0 // misbehaves
  97.     if( m_rs != 0 && m_len > 0 )
  98.         m_rs->SkipItem();
  99. #endif
  100.     delete[] m_buf;
  101.     delete m_cmd;
  102. }
  103. CT_CHAR_TYPE* CByteStreamBuf::getGBuf()
  104. {
  105.     return m_buf;
  106. }
  107. CT_CHAR_TYPE* CByteStreamBuf::getPBuf() 
  108. {
  109.     return m_buf + m_size;
  110. }
  111. void CByteStreamBuf::SetCmd(CDB_SendDataCmd* cmd) {
  112.     delete m_cmd;
  113.     m_cmd = cmd;
  114. }
  115. void CByteStreamBuf::SetRs(CDB_Result* rs) {
  116.     delete m_rs;
  117.     m_rs = rs;
  118.     m_column = m_rs->CurrentItemNo();
  119. }
  120. CT_INT_TYPE CByteStreamBuf::underflow()
  121. {
  122.     if( m_rs == 0 )
  123.         throw runtime_error("CByteStreamBuf::underflow(): CDB_Result* is null");
  124.   
  125.     static size_t total = 0;
  126.     if( m_column < 0 || m_column != m_rs->CurrentItemNo() ) {
  127.         if( m_column < 0 ) {
  128.             _TRACE("Column for ReadItem not set, current column: "
  129.                    << m_rs->CurrentItemNo());
  130. #ifdef _DEBUG
  131.             _ASSERT(0);
  132. #endif
  133.         }
  134.         else
  135.             _TRACE("Total read from ReadItem: " << total);
  136.         total = 0;
  137.         m_column = m_rs->CurrentItemNo();
  138.         return CT_EOF;
  139.     }
  140.     else {
  141.         m_len = m_rs->ReadItem(getGBuf(), m_size);
  142.         _TRACE("Column: " << m_column << ", Bytes read to buffer: " << m_len);
  143.         if( m_len == 0 )
  144.             return CT_EOF;
  145.         total += m_len;
  146.         setg(getGBuf(), getGBuf(), getGBuf() + m_len);
  147.         return CT_TO_INT_TYPE(*getGBuf());
  148.     }
  149.     
  150. }
  151. CT_INT_TYPE CByteStreamBuf::overflow(CT_INT_TYPE c)
  152. {
  153.     if( m_cmd == 0 ) {
  154.         throw runtime_error
  155.             ("CByteStreamBuf::overflow(): CDB_SendDataCmd* is null");
  156.     }
  157.     static size_t total = 0;
  158.     size_t put = m_cmd->SendChunk(pbase(), pptr() - pbase());
  159.     total += put;
  160.     if( put > 0 ) {
  161.         setp(getPBuf(), getPBuf() + m_size );
  162.         if( ! CT_EQ_INT_TYPE(c, CT_EOF) )
  163.             sputc(CT_TO_CHAR_TYPE(c));
  164.         return c;
  165.     }
  166.     else {
  167.         _TRACE("Total sent: " << total);
  168.         total = 0;
  169.         return CT_EOF;
  170.     }
  171.     
  172. }
  173. int CByteStreamBuf::sync()
  174. {
  175.     overflow(CT_EOF);
  176.     return 0;
  177. }
  178. streambuf* 
  179. CByteStreamBuf::setbuf(CT_CHAR_TYPE* /*p*/, streamsize /*n*/)
  180. {
  181.     throw runtime_error("CByteStreamBuf::setbuf(): not allowed");
  182. }
  183. streamsize CByteStreamBuf::showmanyc() 
  184. {
  185.     streamsize left = egptr() - gptr();
  186.     return min(left, (streamsize)1);
  187. }
  188. //======================================================
  189. END_NCBI_SCOPE