123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- //-----------------------------------------------------------------------------
- // (c) 2007 by National Instruments
- // Project: GenApi
- // Author: Eric Gross
- // $Header$
- //
- // License: This file is published under the license of the EMVA GenICam Standard Group.
- // A text file describing the legal terms is included in your installation as 'GenICam_license.pdf'.
- // If for some reason you are missing this file please contact the EMVA or visit the website
- // (http://www.genicam.org) for a full copy.
- //
- // THIS SOFTWARE IS PROVIDED BY THE EMVA GENICAM STANDARD GROUP "AS IS"
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE EMVA GENICAM STANDARD GROUP
- // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- //-----------------------------------------------------------------------------
- /*!
- \file
- \brief Definition of interface IPersistScript and class CFeatureBag
- \ingroup GenApi_PublicUtilities
- */
- #ifndef _GENICAM_PERSISTENCE_H
- #define _GENICAM_PERSISTENCE_H
- #include <GenApi/Types.h>
- #include <GenApi/Pointer.h>
- #include <GenApi/GenApiDll.h>
- #include <list>
- #include <iostream>
- namespace GENAPI_NAMESPACE
- {
- //! Basic interface to persist values to
- interface GENAPI_DECL_ABSTRACT IPersistScript
- {
- //! sets information about the node map
- virtual void SetInfo(const GENICAM_NAMESPACE::gcstring &Info) = 0;
- //! Stores a feature
- virtual void PersistFeature(IValue& item) = 0;
- };
- //! Bag holding streamable features of a nodetree
- class GENAPI_DECL CFeatureBag : public IPersistScript
- {
- public:
- //! sets information about the node map
- virtual void SetInfo(const GENICAM_NAMESPACE::gcstring &Info);
- //! Stores a feature
- virtual void PersistFeature(IValue& item);
- //! Loads the features from the bag to the node tree
- //! \param pNodeMap The node map to load into
- //! \param Verify If true, all streamable features are read back
- //! \param pErrorList If an error occurs during loading the error message is stored in the list and the loading continues
- /*! For Verify=true the list of names in the feature bag is replayed again.
- If a node is a selector it's value is set to the value from the feature bag
- If not the value is read from the camera and compared with the value from the feature bag.
- */
- bool LoadFromBag(INodeMap *pNodeMap, bool Verify = true, GENICAM_NAMESPACE::gcstring_vector *pErrorList = NULL);
- /*! \brief Stores the streamable nodes to this feature bag
- \param pNodeMap The node map to persist
- \param MaxNumPersistSkriptEntries The max number of entries in the container; -1 means unlimited
- \param pFeatureFilter List of valid feature; all feature if NULL.
- \return number of entries in the bag
- */
- int64_t StoreToBag(INodeMap *pNodeMap, const int MaxNumPersistSkriptEntries = -1, GENICAM_NAMESPACE::gcstring_vector *pFeatureFilter = NULL);
- //! compares the content of two feature bags
- bool operator==(const CFeatureBag &FeatureBag) const;
- GENICAM_NAMESPACE::gcstring ToString();
- virtual void Destroy();
- virtual const GENICAM_NAMESPACE::gcstring& GetBagName( void ) const;
- virtual void SetBagName(const GENICAM_NAMESPACE::gcstring& bagName);
- //! fills the bag from a stream
- friend std::istream& operator >>(std::istream &is, CFeatureBag &FeatureBag);
- //! puts the bag into a stream
- friend std::ostream& operator <<(std::ostream &os, const CFeatureBag &FeatureBag);
- private:
- //! The name of the feature bag
- GENICAM_NAMESPACE::gcstring m_BagName;
- GENICAM_NAMESPACE::gcstring_vector m_Names;
- GENICAM_NAMESPACE::gcstring_vector m_Values;
- //! String describing the node map
- GENICAM_NAMESPACE::gcstring m_Info;
- bool LoadFromBagInternal(INodeMap *pNodeMap, bool Verify /* = true */, GENICAM_NAMESPACE::gcstring_vector *pErrorList = NULL);
- int64_t StoreToBagInternal(INodeMap *pNodeMap, const int MaxNumPersistSkriptEntries = -1, GENICAM_NAMESPACE::gcstring_vector *pFeatureFilter = NULL);
- friend class CFeatureBagger;
- };
- //! the magic GUID which indicates that the file or buffer is a GenApi stream created by the CFeatureBag class. Must be the first entry of a file or section.
- #define GENAPI_PERSISTENCE_MAGIC "{05D8C294-F295-4dfb-9D01-096BD04049F4}"
- //! the magic GUID which indicates that the file is a GenApi stream file created by the CFeatureBagger class. Must be the first entry of a file.
- #define GENAPI_PERSISTENCE_MAGIC_FEATUREBAGGER "{4709CB3C-7322-4460-84C3-DA11DDA09939}"
- //! Helper function ignoring lines starting with comment character '#'
- // note: this method must be inlined because it uses istream in the parameter list
- inline std::istream& EatComments(std::istream &is)
- {
- if( is.eof() )
- {
- return is;
- }
- char FirstCharacter = static_cast<char>(is.peek());
- while( FirstCharacter == '#' )
- {
- is.ignore(1024, '\n');
- FirstCharacter = static_cast<char>(is.peek());
- }
- return is;
- }
- #ifndef GENAPI_DONT_USE_DEFAULT_PERSISTENCE_FILE_FORMAT
- //! reads in persistent data from a stream
- // note: this method must be inlined because it uses istream in the parameter list
- // note: May not be used as inline if called against a library where it is already compiled.
- inline std::istream& operator >>(std::istream &is, CFeatureBag &FeatureBag)
- {
- if( is.eof() )
- {
- throw RUNTIME_EXCEPTION("The stream is eof");
- }
- FeatureBag.m_Names.clear();
- FeatureBag.m_Values.clear();
- const int BufferSize = 1024;
- char Buffer[BufferSize] = {0};
- // Check the magic
- is.getline(Buffer, BufferSize, '\n');
- GENICAM_NAMESPACE::gcstring FirstLine(Buffer);
- GENICAM_NAMESPACE::gcstring MagicGUID(GENAPI_PERSISTENCE_MAGIC);
- if( GENICAM_NAMESPACE::gcstring::_npos() == FirstLine.find(MagicGUID) )
- {
- MagicGUID = GENICAM_NAMESPACE::gcstring(GENAPI_PERSISTENCE_MAGIC_FEATUREBAGGER);
- if( GENICAM_NAMESPACE::gcstring::_npos() == FirstLine.find(MagicGUID) )
- {
- throw RUNTIME_EXCEPTION("The stream is not a GenApi feature stream since it is missing the magic GUID in the first line");
- }
- throw RUNTIME_EXCEPTION("The stream has been created using the CFeatureBagger class thus must be restored using the CFeatureBagger class as well");
- }
- EatComments( is );
- char Name[BufferSize] = {0};
- GENICAM_NAMESPACE::gcstring Value("");
- while( !is.eof() )
- {
- is.getline(Name, BufferSize, '\t');
- if (is.fail()) // if reading from stream failed -> stop reading!
- {
- break;
- }
- GENICAM_NAMESPACE::getline(is, Value);
- if (is.fail()) // if reading from stream failed -> stop reading!
- {
- break;
- }
- FeatureBag.m_Names.push_back(Name);
- FeatureBag.m_Values.push_back(Value);
- Name[0] = '\0';
- Value = "";
- EatComments( is );
- }
- return is;
- }
- //! writes out persistent data to a stream
- // note: this method must be inlined because it uses ostream in the parameter list
- // note: May not be used as inline if called against a library where it is already compiled.
- inline std::ostream& operator <<(std::ostream &os, const CFeatureBag &FeatureBag)
- {
- os << "# " GENAPI_PERSISTENCE_MAGIC "\n";
- if( !FeatureBag.m_Info.empty() )
- {
- os << "# GenApi persistence file (version " << GENAPI_VERSION_MAJOR << "." << GENAPI_VERSION_MINOR << "." << GENAPI_VERSION_SUBMINOR << ")\n";
- os << "# " << FeatureBag.m_Info << "\n";
- }
- // This can actually never happen the way the code is written right now, but...
- assert(FeatureBag.m_Names.size() == FeatureBag.m_Values.size());
- GENICAM_NAMESPACE::gcstring_vector::const_iterator pName = FeatureBag.m_Names.begin();
- GENICAM_NAMESPACE::gcstring_vector::const_iterator pValue = FeatureBag.m_Values.begin();
- const GENICAM_NAMESPACE::gcstring_vector::const_iterator endNames = FeatureBag.m_Names.end();
- for( ; pName != endNames; ++pName, ++pValue )
- {
- const GENICAM_NAMESPACE::gcstring Name(*pName);
- const GENICAM_NAMESPACE::gcstring Value(*pValue);
- os << Name << "\t" << Value << "\n";
- }
- return os;
- }
- #endif // #ifndef GENAPI_DONT_USE_DEFAULT_PERSISTENCE_FILE_FORMAT
- //! Class use to bag features
- class GENAPI_DECL CFeatureBagger
- {
- public:
- class GENAPI_DECL const_iterator
- {
- // Ctor / Dtor
- // -------------------------------------------------------------------------
- public:
- const_iterator(CFeatureBag **ppBag = NULL);
- // Operators
- // -------------------------------------------------------------------------
- public:
- const CFeatureBag & operator * (void) const;
- const CFeatureBag * operator -> (void) const;
- const_iterator & operator ++ (void);
- const_iterator operator ++ (int);
- const_iterator & operator += (intptr_t iInc);
- const_iterator operator + (intptr_t iInc) const;
- intptr_t operator - (const const_iterator &iter) const;
- bool operator == (const const_iterator &iter) const;
- bool operator != (const const_iterator &iter) const;
- // Member
- // -------------------------------------------------------------------------
- protected:
- CFeatureBag **_ppb;
- };
- explicit CFeatureBagger();
- virtual ~CFeatureBagger();
- /*! \brief Stores the streamable nodes to this feature bags in different device configurations
- \param handleDefaultNodeMap Stores the current nodemap if True
- \param handleUserSets Store all user sets if True
- \param handleSequencerSets Store all sequencer sets if True
- \param pNodeMap The node map to persist
- \param MaxNumPersistSkriptEntries The max number of entries in the container. -1 means unlimited
- \return number of bags
- */
- size_t Bag(INodeMap *pNodeMap, bool handleDefaultNodeMap = true, bool handleUserSets = false, bool handleSequencerSets = false, const int MaxNumPersistSkriptEntries = -1);
- //! Loads the features from the bag to the node tree
- //! \param Verify If true, all streamable features are read back
- //! \param pErrorList If an error occurs during loading the error message is stored in the list and the loading continues
- /*! For Verify=true the list of names in the feature bag is replayed again.
- If a node is a selector it's value is set to the value from the feature bag
- If not the value is read from the camera and compared with the value from the feature bag.
- */
- bool UnBag(INodeMap *pNodeMap, bool Verify = true, GENICAM_NAMESPACE::gcstring_vector *pErrorList = NULL);
- //! sets information about the node map
- virtual void SetInfo(const GENICAM_NAMESPACE::gcstring &Info);
- // Element access
- // ---------------------------------------------------------------------------
- virtual const_iterator begin(void) const;
- virtual const_iterator end(void) const;
- virtual const CFeatureBag& at(size_t uiIndex) const;
- virtual size_t size(void) const;
- //! puts the bags into a stream
- friend std::ostream& operator <<(std::ostream &os, const CFeatureBagger &featureBagger);
- //! reads the bags from a stream
- friend std::istream& operator >>(std::istream &is, CFeatureBagger &featureBagger);
- private:
- CFeatureBag& AddBag(const GENICAM_NAMESPACE::gcstring &bagName);
- void DeleteAllBags( void );
- template<class _Ty>
- void UnBagCustomAction(INodeMap *pNodeMap, _Ty setNodePtr, const GENICAM_NAMESPACE::gcstring& setNodeValue, CCommandPtr saveNodePtr );
- void *m_pBags;
- //! String describing the node map
- GENICAM_NAMESPACE::gcstring m_Info;
- };
- #ifndef GENAPI_DONT_USE_DEFAULT_PERSISTENCE_FILE_FORMAT
- //! writes out persistent data to a stream
- // note: this method must be inlined because it uses ostream in the parameter list
- // note: May not be used as inline if called against a library where it is already compiled.
- inline std::ostream& operator <<(std::ostream &os, const CFeatureBagger &featureBagger)
- {
- os << "# " GENAPI_PERSISTENCE_MAGIC_FEATUREBAGGER "\n";
- if( !featureBagger.m_Info.empty() )
- {
- os << "# GenApi CFeatureBagger persistence file (version " << GENAPI_VERSION_MAJOR << "." << GENAPI_VERSION_MINOR << "." << GENAPI_VERSION_SUBMINOR << ")\n";
- os << "# " << featureBagger.m_Info << "\n";
- }
- CFeatureBagger::const_iterator it;
- for (it = featureBagger.begin(); it != featureBagger.end(); it++)
- {
- os << "[" << (*it).GetBagName() << "]\n";
- os << (*it);
- }
- return os;
- }
- //! reads back persistent data from a stream
- // note: this method must be inlined because it uses istream in the parameter list
- // note: May not be used as inline if called against a library where it is already compiled.
- inline std::istream& operator >> (std::istream &is, CFeatureBagger &featureBagger)
- {
- if (is.eof())
- {
- throw RUNTIME_EXCEPTION("The stream is eof");
- }
- // Check the magic
- const int BufferSize = 1024;
- char Buffer[BufferSize] = { 0 };
- is.getline(Buffer, BufferSize, '\n');
- GENICAM_NAMESPACE::gcstring FirstLine(Buffer);
- GENICAM_NAMESPACE::gcstring MagicGUID(GENAPI_PERSISTENCE_MAGIC_FEATUREBAGGER);
- bool boCFeatureBagFormatDetected = false;
- if( GENICAM_NAMESPACE::gcstring::_npos() == FirstLine.find(MagicGUID) )
- {
- MagicGUID = GENICAM_NAMESPACE::gcstring(GENAPI_PERSISTENCE_MAGIC);
- if( GENICAM_NAMESPACE::gcstring::_npos() == FirstLine.find(MagicGUID) )
- {
- throw RUNTIME_EXCEPTION("The stream is not a GenApi feature stream since it is missing the magic GUID in the first line");
- }
- boCFeatureBagFormatDetected = true;
- }
- std::stringstream currentBagData;
- if (boCFeatureBagFormatDetected)
- {
- currentBagData << FirstLine;
- }
- else
- {
- EatComments( is );
- }
- featureBagger.DeleteAllBags();
- // Allow to digest the 'CFeatureBag' format using the 'CFeatureBagger' class!
- CFeatureBag *pBag = boCFeatureBagFormatDetected ? &featureBagger.AddBag("All") : NULL;
- while (!is.eof())
- {
- GENICAM_NAMESPACE::gcstring line;
- GENICAM_NAMESPACE::getline(is, line);
- if (is.fail()) // if reading from stream failed -> stop reading!
- {
- break;
- }
- if (!line.empty() && (line[0] == '['))
- {
- if (!currentBagData.str().empty())
- {
- if (pBag)
- {
- currentBagData >> (*pBag);
- }
- currentBagData.str("");
- currentBagData.clear();
- pBag = NULL;
- }
- // this is the beginning of a new section
- const size_t pos = line.find_first_of("]");
- const GENICAM_NAMESPACE::gcstring bagName(line.substr(1, pos - 1));
- if( !bagName.empty() )
- {
- pBag = &featureBagger.AddBag(bagName);
- }
- }
- else
- {
- currentBagData << line << "\n";
- }
- }
- if (!currentBagData.str().empty() && pBag)
- {
- currentBagData >> (*pBag);
- }
- return is;
- }
- #endif // #ifndef GENAPI_DONT_USE_DEFAULT_PERSISTENCE_FILE_FORMAT
- }
- #endif //_GENICAM_PERSISTENCE_H
|