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
00044 class PQXX_LIBEXPORT result : private internal::PQAlloc<internal::pq::PGresult>
00045 {
00046 typedef internal::PQAlloc<internal::pq::PGresult> super;
00047 public:
00048 class const_iterator;
00049 class const_fielditerator;
00050 class const_reverse_fielditerator;
00051 class tuple;
00052 class field;
00053 typedef unsigned long size_type;
00054 typedef signed long difference_type;
00055 typedef tuple reference;
00056 typedef const_iterator pointer;
00057
00059
00070 class PQXX_LIBEXPORT tuple
00071 {
00072 public:
00073 typedef unsigned int size_type;
00074 typedef signed int difference_type;
00075 typedef const_fielditerator const_iterator;
00076 typedef field reference;
00077 typedef const_fielditerator pointer;
00078 typedef const_reverse_fielditerator const_reverse_iterator;
00079
00080 tuple(const result *r, result::size_type i) throw () :
00081 m_Home(r), m_Index(i) {}
00082 ~tuple() throw () {}
00083
00084 bool operator==(const tuple &) const throw ();
00085 bool operator!=(const tuple &rhs) const throw ()
00086 { return !operator==(rhs); }
00087
00088 const_iterator begin() const throw ()
00089 { return const_iterator(*this, 0); }
00090 const_iterator end() const throw ()
00091 { return const_iterator(*this, size()); }
00092
00093 reference front() const throw () { return field(*this, 0); }
00094 reference back() const throw () { return field(*this, size()-1); }
00095
00096 const_reverse_fielditerator rbegin() const;
00097 const_reverse_fielditerator rend() const;
00098
00099 reference operator[](size_type i) const throw ()
00100 { return field(*this, i); }
00101 reference operator[](int i) const throw ()
00102 { return operator[](size_type(i)); }
00103 reference operator[](const char[]) const;
00104 reference operator[](const PGSTD::string &s) const
00105 { return operator[](s.c_str()); }
00106 reference at(size_type) const throw (PGSTD::out_of_range);
00107 reference at(int i) const throw (PGSTD::out_of_range)
00108 { return at(size_type(i)); }
00109 reference at(const char[]) const;
00110 reference at(const PGSTD::string &s) const
00111 { return at(s.c_str()); }
00112
00113 size_type size() const throw () { return m_Home->columns(); }
00114
00115 void swap(tuple &) throw ();
00116
00117 result::size_type rownumber() const throw () { return m_Index; }
00118
00120 size_type column_number(const PGSTD::string &ColName) const
00121 { return m_Home->column_number(ColName); }
00122
00124 size_type column_number(const char ColName[]) const
00125 { return m_Home->column_number(ColName); }
00126
00128 oid column_type(size_type ColNum) const
00129 { return m_Home->column_type(ColNum); }
00130
00132 oid column_type(int ColNum) const
00133 { return column_type(size_type(ColNum)); }
00134
00136 oid column_type(const PGSTD::string &ColName) const
00137 { return column_type(column_number(ColName)); }
00138
00140 oid column_type(const char ColName[]) const
00141 { return column_type(column_number(ColName)); }
00142
00143 result::size_type num() const { return rownumber(); }
00144
00146
00153 oid column_table(size_type ColNum) const
00154 { return m_Home->column_table(ColNum); }
00156
00163 oid column_table(int ColNum) const
00164 { return column_table(size_type(ColNum)); }
00166
00173 oid column_table(const PGSTD::string &ColName) const
00174 { return column_table(column_number(ColName)); }
00175
00176
00177 #ifdef PQXX_DEPRECATED_HEADERS
00178
00179 result::size_type Row() const { return rownumber(); }
00180
00182 size_type ColumnNumber(const PGSTD::string &ColName) const
00183 { return column_number(ColName); }
00184
00186 size_type ColumnNumber(const char ColName[]) const
00187 { return column_number(ColName); }
00188 #endif
00189
00190 protected:
00191 friend class field;
00192 const result *m_Home;
00193 result::size_type m_Index;
00194
00195
00196 tuple();
00197 };
00198
00200
00203 class PQXX_LIBEXPORT field
00204 {
00205 public:
00206 typedef size_t size_type;
00207
00209
00213 field(const tuple &T, tuple::size_type C) throw () :
00214 m_tup(T), m_col(C) {}
00215
00217
00233 bool operator==(const field &) const;
00234
00236
00238 bool operator!=(const field &rhs) const {return !operator==(rhs);}
00239
00241
00246 const char *c_str() const { return home()->GetValue(idx(),col()); }
00247
00249 const char *name() const { return home()->column_name(col()); }
00250
00252 oid type() const { return home()->column_type(col()); }
00253
00255
00262 oid table() const { return home()->column_table(col()); }
00263
00265 template<typename T> bool to(T &Obj) const
00266 {
00267 if (is_null()) return false;
00268 try
00269 {
00270 from_string(c_str(), Obj);
00271 }
00272 catch (const PGSTD::exception &e)
00273 {
00274 throw PGSTD::domain_error("Error reading field " +
00275 PGSTD::string(name()) + ": " +
00276 e.what());
00277 }
00278 return true;
00279 }
00280
00282 template<typename T> bool operator>>(T &Obj) const
00283 { return to(Obj); }
00284
00285 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00286
00287 template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00288
00290
00293 template<> bool to<const char *>(const char *&Obj) const;
00294 #endif
00295
00297 template<typename T> bool to(T &Obj, const T &Default) const
00298 {
00299 const bool NotNull = to(Obj);
00300 if (!NotNull) Obj = Default;
00301 return NotNull;
00302 }
00303
00305
00308 template<typename T> T as(const T &Default) const
00309 {
00310 T Obj;
00311 to(Obj, Default);
00312 return Obj;
00313 }
00314
00316 template<typename T> T as() const
00317 {
00318 T Obj;
00319 const bool NotNull = to(Obj);
00320 if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00321 return Obj;
00322 }
00323
00324 bool is_null() const { return home()->GetIsNull(idx(), col()); }
00325 size_type size() const throw ()
00326 { return home()->GetLength(idx(),col()); }
00327 tuple::size_type num() const { return col(); }
00328
00329 #ifdef PQXX_DEPRECATED_HEADERS
00330
00331 const char *Name() const {return name();}
00332 #endif
00333
00334 private:
00335 const result *home() const throw () { return m_tup.m_Home; }
00336 result::size_type idx() const throw () { return m_tup.m_Index; }
00337
00338 protected:
00339 const tuple::size_type col() const throw () { return m_col; }
00340 tuple m_tup;
00341 tuple::size_type m_col;
00342 };
00343
00344 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00345 const tuple,
00346 result::difference_type,
00347 const_iterator,
00348 tuple> const_iterator_base;
00349
00351
00355 class PQXX_LIBEXPORT const_iterator :
00356 public const_iterator_base,
00357 public tuple
00358 {
00359 public:
00360 typedef const tuple *pointer;
00361 typedef tuple reference;
00362 typedef result::size_type size_type;
00363 typedef result::difference_type difference_type;
00364
00365 const_iterator() throw () : tuple(0,0) {}
00366 const_iterator(const tuple &t) throw () : tuple(t) {}
00367
00379 pointer operator->() const { return this; }
00380 reference operator*() const { return tuple(*this); }
00381
00382 const_iterator operator++(int);
00383 const_iterator &operator++() { ++m_Index; return *this; }
00384 const_iterator operator--(int);
00385 const_iterator &operator--() { --m_Index; return *this; }
00386
00387 const_iterator &operator+=(difference_type i)
00388 { m_Index+=i; return *this; }
00389 const_iterator &operator-=(difference_type i)
00390 { m_Index-=i; return *this; }
00391
00392 bool operator==(const const_iterator &i) const
00393 {return m_Index==i.m_Index;}
00394 bool operator!=(const const_iterator &i) const
00395 {return m_Index!=i.m_Index;}
00396 bool operator<(const const_iterator &i) const
00397 {return m_Index<i.m_Index;}
00398 bool operator<=(const const_iterator &i) const
00399 {return m_Index<=i.m_Index;}
00400 bool operator>(const const_iterator &i) const
00401 {return m_Index>i.m_Index;}
00402 bool operator>=(const const_iterator &i) const
00403 {return m_Index>=i.m_Index;}
00404
00405 inline const_iterator operator+(difference_type) const;
00406 friend const_iterator
00407 operator+(difference_type, const_iterator);
00408 inline const_iterator operator-(difference_type) const;
00409 inline difference_type operator-(const_iterator) const;
00410
00411 private:
00412 friend class pqxx::result;
00413 const_iterator(const pqxx::result *r, result::size_type i) throw () :
00414 tuple(r, i) {}
00415 };
00416
00417 class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00418 {
00419 public:
00420 typedef const_iterator iterator_type;
00421 using iterator_type::iterator_category;
00422 using iterator_type::difference_type;
00423 using iterator_type::pointer;
00424 #ifndef _MSC_VER
00425 using iterator_type::value_type;
00426 using iterator_type::reference;
00427 #else
00428
00429 typedef const tuple &reference;
00430 typedef tuple value_type;
00431 #endif
00432
00433 const_reverse_iterator(const const_reverse_iterator &rhs) :
00434 const_iterator(rhs), m_tmp(rhs) {}
00435 explicit const_reverse_iterator(const const_iterator &rhs) :
00436 const_iterator(rhs), m_tmp() {}
00437
00438 iterator_type base() const throw () { return *this; }
00439
00440 const_reverse_iterator &operator=(const const_reverse_iterator &r)
00441 { iterator_type::operator=(r); return *this; }
00442 pointer operator->() const throw ()
00443 { m_tmp=*this; --m_tmp; return &m_tmp; }
00444 reference operator*() const throw () { return *operator->(); }
00445 const_reverse_iterator operator++()
00446 { iterator_type::operator--(); return *this; }
00447 const_reverse_iterator operator++(int);
00448 const_reverse_iterator &operator--()
00449 { iterator_type::operator++(); return *this; }
00450 const_reverse_iterator operator--(int);
00451 const_reverse_iterator operator+(difference_type i) const
00452 { return const_reverse_iterator(iterator_type(*this)-i); }
00453 const_reverse_iterator &operator+=(difference_type i)
00454 { iterator_type::operator-=(i); return *this; }
00455 const_reverse_iterator operator-(difference_type i)
00456 { return const_reverse_iterator(iterator_type(*this)+i); }
00457 const_reverse_iterator &operator-=(difference_type i)
00458 { iterator_type::operator+=(i); return *this; }
00459
00460 bool operator==(const const_reverse_iterator &rhs) const throw ()
00461 { return iterator_type::operator==(rhs); }
00462 bool operator!=(const const_reverse_iterator &rhs) const throw ()
00463 { return !operator==(rhs); }
00464
00465 bool operator<(const const_reverse_iterator &rhs) const
00466 { return iterator_type::operator>(rhs); }
00467 bool operator<=(const const_reverse_iterator &rhs) const
00468 { return iterator_type::operator>=(rhs); }
00469 bool operator>(const const_reverse_iterator &rhs) const
00470 { return iterator_type::operator<(rhs); }
00471 bool operator>=(const const_reverse_iterator &rhs) const
00472 { return iterator_type::operator<=(rhs); }
00473 difference_type operator-(const const_reverse_iterator &rhs) const
00474 { return rhs.base() - base(); }
00475
00476 private:
00478
00483 mutable iterator_type m_tmp;
00484 };
00485
00486 class PQXX_LIBEXPORT const_fielditerator :
00487 public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00488 const field,
00489 tuple::size_type>,
00490 public field
00491 {
00492 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00493 const field,
00494 tuple::size_type> it;
00495 public:
00496 using it::pointer;
00497 typedef tuple::size_type size_type;
00498 typedef tuple::difference_type difference_type;
00499 typedef field reference;
00500
00501 const_fielditerator(const tuple &T, tuple::size_type C) throw () :
00502 field(T, C) {}
00503 const_fielditerator(const field &F) throw () : field(F) {}
00504
00505 pointer operator->() const { return this; }
00506 reference operator*() const { return field(*this); }
00507
00508 const_fielditerator operator++(int);
00509 const_fielditerator &operator++() { ++m_col; return *this; }
00510 const_fielditerator operator--(int);
00511 const_fielditerator &operator--() { --m_col; return *this; }
00512
00513 const_fielditerator &operator+=(difference_type i)
00514 { m_col+=i; return *this; }
00515 const_fielditerator &operator-=(difference_type i)
00516 { m_col-=i; return *this; }
00517
00518 bool operator==(const const_fielditerator &i) const
00519 {return col()==i.col();}
00520 bool operator!=(const const_fielditerator &i) const
00521 {return col()!=i.col();}
00522 bool operator<(const const_fielditerator &i) const
00523 {return col()<i.col();}
00524 bool operator<=(const const_fielditerator &i) const
00525 {return col()<=i.col();}
00526 bool operator>(const const_fielditerator &i) const
00527 {return col()>i.col();}
00528 bool operator>=(const const_fielditerator &i) const
00529 {return col()>=i.col();}
00530
00531 inline const_fielditerator operator+(difference_type) const;
00532
00533 friend const_fielditerator operator+(difference_type,
00534 const_fielditerator);
00535
00536 inline const_fielditerator operator-(difference_type) const;
00537 inline difference_type operator-(const_fielditerator) const;
00538 };
00539
00540 class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00541 {
00542 public:
00543 typedef const_fielditerator iterator_type;
00544 using iterator_type::iterator_category;
00545 using iterator_type::difference_type;
00546 using iterator_type::pointer;
00547 #ifndef _MSC_VER
00548 using iterator_type::value_type;
00549 using iterator_type::reference;
00550 #else
00551
00552 typedef field value_type;
00553 typedef const field &reference;
00554 #endif
00555
00556 iterator_type base() const throw () { return *this; }
00557 const_reverse_fielditerator(const const_reverse_fielditerator &rhs)
00558 : const_fielditerator(rhs), m_tmp(rhs.m_tmp) {}
00559 explicit
00560 const_reverse_fielditerator(const const_fielditerator &rhs) :
00561 const_fielditerator(rhs), m_tmp(rhs) {}
00562
00563 const_reverse_fielditerator &
00564 operator=(const const_reverse_fielditerator &r)
00565 { iterator_type::operator=(r); return *this; }
00566 pointer operator->() const throw ()
00567 { m_tmp = *this; --m_tmp; return &m_tmp; }
00568 reference operator*() const throw () { return *operator->(); }
00569 const_reverse_fielditerator operator++()
00570 { iterator_type::operator--(); return *this; }
00571 const_reverse_fielditerator operator++(int);
00572 const_reverse_fielditerator &operator--()
00573 { iterator_type::operator++(); return *this; }
00574 const_reverse_fielditerator operator--(int);
00575 const_reverse_fielditerator operator+(difference_type i) const
00576 { return const_reverse_fielditerator(iterator_type(*this)-i); }
00577 const_reverse_fielditerator &operator+=(difference_type i)
00578 { iterator_type::operator-=(i); return *this; }
00579 const_reverse_fielditerator operator-(difference_type i)
00580 { return const_reverse_fielditerator(iterator_type(*this)+i); }
00581 const_reverse_fielditerator &operator-=(difference_type i)
00582 { iterator_type::operator+=(i); return *this; }
00583
00584 bool
00585 operator==(const const_reverse_fielditerator &rhs) const throw ()
00586 { return iterator_type::operator==(rhs); }
00587 bool
00588 operator!=(const const_reverse_fielditerator &rhs) const throw ()
00589 { return !operator==(rhs); }
00590
00591
00592 bool operator<(const const_reverse_fielditerator &rhs) const
00593 { return iterator_type::operator>(rhs); }
00594 bool operator<=(const const_reverse_fielditerator &rhs) const
00595 { return iterator_type::operator>=(rhs); }
00596 bool operator>(const const_reverse_fielditerator &rhs) const
00597 { return iterator_type::operator<(rhs); }
00598 bool operator>=(const const_reverse_fielditerator &rhs) const
00599 { return iterator_type::operator<=(rhs); }
00600 difference_type
00601 operator-(const const_reverse_fielditerator &rhs) const
00602 { return rhs.base() - base(); }
00603
00604 private:
00606
00611 mutable iterator_type m_tmp;
00612 };
00613
00614
00615 result() throw () : super() {}
00616 result(const result &rhs) throw () : super(rhs) {}
00617
00618 result &operator=(const result &rhs) throw ()
00619 { super::operator=(rhs); return *this; }
00620
00621 bool operator==(const result &) const throw ();
00622 bool operator!=(const result &rhs) const throw ()
00623 { return !operator==(rhs); }
00624
00625 const_reverse_iterator rbegin() const
00626 { return const_reverse_iterator(end()); }
00627 const_reverse_iterator rend() const
00628 { return const_reverse_iterator(begin()); }
00629
00630 const_iterator begin() const throw ()
00631 { return const_iterator(this, 0); }
00632 inline const_iterator end() const throw ();
00633
00634 reference front() const throw () { return tuple(this,0); }
00635 reference back() const throw () {return tuple(this,size()-1);}
00636
00637 size_type size() const throw ()
00638 { return c_ptr() ? PQXXPQ::PQntuples(c_ptr()) : 0; }
00639 bool empty() const
00640 { return !c_ptr() || !PQXXPQ::PQntuples(c_ptr()); }
00641 size_type capacity() const throw () { return size(); }
00642
00643 void swap(result &) throw ();
00644
00645 const tuple operator[](size_type i) const throw ()
00646 { return tuple(this, i); }
00647 const tuple at(size_type) const throw (PGSTD::out_of_range);
00648
00649 using super::clear;
00650
00652 tuple::size_type columns() const throw ()
00653 { return PQnfields(c_ptr()); }
00654
00656 tuple::size_type column_number(const char ColName[]) const;
00657
00659 tuple::size_type column_number(const PGSTD::string &Name) const
00660 {return column_number(Name.c_str());}
00661
00663 const char *column_name(tuple::size_type Number) const;
00664
00666 oid column_type(tuple::size_type ColNum) const;
00668 oid column_type(int ColNum) const
00669 { return column_type(tuple::size_type(ColNum)); }
00670
00672 oid column_type(const PGSTD::string &ColName) const
00673 { return column_type(column_number(ColName)); }
00674
00676 oid column_type(const char ColName[]) const
00677 { return column_type(column_number(ColName)); }
00678
00680
00687 oid column_table(tuple::size_type ColNum) const;
00688
00690
00697 oid column_table(int ColNum) const
00698 { return column_table(tuple::size_type(ColNum)); }
00699
00701
00708 oid column_table(const PGSTD::string &ColName) const
00709 { return column_table(column_number(ColName)); }
00710
00712
00715 oid inserted_oid() const { return PQoidValue(c_ptr()); }
00716
00717
00719
00722 size_type affected_rows() const;
00723
00724
00725 #ifdef PQXX_DEPRECATED_HEADERS
00726
00727 typedef tuple Tuple;
00729 typedef field Field;
00731 oid InsertedOid() const { return inserted_oid(); }
00733 size_type AffectedRows() const { return affected_rows(); }
00735 tuple::size_type Columns() const { return columns(); }
00737 tuple::size_type ColumnNumber(const char Name[]) const
00738 {return PQfnumber(c_ptr(),Name);}
00740 tuple::size_type ColumnNumber(const PGSTD::string &Name) const
00741 {return ColumnNumber(Name.c_str());}
00743 const char *ColumnName(tuple::size_type Number) const
00744 {return PQfname(c_ptr(),Number);}
00745 #endif
00746
00747
00748 private:
00749 friend class pqxx::result::field;
00750 const char *GetValue(size_type Row, tuple::size_type Col) const;
00751 bool GetIsNull(size_type Row, tuple::size_type Col) const;
00752 field::size_type GetLength(size_type Row, tuple::size_type Col) const;
00753
00754 friend class connection_base;
00755 friend class pipeline;
00756 explicit result(PQXXPQ::PGresult *rhs) throw () : super(rhs) {}
00757 result &operator=(PQXXPQ::PGresult *rhs) throw ()
00758 { super::operator=(rhs); return *this; }
00759 bool operator!() const throw () { return !c_ptr(); }
00760 operator bool() const throw () { return c_ptr() != 0; }
00761 void CheckStatus(const PGSTD::string &Query) const;
00762 void CheckStatus(const char Query[]) const;
00763 int errorposition() const throw ();
00764 PGSTD::string StatusError() const;
00765
00766 friend class Cursor;
00767 const char *CmdStatus() const throw () { return PQcmdStatus(c_ptr()); }
00768 };
00769
00770
00772
00791 template<typename STREAM>
00792 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)
00793 {
00794 S.write(F.c_str(), F.size());
00795 return S;
00796 }
00797
00798
00800 template<typename T>
00801 inline void from_string(const result::field &F, T &Obj)
00802 { from_string(F.c_str(), Obj); }
00803
00805 template<>
00806 inline PGSTD::string to_string(const result::field &Obj)
00807 { return to_string(Obj.c_str()); }
00808
00809
00811 template<>
00812 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00813 {
00814 if (is_null()) return false;
00815 Obj = c_str();
00816 return true;
00817 }
00818
00820
00825 template<>
00826 inline bool result::field::to<const char *>(const char *&Obj) const
00827 {
00828 if (is_null()) return false;
00829 Obj = c_str();
00830 return true;
00831 }
00832
00833
00834 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00835 { return const_reverse_fielditerator(end()); }
00836 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00837 { return const_reverse_fielditerator(begin()); }
00838
00839 inline result::const_iterator
00840 result::const_iterator::operator+(difference_type o) const
00841 { return const_iterator(m_Home, m_Index + o); }
00842
00843 inline result::const_iterator
00844 operator+(result::const_iterator::difference_type o, result::const_iterator i)
00845 { return i + o; }
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::difference_type
00852 result::const_iterator::operator-(const_iterator i) const
00853 { return num()-i.num(); }
00854
00855 inline result::const_iterator result::end() const throw ()
00856 { return const_iterator(this, size()); }
00857
00858
00859 inline result::const_reverse_iterator
00860 operator+(result::const_reverse_iterator::difference_type n,
00861 const result::const_reverse_iterator &i)
00862 { return result::const_reverse_iterator(i.base() - n); }
00863
00864 inline result::const_fielditerator
00865 result::const_fielditerator::operator+(difference_type o) const
00866 { return const_fielditerator(m_tup, col() + o); }
00867
00868 inline result::const_fielditerator
00869 operator+(result::const_fielditerator::difference_type o,
00870 result::const_fielditerator i)
00871 { return i + o; }
00872
00873 inline result::const_fielditerator
00874 result::const_fielditerator::operator-(difference_type o) const
00875 { return const_fielditerator(m_tup, col() - o); }
00876
00877 inline result::const_fielditerator::difference_type
00878 result::const_fielditerator::operator-(const_fielditerator i) const
00879 { return num()-i.num(); }
00880
00881
00882 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00883 class field_streambuf :
00884 #ifdef PQXX_HAVE_STREAMBUF
00885 public PGSTD::basic_streambuf<CHAR, TRAITS>
00886 #else
00887 public PGSTD::streambuf
00888 #endif
00889 {
00890 public:
00891 typedef CHAR char_type;
00892 typedef TRAITS traits_type;
00893 typedef typename traits_type::int_type int_type;
00894 #ifdef PQXX_HAVE_STREAMBUF
00895 typedef typename traits_type::pos_type pos_type;
00896 typedef typename traits_type::off_type off_type;
00897 #else
00898 typedef streamoff off_type;
00899 typedef streampos pos_type;
00900 #endif
00901 typedef PGSTD::ios::openmode openmode;
00902 typedef PGSTD::ios::seekdir seekdir;
00903
00904 explicit field_streambuf(const result::field &F) :
00905 m_Field(F)
00906 {
00907 initialize();
00908 }
00909
00910 #ifdef PQXX_HAVE_STREAMBUF
00911 protected:
00912 #endif
00913 virtual int sync() { return traits_type::eof(); }
00914
00915 protected:
00916 virtual pos_type seekoff(off_type, seekdir, openmode)
00917 { return traits_type::eof(); }
00918 virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
00919 virtual int_type overflow(int_type) { return traits_type::eof(); }
00920 virtual int_type underflow() { return traits_type::eof(); }
00921
00922 private:
00923 const result::field &m_Field;
00924
00925 int_type initialize()
00926 {
00927 char_type *G =
00928 reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
00929 setg(G, G, G + m_Field.size());
00930 return m_Field.size();
00931 }
00932 };
00933
00934
00936
00944 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00945 class basic_fieldstream :
00946 #ifdef PQXX_HAVE_STREAMBUF
00947 public PGSTD::basic_istream<CHAR, TRAITS>
00948 #else
00949 public PGSTD::istream
00950 #endif
00951 {
00952 #ifdef PQXX_HAVE_STREAMBUF
00953 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00954 #else
00955 typedef PGSTD::istream super;
00956 #endif
00957
00958 public:
00959 typedef CHAR char_type;
00960 typedef TRAITS traits_type;
00961 typedef typename traits_type::int_type int_type;
00962 typedef typename traits_type::pos_type pos_type;
00963 typedef typename traits_type::off_type off_type;
00964
00965 basic_fieldstream(const result::field &F) : super(&m_Buf), m_Buf(F) { }
00966
00967 private:
00968 field_streambuf<CHAR, TRAITS> m_Buf;
00969 };
00970
00971 typedef basic_fieldstream<char> fieldstream;
00972
00973 }
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990