collection.h

Go to the documentation of this file.
00001 /* -*- mode: c++; c-basic-offset: 3 -*-
00002  *
00003  * Copyright (c), GREYC.
00004  * All rights reserved
00005  *
00006  * You may use this file under the terms of the BSD license as follows:
00007  *
00008  * "Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are
00010  * met:
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in
00015  *     the documentation and/or other materials provided with the
00016  *     distribution.
00017  *   * Neither the name of the GREYC, nor the name of its
00018  *     contributors may be used to endorse or promote products
00019  *     derived from this software without specific prior written
00020  *     permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00025  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00026  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00028  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00029  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00030  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00032  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
00033  *
00034  *
00035  * For more information, refer to:
00036  * https://clouard.users.greyc.fr/Pandore
00037  */
00038 
00044 #ifndef __PCOLLECTIONH__
00045 #define __PCOLLECTIONH__
00046 
00047 #include <map>
00048 #include <string>
00049 #include <list>
00050 #include "bundled.h"
00051 #include <sstream>
00052 
00053 namespace pandore {
00054 
00055    // Because VisualC++ cannot use template as: method<Type>(...)
00056    // we use the dummy 0 with the convenient casting.
00057    // So: change the prototype to: method(..., (type)0);
00058 #define SETVALUE(name, type, val) SetValue((name), (val))
00059 #define GETVALUE(name, type)      GetValue((name), (type*)0)
00060 
00061 #define SETARRAY(name, type, val, size) SetArray((name), (val), (size))
00062 #define GETARRAY(name, type)      GetArray((name), (type*)0)
00063 #define GETARRAYSIZE(name, type)  GetArraySize((name), (type*)0)
00064 #define GETNARRAYS(name, type, number, minsize_out) GetNArrays((name), (number), (minsize_out), (type*)0)
00065 
00066 #define SETPOBJECT(name, type, val) SetPobject((name), (val))
00067 #define GETPOBJECT(name, type)     GetPobject((name), (type*)0)
00068 
00069 #define SETPARRAY(name, type, val, size) SetPArray((name), (val), (size))
00070 #define GETPARRAY(name, type)      GetPArray((name), (type*)0)
00071 #define GETPARRAYSIZE(name, type)  GetPArraySize((name), (type*)0)
00072 
00073    class Collection;
00074 
00075 
00076    /* @brief A trait that returns the name of the object Collection.
00077     *
00078     * TypeName is a trait that returns the name
00079     * of the object Collection.
00080     */
00081    template<>
00082    struct TypeName< Collection > {
00083          /*
00084           * Returns the name of the type.
00085           * @return     the string with the name.
00086           */
00087          static std::string Name() { return "Collection"; }
00088    };
00089 
00102    class Collection : public Pobject {
00103       public :
00104 
00105          ~Collection() { Delete(); }
00106 
00111          Typobj Type() const { return Po_Collection; }
00112    
00117          std::string Name() const { return TypeName< Collection >::Name(); }
00118    
00123          Pobject* Clone() const {
00124             std::map< std::string, BundledObject * >::const_iterator i;
00125             Collection *tmp = new Collection;
00126             for (i = _objs.begin(); i != _objs.end(); ++i) {
00127                tmp->Set(i->first, i->second->Clone());
00128             }
00129             return tmp;
00130          }
00131 
00137          Collection &operator=( const Collection &col ) {
00138             this->Delete();
00139             std::map< std::string, BundledObject * >::const_iterator i;
00140             for (i = col._objs.begin(); i != col._objs.end(); ++i) {
00141                this->Set(i->first, i->second->Clone());
00142             }
00143             return *this;
00144          }
00145 
00150          void Erase( const std::string &name ) {
00151             std::map< std::string, BundledObject * >::iterator i = _objs.find(name);
00152             if (i == _objs.end()) {
00153                return;  
00154             }
00155             delete i->second;
00156             _objs.erase(i);
00157          }
00158       
00164          void Delete( ) {
00165             std::map< std::string, BundledObject * >::iterator i;
00166             for (i = _objs.begin(); i != _objs.end(); ++i) {
00167                delete i->second;
00168             }
00169             _objs.clear();
00170          }
00171 
00178          void Rename( const std::string &oldname, const std::string &newname ) {
00179             std::map< std::string, BundledObject * >::iterator i = _objs.find(oldname);
00180             if (i == _objs.end()) {
00181                return;
00182             }
00183             _objs[newname] = i->second;
00184             _objs.erase(i);
00185          }
00186 
00193          bool Exists( const std::string &name ) const {
00194             std::map< std::string, BundledObject * >::const_iterator i = _objs.find(name);
00195             return i != _objs.end();
00196          }
00197 
00207          Errc NbOf( const std::string &name, std::string &type_out, Long &number_out, Long &minsize_out ) const;
00208    
00214          std::string GetType( const std::string &name ) const {
00215             BundledObject *bo = Get(name);
00216             if (!bo) { // Panic
00217                std::cerr << "Error: no attribute `" << name.c_str() << "' in collection." << std::endl;
00218                Exit(FAILURE);
00219             }
00220             return bo->Type();
00221          }
00222          
00227          std::list< std::string > List() const {
00228             std::list< std::string > l;
00229             std::map< std::string, BundledObject * >::const_iterator i;
00230             
00231             for (i = _objs.begin(); i != _objs.end(); ++i) {
00232                l.push_back(i->first);
00233             }
00234             return l;
00235          }
00236    
00243          Errc LoadAttributes( FILE * /*file*/ ) {
00244             return SUCCESS;
00245          }
00246    
00252          Errc SaveAttributes( FILE *file ) const {
00253             Long attr = _objs.size(); 
00254             if (Fencode((void*)&attr, sizeof(attr), 1, file) < 1) {
00255                return FAILURE;
00256             }
00257             return SUCCESS;
00258          }
00259 
00265          Errc LoadData( FILE *file );
00266 
00272          Errc SaveData( FILE *file ) const;
00273    
00283          Pobject* Mask( const Pobject * /*mask*/ ) {
00284             return this;
00285          }
00286 
00297          Pobject* UnMask( const Pobject * /*mask*/, const Pobject * /*reference*/ ) {
00298             return this;
00299          }
00300 
00306          void Set( const std::string &name, BundledObject *bo ) {
00307             std::map< std::string, BundledObject * >::iterator i = _objs.find(name);
00308             if (i != _objs.end()) {
00309                delete i->second;
00310                i->second = bo;
00311             } else {
00312                _objs[name] = bo;
00313             }
00314          }
00315          
00321          BundledObject *Get( const std::string &name ) const {
00322             std::map< std::string, BundledObject * >::const_iterator i = _objs.find(name);
00323             return (i != _objs.end()) ? i->second : NULL;
00324          }
00325  
00334          template< typename T >
00335          void SetValue( const std::string &name, const T &val ) {
00336             Set(name, new BundledValue< T >(val));
00337          }
00338    
00348          template< typename T >
00349          T &GetValue( const std::string & name, const T * /*val*/ ) const {
00350             BundledValue<T>* bvp = dynamic_cast< BundledValue<T>* >(Get(name));
00351             if (!bvp) { // Panic
00352                std::cerr << "Error: cannot convert `" << name.c_str() << "' to `" 
00353                          << TypeName<T>::Name().c_str() << "'." << std::endl;
00354                Exit(FAILURE);
00355             }
00356             return bvp->Value();
00357          } 
00358    
00369          template< typename T >
00370          void SetArray( const std::string &name, T *val, Long size ) {
00371             Set(name, new BundledArray< T >(val, size));
00372          }
00373    
00383          template< typename T >
00384          T* GetArray( const std::string &name, const T * /*val*/ ) const {
00385             BundledArray<T>* bap = dynamic_cast< BundledArray<T>* >(Get(name));
00386             if (!bap) { // Panic
00387                std::cerr << "Error: cannot convert `" << name.c_str() << "' to `Array:" 
00388                          << TypeName<T>::Name().c_str() << "'." << std::endl;
00389                Exit(FAILURE);
00390             }
00391             return bap->Array();
00392          } 
00393    
00403          template< typename T >
00404          Long GetArraySize( const std::string &name, const T * /*val*/ ) const {
00405             BundledArray<T>* bap = dynamic_cast< BundledArray<T>* >(Get(name));
00406             if (!bap) { // Panic
00407                std::cerr << "Error: cannot convert `" << name.c_str() << "' to `Array:" 
00408                          << TypeName<T>::Name().c_str() << "'." << std::endl;
00409                Exit(FAILURE);
00410             }
00411             return bap->NbrElements();
00412          }
00413    
00422          template< typename T >
00423          void SetPobject( const std::string &name, T *val ) {
00424             Set(name, new BundledPobject(val));
00425          }
00426    
00435          template< typename T >
00436          T* GetPobject( const std::string &name, const T * /*val*/ ) const {
00437             BundledPobject* bap = dynamic_cast< BundledPobject* >(Get(name));
00438             if (!bap) { // Panic
00439                std::cerr << "Error: cannot convert `" << name.c_str() << "' to `Pobject:" 
00440                          << TypeName<T>::Name().c_str() << "'." << std::endl;
00441                Exit(FAILURE);
00442             }
00443             return (T*)bap->Object();
00444          } 
00445    
00456          template< typename T >
00457          void SetPArray( const std::string &name, T *val, Long size ) {
00458             Set(name, new BundledPArray((Pobject**)val, size));
00459          }
00460    
00471          template< typename T >
00472          T** GetPArray( const std::string &name, const T * /*val*/ ) const {
00473             BundledPArray* bap = dynamic_cast< BundledPArray* >(Get(name));
00474             if (!bap) { // Panic
00475                std::cerr << "Error: cannot convert `" << name.c_str() << "' to `PArray:" 
00476                          << TypeName<T>::Name().c_str() << "'." << std::endl;
00477                Exit(FAILURE);
00478             }
00479             return (T**)bap->PArray();
00480          } 
00481    
00491          template< typename T >
00492          Long GetPArraySize( const std::string &name, const T * /*val*/ ) const {
00493             BundledPArray* bap = dynamic_cast< BundledPArray* >(Get(name));
00494             if (!bap) { // Panic
00495                std::cerr << "Error: cannot convert `" << name.c_str() << "' to `PArray:" 
00496                          << TypeName<T>::Name().c_str() << "'." << std::endl;
00497                Exit(FAILURE);
00498             }
00499             return bap->NbrElements();
00500          } 
00501    
00512          template< typename T >
00513          T** GetNArrays( const std::string &name, Long n, Long &min_out, const T * /*val*/ ) const {
00514             T **tmp = NULL;
00515             Long nin = MAXLONG;
00516             Long n_= MAXLONG;
00517 
00518             tmp = new T*[n];
00519             for (int i = 0; i < n; ++i) {
00520                std::stringstream name_in;
00521                name_in << name << "." << i + 1;
00522                tmp[i] = this->GETARRAY(name_in.str(), T);
00523                n_ = this->GETARRAYSIZE(name_in.str(), T);
00524                if (n_ < nin) {
00525                   nin = n_;
00526                }
00527             }
00528             min_out = nin;
00529             return tmp;
00530          }
00531    
00532       private :
00533          std::map< std::string, BundledObject* > _objs;
00534    };
00535 
00536 } //End of pandore:: namespace
00537 
00538 #endif // __PCOLLECTIONH__

The Pantheon project
Image Team GREYC Laboratory
UMR CNRS 6072 - ENSICAEN - University of Caen, France
This page was last modified on 19 June 2015