00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef PQXX_LARGEOBJECT_H
00015 #define PQXX_LARGEOBJECT_H
00016
00017 #include <streambuf>
00018
00019 #include <pqxx/transactionitf.h>
00020
00021
00022 namespace pqxx
00023 {
00024
00025 class LargeObjectAccess;
00026
00027
00029
00036 class LargeObject
00037 {
00038 public:
00039 typedef long size_type;
00040
00042 LargeObject();
00043
00045
00047 explicit LargeObject(TransactionItf &T);
00048
00050
00054 explicit LargeObject(Oid O) : m_ID(O) {}
00055
00057
00061 LargeObject(TransactionItf &T, const PGSTD::string &File);
00062
00064
00068 LargeObject(const LargeObjectAccess &O);
00069
00071
00074 Oid id() const throw () { return m_ID; }
00075
00077 bool operator==(const LargeObject &other) const
00078 { return m_ID == other.m_ID; }
00080 bool operator!=(const LargeObject &other) const
00081 { return m_ID != other.m_ID; }
00083 bool operator<=(const LargeObject &other) const
00084 { return m_ID <= other.m_ID; }
00086 bool operator>=(const LargeObject &other) const
00087 { return m_ID >= other.m_ID; }
00089 bool operator<(const LargeObject &other) const
00090 { return m_ID < other.m_ID; }
00092 bool operator>(const LargeObject &other) const
00093 { return m_ID > other.m_ID; }
00094
00096
00100 void to_file(TransactionItf &T, const PGSTD::string &File) const;
00101
00103
00107 void remove(TransactionItf &T) const;
00108
00109 protected:
00110 static PGconn *RawConnection(const TransactionItf &T)
00111 {
00112 return T.Conn().RawConnection();
00113 }
00114
00115 PGSTD::string Reason() const;
00116
00117 private:
00118 Oid m_ID;
00119 };
00120
00121
00123 class LargeObjectAccess : private LargeObject
00124 {
00125 public:
00126 using LargeObject::size_type;
00127
00129
00133 explicit LargeObjectAccess(TransactionItf &T,
00134 PGSTD::ios_base::openmode mode =
00135 PGSTD::ios_base::in |
00136 PGSTD::ios_base::out);
00137
00139
00145 LargeObjectAccess(TransactionItf &T,
00146 Oid O,
00147 PGSTD::ios_base::openmode mode =
00148 PGSTD::ios_base::in |
00149 PGSTD::ios_base::out);
00150
00152
00157 LargeObjectAccess(TransactionItf &T,
00158 LargeObject O,
00159 PGSTD::ios_base::openmode mode =
00160 PGSTD::ios_base::in |
00161 PGSTD::ios_base::out);
00162
00164
00169 LargeObjectAccess(TransactionItf &T,
00170 const PGSTD::string &File,
00171 PGSTD::ios_base::openmode mode =
00172 PGSTD::ios_base::in | PGSTD::ios_base::out);
00173
00174 ~LargeObjectAccess() { close(); }
00175
00177
00180 using LargeObject::id;
00181
00183
00186 void to_file(const PGSTD::string &File) const
00187 {
00188 LargeObject::to_file(m_Trans, File);
00189 }
00190
00192
00196 void write(const char Buf[], size_type Len);
00197
00199
00202 void write(const PGSTD::string &Buf)
00203 { write(Buf.c_str(), Buf.size()); }
00204
00206
00212 size_type read(char Buf[], size_type Len);
00213
00215
00218 size_type seek(size_type dest, PGSTD::ios_base::seekdir dir);
00219
00221
00229 long cseek(long dest, PGSTD::ios_base::seekdir dir) throw ();
00230
00232
00238 long cwrite(const char Buf[], size_type Len) throw ();
00239
00241
00247 long cread(char Buf[], size_type Len) throw ();
00248
00249 using LargeObject::operator==;
00250 using LargeObject::operator!=;
00251 using LargeObject::operator<;
00252 using LargeObject::operator<=;
00253 using LargeObject::operator>;
00254 using LargeObject::operator>=;
00255
00256 private:
00257 PGSTD::string Reason() const;
00258 PGconn *RawConnection() { return LargeObject::RawConnection(m_Trans); }
00259
00260 void open(PGSTD::ios_base::openmode mode);
00261 void close();
00262
00263 TransactionItf &m_Trans;
00264 int m_fd;
00265
00266
00267 LargeObjectAccess();
00268 LargeObjectAccess(const LargeObjectAccess &);
00269 LargeObjectAccess operator=(const LargeObjectAccess &);
00270 };
00271
00272
00274
00279 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00280 class largeobject_streambuf : public PGSTD::basic_streambuf<CHAR, TRAITS>
00281 {
00282 typedef long size_type;
00283 public:
00284 typedef CHAR char_type;
00285 typedef TRAITS traits_type;
00286 typedef typename traits_type::int_type int_type;
00287 typedef typename traits_type::pos_type pos_type;
00288 typedef typename traits_type::off_type off_type;
00289
00290 largeobject_streambuf(TransactionItf &T,
00291 LargeObject O,
00292 PGSTD::ios_base::openmode mode =
00293 PGSTD::ios::in | PGSTD::ios::out,
00294 size_type BufSize=512) :
00295 m_BufSize(BufSize),
00296 m_Obj(T, O),
00297 m_G(0),
00298 m_P(0)
00299 {
00300 initialize(mode);
00301 }
00302
00303 largeobject_streambuf(TransactionItf &T,
00304 Oid O,
00305 PGSTD::ios_base::openmode mode =
00306 PGSTD::ios::in | PGSTD::ios::out,
00307 size_type BufSize=512) :
00308 m_BufSize(BufSize),
00309 m_Obj(T, O),
00310 m_G(0),
00311 m_P(0)
00312 {
00313 initialize(mode);
00314 }
00315
00316 virtual ~largeobject_streambuf()
00317 {
00318 delete [] m_P;
00319 delete [] m_G;
00320 }
00321
00322
00323 protected:
00324 virtual int sync()
00325 {
00326
00327 setg(eback(), eback(), egptr());
00328 return overflow(EoF());
00329 }
00330
00331 virtual pos_type seekoff(off_type offset,
00332 PGSTD::ios_base::seekdir dir,
00333 PGSTD::ios_base::openmode mode =
00334 PGSTD::ios_base::in|PGSTD::ios_base::out)
00335 {
00336 if (!mode) {}
00337 return AdjustEOF(m_Obj.cseek(offset, dir));
00338 }
00339
00340 virtual pos_type seekpos(pos_type pos,
00341 PGSTD::ios_base::openmode mode =
00342 PGSTD::ios_base::in|PGSTD::ios_base::out)
00343 {
00344 if (!mode) {}
00345 return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios_base::beg));
00346 }
00347
00348 virtual int_type overflow(int_type ch = EoF())
00349 {
00350 char *const pp = pptr();
00351 if (!pp) return EoF();
00352 char *const pb = pbase();
00353 int_type result = 0;
00354
00355 if (pp > pb) result = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00356 setp(m_P, m_P + m_BufSize);
00357
00358
00359 if (ch != EoF())
00360 {
00361 *pptr() = char(ch);
00362 pbump(1);
00363 }
00364 return result;
00365 }
00366
00367 virtual int_type underflow()
00368 {
00369 if (!gptr()) return EoF();
00370 char *const eb = eback();
00371 const int result = AdjustEOF(m_Obj.cread(eback(), m_BufSize));
00372 setg(eb, eb, eb + ((result==EoF()) ? 0 : result));
00373 return (!result || (result == EoF())) ? EoF() : *eb;
00374 }
00375
00376 private:
00378 static int_type EoF() { return traits_type::eof(); }
00379
00381 static PGSTD::streampos AdjustEOF(int pos)
00382 {
00383 return (pos == -1) ? EoF() : pos;
00384 }
00385
00386 void initialize(PGSTD::ios_base::openmode mode)
00387 {
00388 if (mode & PGSTD::ios_base::in)
00389 {
00390 m_G = new char_type[m_BufSize];
00391 setg(m_G, m_G, m_G);
00392 }
00393 if (mode & PGSTD::ios_base::out)
00394 {
00395 m_P = new char_type[m_BufSize];
00396 setp(m_P, m_P + m_BufSize);
00397 }
00398 }
00399
00400 const size_type m_BufSize;
00401 LargeObjectAccess m_Obj;
00402
00403
00404 char_type *m_G, *m_P;
00405 };
00406
00407
00409
00416 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00417 class basic_ilostream : public PGSTD::basic_istream<CHAR, TRAITS>
00418 {
00419 public:
00420 typedef CHAR char_type;
00421 typedef TRAITS traits_type;
00422 typedef typename traits_type::int_type int_type;
00423 typedef typename traits_type::pos_type pos_type;
00424 typedef typename traits_type::off_type off_type;
00425
00427
00431 basic_ilostream(TransactionItf &T,
00432 LargeObject O,
00433 LargeObject::size_type BufSize=512) :
00434 PGSTD::basic_istream<CHAR,TRAITS>(&m_Buf),
00435 m_Buf(T, O, in, BufSize)
00436 {
00437 }
00438
00440
00444 basic_ilostream(TransactionItf &T,
00445 Oid O,
00446 LargeObject::size_type BufSize=512) :
00447 PGSTD::basic_istream<CHAR,TRAITS>(&m_Buf),
00448 m_Buf(T, O, in, BufSize)
00449 {
00450 }
00451
00452 private:
00453 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00454 };
00455
00456 typedef basic_ilostream<char> ilostream;
00457
00458
00460
00467 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00468 class basic_olostream : public PGSTD::basic_ostream<CHAR, TRAITS>
00469 {
00470 public:
00471 typedef CHAR char_type;
00472 typedef TRAITS traits_type;
00473 typedef typename traits_type::int_type int_type;
00474 typedef typename traits_type::pos_type pos_type;
00475 typedef typename traits_type::off_type off_type;
00476
00478
00482 basic_olostream(TransactionItf &T,
00483 LargeObject O,
00484 LargeObject::size_type BufSize=512) :
00485 PGSTD::basic_ostream<CHAR,TRAITS>(&m_Buf),
00486 m_Buf(T, O, out, BufSize)
00487 {
00488 }
00489
00491
00495 basic_olostream(TransactionItf &T,
00496 Oid O,
00497 LargeObject::size_type BufSize=512) :
00498 PGSTD::basic_ostream<CHAR,TRAITS>(&m_Buf),
00499 m_Buf(T, O, out, BufSize)
00500 {
00501 }
00502
00503 ~basic_olostream() { m_Buf.pubsync(); m_Buf.pubsync(); }
00504
00505 private:
00506 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00507 };
00508
00509 typedef basic_olostream<char> olostream;
00510
00511
00513
00520 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00521 class basic_lostream : public PGSTD::basic_iostream<CHAR, TRAITS>
00522 {
00523 public:
00524 typedef CHAR char_type;
00525 typedef TRAITS traits_type;
00526 typedef typename traits_type::int_type int_type;
00527 typedef typename traits_type::pos_type pos_type;
00528 typedef typename traits_type::off_type off_type;
00529
00531
00535 basic_lostream(TransactionItf &T,
00536 LargeObject O,
00537 LargeObject::size_type BufSize=512) :
00538 PGSTD::basic_iostream<CHAR,TRAITS>(&m_Buf),
00539 m_Buf(T, O, in | out, BufSize)
00540 {
00541 }
00542
00544
00548 basic_lostream(TransactionItf &T,
00549 Oid O,
00550 LargeObject::size_type BufSize=512) :
00551 PGSTD::basic_iostream<CHAR,TRAITS>(&m_Buf),
00552 m_Buf(T, O, in | out, BufSize)
00553 {
00554 }
00555
00556 ~basic_lostream() { m_Buf.pubsync(); m_Buf.pubsync(); }
00557
00558 private:
00559 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00560 };
00561
00562 typedef basic_lostream<char> lostream;
00563
00564 }
00565
00566 #endif
00567