00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pqxx/libcompiler.h"
00020
00021 #ifdef PQXX_HAVE_IOS
00022 #include <ios>
00023 #endif
00024
00025 #include <stdexcept>
00026
00027 #include "pqxx/util"
00028
00029
00030
00031
00032
00033
00034 namespace pqxx
00035 {
00037
00055 class PQXX_LIBEXPORT result : private internal::PQAlloc<internal::pq::PGresult>
00056 {
00057 typedef internal::PQAlloc<internal::pq::PGresult> super;
00058 public:
00059 class const_iterator;
00060 class const_fielditerator;
00061 class const_reverse_fielditerator;
00062 class tuple;
00063 class field;
00064 typedef unsigned long size_type;
00065 typedef signed long difference_type;
00066 typedef tuple reference;
00067 typedef const_iterator pointer;
00068
00070
00081 class PQXX_LIBEXPORT tuple
00082 {
00083 public:
00084 typedef unsigned int size_type;
00085 typedef signed int difference_type;
00086 typedef const_fielditerator const_iterator;
00087 typedef field reference;
00088 typedef const_fielditerator pointer;
00089 typedef const_reverse_fielditerator const_reverse_iterator;
00090
00091 tuple(const result *r, result::size_type i) throw () :
00092 m_Home(r), m_Index(i) {}
00093 ~tuple() throw () {}
00094
00095 bool operator==(const tuple &) const throw ();
00096 bool operator!=(const tuple &rhs) const throw ()
00097 { return !operator==(rhs); }
00098
00099 const_iterator begin() const throw ()
00100 { return const_iterator(*this, 0); }
00101 const_iterator end() const throw ()
00102 { return const_iterator(*this, size()); }
00103
00104 reference front() const throw () { return field(*this, 0); }
00105 reference back() const throw () { return field(*this, size()-1); }
00106
00107 const_reverse_fielditerator rbegin() const;
00108 const_reverse_fielditerator rend() const;
00109
00110 reference operator[](size_type i) const throw ()
00111 { return field(*this, i); }
00112 reference operator[](int i) const throw ()
00113 { return operator[](size_type(i)); }
00114 reference operator[](const char[]) const;
00115 reference operator[](const PGSTD::string &s) const
00116 { return operator[](s.c_str()); }
00117 reference at(size_type) const throw (PGSTD::out_of_range);
00118 reference at(int i) const throw (PGSTD::out_of_range)
00119 { return at(size_type(i)); }
00120 reference at(const char[]) const;
00121 reference at(const PGSTD::string &s) const
00122 { return at(s.c_str()); }
00123
00124 size_type size() const throw () { return m_Home->columns(); }
00125
00126 void swap(tuple &) throw ();
00127
00128 result::size_type rownumber() const throw () { return m_Index; }
00129
00131 size_type column_number(const PGSTD::string &ColName) const
00132 { return m_Home->column_number(ColName); }
00133
00135 size_type column_number(const char ColName[]) const
00136 { return m_Home->column_number(ColName); }
00137
00139 oid column_type(size_type ColNum) const
00140 { return m_Home->column_type(ColNum); }
00141
00143 oid column_type(int ColNum) const
00144 { return column_type(size_type(ColNum)); }
00145
00147 oid column_type(const PGSTD::string &ColName) const
00148 { return column_type(column_number(ColName)); }
00149
00151 oid column_type(const char ColName[]) const
00152 { return column_type(column_number(ColName)); }
00153
00154 result::size_type num() const { return rownumber(); }
00155
00157
00164 oid column_table(size_type ColNum) const
00165 { return m_Home->column_table(ColNum); }
00167
00174 oid column_table(int ColNum) const
00175 { return column_table(size_type(ColNum)); }
00177
00184 oid column_table(const PGSTD::string &ColName) const
00185 { return column_table(column_number(ColName)); }
00186
00187
00188 #ifdef PQXX_DEPRECATED_HEADERS
00189
00190 result::size_type Row() const { return rownumber(); }
00191
00193 size_type ColumnNumber(const PGSTD::string &ColName) const
00194 { return column_number(ColName); }
00195
00197 size_type ColumnNumber(const char ColName[]) const
00198 { return column_number(ColName); }
00199 #endif
00200
00201 protected:
00202 friend class field;
00203 const result *m_Home;
00204 result::size_type m_Index;
00205
00206
00207 tuple();
00208 };
00209
00211
00214 class PQXX_LIBEXPORT field
00215 {
00216 public:
00217 typedef size_t size_type;
00218
00220
00224 field(const tuple &T, tuple::size_type C) throw () :
00225 m_tup(T), m_col(C) {}
00226
00228
00244 bool operator==(const field &) const;
00245
00247
00249 bool operator!=(const field &rhs) const {return !operator==(rhs);}
00250
00252
00257 const char *c_str() const { return home()->GetValue(idx(),col()); }
00258
00260 const char *name() const { return home()->column_name(col()); }
00261
00263 oid type() const { return home()->column_type(col()); }
00264
00266
00273 oid table() const { return home()->column_table(col()); }
00274
00276 template<typename T> bool to(T &Obj) const
00277 {
00278 if (is_null()) return false;
00279 try
00280 {
00281 from_string(c_str(), Obj);
00282 }
00283 catch (const PGSTD::exception &e)
00284 {
00285 throw PGSTD::domain_error("Error reading field " +
00286 PGSTD::string(name()) + ": " +
00287 e.what());
00288 }
00289 return true;
00290 }
00291
00293 template<typename T> bool operator>>(T &Obj) const
00294 { return to(Obj); }
00295
00296 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00297
00298 template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00299
00301
00304 template<> bool to<const char *>(const char *&Obj) const;
00305 #endif
00306
00308 template<typename T> bool to(T &Obj, const T &Default) const
00309 {
00310 const bool NotNull = to(Obj);
00311 if (!NotNull) Obj = Default;
00312 return NotNull;
00313 }
00314
00316
00319 template<typename T> T as(const T &Default) const
00320 {
00321 T Obj;
00322 to(Obj, Default);
00323 return Obj;
00324 }
00325
00327 template<typename T> T as() const
00328 {
00329 T Obj;
00330 const bool NotNull = to(Obj);
00331 if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00332 return Obj;
00333 }
00334
00335 bool is_null() const { return home()->GetIsNull(idx(), col()); }
00336 size_type size() const throw ()
00337 { return home()->GetLength(idx(),col()); }
00338 tuple::size_type num() const { return col(); }
00339
00340 #ifdef PQXX_DEPRECATED_HEADERS
00341
00342 const char *Name() const {return name();}
00343 #endif
00344
00345 private:
00346 const result *home() const throw () { return m_tup.m_Home; }
00347 result::size_type idx() const throw () { return m_tup.m_Index; }
00348
00349 protected:
00350 const tuple::size_type col() const throw () { return m_col; }
00351 tuple m_tup;
00352 tuple::size_type m_col;
00353 };
00354
00355 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00356 const tuple,
00357 result::difference_type,
00358 const_iterator,
00359 tuple> const_iterator_base;
00360
00362
00366 class PQXX_LIBEXPORT const_iterator :
00367 public const_iterator_base,
00368 public tuple
00369 {
00370 public:
00371 typedef const tuple *pointer;
00372 typedef tuple reference;
00373 typedef result::size_type size_type;
00374 typedef result::difference_type difference_type;
00375
00376 const_iterator() throw () : tuple(0,0) {}
00377 const_iterator(const tuple &t) throw () : tuple(t) {}
00378
00390 pointer operator->() const { return this; }
00391 reference operator*() const { return tuple(*this); }
00392
00393 const_iterator operator++(int);
00394 const_iterator &operator++() { ++m_Index; return *this; }
00395 const_iterator operator--(int);
00396 const_iterator &operator--() { --m_Index; return *this; }
00397
00398 const_iterator &operator+=(difference_type i)
00399 { m_Index+=i; return *this; }
00400 const_iterator &operator-=(difference_type i)
00401 { m_Index-=i; return *this; }
00402
00403 bool operator==(const const_iterator &i) const
00404 {return m_Index==i.m_Index;}
00405 bool operator!=(const const_iterator &i) const
00406 {return m_Index!=i.m_Index;}
00407 bool operator<(const const_iterator &i) const
00408 {return m_Index<i.m_Index;}
00409 bool operator<=(const const_iterator &i) const
00410 {return m_Index<=i.m_Index;}
00411 bool operator>(const const_iterator &i) const
00412 {return m_Index>i.m_Index;}
00413 bool operator>=(const const_iterator &i) const
00414 {return m_Index>=i.m_Index;}
00415
00416 inline const_iterator operator+(difference_type) const;
00417 friend const_iterator
00418 operator+(difference_type, const_iterator);
00419 inline const_iterator operator-(difference_type) const;
00420 inline difference_type operator-(const_iterator) const;
00421
00422 private:
00423 friend class pqxx::result;
00424 const_iterator(const pqxx::result *r, result::size_type i) throw () :
00425 tuple(r, i) {}
00426 };
00427
00428 class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00429 {
00430 public:
00431 typedef const_iterator iterator_type;
00432 using iterator_type::iterator_category;
00433 using iterator_type::difference_type;
00434 using iterator_type::pointer;
00435 #ifndef _MSC_VER
00436 using iterator_type::value_type;
00437 using iterator_type::reference;
00438 #else
00439
00440 typedef const tuple &reference;
00441 typedef tuple value_type;
00442 #endif
00443
00444 const_reverse_iterator(const const_reverse_iterator &rhs) :
00445 const_iterator(rhs), m_tmp(rhs) {}
00446 explicit const_reverse_iterator(const const_iterator &rhs) :
00447 const_iterator(rhs), m_tmp() {}
00448
00449 iterator_type base() const throw () { return *this; }
00450
00451 const_reverse_iterator &operator=(const const_reverse_iterator &r)
00452 { iterator_type::operator=(r); return *this; }
00453 pointer operator->() const throw ()
00454 { m_tmp=*this; --m_tmp; return &m_tmp; }
00455 reference operator*() const throw () { return *operator->(); }
00456 const_reverse_iterator operator++()
00457 { iterator_type::operator--(); return *this; }
00458 const_reverse_iterator operator++(int);
00459 const_reverse_iterator &operator--()
00460 { iterator_type::operator++(); return *this; }
00461 const_reverse_iterator operator--(int);
00462 const_reverse_iterator operator+(difference_type i) const
00463 { return const_reverse_iterator(iterator_type(*this)-i); }
00464 const_reverse_iterator &operator+=(difference_type i)
00465 { iterator_type::operator-=(i); return *this; }
00466 const_reverse_iterator operator-(difference_type i)
00467 { return const_reverse_iterator(iterator_type(*this)+i); }
00468 const_reverse_iterator &operator-=(difference_type i)
00469 { iterator_type::operator+=(i); return *this; }
00470
00471 bool operator==(const const_reverse_iterator &rhs) const throw ()
00472 { return iterator_type::operator==(rhs); }
00473 bool operator!=(const const_reverse_iterator &rhs) const throw ()
00474 { return !operator==(rhs); }
00475
00476 bool operator<(const const_reverse_iterator &rhs) const
00477 { return iterator_type::operator>(rhs); }
00478 bool operator<=(const const_reverse_iterator &rhs) const
00479 { return iterator_type::operator>=(rhs); }
00480 bool operator>(const const_reverse_iterator &rhs) const
00481 { return iterator_type::operator<(rhs); }
00482 bool operator>=(const const_reverse_iterator &rhs) const
00483 { return iterator_type::operator<=(rhs); }
00484 difference_type operator-(const const_reverse_iterator &rhs) const
00485 { return rhs.base() - base(); }
00486
00487 private:
00489
00494 mutable iterator_type m_tmp;
00495 };
00496
00497 class PQXX_LIBEXPORT const_fielditerator :
00498 public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00499 const field,
00500 tuple::size_type>,
00501 public field
00502 {
00503 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00504 const field,
00505 tuple::size_type> it;
00506 public:
00507 using it::pointer;
00508 typedef tuple::size_type size_type;
00509 typedef tuple::difference_type difference_type;
00510 typedef field reference;
00511
00512 const_fielditerator(const tuple &T, tuple::size_type C) throw () :
00513 field(T, C) {}
00514 const_fielditerator(const field &F) throw () : field(F) {}
00515
00516 pointer operator->() const { return this; }
00517 reference operator*() const { return field(*this); }
00518
00519 const_fielditerator operator++(int);
00520 const_fielditerator &operator++() { ++m_col; return *this; }
00521 const_fielditerator operator--(int);
00522 const_fielditerator &operator--() { --m_col; return *this; }
00523
00524 const_fielditerator &operator+=(difference_type i)
00525 { m_col+=i; return *this; }
00526 const_fielditerator &operator-=(difference_type i)
00527 { m_col-=i; return *this; }
00528
00529 bool operator==(const const_fielditerator &i) const
00530 {return col()==i.col();}
00531 bool operator!=(const const_fielditerator &i) const
00532 {return col()!=i.col();}
00533 bool operator<(const const_fielditerator &i) const
00534 {return col()<i.col();}
00535 bool operator<=(const const_fielditerator &i) const
00536 {return col()<=i.col();}
00537 bool operator>(const const_fielditerator &i) const
00538 {return col()>i.col();}
00539 bool operator>=(const const_fielditerator &i) const
00540 {return col()>=i.col();}
00541
00542 inline const_fielditerator operator+(difference_type) const;
00543
00544 friend const_fielditerator operator+(difference_type,
00545 const_fielditerator);
00546
00547 inline const_fielditerator operator-(difference_type) const;
00548 inline difference_type operator-(const_fielditerator) const;
00549 };
00550
00551 class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00552 {
00553 public:
00554 typedef const_fielditerator iterator_type;
00555 using iterator_type::iterator_category;
00556 using iterator_type::difference_type;
00557 using iterator_type::pointer;
00558 #ifndef _MSC_VER
00559 using iterator_type::value_type;
00560 using iterator_type::reference;
00561 #else
00562
00563 typedef field value_type;
00564 typedef const field &reference;
00565 #endif
00566
00567 iterator_type base() const throw () { return *this; }
00568 const_reverse_fielditerator(const const_reverse_fielditerator &rhs)
00569 : const_fielditerator(rhs), m_tmp(rhs.m_tmp) {}
00570 explicit
00571 const_reverse_fielditerator(const const_fielditerator &rhs) :
00572 const_fielditerator(rhs), m_tmp(rhs) {}
00573
00574 const_reverse_fielditerator &
00575 operator=(const const_reverse_fielditerator &r)
00576 { iterator_type::operator=(r); return *this; }
00577 pointer operator->() const throw ()
00578 { m_tmp = *this; --m_tmp; return &m_tmp; }
00579 reference operator*() const throw () { return *operator->(); }
00580 const_reverse_fielditerator operator++()
00581 { iterator_type::operator--(); return *this; }
00582 const_reverse_fielditerator operator++(int);
00583 const_reverse_fielditerator &operator--()
00584 { iterator_type::operator++(); return *this; }
00585 const_reverse_fielditerator operator--(int);
00586 const_reverse_fielditerator operator+(difference_type i) const
00587 { return const_reverse_fielditerator(iterator_type(*this)-i); }
00588 const_reverse_fielditerator &operator+=(difference_type i)
00589 { iterator_type::operator-=(i); return *this; }
00590 const_reverse_fielditerator operator-(difference_type i)
00591 { return const_reverse_fielditerator(iterator_type(*this)+i); }
00592 const_reverse_fielditerator &operator-=(difference_type i)
00593 { iterator_type::operator+=(i); return *this; }
00594
00595 bool
00596 operator==(const const_reverse_fielditerator &rhs) const throw ()
00597 { return iterator_type::operator==(rhs); }
00598 bool
00599 operator!=(const const_reverse_fielditerator &rhs) const throw ()
00600 { return !operator==(rhs); }
00601
00602
00603 bool operator<(const const_reverse_fielditerator &rhs) const
00604 { return iterator_type::operator>(rhs); }
00605 bool operator<=(const const_reverse_fielditerator &rhs) const
00606 { return iterator_type::operator>=(rhs); }
00607 bool operator>(const const_reverse_fielditerator &rhs) const
00608 { return iterator_type::operator<(rhs); }
00609 bool operator>=(const const_reverse_fielditerator &rhs) const
00610 { return iterator_type::operator<=(rhs); }
00611 difference_type
00612 operator-(const const_reverse_fielditerator &rhs) const
00613 { return rhs.base() - base(); }
00614
00615 private:
00617
00622 mutable iterator_type m_tmp;
00623 };
00624
00625
00626 result() throw () : super() {}
00627 result(const result &rhs) throw () : super(rhs) {}
00628
00629 result &operator=(const result &rhs) throw ()
00630 { super::operator=(rhs); return *this; }
00631
00632 bool operator==(const result &) const throw ();
00633 bool operator!=(const result &rhs) const throw ()
00634 { return !operator==(rhs); }
00635
00636 const_reverse_iterator rbegin() const
00637 { return const_reverse_iterator(end()); }
00638 const_reverse_iterator rend() const
00639 { return const_reverse_iterator(begin()); }
00640
00641 const_iterator begin() const throw ()
00642 { return const_iterator(this, 0); }
00643 inline const_iterator end() const throw ();
00644
00645 reference front() const throw () { return tuple(this,0); }
00646 reference back() const throw () {return tuple(this,size()-1);}
00647
00648 size_type size() const throw ();
00649 bool empty() const throw ();
00650 size_type capacity() const throw () { return size(); }
00651
00652 void swap(result &) throw ();
00653
00654 const tuple operator[](size_type i) const throw ()
00655 { return tuple(this, i); }
00656 const tuple at(size_type) const throw (PGSTD::out_of_range);
00657
00658 using super::clear;
00659
00661 tuple::size_type columns() const throw ();
00662
00664 tuple::size_type column_number(const char ColName[]) const;
00665
00667 tuple::size_type column_number(const PGSTD::string &Name) const
00668 {return column_number(Name.c_str());}
00669
00671 const char *column_name(tuple::size_type Number) const;
00672
00674 oid column_type(tuple::size_type ColNum) const;
00676 oid column_type(int ColNum) const
00677 { return column_type(tuple::size_type(ColNum)); }
00678
00680 oid column_type(const PGSTD::string &ColName) const
00681 { return column_type(column_number(ColName)); }
00682
00684 oid column_type(const char ColName[]) const
00685 { return column_type(column_number(ColName)); }
00686
00688
00695 oid column_table(tuple::size_type ColNum) const;
00696
00698
00705 oid column_table(int ColNum) const
00706 { return column_table(tuple::size_type(ColNum)); }
00707
00709
00716 oid column_table(const PGSTD::string &ColName) const
00717 { return column_table(column_number(ColName)); }
00718
00720
00723 oid inserted_oid() const;
00724
00725
00727
00730 size_type affected_rows() const;
00731
00732
00733 #ifdef PQXX_DEPRECATED_HEADERS
00734
00735 typedef tuple Tuple;
00737 typedef field Field;
00739 oid InsertedOid() const { return inserted_oid(); }
00741 size_type AffectedRows() const { return affected_rows(); }
00743 tuple::size_type Columns() const { return columns(); }
00745 tuple::size_type ColumnNumber(const char Name[]) const
00746 {return column_number(Name);}
00748 tuple::size_type ColumnNumber(const PGSTD::string &Name) const
00749 {return column_number(Name);}
00751 const char *ColumnName(tuple::size_type Number) const
00752 {return column_name(Number);}
00753 #endif
00754
00755
00756 private:
00757 friend class pqxx::result::field;
00758 const char *GetValue(size_type Row, tuple::size_type Col) const;
00759 bool GetIsNull(size_type Row, tuple::size_type Col) const;
00760 field::size_type GetLength(size_type, tuple::size_type) const;
00761
00762 friend class connection_base;
00763 friend class pipeline;
00764 explicit result(internal::pq::PGresult *rhs) throw () : super(rhs) {}
00765 result &operator=(internal::pq::PGresult *rhs) throw ()
00766 { super::operator=(rhs); return *this; }
00767 bool operator!() const throw () { return !c_ptr(); }
00768 operator bool() const throw () { return c_ptr() != 0; }
00769 void PQXX_PRIVATE CheckStatus(const PGSTD::string &Query) const;
00770 void PQXX_PRIVATE CheckStatus(const char Query[]) const;
00771 int PQXX_PRIVATE errorposition() const throw ();
00772 PGSTD::string PQXX_PRIVATE StatusError() const;
00773
00774 friend class Cursor;
00775 const char *CmdStatus() const throw ();
00776 };
00777
00778
00780
00799 template<typename STREAM>
00800 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)
00801 {
00802 S.write(F.c_str(), F.size());
00803 return S;
00804 }
00805
00806
00808 template<typename T>
00809 inline void from_string(const result::field &F, T &Obj)
00810 { from_string(F.c_str(), Obj); }
00811
00813 template<>
00814 inline PGSTD::string to_string(const result::field &Obj)
00815 { return to_string(Obj.c_str()); }
00816
00817
00819 template<>
00820 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00821 {
00822 if (is_null()) return false;
00823 Obj = c_str();
00824 return true;
00825 }
00826
00828
00833 template<>
00834 inline bool result::field::to<const char *>(const char *&Obj) const
00835 {
00836 if (is_null()) return false;
00837 Obj = c_str();
00838 return true;
00839 }
00840
00841
00842 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00843 { return const_reverse_fielditerator(end()); }
00844 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00845 { return const_reverse_fielditerator(begin()); }
00846
00847 inline result::const_iterator
00848 result::const_iterator::operator+(difference_type o) const
00849 { return const_iterator(m_Home, m_Index + o); }
00850
00851 inline result::const_iterator
00852 operator+(result::const_iterator::difference_type o, result::const_iterator i)
00853 { return i + o; }
00854
00855 inline result::const_iterator
00856 result::const_iterator::operator-(difference_type o) const
00857 { return const_iterator(m_Home, m_Index - o); }
00858
00859 inline result::const_iterator::difference_type
00860 result::const_iterator::operator-(const_iterator i) const
00861 { return num()-i.num(); }
00862
00863 inline result::const_iterator result::end() const throw ()
00864 { return const_iterator(this, size()); }
00865
00866
00867 inline result::const_reverse_iterator
00868 operator+(result::const_reverse_iterator::difference_type n,
00869 const result::const_reverse_iterator &i)
00870 { return result::const_reverse_iterator(i.base() - n); }
00871
00872 inline result::const_fielditerator
00873 result::const_fielditerator::operator+(difference_type o) const
00874 { return const_fielditerator(m_tup, col() + o); }
00875
00876 inline result::const_fielditerator
00877 operator+(result::const_fielditerator::difference_type o,
00878 result::const_fielditerator i)
00879 { return i + o; }
00880
00881 inline result::const_fielditerator
00882 result::const_fielditerator::operator-(difference_type o) const
00883 { return const_fielditerator(m_tup, col() - o); }
00884
00885 inline result::const_fielditerator::difference_type
00886 result::const_fielditerator::operator-(const_fielditerator i) const
00887 { return num()-i.num(); }
00888
00889
00890 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00891 class field_streambuf :
00892 #ifdef PQXX_HAVE_STREAMBUF
00893 public PGSTD::basic_streambuf<CHAR, TRAITS>
00894 #else
00895 public PGSTD::streambuf
00896 #endif
00897 {
00898 public:
00899 typedef CHAR char_type;
00900 typedef TRAITS traits_type;
00901 typedef typename traits_type::int_type int_type;
00902 #ifdef PQXX_HAVE_STREAMBUF
00903 typedef typename traits_type::pos_type pos_type;
00904 typedef typename traits_type::off_type off_type;
00905 #else
00906 typedef streamoff off_type;
00907 typedef streampos pos_type;
00908 #endif
00909 typedef PGSTD::ios::openmode openmode;
00910 typedef PGSTD::ios::seekdir seekdir;
00911
00912 explicit field_streambuf(const result::field &F) :
00913 m_Field(F)
00914 {
00915 initialize();
00916 }
00917
00918 #ifdef PQXX_HAVE_STREAMBUF
00919 protected:
00920 #endif
00921 virtual int sync() { return traits_type::eof(); }
00922
00923 protected:
00924 virtual pos_type seekoff(off_type, seekdir, openmode)
00925 { return traits_type::eof(); }
00926 virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
00927 virtual int_type overflow(int_type) { return traits_type::eof(); }
00928 virtual int_type underflow() { return traits_type::eof(); }
00929
00930 private:
00931 const result::field &m_Field;
00932
00933 int_type initialize()
00934 {
00935 char_type *G =
00936 reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
00937 setg(G, G, G + m_Field.size());
00938 return m_Field.size();
00939 }
00940 };
00941
00942
00944
00952 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00953 class basic_fieldstream :
00954 #ifdef PQXX_HAVE_STREAMBUF
00955 public PGSTD::basic_istream<CHAR, TRAITS>
00956 #else
00957 public PGSTD::istream
00958 #endif
00959 {
00960 #ifdef PQXX_HAVE_STREAMBUF
00961 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00962 #else
00963 typedef PGSTD::istream super;
00964 #endif
00965
00966 public:
00967 typedef CHAR char_type;
00968 typedef TRAITS traits_type;
00969 typedef typename traits_type::int_type int_type;
00970 typedef typename traits_type::pos_type pos_type;
00971 typedef typename traits_type::off_type off_type;
00972
00973 basic_fieldstream(const result::field &F) : super(0), m_Buf(F)
00974 { super::init(&m_Buf); }
00975
00976 private:
00977 field_streambuf<CHAR, TRAITS> m_Buf;
00978 };
00979
00980 typedef basic_fieldstream<char> fieldstream;
00981
00982 }
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999