00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef PQXX_H_RESULT
00020 #define PQXX_H_RESULT
00021
00022 #include "pqxx/compiler-public.hxx"
00023 #include "pqxx/compiler-internal-pre.hxx"
00024
00025 #ifdef PQXX_HAVE_IOS
00026 #include <ios>
00027 #endif
00028
00029 #include <stdexcept>
00030
00031 #include "pqxx/except"
00032 #include "pqxx/util"
00033
00034
00035
00036
00037
00038
00039 namespace pqxx
00040 {
00041 class result;
00042
00043 namespace internal
00044 {
00045 class sql_cursor;
00046
00048 struct PQXX_PRIVATE result_data
00049 {
00051
00054 pqxx::internal::pq::PGresult *data;
00055
00057 int protocol;
00058
00060 PGSTD::string query;
00061
00062 int encoding_code;
00063
00064
00065
00066 result_data();
00067 result_data(pqxx::internal::pq::PGresult *,
00068 int protocol,
00069 const PGSTD::string &,
00070 int encoding_code);
00071 ~result_data();
00072 };
00073
00074 void PQXX_LIBEXPORT freemem_result_data(result_data *) throw ();
00075 template<> inline
00076 void PQAlloc<result_data>::freemem() throw () { freemem_result_data(m_Obj); }
00077 }
00078
00079
00081
00101 class PQXX_LIBEXPORT result : private internal::PQAlloc<internal::result_data>
00102 {
00103 typedef internal::PQAlloc<internal::result_data> super;
00104 public:
00105 class const_iterator;
00106 class const_fielditerator;
00107 class const_reverse_fielditerator;
00108 class tuple;
00109 class field;
00110 typedef unsigned long size_type;
00111 typedef signed long difference_type;
00112 typedef tuple reference;
00113 typedef const_iterator pointer;
00114
00116
00127 class PQXX_LIBEXPORT tuple
00128 {
00129 public:
00130 typedef unsigned int size_type;
00131 typedef signed int difference_type;
00132 typedef const_fielditerator const_iterator;
00133 typedef field reference;
00134 typedef const_fielditerator pointer;
00135 typedef const_reverse_fielditerator const_reverse_iterator;
00136
00137 tuple(const result *r, result::size_type i) throw () :
00138 m_Home(r), m_Index(i) {}
00139 ~tuple() throw () {}
00140
00145 bool operator==(const tuple &) const throw ();
00146 bool operator!=(const tuple &rhs) const throw ()
00147 { return !operator==(rhs); }
00149
00150 const_iterator begin() const throw ()
00151 { return const_iterator(*this, 0); }
00152 const_iterator end() const throw ()
00153 { return const_iterator(*this, size()); }
00154
00159 reference front() const throw () { return field(*this, 0); }
00160 reference back() const throw () { return field(*this, size()-1); }
00161
00162 const_reverse_fielditerator rbegin() const;
00163 const_reverse_fielditerator rend() const;
00164
00165 reference operator[](size_type i) const throw ()
00166 { return field(*this, i); }
00167 reference operator[](int i) const throw ()
00168 { return operator[](size_type(i)); }
00169 reference operator[](const char[]) const;
00170 reference operator[](const PGSTD::string &s) const
00171 { return operator[](s.c_str()); }
00172 reference at(size_type) const throw (range_error);
00173 reference at(int i) const throw (range_error)
00174 { return at(size_type(i)); }
00175 reference at(const char[]) const;
00176 reference at(const PGSTD::string &s) const
00177 { return at(s.c_str()); }
00179
00180 size_type size() const throw () { return m_Home->columns(); }
00181
00182 void swap(tuple &) throw ();
00183
00184 result::size_type rownumber() const throw () { return m_Index; }
00185
00190
00191 size_type column_number(const PGSTD::string &ColName) const
00192 { return m_Home->column_number(ColName); }
00193
00195 size_type column_number(const char ColName[]) const
00196 { return m_Home->column_number(ColName); }
00197
00199 oid column_type(size_type ColNum) const
00200 { return m_Home->column_type(ColNum); }
00201
00203 oid column_type(int ColNum) const
00204 { return column_type(size_type(ColNum)); }
00205
00207 oid column_type(const PGSTD::string &ColName) const
00208 { return column_type(column_number(ColName)); }
00209
00211 oid column_type(const char ColName[]) const
00212 { return column_type(column_number(ColName)); }
00213
00215
00222 oid column_table(size_type ColNum) const
00223 { return m_Home->column_table(ColNum); }
00225
00232 oid column_table(int ColNum) const
00233 { return column_table(size_type(ColNum)); }
00235
00242 oid column_table(const PGSTD::string &ColName) const
00243 { return column_table(column_number(ColName)); }
00244
00246
00256 size_type table_column(size_type ColNum) const
00257 { return m_Home->table_column(ColNum); }
00258
00260 size_type table_column(int ColNum) const
00261 { return table_column(size_type(ColNum)); }
00262
00264 size_type table_column(const PGSTD::string &ColName) const
00265 { return table_column(column_number(ColName)); }
00267
00268 result::size_type num() const { return rownumber(); }
00269
00270
00271 protected:
00272 friend class field;
00273 const result *m_Home;
00274 result::size_type m_Index;
00275
00276
00277 tuple();
00278 };
00279
00281
00284 class PQXX_LIBEXPORT field
00285 {
00286 public:
00287 typedef size_t size_type;
00288
00290
00294 field(const tuple &T, tuple::size_type C) throw () :
00295 m_tup(T), m_col(C) {}
00296
00301
00302
00318 bool operator==(const field &) const;
00319
00321
00323 bool operator!=(const field &rhs) const {return !operator==(rhs);}
00325
00330
00331 const char *name() const { return home()->column_name(col()); }
00332
00334 oid type() const { return home()->column_type(col()); }
00335
00337
00344 oid table() const { return home()->column_table(col()); }
00345
00346 tuple::size_type num() const { return col(); }
00347
00349 tuple::size_type table_column() const
00350 { return home()->table_column(col()); }
00352
00357
00358
00363 const char *c_str() const { return home()->GetValue(idx(),col()); }
00364
00366 template<typename T> bool to(T &Obj) const
00367 {
00368 const char *const bytes = c_str();
00369 if (!bytes[0] && is_null()) return false;
00370 from_string(bytes, Obj);
00371 return true;
00372 }
00373
00375 template<typename T> bool operator>>(T &Obj) const
00376 { return to(Obj); }
00377
00378 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00380 template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00381
00383
00386 template<> bool to<const char *>(const char *&Obj) const;
00387 #endif
00388
00390 template<typename T> bool to(T &Obj, const T &Default) const
00391 {
00392 const bool NotNull = to(Obj);
00393 if (!NotNull) Obj = Default;
00394 return NotNull;
00395 }
00396
00398
00401 template<typename T> T as(const T &Default) const
00402 {
00403 T Obj;
00404 to(Obj, Default);
00405 return Obj;
00406 }
00407
00409 template<typename T> T as() const
00410 {
00411 T Obj;
00412 const bool NotNull = to(Obj);
00413 if (!NotNull) Obj = string_traits<T>::null();
00414 return Obj;
00415 }
00416
00417 bool is_null() const { return home()->GetIsNull(idx(), col()); }
00418 size_type size() const throw ()
00419 { return home()->GetLength(idx(),col()); }
00421
00422
00423 private:
00424 const result *home() const throw () { return m_tup.m_Home; }
00425 result::size_type idx() const throw () { return m_tup.m_Index; }
00426
00427 protected:
00428 tuple::size_type col() const throw () { return m_col; }
00429 tuple m_tup;
00430 tuple::size_type m_col;
00431 };
00432
00433 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00434 const tuple,
00435 result::difference_type,
00436 const_iterator,
00437 tuple>
00438 const_iterator_base;
00439
00441
00445 class PQXX_LIBEXPORT const_iterator :
00446 public const_iterator_base,
00447 public tuple
00448 {
00449 public:
00450 typedef const tuple *pointer;
00451 typedef tuple reference;
00452 typedef result::size_type size_type;
00453 typedef result::difference_type difference_type;
00454
00455 const_iterator() throw () : tuple(0,0) {}
00456 const_iterator(const tuple &t) throw () : tuple(t) {}
00457
00473 pointer operator->() const { return this; }
00474 reference operator*() const { return tuple(*this); }
00476
00481 const_iterator operator++(int);
00482 const_iterator &operator++() { ++m_Index; return *this; }
00483 const_iterator operator--(int);
00484 const_iterator &operator--() { --m_Index; return *this; }
00485
00486 const_iterator &operator+=(difference_type i)
00487 { m_Index+=i; return *this; }
00488 const_iterator &operator-=(difference_type i)
00489 { m_Index-=i; return *this; }
00491
00496 bool operator==(const const_iterator &i) const
00497 {return m_Index==i.m_Index;}
00498 bool operator!=(const const_iterator &i) const
00499 {return m_Index!=i.m_Index;}
00500 bool operator<(const const_iterator &i) const
00501 {return m_Index<i.m_Index;}
00502 bool operator<=(const const_iterator &i) const
00503 {return m_Index<=i.m_Index;}
00504 bool operator>(const const_iterator &i) const
00505 {return m_Index>i.m_Index;}
00506 bool operator>=(const const_iterator &i) const
00507 {return m_Index>=i.m_Index;}
00509
00514 inline const_iterator operator+(difference_type) const;
00515 friend const_iterator
00516 operator+(difference_type, const_iterator);
00517 inline const_iterator operator-(difference_type) const;
00518 inline difference_type operator-(const_iterator) const;
00520
00521 private:
00522 friend class pqxx::result;
00523 const_iterator(const pqxx::result *r, result::size_type i) throw () :
00524 tuple(r, i) {}
00525 };
00526
00527 class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00528 {
00529 public:
00530 typedef pqxx::result::const_iterator super;
00531 typedef pqxx::result::const_iterator iterator_type;
00532 using iterator_type::iterator_category;
00533 using iterator_type::difference_type;
00534 using iterator_type::pointer;
00535 #ifndef _MSC_VER
00536 using iterator_type::value_type;
00537 using iterator_type::reference;
00538 #else
00539
00540 typedef const tuple &reference;
00541 typedef tuple value_type;
00542 #endif
00543
00544 const_reverse_iterator(const const_reverse_iterator &rhs) :
00545 const_iterator(rhs) {}
00546 explicit const_reverse_iterator(const const_iterator &rhs) :
00547 const_iterator(rhs) { super::operator--(); }
00548
00549 iterator_type base() const throw ();
00550
00555 using const_iterator::operator->;
00556 using const_iterator::operator*;
00558
00563 const_reverse_iterator &operator=(const const_reverse_iterator &r)
00564 { iterator_type::operator=(r); return *this; }
00565 const_reverse_iterator operator++()
00566 { iterator_type::operator--(); return *this; }
00567 const_reverse_iterator operator++(int);
00568 const_reverse_iterator &operator--()
00569 { iterator_type::operator++(); return *this; }
00570 const_reverse_iterator operator--(int);
00571 const_reverse_iterator &operator+=(difference_type i)
00572 { iterator_type::operator-=(i); return *this; }
00573 const_reverse_iterator &operator-=(difference_type i)
00574 { iterator_type::operator+=(i); return *this; }
00576
00581 const_reverse_iterator operator+(difference_type i) const
00582 { return const_reverse_iterator(base()-i); }
00583 const_reverse_iterator operator-(difference_type i)
00584 { return const_reverse_iterator(base()+i); }
00585 difference_type operator-(const const_reverse_iterator &rhs) const
00586 { return rhs.const_iterator::operator-(*this); }
00588
00593 bool operator==(const const_reverse_iterator &rhs) const throw ()
00594 { return iterator_type::operator==(rhs); }
00595 bool operator!=(const const_reverse_iterator &rhs) const throw ()
00596 { return !operator==(rhs); }
00597
00598 bool operator<(const const_reverse_iterator &rhs) const
00599 { return iterator_type::operator>(rhs); }
00600 bool operator<=(const const_reverse_iterator &rhs) const
00601 { return iterator_type::operator>=(rhs); }
00602 bool operator>(const const_reverse_iterator &rhs) const
00603 { return iterator_type::operator<(rhs); }
00604 bool operator>=(const const_reverse_iterator &rhs) const
00605 { return iterator_type::operator<=(rhs); }
00607 };
00608
00609 class PQXX_LIBEXPORT const_fielditerator :
00610 public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00611 const field,
00612 tuple::size_type>,
00613 public field
00614 {
00615 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00616 const field,
00617 tuple::size_type> it;
00618 public:
00619 using it::pointer;
00620 typedef tuple::size_type size_type;
00621 typedef tuple::difference_type difference_type;
00622 typedef field reference;
00623
00624 const_fielditerator(const tuple &T, tuple::size_type C) throw () :
00625 field(T, C) {}
00626 const_fielditerator(const field &F) throw () : field(F) {}
00627
00632 pointer operator->() const { return this; }
00633 reference operator*() const { return field(*this); }
00635
00640 const_fielditerator operator++(int);
00641 const_fielditerator &operator++() { ++m_col; return *this; }
00642 const_fielditerator operator--(int);
00643 const_fielditerator &operator--() { --m_col; return *this; }
00644
00645 const_fielditerator &operator+=(difference_type i)
00646 { m_col+=i; return *this; }
00647 const_fielditerator &operator-=(difference_type i)
00648 { m_col-=i; return *this; }
00650
00655 bool operator==(const const_fielditerator &i) const
00656 {return col()==i.col();}
00657 bool operator!=(const const_fielditerator &i) const
00658 {return col()!=i.col();}
00659 bool operator<(const const_fielditerator &i) const
00660 {return col()<i.col();}
00661 bool operator<=(const const_fielditerator &i) const
00662 {return col()<=i.col();}
00663 bool operator>(const const_fielditerator &i) const
00664 {return col()>i.col();}
00665 bool operator>=(const const_fielditerator &i) const
00666 {return col()>=i.col();}
00668
00673 inline const_fielditerator operator+(difference_type) const;
00674
00675 friend const_fielditerator operator+(difference_type,
00676 const_fielditerator);
00677
00678 inline const_fielditerator operator-(difference_type) const;
00679 inline difference_type operator-(const_fielditerator) const;
00681 };
00682
00683 class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00684 {
00685 public:
00686 typedef const_fielditerator super;
00687 typedef const_fielditerator iterator_type;
00688 using iterator_type::iterator_category;
00689 using iterator_type::difference_type;
00690 using iterator_type::pointer;
00691 #ifndef _MSC_VER
00692 using iterator_type::value_type;
00693 using iterator_type::reference;
00694 #else
00695
00696 typedef field value_type;
00697 typedef const field &reference;
00698 #endif
00699
00700 const_reverse_fielditerator(const const_reverse_fielditerator &r) :
00701 const_fielditerator(r) {}
00702 explicit
00703 const_reverse_fielditerator(const super &rhs) throw() :
00704 const_fielditerator(rhs) { super::operator--(); }
00705
00706 iterator_type base() const throw ();
00707
00712 using iterator_type::operator->;
00713 using iterator_type::operator*;
00715
00720 const_reverse_fielditerator &
00721 operator=(const const_reverse_fielditerator &r)
00722 { iterator_type::operator=(r); return *this; }
00723 const_reverse_fielditerator operator++()
00724 { iterator_type::operator--(); return *this; }
00725 const_reverse_fielditerator operator++(int);
00726 const_reverse_fielditerator &operator--()
00727 { iterator_type::operator++(); return *this; }
00728 const_reverse_fielditerator operator--(int);
00729 const_reverse_fielditerator &operator+=(difference_type i)
00730 { iterator_type::operator-=(i); return *this; }
00731 const_reverse_fielditerator &operator-=(difference_type i)
00732 { iterator_type::operator+=(i); return *this; }
00734
00739 const_reverse_fielditerator operator+(difference_type i) const
00740 { return const_reverse_fielditerator(base()-i); }
00741 const_reverse_fielditerator operator-(difference_type i)
00742 { return const_reverse_fielditerator(base()+i); }
00743 difference_type
00744 operator-(const const_reverse_fielditerator &rhs) const
00745 { return rhs.const_fielditerator::operator-(*this); }
00747
00752 bool
00753 operator==(const const_reverse_fielditerator &rhs) const throw ()
00754 { return iterator_type::operator==(rhs); }
00755 bool
00756 operator!=(const const_reverse_fielditerator &rhs) const throw ()
00757 { return !operator==(rhs); }
00758
00759 bool operator<(const const_reverse_fielditerator &rhs) const
00760 { return iterator_type::operator>(rhs); }
00761 bool operator<=(const const_reverse_fielditerator &rhs) const
00762 { return iterator_type::operator>=(rhs); }
00763 bool operator>(const const_reverse_fielditerator &rhs) const
00764 { return iterator_type::operator<(rhs); }
00765 bool operator>=(const const_reverse_fielditerator &rhs) const
00766 { return iterator_type::operator<=(rhs); }
00768 };
00769
00770
00771 result() throw () : super(), m_data(0) {}
00772 result(const result &rhs) throw () :
00773 super(rhs), m_data(rhs.m_data) {}
00774
00775 result &operator=(const result &rhs) throw ()
00776 { super::operator=(rhs); m_data=rhs.m_data; return *this; }
00777
00782 bool operator==(const result &) const throw ();
00783 bool operator!=(const result &rhs) const throw ()
00784 { return !operator==(rhs); }
00786
00787 const_reverse_iterator rbegin() const
00788 { return const_reverse_iterator(end()); }
00789 const_reverse_iterator rend() const
00790 { return const_reverse_iterator(begin()); }
00791
00792 const_iterator begin() const throw ()
00793 { return const_iterator(this, 0); }
00794 inline const_iterator end() const throw ();
00795
00796 reference front() const throw () { return tuple(this,0); }
00797 reference back() const throw () {return tuple(this,size()-1);}
00798
00799 size_type size() const throw ();
00800 bool empty() const throw ();
00801 size_type capacity() const throw () { return size(); }
00802
00803 void swap(result &) throw ();
00804
00805 const tuple operator[](size_type i) const throw ()
00806 { return tuple(this, i); }
00807 const tuple at(size_type) const throw (range_error);
00808
00809 void clear() throw () { super::clear(); m_data = 0; }
00810
00815
00816 tuple::size_type columns() const throw ();
00817
00819 tuple::size_type column_number(const char ColName[]) const;
00820
00822 tuple::size_type column_number(const PGSTD::string &Name) const
00823 {return column_number(Name.c_str());}
00824
00826 const char *column_name(tuple::size_type Number) const;
00827
00829 oid column_type(tuple::size_type ColNum) const;
00831 oid column_type(int ColNum) const
00832 { return column_type(tuple::size_type(ColNum)); }
00833
00835 oid column_type(const PGSTD::string &ColName) const
00836 { return column_type(column_number(ColName)); }
00837
00839 oid column_type(const char ColName[]) const
00840 { return column_type(column_number(ColName)); }
00841
00843
00850 oid column_table(tuple::size_type ColNum) const;
00851
00853
00860 oid column_table(int ColNum) const
00861 { return column_table(tuple::size_type(ColNum)); }
00862
00864
00871 oid column_table(const PGSTD::string &ColName) const
00872 { return column_table(column_number(ColName)); }
00873
00875 tuple::size_type table_column(tuple::size_type ColNum) const;
00876
00878 tuple::size_type table_column(int ColNum) const
00879 { return table_column(tuple::size_type(ColNum)); }
00880
00882 tuple::size_type table_column(const PGSTD::string &ColName) const
00883 { return table_column(column_number(ColName)); }
00885
00887 const PGSTD::string &query() const throw ();
00888
00890
00893 oid inserted_oid() const;
00894
00895
00897
00900 size_type affected_rows() const;
00901
00902
00903 private:
00904 friend class pqxx::result::field;
00905 const char *GetValue(size_type Row, tuple::size_type Col) const;
00906 bool GetIsNull(size_type Row, tuple::size_type Col) const;
00907 field::size_type GetLength(size_type, tuple::size_type) const;
00908
00909 friend class connection_base;
00910 friend class pipeline;
00911 result(internal::pq::PGresult *rhs,
00912 int protocol,
00913 const PGSTD::string &Query,
00914 int encoding_code);
00915 bool operator!() const throw () { return !m_data; }
00916 operator bool() const throw () { return m_data != 0; }
00917
00918 void PQXX_PRIVATE CheckStatus() const;
00919
00920 void PQXX_PRIVATE ThrowSQLError(const PGSTD::string &Err,
00921 const PGSTD::string &Query) const;
00922 int PQXX_PRIVATE errorposition() const throw ();
00923 PGSTD::string PQXX_PRIVATE StatusError() const;
00924
00925 friend class Cursor;
00926 friend class internal::sql_cursor;
00927 const char *CmdStatus() const throw ();
00928
00930 pqxx::internal::pq::PGresult *m_data;
00931
00932 static const PGSTD::string PQXX_PRIVATE s_empty_string;
00933 };
00934
00935
00937
00957 template<typename CHAR>
00958 inline PGSTD::basic_ostream<CHAR> &operator<<(
00959 PGSTD::basic_ostream<CHAR> &S, const pqxx::result::field &F)
00960 {
00961 S.write(F.c_str(), F.size());
00962 return S;
00963 }
00964
00965
00967 template<typename T>
00968 inline void from_string(const result::field &F, T &Obj)
00969 { from_string(F.c_str(), Obj, F.size()); }
00970
00972 template<>
00973 inline PGSTD::string to_string(const result::field &Obj)
00974 { return PGSTD::string(Obj.c_str(), Obj.size()); }
00975
00976
00978 template<>
00979 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00980 {
00981 const char *const bytes = c_str();
00982 if (!bytes[0] && is_null()) return false;
00983 Obj = PGSTD::string(bytes, size());
00984 return true;
00985 }
00986
00988
00993 template<>
00994 inline bool result::field::to<const char *>(const char *&Obj) const
00995 {
00996 if (is_null()) return false;
00997 Obj = c_str();
00998 return true;
00999 }
01000
01001
01002 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
01003 { return const_reverse_fielditerator(end()); }
01004 inline result::tuple::const_reverse_iterator result::tuple::rend() const
01005 { return const_reverse_fielditerator(begin()); }
01006
01007 inline result::const_iterator
01008 result::const_iterator::operator+(difference_type o) const
01009 { return const_iterator(m_Home, m_Index + o); }
01010
01011 inline result::const_iterator
01012 operator+(result::const_iterator::difference_type o, result::const_iterator i)
01013 { return i + o; }
01014
01015 inline result::const_iterator
01016 result::const_iterator::operator-(difference_type o) const
01017 { return const_iterator(m_Home, m_Index - o); }
01018
01019 inline result::const_iterator::difference_type
01020 result::const_iterator::operator-(const_iterator i) const
01021 { return num()-i.num(); }
01022
01023 inline result::const_iterator result::end() const throw ()
01024 { return const_iterator(this, size()); }
01025
01026
01027 inline result::const_reverse_iterator
01028 operator+(result::const_reverse_iterator::difference_type n,
01029 const result::const_reverse_iterator &i)
01030 { return result::const_reverse_iterator(i.base() - n); }
01031
01032 inline result::const_fielditerator
01033 result::const_fielditerator::operator+(difference_type o) const
01034 { return const_fielditerator(m_tup, col() + o); }
01035
01036 inline result::const_fielditerator
01037 operator+(result::const_fielditerator::difference_type o,
01038 result::const_fielditerator i)
01039 { return i + o; }
01040
01041 inline result::const_fielditerator
01042 result::const_fielditerator::operator-(difference_type o) const
01043 { return const_fielditerator(m_tup, col() - o); }
01044
01045 inline result::const_fielditerator::difference_type
01046 result::const_fielditerator::operator-(const_fielditerator i) const
01047 { return num()-i.num(); }
01048
01049
01050 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01051 class field_streambuf :
01052 #ifdef PQXX_HAVE_STREAMBUF
01053 public PGSTD::basic_streambuf<CHAR, TRAITS>
01054 #else
01055 public PGSTD::streambuf
01056 #endif
01057 {
01058 public:
01059 typedef CHAR char_type;
01060 typedef TRAITS traits_type;
01061 typedef typename traits_type::int_type int_type;
01062 #ifdef PQXX_HAVE_STREAMBUF
01063 typedef typename traits_type::pos_type pos_type;
01064 typedef typename traits_type::off_type off_type;
01065 #else
01066 typedef streamoff off_type;
01067 typedef streampos pos_type;
01068 #endif
01069 typedef PGSTD::ios::openmode openmode;
01070 typedef PGSTD::ios::seekdir seekdir;
01071
01072 explicit field_streambuf(const result::field &F) :
01073 m_Field(F)
01074 {
01075 initialize();
01076 }
01077
01078 #ifdef PQXX_HAVE_STREAMBUF
01079 protected:
01080 #endif
01081 virtual int sync() { return traits_type::eof(); }
01082
01083 protected:
01084 virtual pos_type seekoff(off_type, seekdir, openmode)
01085 { return traits_type::eof(); }
01086 virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
01087 virtual int_type overflow(int_type) { return traits_type::eof(); }
01088 virtual int_type underflow() { return traits_type::eof(); }
01089
01090 private:
01091 const result::field &m_Field;
01092
01093 int_type initialize()
01094 {
01095 char_type *G =
01096 reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
01097 setg(G, G, G + m_Field.size());
01098 return int_type(m_Field.size());
01099 }
01100 };
01101
01102
01104
01112 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01113 class basic_fieldstream :
01114 #ifdef PQXX_HAVE_STREAMBUF
01115 public PGSTD::basic_istream<CHAR, TRAITS>
01116 #else
01117 public PGSTD::istream
01118 #endif
01119 {
01120 #ifdef PQXX_HAVE_STREAMBUF
01121 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
01122 #else
01123 typedef PGSTD::istream super;
01124 #endif
01125
01126 public:
01127 typedef CHAR char_type;
01128 typedef TRAITS traits_type;
01129 typedef typename traits_type::int_type int_type;
01130 typedef typename traits_type::pos_type pos_type;
01131 typedef typename traits_type::off_type off_type;
01132
01133 basic_fieldstream(const result::field &F) : super(0), m_Buf(F)
01134 { super::init(&m_Buf); }
01135
01136 private:
01137 field_streambuf<CHAR, TRAITS> m_Buf;
01138 };
01139
01140 typedef basic_fieldstream<char> fieldstream;
01141
01142 }
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160 #include "pqxx/compiler-internal-post.hxx"
01161
01162 #endif
01163