Filestream.h
Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 //  (c) 2007 by Basler Vision Technologies
00003 //  Section: Vision Components
00004 //  Project: GenApi
00005 //  Author:  Thies Moeller
00006 //  $Header$
00007 //
00008 //  License: This file is published under the license of the EMVA GenICam  Standard Group.
00009 //  A text file describing the legal terms is included in  your installation as 'GenICam_license.pdf'.
00010 //  If for some reason you are missing  this file please contact the EMVA or visit the website
00011 //  (http://www.genicam.org) for a full copy.
00012 //
00013 //  THIS SOFTWARE IS PROVIDED BY THE EMVA GENICAM STANDARD GROUP "AS IS"
00014 //  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00015 //  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00016 //  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE EMVA GENICAM STANDARD  GROUP
00017 //  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  SPECIAL,
00018 //  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  LIMITED TO,
00019 //  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  DATA, OR PROFITS;
00020 //  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  THEORY OF LIABILITY,
00021 //  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)
00022 //  ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00023 //  POSSIBILITY OF SUCH DAMAGE.
00024 //-----------------------------------------------------------------------------
00030 #ifndef GENAPI_FILESTREAM_H_
00031 #define GENAPI_FILESTREAM_H_
00032 
00033 // #include <algorithm>
00034 // #include <iostream>
00035 // #include <streambuf>
00036 #include <iomanip>
00037 #include <iosfwd>
00038 #include <cstring> // memcpy
00039 //#include <cstdlib>
00040 //#include <memory>
00041 
00042 #include <Base/GCUtilities.h>
00043 
00044 #include <GenICamFwd.h>
00045 
00046 
00047 #if (__GNUC__)
00048 #  include <unistd.h>
00049 #endif
00050 
00051 // We cannot use std::streamsize because in VC90/Win32 this was int but in VC120 it is int64
00052 // So in order to preserve compiler interoperability we need to use our own declaration
00053 typedef int64_t GenICam_streamsize;
00054 
00055 
00056 // FileProtocolAdapter was a header only class before.
00057 // Since it has been moved to GenApi.dll the user now has to explicitly link against GenApi import library to use it
00058 // To minimize the pain we add the genapi lib  using pragmas
00059 #if defined (_MSC_VER)
00060 
00061 #   include <Base/GCLinkage.h>
00062 
00063 // you can define GENICAM_NO_AUTO_IMPLIB to turn off automatic linkage of genicam libs
00064 // you can define GENICAM_FORCE_AUTO_IMPLIB to enforce automatic linkage of genicam libs
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&); // not implemented
00116         FileProtocolAdapter& operator=(const FileProtocolAdapter&); // not implemented
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         // implementation details
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             // GET next ptr
00256             using std::basic_streambuf<CharType, Traits>::gptr;
00257             // GET end ptr
00258             using std::basic_streambuf<CharType, Traits>::egptr;
00259             // GET begin ptr
00260             using std::basic_streambuf<CharType, Traits>::eback;
00261             // increment next pointer
00262             using std::basic_streambuf<CharType, Traits>::gbump;
00263             // set buffer info
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                 // This already handled by the base class constructor, right?
00270         // std::basic_streambuf<CharType, Traits>::_Init();
00271         };
00272 
00273 
00274         ~IDevFileStreamBuf()
00275         {
00276             // catch and dump all exceptions - we're in a destructor...
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             // get file protocol adapter
00287             m_pAdapter = new FileProtocolAdapter();
00288 
00289             // open file via Adapter
00290             if (!m_pAdapter || !m_pAdapter->attach(pInterface)){
00291                 delete m_pAdapter;
00292                 m_pAdapter = 0;
00293                 return 0;
00294             }
00295 
00296             // open file via Adapter
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             // allocate buffer according to fileinfo
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             // setg(buffer+pbSize, buffer+pbSize, buffer+pbSize);
00318             setg(m_pBuffer, m_pBuffer + m_BufSize,m_pBuffer + m_BufSize);
00319 
00320         #ifdef _MSC_VER
00321         // is this reasonable?
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                 // close file
00340                 if(m_pAdapter->closeFile(m_file.c_str())){
00341                     // no error
00342                     ret = this;
00343                 }
00344                 delete m_pAdapter;
00345                 m_pAdapter = 0;
00346                 // buffer
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         // prohibit copying and assignment
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             // PUT begin
00420             using std::basic_streambuf<CharType, Traits>::pbase;
00421             // PUT next
00422             using std::basic_streambuf<CharType, Traits>::pptr;
00423             // PUT end
00424             using std::basic_streambuf<CharType, Traits>::epptr;
00425             // increment next pointer
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             // create Genicam Access
00440             m_pAdapter = new FileProtocolAdapter();
00441 
00442             // attach to nodemap
00443             if (!m_pAdapter || !m_pAdapter->attach(pInterface)){
00444                 delete m_pAdapter;
00445                 m_pAdapter = 0;
00446                 return 0;
00447             }
00448 
00449 
00450             // open file via Adapter
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             // allocate buffer according to fileinfo
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                 // close file
00488                 if(m_pAdapter->closeFile(m_file)){
00489                     // no error
00490                     if ( syncFailed ){
00491                         ret = 0;
00492                     } else {
00493                     ret = this;
00494                 }
00495                 }
00496                 delete m_pAdapter;
00497                 m_pAdapter = 0;
00498                 // buffer
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; // buffer[bufSize];
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         // prohibit copying assignment
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         // Non-standard types:
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         /* bool is_open() {
00613             return m_streambuf.is_open();
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         // Non-standard types:
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         /* bool is_open() {
00714             return m_streambuf.is_open();
00715         } */
00716 
00717         bool is_open() const {
00718             return m_streambuf.is_open();
00719         }
00720 
00721         /* @brief
00722         *   Open file on device in write mode
00723         *
00724         *  @param  pInterface  NodeMap of the device to which the FileProtocolAdapter is attached
00725         *  @param  pFileName  Name of the file to open
00726         *  @param  mode open mode
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 /*GENAPI_FILESTREAM_H_*/


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Thu Jun 6 2019 18:42:46