1 /* 2 This file is part of libodbc++. 3 4 Copyright (C) 1999-2000 Manush Dodunekov <manush@stendahls.net> 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Library General Public 8 License as published by the Free Software Foundation; either 9 version 2 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Library General Public License for more details. 15 16 You should have received a copy of the GNU Library General Public License 17 along with this library; see the file COPYING. If not, write to 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 Boston, MA 02111-1307, USA. 20 */ 21 22 #ifndef __DATASTREAM_H 23 #define __DATASTREAM_H 24 25 #include <odbc++/types.h> 26 27 #if defined(ODBCXX_HAVE_ISO_CXXLIB) 28 # include <istream> 29 # include <streambuf> 30 #else 31 # include <iostream> 32 # include <streambuf.h> 33 #endif 34 35 #include <cstdio> // for EOF 36 37 #if defined(ODBCXX_QT) 38 # include <qiodevice.h> 39 #endif 40 41 namespace odbc { 42 43 #if !defined(ODBCXX_QT) 44 45 46 class DataStreamBuf : public ODBCXX_STREAMBUF { 47 friend class DataStreamBase; 48 friend class DataStream; 49 private: 50 ErrorHandler* errorHandler_; 51 SQLHSTMT hstmt_; 52 int column_; 53 int cType_; 54 DATASTATUS_TYPE& dataStatus_; 55 size_t bufferSize_; 56 57 virtual int_type underflow(); 58 overflow(int)59 virtual int_type overflow(int) { 60 return EOF; 61 } 62 sync()63 virtual int sync() { 64 //what can we do? 65 return 0; 66 } 67 68 virtual 69 #if !defined(ODBCXX_HAVE_ISO_CXXLIB) 70 int 71 #else 72 std::streamsize 73 #endif showmanyc()74 showmanyc() { 75 if(this->gptr() < this->egptr()) { 76 return this->egptr() - this->gptr(); 77 } 78 return 0; 79 } 80 81 DataStreamBuf(ErrorHandler* eh, SQLHSTMT hstmt, int col, int cType, 82 DATASTATUS_TYPE& dataStatus); 83 virtual ~DataStreamBuf(); 84 }; 85 86 #if !defined(ODBCXX_HAVE_ISO_CXXLIB) 87 88 class DataStreamBase : public virtual ios { 89 private: 90 DataStreamBuf buf_; 91 92 protected: DataStreamBase(ErrorHandler * eh,SQLHSTMT hstmt,int column,int cType,DATASTATUS_TYPE & ds)93 DataStreamBase(ErrorHandler* eh, SQLHSTMT hstmt, int column, 94 int cType,DATASTATUS_TYPE& ds) 95 :buf_(eh,hstmt,column,cType,ds) {} 96 ~DataStreamBase()97 virtual ~DataStreamBase() {} rdbuf()98 virtual DataStreamBuf* rdbuf() { 99 return &buf_; 100 } 101 }; 102 103 class DataStream : public DataStreamBase, public ODBCXX_STREAM 104 #else 105 class DataStream : public ODBCXX_STREAM 106 #endif 107 { 108 friend class ResultSet; 109 friend class PreparedStatement; 110 friend class Rowset; 111 private: DataStream(ErrorHandler * eh,SQLHSTMT hstmt,int column,int cType,DATASTATUS_TYPE & ds)112 DataStream(ErrorHandler* eh, SQLHSTMT hstmt, int column, int cType, 113 DATASTATUS_TYPE& ds) 114 : 115 #if !defined(ODBCXX_HAVE_ISO_CXXLIB) 116 DataStreamBase(eh,hstmt,column,cType,ds),ODBCXX_STREAM(this->rdbuf()) 117 #else 118 # if !defined(_MSC_VER) 119 ODBCXX_STREAM(ODBCXX_OPERATOR_NEW_DEBUG(__FILE__, __LINE__) odbc::DataStreamBuf(eh,hstmt,column,cType,ds)) 120 # else 121 // Some bug in MSC makes it fail to realise that std::istream 122 // is inherited by this class 123 std::basic_istream<ODBCXX_CHAR_TYPE, std::char_traits<ODBCXX_CHAR_TYPE> > 124 (ODBCXX_OPERATOR_NEW_DEBUG(__FILE__, __LINE__) odbc::DataStreamBuf(eh,hstmt,column,cType,ds)) 125 # endif // _MSC_VER 126 #endif 127 { 128 #ifndef THROWING_SHIT_IN_THE_CONSTRUCTOR_IS_A_BAD_IDEA_MAN 129 // fetch the first chunk of data - otherwise we don't know whether it's 130 // NULL or not 131 odbc::DataStreamBuf* dsbuff = dynamic_cast<odbc::DataStreamBuf*>(rdbuf()); 132 if(dsbuff != NULL) 133 { dsbuff->underflow();} 134 #endif // THROWING_SHIT_IN_THE_CONSTRUCTOR_IS_A_BAD_IDEA_MAN 135 } ~DataStream()136 ~DataStream() { 137 #if defined(ODBCXX_HAVE_ISO_CXXLIB) 138 ODBCXX_OPERATOR_DELETE_DEBUG(__FILE__, __LINE__) this->rdbuf(); 139 #endif 140 } 141 }; 142 143 #else // defined(ODBCXX_QT) 144 145 146 class DataStream : public QIODevice { 147 public: 148 149 # if QT_VERSION >= 300 150 typedef QIODevice::Offset SizeType; 151 typedef Q_LONG BlockRetType; 152 typedef Q_ULONG BlockLenType; 153 # else 154 typedef uint SizeType; 155 typedef int BlockRetType; 156 typedef uint BlockLenType; 157 # endif 158 159 DataStream(ErrorHandler* eh, SQLHSTMT hstmt, int column, int cType, 160 SQLINTEGER& ds); 161 virtual ~DataStream(); 162 163 virtual bool open(int) { 164 return false; 165 } 166 167 virtual void close() {} 168 virtual void flush() {} 169 170 virtual SizeType size() const { 171 return 0; 172 } 173 174 virtual BlockRetType readBlock(char* data, BlockLenType len); 175 176 // not writable 177 virtual BlockRetType writeBlock(const char* data, BlockLenType len) { 178 return -1; 179 } 180 181 virtual int putch(int) { 182 return -1; 183 } 184 185 virtual int ungetch(int) { 186 return -1; 187 } 188 189 virtual int getch(); 190 191 private: 192 ErrorHandler* errorHandler_; 193 SQLHSTMT hstmt_; 194 int column_; 195 int cType_; 196 SQLINTEGER& dataStatus_; 197 size_t bufferStart_; 198 size_t bufferEnd_; 199 bool eof_; 200 size_t bufferSize_; 201 char* buffer_; 202 203 void _readStep(); 204 }; 205 #endif 206 } // namespace odbc 207 208 #endif //__DATASTREAM_H 209