00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pqxx/config.h"
00020
00021 #ifdef HAVE_STREAMBUF
00022 #include <streambuf>
00023 #else
00024 #include <streambuf.h>
00025 #endif
00026
00027 #include "pqxx/dbtransaction"
00028
00029
00030 namespace pqxx
00031 {
00032
00033 class largeobjectaccess;
00034
00036
00043 class PQXX_LIBEXPORT largeobject
00044 {
00045 public:
00046 typedef long size_type;
00047
00049 largeobject();
00050
00052
00054 explicit largeobject(dbtransaction &T);
00055
00057
00061 explicit largeobject(oid O) : m_ID(O) {}
00062
00064
00068 largeobject(dbtransaction &T, const PGSTD::string &File);
00069
00071
00075 largeobject(const largeobjectaccess &O);
00076
00078
00082 oid id() const throw () { return m_ID; }
00083
00085 bool operator==(const largeobject &other) const
00086 { return m_ID == other.m_ID; }
00088 bool operator!=(const largeobject &other) const
00089 { return m_ID != other.m_ID; }
00091 bool operator<=(const largeobject &other) const
00092 { return m_ID <= other.m_ID; }
00094 bool operator>=(const largeobject &other) const
00095 { return m_ID >= other.m_ID; }
00097 bool operator<(const largeobject &other) const
00098 { return m_ID < other.m_ID; }
00100 bool operator>(const largeobject &other) const
00101 { return m_ID > other.m_ID; }
00102
00104
00108 void to_file(dbtransaction &T, const PGSTD::string &File) const;
00109
00111
00115 void remove(dbtransaction &T) const;
00116
00117 protected:
00118 static PGconn *RawConnection(const dbtransaction &T)
00119 {
00120 return T.conn().RawConnection();
00121 }
00122
00123 PGSTD::string Reason() const;
00124
00125 private:
00126 oid m_ID;
00127 };
00128
00129
00130
00131
00133 class PQXX_LIBEXPORT largeobjectaccess : private largeobject
00134 {
00135 public:
00136 using largeobject::size_type;
00137 typedef long off_type;
00138 typedef size_type pos_type;
00139
00141
00145 typedef PGSTD::ios::openmode openmode;
00146
00148
00152 typedef PGSTD::ios::seekdir seekdir;
00153
00155
00159 explicit largeobjectaccess(dbtransaction &T,
00160 openmode mode =
00161 PGSTD::ios::in |
00162 PGSTD::ios::out);
00163
00165
00171 largeobjectaccess(dbtransaction &T,
00172 oid O,
00173 openmode mode =
00174 PGSTD::ios::in |
00175 PGSTD::ios::out);
00176
00178
00183 largeobjectaccess(dbtransaction &T,
00184 largeobject O,
00185 openmode mode = PGSTD::ios::in | PGSTD::ios::out);
00186
00188
00193 largeobjectaccess(dbtransaction &T,
00194 const PGSTD::string &File,
00195 openmode mode =
00196 PGSTD::ios::in | PGSTD::ios::out);
00197
00198 ~largeobjectaccess() { close(); }
00199
00201
00204 using largeobject::id;
00205
00207
00210 void to_file(const PGSTD::string &File) const
00211 {
00212 largeobject::to_file(m_Trans, File);
00213 }
00214
00215 #ifdef BROKEN_USING_DECL
00216
00217
00221 void to_file(dbtransaction &T, const PGSTD::string &F) const
00222 { largeobject::to_file(T, F); }
00223 #else
00224 using largeobject::to_file;
00225 #endif
00226
00227
00229
00233 void write(const char Buf[], size_type Len);
00234
00236
00239 void write(const PGSTD::string &Buf)
00240 { write(Buf.c_str(), Buf.size()); }
00241
00243
00249 size_type read(char Buf[], size_type Len);
00250
00252
00255 size_type seek(size_type dest, seekdir dir);
00256
00258
00266 pos_type cseek(off_type dest, seekdir dir) throw ();
00267
00269
00275 off_type cwrite(const char Buf[], size_type Len) throw ();
00276
00278
00284 off_type cread(char Buf[], size_type Len) throw ();
00285
00286 using largeobject::remove;
00287
00288 using largeobject::operator==;
00289 using largeobject::operator!=;
00290 using largeobject::operator<;
00291 using largeobject::operator<=;
00292 using largeobject::operator>;
00293 using largeobject::operator>=;
00294
00295 private:
00296 PGSTD::string Reason() const;
00297 PGconn *RawConnection() { return largeobject::RawConnection(m_Trans); }
00298
00299 void open(openmode mode);
00300 void close();
00301
00302 dbtransaction &m_Trans;
00303 int m_fd;
00304
00305
00306 largeobjectaccess();
00307 largeobjectaccess(const largeobjectaccess &);
00308 largeobjectaccess operator=(const largeobjectaccess &);
00309 };
00310
00311
00313
00321 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00322 class largeobject_streambuf :
00323 #ifdef HAVE_STREAMBUF
00324 public PGSTD::basic_streambuf<CHAR, TRAITS>
00325 #else
00326 public PGSTD::streambuf
00327 #endif
00328 {
00329 typedef long size_type;
00330 public:
00331 typedef CHAR char_type;
00332 typedef TRAITS traits_type;
00333 typedef typename traits_type::int_type int_type;
00334 #ifdef HAVE_STREAMBUF
00335 typedef typename traits_type::pos_type pos_type;
00336 typedef typename traits_type::off_type off_type;
00337 #else
00338 typedef streamoff off_type;
00339 typedef streampos pos_type;
00340 #endif
00341 typedef largeobjectaccess::openmode openmode;
00342 typedef largeobjectaccess::seekdir seekdir;
00343
00344 largeobject_streambuf(dbtransaction &T,
00345 largeobject O,
00346 openmode mode = in | out,
00347 size_type BufSize=512) :
00348 m_BufSize(BufSize),
00349 m_Obj(T, O),
00350 m_G(0),
00351 m_P(0)
00352 {
00353 initialize(mode);
00354 }
00355
00356 largeobject_streambuf(dbtransaction &T,
00357 oid O,
00358 openmode mode = in | out,
00359 size_type BufSize=512) :
00360 m_BufSize(BufSize),
00361 m_Obj(T, O),
00362 m_G(0),
00363 m_P(0)
00364 {
00365 initialize(mode);
00366 }
00367
00368 virtual ~largeobject_streambuf()
00369 {
00370 delete [] m_P;
00371 delete [] m_G;
00372 }
00373
00374
00375 #ifdef HAVE_STREAMBUF
00376 protected:
00377 #endif
00378 virtual int sync()
00379 {
00380
00381 setg(eback(), eback(), egptr());
00382 return overflow(EoF());
00383 }
00384
00385 protected:
00386 virtual pos_type seekoff(off_type offset,
00387 seekdir dir,
00388 openmode mode = in|out)
00389 {
00390 if (!mode) {}
00391 return AdjustEOF(m_Obj.cseek(offset, dir));
00392 }
00393
00394 virtual pos_type seekpos(pos_type pos,
00395 openmode mode = in|out)
00396 {
00397 if (!mode) {}
00398 return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios::beg));
00399 }
00400
00401 virtual int_type overflow(int_type ch = EoF())
00402 {
00403 char *const pp = pptr();
00404 if (!pp) return EoF();
00405 char *const pb = pbase();
00406 int_type res = 0;
00407
00408 if (pp > pb) res = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00409 setp(m_P, m_P + m_BufSize);
00410
00411
00412 if (ch != EoF())
00413 {
00414 *pptr() = char(ch);
00415 pbump(1);
00416 }
00417 return res;
00418 }
00419
00420 virtual int_type underflow()
00421 {
00422 if (!gptr()) return EoF();
00423 char *const eb = eback();
00424 const int res = AdjustEOF(m_Obj.cread(eback(), m_BufSize));
00425 setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
00426 return (!res || (res == EoF())) ? EoF() : *eb;
00427 }
00428
00429 private:
00431 static int_type EoF() { return traits_type::eof(); }
00432
00434 static PGSTD::streampos AdjustEOF(int pos)
00435 {
00436 return (pos == -1) ? EoF() : pos;
00437 }
00438
00439 void initialize(openmode mode)
00440 {
00441 if (mode & PGSTD::ios::in)
00442 {
00443 m_G = new char_type[m_BufSize];
00444 setg(m_G, m_G, m_G);
00445 }
00446 if (mode & PGSTD::ios::out)
00447 {
00448 m_P = new char_type[m_BufSize];
00449 setp(m_P, m_P + m_BufSize);
00450 }
00451 }
00452
00453 const size_type m_BufSize;
00454 largeobjectaccess m_Obj;
00455
00456
00457 char_type *m_G, *m_P;
00458 };
00459
00460
00462
00470 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00471 class basic_ilostream :
00472 #ifdef HAVE_STREAMBUF
00473 public PGSTD::basic_istream<CHAR, TRAITS>
00474 #else
00475 public PGSTD::istream
00476 #endif
00477 {
00478 #ifdef HAVE_STREAMBUF
00479 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00480 #else
00481 typedef PGSTD::istream super;
00482 #endif
00483
00484 public:
00485 typedef CHAR char_type;
00486 typedef TRAITS traits_type;
00487 typedef typename traits_type::int_type int_type;
00488 typedef typename traits_type::pos_type pos_type;
00489 typedef typename traits_type::off_type off_type;
00490
00492
00496 basic_ilostream(dbtransaction &T,
00497 largeobject O,
00498 largeobject::size_type BufSize=512) :
00499 super(&m_Buf),
00500 m_Buf(T, O, in, BufSize)
00501 {
00502 }
00503
00505
00509 basic_ilostream(dbtransaction &T,
00510 oid O,
00511 largeobject::size_type BufSize=512) :
00512 super(&m_Buf),
00513 m_Buf(T, O, in, BufSize)
00514 {
00515 }
00516
00517 private:
00518 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00519 };
00520
00521 typedef basic_ilostream<char> ilostream;
00522
00523
00525
00533 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00534 class basic_olostream :
00535 #ifdef HAVE_STREAMBUF
00536 public PGSTD::basic_ostream<CHAR, TRAITS>
00537 #else
00538 public PGSTD::ostream
00539 #endif
00540 {
00541 #ifdef HAVE_STREAMBUF
00542 typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00543 #else
00544 typedef PGSTD::ostream super;
00545 #endif
00546 public:
00547 typedef CHAR char_type;
00548 typedef TRAITS traits_type;
00549 typedef typename traits_type::int_type int_type;
00550 typedef typename traits_type::pos_type pos_type;
00551 typedef typename traits_type::off_type off_type;
00552
00554
00558 basic_olostream(dbtransaction &T,
00559 largeobject O,
00560 largeobject::size_type BufSize=512) :
00561 super(&m_Buf),
00562 m_Buf(T, O, out, BufSize)
00563 {
00564 }
00565
00567
00571 basic_olostream(dbtransaction &T,
00572 oid O,
00573 largeobject::size_type BufSize=512) :
00574 super(&m_Buf),
00575 m_Buf(T, O, out, BufSize)
00576 {
00577 }
00578
00579 ~basic_olostream()
00580 {
00581 #ifdef HAVE_STREAMBUF
00582 m_Buf.pubsync(); m_Buf.pubsync();
00583 #else
00584 m_Buf.sync(); m_Buf.sync();
00585 #endif
00586 }
00587
00588 private:
00589 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00590 };
00591
00592 typedef basic_olostream<char> olostream;
00593
00594
00596
00604 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00605 class basic_lostream :
00606 #ifdef HAVE_STREAMBUF
00607 public PGSTD::basic_iostream<CHAR, TRAITS>
00608 #else
00609 public PGSTD::iostream
00610 #endif
00611 {
00612 #ifdef HAVE_STREAMBUF
00613 typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00614 #else
00615 typedef PGSTD::iostream super;
00616 #endif
00617
00618 public:
00619 typedef CHAR char_type;
00620 typedef TRAITS traits_type;
00621 typedef typename traits_type::int_type int_type;
00622 typedef typename traits_type::pos_type pos_type;
00623 typedef typename traits_type::off_type off_type;
00624
00626
00630 basic_lostream(dbtransaction &T,
00631 largeobject O,
00632 largeobject::size_type BufSize=512) :
00633 super(&m_Buf),
00634 m_Buf(T, O, in | out, BufSize)
00635 {
00636 }
00637
00639
00643 basic_lostream(dbtransaction &T,
00644 oid O,
00645 largeobject::size_type BufSize=512) :
00646 super(&m_Buf),
00647 m_Buf(T, O, in | out, BufSize)
00648 {
00649 }
00650
00651 ~basic_lostream()
00652 {
00653 #ifdef HAVE_STREAMBUF
00654 m_Buf.pubsync(); m_Buf.pubsync();
00655 #else
00656 m_Buf.sync(); m_Buf.sync();
00657 #endif
00658 }
00659
00660 private:
00661 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00662 };
00663
00664 typedef basic_lostream<char> lostream;
00665
00666 }
00667
00668