GenApi  3.5.1
Filestream.h
1 //-----------------------------------------------------------------------------
2 // (c) 2007 by Basler Vision Technologies
3 // Author: Thies Moeller
4 //
5 // License: This file is published under the license of the EMVA GenICam Standard Group.
6 // A text file describing the legal terms is included in your installation as 'GenICam_license.pdf'.
7 // If for some reason you are missing this file please contact the EMVA or visit the website
8 // (http://www.genicam.org) for a full copy.
9 //
10 // THIS SOFTWARE IS PROVIDED BY THE EMVA GENICAM STANDARD GROUP "AS IS"
11 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
12 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
13 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE EMVA GENICAM STANDARD GROUP
14 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
15 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
17 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
18 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20 // POSSIBILITY OF SUCH DAMAGE.
21 //
22 //-----------------------------------------------------------------------------
28 #ifndef GENAPI_FILESTREAM_H_
29 #define GENAPI_FILESTREAM_H_
30 
31 // #include <algorithm>
32 // #include <iostream>
33 // #include <streambuf>
34 #include <cstring>
35 #include <iomanip>
36 #include <iosfwd>
37 #include <cstring> // memcpy
38 //#include <cstdlib>
39 //#include <memory>
40 
41 #include <Base/GCUtilities.h>
42 
43 #include <GenICamFwd.h>
44 
45 
46 #if (__GNUC__)
47 # include <unistd.h>
48 #endif
49 
50 // We cannot use std::streamsize because in VC90/Win32 this was int but in VC120 it is int64
51 // So in order to preserve compiler interoperability we need to use our own declaration
52 typedef int64_t GenICam_streamsize;
53 
54 
55 // FileProtocolAdapter was a header only class before.
56 // Since it has been moved to GenApi.dll the user now has to explicitly link against GenApi import library to use it
57 // To minimize the pain we add the genapi lib using pragmas
58 #if defined (_MSC_VER)
59 
60 # include <Base/GCLinkage.h>
61 
62 // you can define GENICAM_NO_AUTO_IMPLIB to turn off automatic linkage of genicam libs
63 // you can define GENICAM_FORCE_AUTO_IMPLIB to enforce automatic linkage of genicam libs
64 # if defined(GENICAM_FORCE_AUTO_IMPLIB) || (!defined(GENICAM_NO_AUTO_IMPLIB) && !defined(GENAPI_EXPORTS))
65 # if defined (_WIN32) && defined (_MT )
66 # pragma comment(lib, LIB_NAME( "GenApi" ))
67 # else
68 # error Invalid configuration
69 # endif
70 # endif
71 
72 #endif // _MSC_VER
73 
74 #if defined (_MSC_VER)
75 # pragma warning(push)
76 # pragma warning (disable: 4251) // class 'GenApi::CPointer<T>' needs to have dll-interface to be used by clients of class 'GenICam::FileProtocolAdapter'
77 #endif
78 
79 namespace GENAPI_NAMESPACE
80 {
85  GENICAM_INTERFACE GENAPI_DECL_ABSTRACT IFileProtocolAdapter
86  {
87  virtual bool attach(GENAPI_NAMESPACE::INodeMap * pInterface) = 0;
88  virtual bool openFile(const char * pFileName, std::ios_base::openmode mode) = 0;
89  virtual bool closeFile(const char * pFileName) = 0;
90  virtual GenICam_streamsize write(const char * buf, int64_t offs, int64_t len, const char * pFileName) = 0;
91  virtual GenICam_streamsize read(char * buf, int64_t offs, GenICam_streamsize len, const char * pFileName) = 0;
92  virtual int64_t getBufSize(const char * pFileName, std::ios_base::openmode mode) = 0;
93  virtual bool deleteFile(const char * pFileName) = 0;
94 
95  };
104  class GENAPI_DECL FileProtocolAdapter : public IFileProtocolAdapter {
105  public:
112  virtual ~FileProtocolAdapter();
113  private:
114  FileProtocolAdapter(const FileProtocolAdapter&); // not implemented
115  FileProtocolAdapter& operator=(const FileProtocolAdapter&); // not implemented
116  public:
117 
128  virtual bool attach(GENAPI_NAMESPACE::INodeMap * pInterface );
129 
130 
145  virtual bool openFile(const char * pFileName, std::ios_base::openmode mode);
146 
147 
158  virtual bool closeFile(const char * pFileName);
159 
160 
181  virtual GenICam_streamsize write(const char * buf, int64_t offs, int64_t len, const char * pFileName);
182 
183 
204  virtual GenICam_streamsize read(char * buf, int64_t offs, GenICam_streamsize len, const char * pFileName);
205 
206 
221  virtual int64_t getBufSize(const char * pFileName, std::ios_base::openmode mode);
222 
223 
234  virtual bool deleteFile(const char * pFileName);
235 
236  private:
237  void WaitUntilFileOperationExecuteDone( bool Validate = true );
238 
239  private:
240  // implementation details
241  struct FileProtocolAdapterImpl;
242  FileProtocolAdapterImpl* m_pImpl;
243  };
244 
245 
246  template<typename CharType, typename Traits> class IDevFileStreamBuf
247  : public std::basic_streambuf<CharType, Traits> {
248 
249  typedef Traits traits_type;
250  typedef typename Traits::int_type int_type;
251  typedef typename Traits::char_type char_type;
252  typedef IDevFileStreamBuf<CharType, Traits> filebuf_type;
253 
254  // GET next ptr
255  using std::basic_streambuf<CharType, Traits>::gptr;
256  // GET end ptr
257  using std::basic_streambuf<CharType, Traits>::egptr;
258  // GET begin ptr
259  using std::basic_streambuf<CharType, Traits>::eback;
260  // increment next pointer
261  using std::basic_streambuf<CharType, Traits>::gbump;
262  // set buffer info
263  using std::basic_streambuf<CharType, Traits>::setg;
264 
265  public:
266  IDevFileStreamBuf()
267  : m_pBuffer(0), m_BufSize(0), m_pAdapter(0), m_fpos(0) {
268  // This already handled by the base class constructor, right?
269  // std::basic_streambuf<CharType, Traits>::_Init();
270  };
271 
272 
273  ~IDevFileStreamBuf()
274  {
275  // catch and dump all exceptions - we're in a destructor...
276  try
277  {
278  this->close();
279  }
280  catch(...)
281  {}
282  }
283 
284  filebuf_type *open(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName, std::ios_base::openmode mode = std::ios_base::in ) {
285  // get file protocol adapter
286  m_pAdapter = new FileProtocolAdapter();
287 
288  // open file via Adapter
289  if (!m_pAdapter || !m_pAdapter->attach(pInterface)){
290  delete m_pAdapter;
291  m_pAdapter = 0;
292  return 0;
293  }
294 
295  // open file via Adapter
296  try
297  {
298  if (!(m_pAdapter->openFile(pFileName, mode))){
299  delete m_pAdapter;
300  m_pAdapter = 0;
301  return 0;
302  }
303  }
304  catch (...)
305  {
306  delete m_pAdapter;
307  m_pAdapter = 0;
308  throw;
309  }
310 
311  m_file = pFileName;
312  // allocate buffer according to fileinfo
313  m_BufSize = (GenICam_streamsize)m_pAdapter->getBufSize(m_file.c_str(), mode);
314  m_pBuffer = new char_type[(unsigned int)m_BufSize / sizeof(char_type)];
315 
316  // setg(buffer+pbSize, buffer+pbSize, buffer+pbSize);
317  setg(m_pBuffer, m_pBuffer + m_BufSize,m_pBuffer + m_BufSize);
318 
319  #ifdef _MSC_VER
320  // is this reasonable?
321  std::basic_streambuf<CharType, Traits>::_Init();
322  #endif
323 
324  return this;
325  }
326 
327 
328 
329  bool
330  is_open() const
331  {
332  return m_pAdapter != 0;
333  }
334 
335  filebuf_type *close() {
336  filebuf_type * ret = 0;
337  if (this->is_open()) {
338  // close file
339  if(m_pAdapter->closeFile(m_file.c_str())){
340  // no error
341  ret = this;
342  }
343  delete m_pAdapter;
344  m_pAdapter = 0;
345  // buffer
346  delete[] m_pBuffer;
347  m_pBuffer = 0;
348  }
349  return ret;
350  }
351 
352 
353  protected:
354  int_type underflow() {
355  if (gptr() < egptr() )
356  return traits_type::to_int_type(*gptr());
357 
358  if (buffer_in() < 0)
359  return traits_type::eof();
360  else
361  return traits_type::to_int_type(*gptr());
362 
363  }
364 
365  int_type pbackfail(int_type c) {
366  if (gptr() != eback() || eback()<gptr()) {
367  gbump(-1);
368  if (!traits_type::eq_int_type(c, traits_type::eof() ) )
369  *(gptr()) = static_cast<char_type>(traits_type::not_eof(c));
370  return traits_type::not_eof(c);
371  } else
372  return traits_type::eof();
373  }
374 
375  private:
376  char_type * m_pBuffer;
377  GenICam_streamsize m_BufSize;
378 
380  FileProtocolAdapter * m_pAdapter;
381  int64_t m_fpos;
382 
383 
384 
385  int buffer_in() {
386 
387  GenICam_streamsize retval = m_pAdapter->read(m_pBuffer, m_fpos, m_BufSize, m_file.c_str());
388 
389  if (retval <= 0) {
390  setg(0, 0, 0);
391  return -1;
392  } else {
393  setg(m_pBuffer, m_pBuffer , m_pBuffer + retval);
394  m_fpos += retval;
395  return GENICAM_NAMESPACE::INTEGRAL_CAST2<int, GenICam_streamsize>(retval);
396  }
397  }
398 
399 
400  // prohibit copying and assignment
401  IDevFileStreamBuf(const IDevFileStreamBuf&);
402  IDevFileStreamBuf& operator=(const IDevFileStreamBuf&);
403  };
404 
405 
406  template<typename CharType, typename Traits> class ODevFileStreamBuf
407  : public std::basic_streambuf<CharType, Traits> {
408  typedef Traits traits_type;
409 
410  typedef typename Traits::int_type int_type;
411  typedef typename Traits::char_type char_type;
412  typedef typename Traits::pos_type pos_type;
413  typedef typename Traits::off_type off_type;
414 
415  typedef ODevFileStreamBuf<CharType, Traits> filebuf_type;
416 
417 
418  // PUT begin
419  using std::basic_streambuf<CharType, Traits>::pbase;
420  // PUT next
421  using std::basic_streambuf<CharType, Traits>::pptr;
422  // PUT end
423  using std::basic_streambuf<CharType, Traits>::epptr;
424  // increment next pointer
425  using std::basic_streambuf<CharType, Traits>::pbump;
426 
427  public:
428  ODevFileStreamBuf()
429  : m_pBuffer(0), m_file(0), m_pAdapter(0), m_fpos(0) {
430  }
431 
432  ~ODevFileStreamBuf() {
433  this->close();
434  }
435 
436  filebuf_type *open(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName, std::ios_base::openmode mode) {
437 
438  FileProtocolAdapter *pAdapter = NULL;
439  char_type *pBuffer = NULL;
440  filebuf_type *pFileBuf = NULL;
441  try
442  {
443  pAdapter = new FileProtocolAdapter();
444  if (pAdapter)
445  {
446  if (pAdapter->attach( pInterface ))
447  {
448  if (pAdapter->openFile( pFileName, mode ))
449  {
450  if (int64_t bufSize = pAdapter->getBufSize( pFileName, mode ))
451  {
452  pBuffer = new char_type[GENICAM_NAMESPACE::INTEGRAL_CAST<size_t>( bufSize ) / sizeof( char_type )];
453  if (pBuffer)
454  {
455  std::basic_streambuf<CharType, Traits>::setp( pBuffer, pBuffer + bufSize );
456  m_file = pFileName;
457  std::swap( m_pAdapter, pAdapter );
458  std::swap( m_pBuffer, pBuffer );
459  pFileBuf = this;
460  }
461  }
462  }
463  }
464  }
465  }
466  catch (...)
467  {
468  delete pAdapter;
469  delete [] pBuffer;
470  throw;
471  }
472  delete pAdapter;
473  delete [] pBuffer;
474 
475  return pFileBuf;
476 
477  }
478 
479  bool
480  is_open() const {
481  return m_pAdapter != 0;
482  }
483 
484  filebuf_type *close() {
485  filebuf_type * ret = 0;
486  bool syncFailed = false;
487  if (this->is_open()) {
488  if (sync()){
489  syncFailed = true;
490  };
491  // close file
492  if(m_pAdapter->closeFile(m_file)){
493  // no error
494  if ( syncFailed ){
495  ret = 0;
496  } else {
497  ret = this;
498  }
499  }
500  delete m_pAdapter;
501  m_pAdapter = 0;
502  // buffer
503  delete[] m_pBuffer;
504  m_pBuffer = 0;
505  }
506  return ret;
507  }
508 
509  protected:
510  GenICam_streamsize xsputn(const char_type * s, GenICam_streamsize n) {
511  if (n < epptr() - pptr() ) {
512  memcpy( pptr(), s, (size_t)(n * sizeof(char_type)));
513  pbump( GENICAM_NAMESPACE::INTEGRAL_CAST2<int>(n) );
514  return n;
515  } else {
516  for (GenICam_streamsize i = 0; i<n; ++i) {
517  if (traits_type::eq_int_type(std::basic_streambuf<CharType, Traits>::sputc(s[i]), traits_type::eof()))
518  return i;
519  }
520  return n;
521  }
522 
523  }
524  int_type overflow(int_type c = traits_type::eof()) {
525  if (buffer_out() < 0) {
526  return traits_type::eof();
527  } else {
528  if (!traits_type::eq_int_type (c, traits_type::eof() ) )
529  return std::basic_streambuf<CharType, Traits>::sputc(static_cast<char_type>(c));
530  else
531  return traits_type::not_eof(c);
532  }
533 
534  }
535  int sync() {
536  return GENICAM_NAMESPACE::INTEGRAL_CAST<int>(buffer_out());
537  }
538 
539  private:
540  char_type * m_pBuffer; // buffer[bufSize];
541  const char * m_file;
542  FileProtocolAdapter * m_pAdapter;
543  int64_t m_fpos;
544 
545  int64_t buffer_out() {
546  int64_t cnt = pptr() - pbase();
547 
548  int64_t retval;
549  int64_t res = m_pAdapter->write(m_pBuffer, m_fpos, cnt, m_file);
550 
551  if (res != cnt) {
552  retval = -1;
553  } else {
554  retval = 0;
555  }
556  m_fpos += res;
557 
558  pbump(- GENICAM_NAMESPACE::INTEGRAL_CAST<int>(cnt));
559  return retval;
560  }
561 
562  // prohibit copying assignment
563  ODevFileStreamBuf(const ODevFileStreamBuf&);
564  ODevFileStreamBuf & operator =(const ODevFileStreamBuf&);
565  };
566 
567  template<typename CharType, typename Traits> class ODevFileStreamBase
568  : public std::basic_ostream<CharType, Traits> {
569  public:
570  // Non-standard types:
571  typedef ODevFileStreamBuf<CharType, Traits> filebuf_type;
572  typedef std::basic_ios<CharType, Traits> ios_type;
573  typedef std::basic_ostream<CharType, Traits> ostream_type;
574 
575  private:
576  filebuf_type m_streambuf;
577  public:
578 
579 #if defined (_MSC_VER)
580  ODevFileStreamBase()
581  : ostream_type(std::_Noinit), m_streambuf() {
582  this->init(&m_streambuf);
583  }
584 
585  ODevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName, std::ios_base::openmode mode = std::ios_base::out|std::ios_base::trunc)
586  : ostream_type(std::_Noinit), m_streambuf() {
587  this->init(&m_streambuf);
588  this->open(pInterface, pFileName, mode);
589  }
590  ;
591 
592 #elif defined (__GNUC__)
593  ODevFileStreamBase()
594  : ostream_type(), m_streambuf() {
595  this->init(&m_streambuf);
596  }
597 
598  ODevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName, std::ios_base::openmode mode = std::ios_base::out|std::ios_base::trunc)
599  : ostream_type(), m_streambuf() {
600  this->init(&m_streambuf);
601  this->open(pInterface, pFileName, mode);
602  }
603  ;
604 
605 
606 #else
607 # error Unknown C++ library
608 #endif
609 
610 
611 
612  filebuf_type *rdbuf() const {
613  return const_cast<filebuf_type*>(&m_streambuf);
614  }
615 
616  /* bool is_open() {
617  return m_streambuf.is_open();
618  } */
619 
620  bool is_open() const {
621  return m_streambuf.is_open();
622  }
623 
633  void open(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
634  std::ios_base::openmode mode = std::ios_base::out | std::ios_base::trunc) {
635  if (!m_streambuf.open(pInterface,pFileName, mode)){
636  this->setstate(std::ios_base::failbit);
637  }
638  else{
639  this->clear();
640  }
641  }
642 
647  void close() {
648  if (!m_streambuf.close())
649  this->setstate(std::ios_base::failbit);
650  }
651  };
652 
653  template<typename CharType, typename Traits> class IDevFileStreamBase
654  : public std::basic_istream<CharType, Traits> {
655  public:
656 
657  // Non-standard types:
658  typedef IDevFileStreamBuf<CharType, Traits> filebuf_type;
659  typedef std::basic_ios<CharType, Traits> ios_type;
660  typedef std::basic_istream<CharType, Traits> istream_type;
661 
662  private:
663  filebuf_type m_streambuf;
664  public:
665 
666 #if defined (_MSC_VER)
667  IDevFileStreamBase()
668  : istream_type(std::_Noinit), m_streambuf() {
669  this->init(&m_streambuf);
670  }
671 
672  IDevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
673  std::ios_base::openmode mode = std::ios_base::in)
674  : istream_type(std::_Noinit), m_streambuf() {
675  this->init(&m_streambuf);
676  this->open(pInterface, pFileName, mode);
677  }
678  ;
679 
680 #elif defined (__APPLE__)
681  IDevFileStreamBase()
682  : istream_type(0), m_streambuf() {
683  this->init(&m_streambuf);
684  }
685 
686  IDevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
687  std::ios_base::openmode mode = std::ios_base::in)
688  : istream_type(0), m_streambuf() {
689  this->init(&m_streambuf);
690  this->open(pInterface, pFileName, mode);
691  }
692  ;
693 
694 #elif defined (__GNUC__)
695  IDevFileStreamBase()
696  : istream_type(), m_streambuf() {
697  this->init(&m_streambuf);
698  }
699 
700  IDevFileStreamBase(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
701  std::ios_base::openmode mode = std::ios_base::in)
702  : istream_type(), m_streambuf() {
703  this->init(&m_streambuf);
704  this->open(pInterface, pFileName, mode);
705  }
706  ;
707 
708 #else
709 # error Unknown C++ library
710 #endif
711 
712 
713  filebuf_type *rdbuf() const {
714  return const_cast<filebuf_type*>(&m_streambuf);
715  }
716 
717  /* bool is_open() {
718  return m_streambuf.is_open();
719  } */
720 
721  bool is_open() const {
722  return m_streambuf.is_open();
723  }
724 
725  /* @brief
726  * Open file on device in write mode
727  *
728  * @param pInterface NodeMap of the device to which the FileProtocolAdapter is attached
729  * @param pFileName Name of the file to open
730  * @param mode open mode
731  */
732  void open(GENAPI_NAMESPACE::INodeMap * pInterface, const char * pFileName,
733  std::ios_base::openmode mode = std::ios_base::in) {
734  if (!m_streambuf.open(pInterface,pFileName, mode))
735  this->setstate(std::ios_base::failbit);
736  else
737  this->clear();
738  }
739 
743  void close() {
744  if (!m_streambuf.close())
745  this->setstate(std::ios_base::failbit);
746  }
747  };
748 
749  typedef ODevFileStreamBase<char, std::char_traits<char> > ODevFileStream;
750  typedef IDevFileStreamBase<char, std::char_traits<char> > IDevFileStream;
751 }
752 
753 #if defined (_MSC_VER)
754 # pragma warning(pop)
755 #endif
756 
757 
758 #endif /*GENAPI_FILESTREAM_H_*/
virtual int64_t getBufSize(const char *pFileName, std::ios_base::openmode mode)
fetch max FileAccessBuffer length for a file
virtual bool openFile(const char *pFileName, std::ios_base::openmode mode)
open a file on the device
Adapter between the std::iostreambuf and the SFNC Features representing the device filesystem...
Definition: Filestream.h:104
virtual GenICam_streamsize write(const char *buf, int64_t offs, int64_t len, const char *pFileName)
writes data into a file
virtual GenICam_streamsize read(char *buf, int64_t offs, GenICam_streamsize len, const char *pFileName)
read data from the device into a buffer
virtual IBoolean & operator=(bool Value)
Set node value.
Definition: IBoolean.h:62
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT IFileProtocolAdapter
Adapter between the std::iostreambuf and the SFNC Features representing the device filesystem...
Definition: Filestream.h:86
Forward declarations for GenICam types.
GENICAM_INTERFACE INodeMap
Interface to access the node map.
Definition: INode.h:50
A string class which is a clone of std::string.
Definition: GCString.h:50
virtual bool attach(GENAPI_NAMESPACE::INodeMap *pInterface)
attach file protocol adapter to nodemap
Definition: ChunkAdapter.h:37
GenICam common utilities.