00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00030 #ifndef GENAPI_FILESTREAM_H_
00031 #define GENAPI_FILESTREAM_H_
00032
00033
00034
00035
00036 #include <iomanip>
00037 #include <iosfwd>
00038 #include <cstring>
00039
00040
00041
00042 #include <Base/GCUtilities.h>
00043
00044 #include <GenICamFwd.h>
00045
00046
00047 #if (__GNUC__)
00048 # include <unistd.h>
00049 #endif
00050
00051
00052
00053 typedef int64_t GenICam_streamsize;
00054
00055
00056
00057
00058
00059 #if defined (_MSC_VER)
00060
00061 # include <Base/GCLinkage.h>
00062
00063
00064
00065 # if defined(GENICAM_FORCE_AUTO_IMPLIB) || (!defined(GENICAM_NO_AUTO_IMPLIB) && !defined(GENAPI_EXPORTS))
00066 # if defined (_WIN32) && defined (_MT )
00067 # pragma comment(lib, LIB_NAME( "GenApi" ))
00068 # else
00069 # error Invalid configuration
00070 # endif
00071 # endif
00072
00073 #endif // _MSC_VER
00074
00075 #if defined (_MSC_VER)
00076 # pragma warning(push)
00077 # pragma warning (disable: 4251) // class 'GenApi::CPointer<T>' needs to have dll-interface to be used by clients of class 'GenICam::FileProtocolAdapter'
00078 #endif
00079
00080 namespace GENAPI_NAMESPACE
00081 {
00086 interface GENAPI_DECL_ABSTRACT IFileProtocolAdapter
00087 {
00088 virtual bool attach(GENAPI_NAMESPACE::INodeMap * pInterface) = 0;
00089 virtual bool openFile(const char * pFileName, std::ios_base::openmode mode) = 0;
00090 virtual bool closeFile(const char * pFileName) = 0;
00091 virtual GenICam_streamsize write(const char * buf, int64_t offs, int64_t len, const char * pFileName) = 0;
00092 virtual GenICam_streamsize read(char * buf, int64_t offs, GenICam_streamsize len, const char * pFileName) = 0;
00093 virtual int64_t getBufSize(const char * pFileName, std::ios_base::openmode mode) = 0;
00094 virtual bool deleteFile(const char * pFileName) = 0;
00095
00096 };
00105 class GENAPI_DECL FileProtocolAdapter : public IFileProtocolAdapter {
00106 public:
00112 FileProtocolAdapter();
00113 virtual ~FileProtocolAdapter();
00114 private:
00115 FileProtocolAdapter(const FileProtocolAdapter&);
00116 FileProtocolAdapter& operator=(const FileProtocolAdapter&);
00117 public:
00118
00129 virtual bool attach(GENAPI_NAMESPACE::INodeMap * pInterface );
00130
00131
00146 virtual bool openFile(const char * pFileName, std::ios_base::openmode mode);
00147
00148
00159 virtual bool closeFile(const char * pFileName);
00160
00161
00182 virtual GenICam_streamsize write(const char * buf, int64_t offs, int64_t len, const char * pFileName);
00183
00184
00205 virtual GenICam_streamsize read(char * buf, int64_t offs, GenICam_streamsize len, const char * pFileName);
00206
00207
00222 virtual int64_t getBufSize(const char * pFileName, std::ios_base::openmode mode);
00223
00224
00235 virtual bool deleteFile(const char * pFileName);
00236
00237 private:
00238 void WaitUntilFileOperationExecuteDone( bool Validate = true );
00239
00240 private:
00241
00242 struct FileProtocolAdapterImpl;
00243 FileProtocolAdapterImpl* m_pImpl;
00244 };
00245
00246
00247 template<typename CharType, typename Traits> class IDevFileStreamBuf
00248 : public std::basic_streambuf<CharType, Traits> {
00249
00250 typedef Traits traits_type;
00251 typedef typename Traits::int_type int_type;
00252 typedef typename Traits::char_type char_type;
00253 typedef IDevFileStreamBuf<CharType, Traits> filebuf_type;
00254
00255
00256 using std::basic_streambuf<CharType, Traits>::gptr;
00257
00258 using std::basic_streambuf<CharType, Traits>::egptr;
00259
00260 using std::basic_streambuf<CharType, Traits>::eback;
00261
00262 using std::basic_streambuf<CharType, Traits>::gbump;
00263
00264 using std::basic_streambuf<CharType, Traits>::setg;
00265
00266 public:
00267 IDevFileStreamBuf()
00268 : m_pBuffer(0), m_BufSize(0), m_pAdapter(0), m_fpos(0) {
00269
00270
00271 };
00272
00273
00274 ~IDevFileStreamBuf()
00275 {
00276
00277 try
00278 {
00279 this->close();
00280 }
00281 catch(...)
00282 {}
00283 }
00284
00285 filebuf_type *open(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName, std::ios_base::openmode mode = std::ios_base::in ) {
00286
00287 m_pAdapter = new FileProtocolAdapter();
00288
00289
00290 if (!m_pAdapter || !m_pAdapter->attach(pInterface)){
00291 delete m_pAdapter;
00292 m_pAdapter = 0;
00293 return 0;
00294 }
00295
00296
00297 try
00298 {
00299 if (!(m_pAdapter->openFile(pFileName, mode))){
00300 delete m_pAdapter;
00301 m_pAdapter = 0;
00302 return 0;
00303 }
00304 }
00305 catch (...)
00306 {
00307 delete m_pAdapter;
00308 m_pAdapter = 0;
00309 throw;
00310 }
00311
00312 m_file = pFileName;
00313
00314 m_BufSize = (GenICam_streamsize)m_pAdapter->getBufSize(m_file.c_str(), mode);
00315 m_pBuffer = new char_type[(unsigned int)m_BufSize / sizeof(char_type)];
00316
00317
00318 setg(m_pBuffer, m_pBuffer + m_BufSize,m_pBuffer + m_BufSize);
00319
00320 #ifdef _MSC_VER
00321
00322 std::basic_streambuf<CharType, Traits>::_Init();
00323 #endif
00324
00325 return this;
00326 }
00327
00328
00329
00330 bool
00331 is_open() const
00332 {
00333 return m_pAdapter != 0;
00334 }
00335
00336 filebuf_type *close() {
00337 filebuf_type * ret = 0;
00338 if (this->is_open()) {
00339
00340 if(m_pAdapter->closeFile(m_file.c_str())){
00341
00342 ret = this;
00343 }
00344 delete m_pAdapter;
00345 m_pAdapter = 0;
00346
00347 delete[] m_pBuffer;
00348 m_pBuffer = 0;
00349 }
00350 return ret;
00351 }
00352
00353
00354 protected:
00355 int_type underflow() {
00356 if (gptr() < egptr() )
00357 return traits_type::to_int_type(*gptr());
00358
00359 if (buffer_in() < 0)
00360 return traits_type::eof();
00361 else
00362 return traits_type::to_int_type(*gptr());
00363
00364 }
00365
00366 int_type pbackfail(int_type c) {
00367 if (gptr() != eback() || eback()<gptr()) {
00368 gbump(-1);
00369 if (!traits_type::eq_int_type(c, traits_type::eof() ) )
00370 *(gptr()) = static_cast<char_type>(traits_type::not_eof(c));
00371 return traits_type::not_eof(c);
00372 } else
00373 return traits_type::eof();
00374 }
00375
00376 private:
00377 char_type * m_pBuffer;
00378 GenICam_streamsize m_BufSize;
00379
00380 GENICAM_NAMESPACE::gcstring m_file;
00381 FileProtocolAdapter * m_pAdapter;
00382 int64_t m_fpos;
00383
00384
00385
00386 int buffer_in() {
00387
00388 GenICam_streamsize retval = m_pAdapter->read(m_pBuffer, m_fpos, m_BufSize, m_file.c_str());
00389
00390 if (retval <= 0) {
00391 setg(0, 0, 0);
00392 return -1;
00393 } else {
00394 setg(m_pBuffer, m_pBuffer , m_pBuffer + retval);
00395 m_fpos += retval;
00396 return GENICAM_NAMESPACE::INTEGRAL_CAST2<int, GenICam_streamsize>(retval);
00397 }
00398 }
00399
00400
00401
00402 IDevFileStreamBuf(const IDevFileStreamBuf&);
00403 IDevFileStreamBuf& operator=(const IDevFileStreamBuf&);
00404 };
00405
00406
00407 template<typename CharType, typename Traits> class ODevFileStreamBuf
00408 : public std::basic_streambuf<CharType, Traits> {
00409 typedef Traits traits_type;
00410
00411 typedef typename Traits::int_type int_type;
00412 typedef typename Traits::char_type char_type;
00413 typedef typename Traits::pos_type pos_type;
00414 typedef typename Traits::off_type off_type;
00415
00416 typedef ODevFileStreamBuf<CharType, Traits> filebuf_type;
00417
00418
00419
00420 using std::basic_streambuf<CharType, Traits>::pbase;
00421
00422 using std::basic_streambuf<CharType, Traits>::pptr;
00423
00424 using std::basic_streambuf<CharType, Traits>::epptr;
00425
00426 using std::basic_streambuf<CharType, Traits>::pbump;
00427
00428 public:
00429 ODevFileStreamBuf()
00430 : m_pBuffer(0), m_file(0), m_pAdapter(0), m_fpos(0) {
00431 }
00432
00433 ~ODevFileStreamBuf() {
00434 this->close();
00435 }
00436
00437 filebuf_type *open(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName, std::ios_base::openmode mode) {
00438
00439
00440 m_pAdapter = new FileProtocolAdapter();
00441
00442
00443 if (!m_pAdapter || !m_pAdapter->attach(pInterface)){
00444 delete m_pAdapter;
00445 m_pAdapter = 0;
00446 return 0;
00447 }
00448
00449
00450
00451 try
00452 {
00453 if (!(m_pAdapter->openFile(pFileName, mode))){
00454 delete m_pAdapter;
00455 m_pAdapter = 0;
00456 return 0;
00457 }
00458 }
00459 catch (...)
00460 {
00461 delete m_pAdapter;
00462 m_pAdapter = 0;
00463 throw;
00464 }
00465
00466 m_file = pFileName;
00467
00468 const int64_t bufSize = m_pAdapter->getBufSize(m_file,mode);
00469 m_pBuffer = new char_type[GENICAM_NAMESPACE::INTEGRAL_CAST<size_t>(bufSize) / sizeof(char_type)];
00470 std::basic_streambuf<CharType, Traits>::setp(m_pBuffer, m_pBuffer + bufSize);
00471
00472 return this;
00473 }
00474
00475 bool
00476 is_open() const {
00477 return m_pAdapter != 0;
00478 }
00479
00480 filebuf_type *close() {
00481 filebuf_type * ret = 0;
00482 bool syncFailed = false;
00483 if (this->is_open()) {
00484 if (sync()){
00485 syncFailed = true;
00486 };
00487
00488 if(m_pAdapter->closeFile(m_file)){
00489
00490 if ( syncFailed ){
00491 ret = 0;
00492 } else {
00493 ret = this;
00494 }
00495 }
00496 delete m_pAdapter;
00497 m_pAdapter = 0;
00498
00499 delete[] m_pBuffer;
00500 m_pBuffer = 0;
00501 }
00502 return ret;
00503 }
00504
00505 protected:
00506 GenICam_streamsize xsputn(const char_type * s, GenICam_streamsize n) {
00507 if (n < epptr() - pptr() ) {
00508 memcpy( pptr(), s, (size_t)(n * sizeof(char_type)));
00509 pbump( GENICAM_NAMESPACE::INTEGRAL_CAST2<int>(n) );
00510 return n;
00511 } else {
00512 for (GenICam_streamsize i = 0; i<n; ++i) {
00513 if (traits_type::eq_int_type(std::basic_streambuf<CharType, Traits>::sputc(s[i]), traits_type::eof()))
00514 return i;
00515 }
00516 return n;
00517 }
00518
00519 }
00520 int_type overflow(int_type c = traits_type::eof()) {
00521 if (buffer_out() < 0) {
00522 return traits_type::eof();
00523 } else {
00524 if (!traits_type::eq_int_type (c, traits_type::eof() ) )
00525 return std::basic_streambuf<CharType, Traits>::sputc(static_cast<char_type>(c));
00526 else
00527 return traits_type::not_eof(c);
00528 }
00529
00530 }
00531 int sync() {
00532 return GENICAM_NAMESPACE::INTEGRAL_CAST<int>(buffer_out());
00533 }
00534
00535 private:
00536 char_type * m_pBuffer;
00537 const char * m_file;
00538 FileProtocolAdapter * m_pAdapter;
00539 int64_t m_fpos;
00540
00541 int64_t buffer_out() {
00542 int64_t cnt = pptr() - pbase();
00543
00544 int64_t retval;
00545 int64_t res = m_pAdapter->write(m_pBuffer, m_fpos, cnt, m_file);
00546
00547 if (res != cnt) {
00548 retval = -1;
00549 } else {
00550 retval = 0;
00551 }
00552 m_fpos += res;
00553
00554 pbump(- GENICAM_NAMESPACE::INTEGRAL_CAST<int>(cnt));
00555 return retval;
00556 }
00557
00558
00559 ODevFileStreamBuf(const ODevFileStreamBuf&);
00560 ODevFileStreamBuf & operator =(const ODevFileStreamBuf&);
00561 };
00562
00563 template<typename CharType, typename Traits> class ODevFileStreamBase
00564 : public std::basic_ostream<CharType, Traits> {
00565 public:
00566
00567 typedef ODevFileStreamBuf<CharType, Traits> filebuf_type;
00568 typedef std::basic_ios<CharType, Traits> ios_type;
00569 typedef std::basic_ostream<CharType, Traits> ostream_type;
00570
00571 private:
00572 filebuf_type m_streambuf;
00573 public:
00574
00575 #if defined (_MSC_VER)
00576 ODevFileStreamBase()
00577 : ostream_type(std::_Noinit), m_streambuf() {
00578 this->init(&m_streambuf);
00579 }
00580
00581 ODevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName, std::ios_base::openmode mode = std::ios_base::out|std::ios_base::trunc)
00582 : ostream_type(std::_Noinit), m_streambuf() {
00583 this->init(&m_streambuf);
00584 this->open(pInterface, pFileName, mode);
00585 }
00586 ;
00587
00588 #elif defined (__GNUC__)
00589 ODevFileStreamBase()
00590 : ostream_type(), m_streambuf() {
00591 this->init(&m_streambuf);
00592 }
00593
00594 ODevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName, std::ios_base::openmode mode = std::ios_base::out|std::ios_base::trunc)
00595 : ostream_type(), m_streambuf() {
00596 this->init(&m_streambuf);
00597 this->open(pInterface, pFileName, mode);
00598 }
00599 ;
00600
00601
00602 #else
00603 # error Unknown C++ library
00604 #endif
00605
00606
00607
00608 filebuf_type *rdbuf() const {
00609 return const_cast<filebuf_type*>(&m_streambuf);
00610 }
00611
00612
00613
00614
00615
00616 bool is_open() const {
00617 return m_streambuf.is_open();
00618 }
00619
00629 void open(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
00630 std::ios_base::openmode mode = std::ios_base::out | std::ios_base::trunc) {
00631 if (!m_streambuf.open(pInterface,pFileName, mode)){
00632 this->setstate(std::ios_base::failbit);
00633 }
00634 else{
00635 this->clear();
00636 }
00637 }
00638
00643 void close() {
00644 if (!m_streambuf.close())
00645 this->setstate(std::ios_base::failbit);
00646 }
00647 };
00648
00649 template<typename CharType, typename Traits> class IDevFileStreamBase
00650 : public std::basic_istream<CharType, Traits> {
00651 public:
00652
00653
00654 typedef IDevFileStreamBuf<CharType, Traits> filebuf_type;
00655 typedef std::basic_ios<CharType, Traits> ios_type;
00656 typedef std::basic_istream<CharType, Traits> istream_type;
00657
00658 private:
00659 filebuf_type m_streambuf;
00660 public:
00661
00662 #if defined (_MSC_VER)
00663 IDevFileStreamBase()
00664 : istream_type(std::_Noinit), m_streambuf() {
00665 this->init(&m_streambuf);
00666 }
00667
00668 IDevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
00669 std::ios_base::openmode mode = std::ios_base::in)
00670 : istream_type(std::_Noinit), m_streambuf() {
00671 this->init(&m_streambuf);
00672 this->open(pInterface, pFileName, mode);
00673 }
00674 ;
00675
00676 #elif defined (__APPLE__)
00677 IDevFileStreamBase()
00678 : istream_type(0), m_streambuf() {
00679 this->init(&m_streambuf);
00680 }
00681
00682 IDevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
00683 std::ios_base::openmode mode = std::ios_base::in)
00684 : istream_type(0), m_streambuf() {
00685 this->init(&m_streambuf);
00686 this->open(pInterface, pFileName, mode);
00687 }
00688 ;
00689
00690 #elif defined (__GNUC__)
00691 IDevFileStreamBase()
00692 : istream_type(), m_streambuf() {
00693 this->init(&m_streambuf);
00694 }
00695
00696 IDevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
00697 std::ios_base::openmode mode = std::ios_base::in)
00698 : istream_type(), m_streambuf() {
00699 this->init(&m_streambuf);
00700 this->open(pInterface, pFileName, mode);
00701 }
00702 ;
00703
00704 #else
00705 # error Unknown C++ library
00706 #endif
00707
00708
00709 filebuf_type *rdbuf() const {
00710 return const_cast<filebuf_type*>(&m_streambuf);
00711 }
00712
00713
00714
00715
00716
00717 bool is_open() const {
00718 return m_streambuf.is_open();
00719 }
00720
00721
00722
00723
00724
00725
00726
00727
00728 void open(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
00729 std::ios_base::openmode mode = std::ios_base::in) {
00730 if (!m_streambuf.open(pInterface,pFileName, mode))
00731 this->setstate(std::ios_base::failbit);
00732 else
00733 this->clear();
00734 }
00735
00739 void close() {
00740 if (!m_streambuf.close())
00741 this->setstate(std::ios_base::failbit);
00742 }
00743 };
00744
00745 typedef ODevFileStreamBase<char, std::char_traits<char> > ODevFileStream;
00746 typedef IDevFileStreamBase<char, std::char_traits<char> > IDevFileStream;
00747 }
00748
00749 #if defined (_MSC_VER)
00750 # pragma warning(pop)
00751 #endif
00752
00753
00754 #endif