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
52typedef 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
79namespace 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_*/
GenICam common utilities.
Forward declarations for GenICam types.
virtual IBoolean & operator=(bool Value)
Set node value.
Definition IBoolean.h:62
Adapter between the std::iostreambuf and the SFNC Features representing the device filesystem.
Definition Filestream.h:104
virtual int64_t getBufSize(const char *pFileName, std::ios_base::openmode mode)
fetch max FileAccessBuffer length for a file
virtual GenICam_streamsize write(const char *buf, int64_t offs, int64_t len, const char *pFileName)
writes data into a file
virtual bool attach(GENAPI_NAMESPACE::INodeMap *pInterface)
attach file protocol adapter to nodemap
virtual bool closeFile(const char *pFileName)
close a file on the device
virtual bool deleteFile(const char *pFileName)
Delete the content of the file.
virtual bool openFile(const char *pFileName, std::ios_base::openmode mode)
open a file on the device
virtual GenICam_streamsize read(char *buf, int64_t offs, GenICam_streamsize len, const char *pFileName)
read data from the device into a buffer
A string class which is a clone of std::string.
Definition GCString.h:51
GENICAM_INTERFACE INodeMap
Interface to access the node map.
Definition INode.h:50