00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pqxx/compiler-public.hxx"
00020 #include "pqxx/compiler-internal-pre.hxx"
00021
00022 #ifdef PQXX_HAVE_IOS
00023 #include <ios>
00024 #endif
00025
00026 #include <stdexcept>
00027
00028 #include "pqxx/util"
00029
00030
00031
00032
00033
00034
00035 namespace pqxx
00036 {
00037 class result;
00038
00039 namespace internal
00040 {
00042 struct PQXX_PRIVATE result_data
00043 {
00045
00048 pqxx::internal::pq::PGresult *data;
00049
00051 int protocol;
00052
00054 PGSTD::string query;
00055
00056
00057
00058 result_data();
00059 result_data(pqxx::internal::pq::PGresult *, int, const PGSTD::string &);
00060 ~result_data();
00061 };
00062
00063 void freemem_result_data(result_data *) throw ();
00064 template<> inline
00065 void PQAlloc<result_data>::freemem() throw () { freemem_result_data(m_Obj); }
00066 }
00067
00068
00070
00090 class PQXX_LIBEXPORT result : private internal::PQAlloc<internal::result_data>
00091 {
00092 typedef internal::PQAlloc<internal::result_data> super;
00093 public:
00094 class const_iterator;
00095 class const_fielditerator;
00096 class const_reverse_fielditerator;
00097 class tuple;
00098 class field;
00099 typedef unsigned long size_type;
00100 typedef signed long difference_type;
00101 typedef tuple reference;
00102 typedef const_iterator pointer;
00103
00105
00116 class PQXX_LIBEXPORT tuple
00117 {
00118 public:
00119 typedef unsigned int size_type;
00120 typedef signed int difference_type;
00121 typedef const_fielditerator const_iterator;
00122 typedef field reference;
00123 typedef const_fielditerator pointer;
00124 typedef const_reverse_fielditerator const_reverse_iterator;
00125
00126 tuple(const result *r, result::size_type i) throw () :
00127 m_Home(r), m_Index(i) {}
00128 ~tuple() throw () {}
00129
00134 bool operator==(const tuple &) const throw ();
00135 bool operator!=(const tuple &rhs) const throw ()
00136 { return !operator==(rhs); }
00138
00139 const_iterator begin() const throw ()
00140 { return const_iterator(*this, 0); }
00141 const_iterator end() const throw ()
00142 { return const_iterator(*this, size()); }
00143
00148 reference front() const throw () { return field(*this, 0); }
00149 reference back() const throw () { return field(*this, size()-1); }
00150
00151 const_reverse_fielditerator rbegin() const;
00152 const_reverse_fielditerator rend() const;
00153
00154 reference operator[](size_type i) const throw ()
00155 { return field(*this, i); }
00156 reference operator[](int i) const throw ()
00157 { return operator[](size_type(i)); }
00158 reference operator[](const char[]) const;
00159 reference operator[](const PGSTD::string &s) const
00160 { return operator[](s.c_str()); }
00161 reference at(size_type) const throw (PGSTD::out_of_range);
00162 reference at(int i) const throw (PGSTD::out_of_range)
00163 { return at(size_type(i)); }
00164 reference at(const char[]) const;
00165 reference at(const PGSTD::string &s) const
00166 { return at(s.c_str()); }
00168
00169 size_type size() const throw () { return m_Home->columns(); }
00170
00171 void swap(tuple &) throw ();
00172
00173 result::size_type rownumber() const throw () { return m_Index; }
00174
00179
00180 size_type column_number(const PGSTD::string &ColName) const
00181 { return m_Home->column_number(ColName); }
00182
00184 size_type column_number(const char ColName[]) const
00185 { return m_Home->column_number(ColName); }
00186
00188 oid column_type(size_type ColNum) const
00189 { return m_Home->column_type(ColNum); }
00190
00192 oid column_type(int ColNum) const
00193 { return column_type(size_type(ColNum)); }
00194
00196 oid column_type(const PGSTD::string &ColName) const
00197 { return column_type(column_number(ColName)); }
00198
00200 oid column_type(const char ColName[]) const
00201 { return column_type(column_number(ColName)); }
00202
00204
00211 oid column_table(size_type ColNum) const
00212 { return m_Home->column_table(ColNum); }
00214
00221 oid column_table(int ColNum) const
00222 { return column_table(size_type(ColNum)); }
00224
00231 oid column_table(const PGSTD::string &ColName) const
00232 { return column_table(column_number(ColName)); }
00233
00235
00245 size_type table_column(size_type ColNum) const
00246 { return m_Home->table_column(ColNum); }
00247
00249 size_type table_column(int ColNum) const
00250 { return table_column(size_type(ColNum)); }
00251
00253 size_type table_column(const PGSTD::string &ColName) const
00254 { return table_column(column_number(ColName)); }
00256
00257 result::size_type num() const { return rownumber(); }
00258
00259
00260 protected:
00261 friend class field;
00262 const result *m_Home;
00263 result::size_type m_Index;
00264
00265
00266 tuple();
00267 };
00268
00270
00273 class PQXX_LIBEXPORT field
00274 {
00275 public:
00276 typedef size_t size_type;
00277
00279
00283 field(const tuple &T, tuple::size_type C) throw () :
00284 m_tup(T), m_col(C) {}
00285
00290
00291
00307 bool operator==(const field &) const;
00308
00310
00312 bool operator!=(const field &rhs) const {return !operator==(rhs);}
00314
00319
00320 const char *name() const { return home()->column_name(col()); }
00321
00323 oid type() const { return home()->column_type(col()); }
00324
00326
00333 oid table() const { return home()->column_table(col()); }
00334
00335 tuple::size_type num() const { return col(); }
00336
00338 tuple::size_type table_column() const
00339 { return home()->table_column(col()); }
00341
00346
00347
00352 const char *c_str() const { return home()->GetValue(idx(),col()); }
00353
00355 template<typename T> bool to(T &Obj) const
00356 {
00357 const char *const bytes = c_str();
00358 if (!bytes[0] && is_null()) return false;
00359 from_string(bytes, Obj);
00360 return true;
00361 }
00362
00364 template<typename T> bool operator>>(T &Obj) const
00365 { return to(Obj); }
00366
00367 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00369 template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00370
00372
00375 template<> bool to<const char *>(const char *&Obj) const;
00376 #endif
00377
00379 template<typename T> bool to(T &Obj, const T &Default) const
00380 {
00381 const bool NotNull = to(Obj);
00382 if (!NotNull) Obj = Default;
00383 return NotNull;
00384 }
00385
00387
00390 template<typename T> T as(const T &Default) const
00391 {
00392 T Obj;
00393 to(Obj, Default);
00394 return Obj;
00395 }
00396
00398 template<typename T> T as() const
00399 {
00400 T Obj;
00401 const bool NotNull = to(Obj);
00402 if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00403 return Obj;
00404 }
00405
00406 bool is_null() const { return home()->GetIsNull(idx(), col()); }
00407 size_type size() const throw ()
00408 { return home()->GetLength(idx(),col()); }
00410
00411
00412 private:
00413 const result *home() const throw () { return m_tup.m_Home; }
00414 result::size_type idx() const throw () { return m_tup.m_Index; }
00415
00416 protected:
00417 tuple::size_type col() const throw () { return m_col; }
00418 tuple m_tup;
00419 tuple::size_type m_col;
00420 };
00421
00422 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00423 const tuple,
00424 result::difference_type,
00425 const_iterator,
00426 tuple>
00427 const_iterator_base;
00428
00430
00434 class PQXX_LIBEXPORT const_iterator :
00435 public const_iterator_base,
00436 public tuple
00437 {
00438 public:
00439 typedef const tuple *pointer;
00440 typedef tuple reference;
00441 typedef result::size_type size_type;
00442 typedef result::difference_type difference_type;
00443
00444 const_iterator() throw () : tuple(0,0) {}
00445 const_iterator(const tuple &t) throw () : tuple(t) {}
00446
00462 pointer operator->() const { return this; }
00463 reference operator*() const { return tuple(*this); }
00465
00470 const_iterator operator++(int);
00471 const_iterator &operator++() { ++m_Index; return *this; }
00472 const_iterator operator--(int);
00473 const_iterator &operator--() { --m_Index; return *this; }
00474
00475 const_iterator &operator+=(difference_type i)
00476 { m_Index+=i; return *this; }
00477 const_iterator &operator-=(difference_type i)
00478 { m_Index-=i; return *this; }
00480
00485 bool operator==(const const_iterator &i) const
00486 {return m_Index==i.m_Index;}
00487 bool operator!=(const const_iterator &i) const
00488 {return m_Index!=i.m_Index;}
00489 bool operator<(const const_iterator &i) const
00490 {return m_Index<i.m_Index;}
00491 bool operator<=(const const_iterator &i) const
00492 {return m_Index<=i.m_Index;}
00493 bool operator>(const const_iterator &i) const
00494 {return m_Index>i.m_Index;}
00495 bool operator>=(const const_iterator &i) const
00496 {return m_Index>=i.m_Index;}
00498
00503 inline const_iterator operator+(difference_type) const;
00504 friend const_iterator
00505 operator+(difference_type, const_iterator);
00506 inline const_iterator operator-(difference_type) const;
00507 inline difference_type operator-(const_iterator) const;
00509
00510 private:
00511 friend class pqxx::result;
00512 const_iterator(const pqxx::result *r, result::size_type i) throw () :
00513 tuple(r, i) {}
00514 };
00515
00516 class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00517 {
00518 public:
00519 typedef pqxx::result::const_iterator super;
00520 typedef pqxx::result::const_iterator iterator_type;
00521 using iterator_type::iterator_category;
00522 using iterator_type::difference_type;
00523 using iterator_type::pointer;
00524 #ifndef _MSC_VER
00525 using iterator_type::value_type;
00526 using iterator_type::reference;
00527 #else
00528
00529 typedef const tuple &reference;
00530 typedef tuple value_type;
00531 #endif
00532
00533 const_reverse_iterator(const const_reverse_iterator &rhs) :
00534 const_iterator(rhs) {}
00535 explicit const_reverse_iterator(const const_iterator &rhs) :
00536 const_iterator(rhs) { super::operator--(); }
00537
00538 iterator_type base() const throw ();
00539
00544 using const_iterator::operator->;
00545 using const_iterator::operator*;
00547
00552 const_reverse_iterator &operator=(const const_reverse_iterator &r)
00553 { iterator_type::operator=(r); return *this; }
00554 const_reverse_iterator operator++()
00555 { iterator_type::operator--(); return *this; }
00556 const_reverse_iterator operator++(int);
00557 const_reverse_iterator &operator--()
00558 { iterator_type::operator++(); return *this; }
00559 const_reverse_iterator operator--(int);
00560 const_reverse_iterator &operator+=(difference_type i)
00561 { iterator_type::operator-=(i); return *this; }
00562 const_reverse_iterator &operator-=(difference_type i)
00563 { iterator_type::operator+=(i); return *this; }
00565
00570 const_reverse_iterator operator+(difference_type i) const
00571 { return const_reverse_iterator(base()-i); }
00572 const_reverse_iterator operator-(difference_type i)
00573 { return const_reverse_iterator(base()+i); }
00574 difference_type operator-(const const_reverse_iterator &rhs) const
00575 { return rhs.const_iterator::operator-(*this); }
00577
00582 bool operator==(const const_reverse_iterator &rhs) const throw ()
00583 { return iterator_type::operator==(rhs); }
00584 bool operator!=(const const_reverse_iterator &rhs) const throw ()
00585 { return !operator==(rhs); }
00586
00587 bool operator<(const const_reverse_iterator &rhs) const
00588 { return iterator_type::operator>(rhs); }
00589 bool operator<=(const const_reverse_iterator &rhs) const
00590 { return iterator_type::operator>=(rhs); }
00591 bool operator>(const const_reverse_iterator &rhs) const
00592 { return iterator_type::operator<(rhs); }
00593 bool operator>=(const const_reverse_iterator &rhs) const
00594 { return iterator_type::operator<=(rhs); }
00596 };
00597
00598 class PQXX_LIBEXPORT const_fielditerator :
00599 public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00600 const field,
00601 tuple::size_type>,
00602 public field
00603 {
00604 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00605 const field,
00606 tuple::size_type> it;
00607 public:
00608 using it::pointer;
00609 typedef tuple::size_type size_type;
00610 typedef tuple::difference_type difference_type;
00611 typedef field reference;
00612
00613 const_fielditerator(const tuple &T, tuple::size_type C) throw () :
00614 field(T, C) {}
00615 const_fielditerator(const field &F) throw () : field(F) {}
00616
00621 pointer operator->() const { return this; }
00622 reference operator*() const { return field(*this); }
00624
00629 const_fielditerator operator++(int);
00630 const_fielditerator &operator++() { ++m_col; return *this; }
00631 const_fielditerator operator--(int);
00632 const_fielditerator &operator--() { --m_col; return *this; }
00633
00634 const_fielditerator &operator+=(difference_type i)
00635 { m_col+=i; return *this; }
00636 const_fielditerator &operator-=(difference_type i)
00637 { m_col-=i; return *this; }
00639
00644 bool operator==(const const_fielditerator &i) const
00645 {return col()==i.col();}
00646 bool operator!=(const const_fielditerator &i) const
00647 {return col()!=i.col();}
00648 bool operator<(const const_fielditerator &i) const
00649 {return col()<i.col();}
00650 bool operator<=(const const_fielditerator &i) const
00651 {return col()<=i.col();}
00652 bool operator>(const const_fielditerator &i) const
00653 {return col()>i.col();}
00654 bool operator>=(const const_fielditerator &i) const
00655 {return col()>=i.col();}
00657
00662 inline const_fielditerator operator+(difference_type) const;
00663
00664 friend const_fielditerator operator+(difference_type,
00665 const_fielditerator);
00666
00667 inline const_fielditerator operator-(difference_type) const;
00668 inline difference_type operator-(const_fielditerator) const;
00670 };
00671
00672 class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00673 {
00674 public:
00675 typedef const_fielditerator super;
00676 typedef const_fielditerator iterator_type;
00677 using iterator_type::iterator_category;
00678 using iterator_type::difference_type;
00679 using iterator_type::pointer;
00680 #ifndef _MSC_VER
00681 using iterator_type::value_type;
00682 using iterator_type::reference;
00683 #else
00684
00685 typedef field value_type;
00686 typedef const field &reference;
00687 #endif
00688
00689 const_reverse_fielditerator(const const_reverse_fielditerator &r) :
00690 const_fielditerator(r) {}
00691 explicit
00692 const_reverse_fielditerator(const super &rhs) throw() :
00693 const_fielditerator(rhs) { super::operator--(); }
00694
00695 iterator_type base() const throw ();
00696
00701 using iterator_type::operator->;
00702 using iterator_type::operator*;
00704
00709 const_reverse_fielditerator &
00710 operator=(const const_reverse_fielditerator &r)
00711 { iterator_type::operator=(r); return *this; }
00712 const_reverse_fielditerator operator++()
00713 { iterator_type::operator--(); return *this; }
00714 const_reverse_fielditerator operator++(int);
00715 const_reverse_fielditerator &operator--()
00716 { iterator_type::operator++(); return *this; }
00717 const_reverse_fielditerator operator--(int);
00718 const_reverse_fielditerator &operator+=(difference_type i)
00719 { iterator_type::operator-=(i); return *this; }
00720 const_reverse_fielditerator &operator-=(difference_type i)
00721 { iterator_type::operator+=(i); return *this; }
00723
00728 const_reverse_fielditerator operator+(difference_type i) const
00729 { return const_reverse_fielditerator(base()-i); }
00730 const_reverse_fielditerator operator-(difference_type i)
00731 { return const_reverse_fielditerator(base()+i); }
00732 difference_type
00733 operator-(const const_reverse_fielditerator &rhs) const
00734 { return rhs.const_fielditerator::operator-(*this); }
00736
00741 bool
00742 operator==(const const_reverse_fielditerator &rhs) const throw ()
00743 { return iterator_type::operator==(rhs); }
00744 bool
00745 operator!=(const const_reverse_fielditerator &rhs) const throw ()
00746 { return !operator==(rhs); }
00747
00748 bool operator<(const const_reverse_fielditerator &rhs) const
00749 { return iterator_type::operator>(rhs); }
00750 bool operator<=(const const_reverse_fielditerator &rhs) const
00751 { return iterator_type::operator>=(rhs); }
00752 bool operator>(const const_reverse_fielditerator &rhs) const
00753 { return iterator_type::operator<(rhs); }
00754 bool operator>=(const const_reverse_fielditerator &rhs) const
00755 { return iterator_type::operator<=(rhs); }
00757 };
00758
00759
00760 result() throw () : super(), m_data(0) {}
00761 result(const result &rhs) throw () :
00762 super(rhs), m_data(rhs.m_data) {}
00763
00764 result &operator=(const result &rhs) throw ()
00765 { super::operator=(rhs); m_data=rhs.m_data; return *this; }
00766
00771 bool operator==(const result &) const throw ();
00772 bool operator!=(const result &rhs) const throw ()
00773 { return !operator==(rhs); }
00775
00776 const_reverse_iterator rbegin() const
00777 { return const_reverse_iterator(end()); }
00778 const_reverse_iterator rend() const
00779 { return const_reverse_iterator(begin()); }
00780
00781 const_iterator begin() const throw ()
00782 { return const_iterator(this, 0); }
00783 inline const_iterator end() const throw ();
00784
00785 reference front() const throw () { return tuple(this,0); }
00786 reference back() const throw () {return tuple(this,size()-1);}
00787
00788 size_type size() const throw ();
00789 bool empty() const throw ();
00790 size_type capacity() const throw () { return size(); }
00791
00792 void swap(result &) throw ();
00793
00794 const tuple operator[](size_type i) const throw ()
00795 { return tuple(this, i); }
00796 const tuple at(size_type) const throw (PGSTD::out_of_range);
00797
00798 void clear() throw () { super::clear(); m_data = 0; }
00799
00804
00805 tuple::size_type columns() const throw ();
00806
00808 tuple::size_type column_number(const char ColName[]) const;
00809
00811 tuple::size_type column_number(const PGSTD::string &Name) const
00812 {return column_number(Name.c_str());}
00813
00815 const char *column_name(tuple::size_type Number) const;
00816
00818 oid column_type(tuple::size_type ColNum) const;
00820 oid column_type(int ColNum) const
00821 { return column_type(tuple::size_type(ColNum)); }
00822
00824 oid column_type(const PGSTD::string &ColName) const
00825 { return column_type(column_number(ColName)); }
00826
00828 oid column_type(const char ColName[]) const
00829 { return column_type(column_number(ColName)); }
00830
00832
00839 oid column_table(tuple::size_type ColNum) const;
00840
00842
00849 oid column_table(int ColNum) const
00850 { return column_table(tuple::size_type(ColNum)); }
00851
00853
00860 oid column_table(const PGSTD::string &ColName) const
00861 { return column_table(column_number(ColName)); }
00862
00864 tuple::size_type table_column(tuple::size_type ColNum) const;
00865
00867 tuple::size_type table_column(int ColNum) const
00868 { return table_column(tuple::size_type(ColNum)); }
00869
00871 tuple::size_type table_column(const PGSTD::string &ColName) const
00872 { return table_column(column_number(ColName)); }
00874
00876 const PGSTD::string &query() const throw ();
00877
00879
00882 oid inserted_oid() const;
00883
00884
00886
00889 size_type affected_rows() const;
00890
00891
00892 private:
00893 friend class pqxx::result::field;
00894 const char *GetValue(size_type Row, tuple::size_type Col) const;
00895 bool GetIsNull(size_type Row, tuple::size_type Col) const;
00896 field::size_type GetLength(size_type, tuple::size_type) const;
00897
00898 friend class connection_base;
00899 friend class pipeline;
00900 result(internal::pq::PGresult *rhs,
00901 int protocol,
00902 const PGSTD::string &Query=PGSTD::string());
00903 bool operator!() const throw () { return !m_data; }
00904 operator bool() const throw () { return m_data != 0; }
00905
00906 void PQXX_PRIVATE CheckStatus() const;
00907
00908 void PQXX_PRIVATE ThrowSQLError(const PGSTD::string &Err,
00909 const PGSTD::string &Query) const;
00910 int PQXX_PRIVATE errorposition() const throw ();
00911 PGSTD::string PQXX_PRIVATE StatusError() const;
00912
00913 friend class Cursor;
00914 friend class cursor_base;
00915 const char *CmdStatus() const throw ();
00916
00918 pqxx::internal::pq::PGresult *m_data;
00919
00920 static const PGSTD::string PQXX_PRIVATE s_empty_string;
00921 };
00922
00923
00925
00945 template<typename STREAM>
00946 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)
00947 {
00948 S.write(F.c_str(), F.size());
00949 return S;
00950 }
00951
00952
00954 template<typename T>
00955 inline void from_string(const result::field &F, T &Obj)
00956 { from_string(F.c_str(), Obj, F.size()); }
00957
00959 template<>
00960 inline PGSTD::string to_string(const result::field &Obj)
00961 { return PGSTD::string(Obj.c_str(), Obj.size()); }
00962
00963
00965 template<>
00966 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00967 {
00968 const char *const bytes = c_str();
00969 if (!bytes[0] && is_null()) return false;
00970 Obj = PGSTD::string(bytes, size());
00971 return true;
00972 }
00973
00975
00980 template<>
00981 inline bool result::field::to<const char *>(const char *&Obj) const
00982 {
00983 if (is_null()) return false;
00984 Obj = c_str();
00985 return true;
00986 }
00987
00988
00989 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00990 { return const_reverse_fielditerator(end()); }
00991 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00992 { return const_reverse_fielditerator(begin()); }
00993
00994 inline result::const_iterator
00995 result::const_iterator::operator+(difference_type o) const
00996 { return const_iterator(m_Home, m_Index + o); }
00997
00998 inline result::const_iterator
00999 operator+(result::const_iterator::difference_type o, result::const_iterator i)
01000 { return i + o; }
01001
01002 inline result::const_iterator
01003 result::const_iterator::operator-(difference_type o) const
01004 { return const_iterator(m_Home, m_Index - o); }
01005
01006 inline result::const_iterator::difference_type
01007 result::const_iterator::operator-(const_iterator i) const
01008 { return num()-i.num(); }
01009
01010 inline result::const_iterator result::end() const throw ()
01011 { return const_iterator(this, size()); }
01012
01013
01014 inline result::const_reverse_iterator
01015 operator+(result::const_reverse_iterator::difference_type n,
01016 const result::const_reverse_iterator &i)
01017 { return result::const_reverse_iterator(i.base() - n); }
01018
01019 inline result::const_fielditerator
01020 result::const_fielditerator::operator+(difference_type o) const
01021 { return const_fielditerator(m_tup, col() + o); }
01022
01023 inline result::const_fielditerator
01024 operator+(result::const_fielditerator::difference_type o,
01025 result::const_fielditerator i)
01026 { return i + o; }
01027
01028 inline result::const_fielditerator
01029 result::const_fielditerator::operator-(difference_type o) const
01030 { return const_fielditerator(m_tup, col() - o); }
01031
01032 inline result::const_fielditerator::difference_type
01033 result::const_fielditerator::operator-(const_fielditerator i) const
01034 { return num()-i.num(); }
01035
01036
01037 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01038 class field_streambuf :
01039 #ifdef PQXX_HAVE_STREAMBUF
01040 public PGSTD::basic_streambuf<CHAR, TRAITS>
01041 #else
01042 public PGSTD::streambuf
01043 #endif
01044 {
01045 public:
01046 typedef CHAR char_type;
01047 typedef TRAITS traits_type;
01048 typedef typename traits_type::int_type int_type;
01049 #ifdef PQXX_HAVE_STREAMBUF
01050 typedef typename traits_type::pos_type pos_type;
01051 typedef typename traits_type::off_type off_type;
01052 #else
01053 typedef streamoff off_type;
01054 typedef streampos pos_type;
01055 #endif
01056 typedef PGSTD::ios::openmode openmode;
01057 typedef PGSTD::ios::seekdir seekdir;
01058
01059 explicit field_streambuf(const result::field &F) :
01060 m_Field(F)
01061 {
01062 initialize();
01063 }
01064
01065 #ifdef PQXX_HAVE_STREAMBUF
01066 protected:
01067 #endif
01068 virtual int sync() { return traits_type::eof(); }
01069
01070 protected:
01071 virtual pos_type seekoff(off_type, seekdir, openmode)
01072 { return traits_type::eof(); }
01073 virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
01074 virtual int_type overflow(int_type) { return traits_type::eof(); }
01075 virtual int_type underflow() { return traits_type::eof(); }
01076
01077 private:
01078 const result::field &m_Field;
01079
01080 int_type initialize()
01081 {
01082 char_type *G =
01083 reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
01084 setg(G, G, G + m_Field.size());
01085 return m_Field.size();
01086 }
01087 };
01088
01089
01091
01099 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01100 class basic_fieldstream :
01101 #ifdef PQXX_HAVE_STREAMBUF
01102 public PGSTD::basic_istream<CHAR, TRAITS>
01103 #else
01104 public PGSTD::istream
01105 #endif
01106 {
01107 #ifdef PQXX_HAVE_STREAMBUF
01108 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
01109 #else
01110 typedef PGSTD::istream super;
01111 #endif
01112
01113 public:
01114 typedef CHAR char_type;
01115 typedef TRAITS traits_type;
01116 typedef typename traits_type::int_type int_type;
01117 typedef typename traits_type::pos_type pos_type;
01118 typedef typename traits_type::off_type off_type;
01119
01120 basic_fieldstream(const result::field &F) : super(0), m_Buf(F)
01121 { super::init(&m_Buf); }
01122
01123 private:
01124 field_streambuf<CHAR, TRAITS> m_Buf;
01125 };
01126
01127 typedef basic_fieldstream<char> fieldstream;
01128
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 #include "pqxx/compiler-internal-post.hxx"