storage.h

Go to the documentation of this file.
00001 #ifndef VVELIB_STORAGE_STORAGE_H
00002 #define VVELIB_STORAGE_STORAGE_H
00003 
00009 #include <config.h>
00010 #include <QString>
00011 #include <cstddef>
00012 #include <string>
00013 #include <vector>
00014 #include <list>
00015 #include <map>
00016 #include <set>
00017 #include <util/unorderedmap.h>
00018 
00019 #ifdef USE_HASH
00020 #include <QHash>
00021 
00022 namespace std
00023 {
00024 #ifdef CXX_NEEDS_TR1
00025   namespace tr1
00026   {
00027 #endif
00028     template <>
00029     struct hash<QString>
00030     {
00031       size_t operator()(const QString& s) const
00032       {
00033         return qHash(s);
00034       }
00035     };
00036 #ifdef CXX_NEEDS_TR1
00037   }
00038 #endif
00039 }
00040 #endif
00041 
00042 class Model;
00043 
00179 namespace storage
00180 {
00181 
00185   enum Options
00186   {
00188     TypeChecking
00189   };
00190 
00194   enum TypeCheckingOption
00195   {
00197     TCO_Exact,
00204     TCO_Strict,
00211     TCO_Permissive,
00215     TCO_PermissiveNoWarning,
00220     TCO_NoCheck
00221   };
00222 
00226   enum STORAGE_ERROR
00227   {
00233     NO__ERROR = 0,
00239     IO_ERROR,
00246     BAD_CONTENT,
00254     TYPE_CHECK_ERROR,
00262     TYPE_CONVERSION_ERROR,
00266     NO_FIELD_ERROR,
00273     REFERENCE_ERROR,
00279     USER_ERROR,
00283     UNKNOWN_ERROR
00284   };
00285 
00286   template <typename T>
00287   struct pointer_traits;
00288 
00289   template <typename T>
00290   struct pointer_traits<T*>
00291   {
00292     typedef T pointee;
00293   };
00294 
00295   template <typename Ptr>
00296   Ptr create_object(Ptr const& p)
00297   {
00298     if(p != 0)
00299       delete p;
00300     typedef typename pointer_traits<Ptr>::pointee pointee;
00301     return new pointee();
00302   }
00303 
00304   struct Reference
00305   {
00306     virtual ~Reference() {}
00307     Reference()
00308       : count(1)
00309     {}
00310 
00311     int count;
00312   };
00313 
00314   template <typename Ptr>
00315   struct RealReference : public Reference
00316   {
00317     RealReference(Ptr p=Ptr())
00318       : Reference()
00319       , value(p)
00320     { }
00321 
00322     Ptr value;
00323   };
00324 
00325   struct ReferencePtr
00326   {
00327     ReferencePtr(Reference* r = 0)
00328       : ptr(r)
00329     {
00330     }
00331 
00332     ReferencePtr(const ReferencePtr& copy)
00333       : ptr(copy.ptr)
00334     {
00335       if(ptr)
00336         ptr->count++;
00337     }
00338 
00339     void release()
00340     {
00341       if(ptr)
00342       {
00343         ptr->count--;
00344         if(ptr->count == 0)
00345         {
00346           delete ptr;
00347           ptr = 0;
00348         }
00349       }
00350     }
00351 
00352     ~ReferencePtr()
00353     {
00354       release();
00355     }
00356 
00357     bool operator==(const ReferencePtr& other) const
00358     {
00359       return ptr == other.ptr;
00360     }
00361 
00362     ReferencePtr& operator=(const ReferencePtr& other)
00363     {
00364       if(other.ptr == ptr)
00365         return *this;
00366       release();
00367       ptr = other.ptr;
00368       if(ptr)
00369         ptr->count++;
00370       return *this;
00371     }
00372 
00373     Reference *ptr;
00374   };
00375 
00376   template <typename Ptr>
00377   ReferencePtr make_reference(Ptr& p)
00378   {
00379     return ReferencePtr(new RealReference<Ptr>(p));
00380   }
00381 
00387   class VVEStorage
00388   {
00389   public:
00391     typedef ptrdiff_t reference_t;
00392 
00393 #ifdef USE_HASH
00394     typedef std::unordered_map<size_t, ReferencePtr> ref_map;
00395     typedef std::unordered_map<QString, ref_map> ref_map_type;
00396 #else
00397     typedef std::map<size_t, ReferencePtr> ref_map;
00398     typedef std::map<QString, ref_map> ref_map_type;
00399 #endif
00400 
00401     ref_map_type references;
00402 
00403     VVEStorage();
00405     virtual ~VVEStorage() {}
00406 
00413     virtual bool setOption(int , int ) { return false; }
00414 
00421     virtual bool startCompound(const QString& name) = 0;
00425     virtual bool endCompound() = 0;
00426 
00432     virtual bool ignore(const QString& /*name*/ ) { return true; }
00433 
00448     virtual int startReference(const QString& name, const QString& ref_type, reference_t ref) = 0;
00452     virtual bool endReference() = 0;
00453 
00457     virtual void clear();
00458 
00462     virtual bool serialize(const QString& filename, Model* model) = 0;
00463 
00467     virtual bool reader() = 0;
00471     virtual bool writer() = 0;
00472 
00474 
00475 
00477     virtual bool field(const QString& name, bool& value) = 0;
00478 #ifndef _MSC_VER
00479 
00480     virtual bool field(const QString& name, wchar_t& value) = 0;
00481 #endif
00482 
00483     virtual bool field(const QString& name, char& value) = 0;
00485     virtual bool field(const QString& name, signed char& value) = 0;
00487     virtual bool field(const QString& name, short& value) = 0;
00489     virtual bool field(const QString& name, int& value) = 0;
00491     virtual bool field(const QString& name, long& value) = 0;
00493     virtual bool field(const QString& name, long long& value) = 0;
00495     virtual bool field(const QString& name, unsigned char& value) = 0;
00497     virtual bool field(const QString& name, unsigned short& value) = 0;
00499     virtual bool field(const QString& name, unsigned int& value) = 0;
00501     virtual bool field(const QString& name, unsigned long& value) = 0;
00503     virtual bool field(const QString& name, unsigned long long& value) = 0;
00505     virtual bool field(const QString& name, float& value) = 0;
00507     virtual bool field(const QString& name, double& value) = 0;
00509     virtual bool field(const QString& name, long double& value) = 0;
00511     virtual bool field(const QString& name, QString& value) = 0;
00513     virtual bool field(const QString& name, std::string& value) = 0;
00515 
00525     template <typename T>
00526     bool field(const QString& name, T& value)
00527     {
00528       bool result = false;
00529       if(startCompound(name))
00530       {
00531         result = serialization(*this, value);
00532         if(!result)
00533           return false;
00534         result &= endCompound();
00535       }
00536       return result;
00537     }
00538 
00549     template <typename T, typename Model>
00550     bool field(const QString& name, T& value, Model* model)
00551     {
00552       bool result = false;
00553       bool no_name = name.isEmpty();
00554       if(startCompound(name))
00555       {
00556         result = model->serialize(*this, value);
00557         result &= endCompound();
00558       }
00559       return result;
00560     }
00561 
00570     template <typename Ptr>
00571     bool reference(const QString& name, const QString& type, Ptr& value)
00572     {
00573       int ref = startReference(name, type, (char*)(&*value) - (char*)0);
00574       if(ref < 0)
00575         return false;
00576       if(!find_reference(type, ref, value))
00577       {
00578         if(reader())
00579           value = create_object(value);
00580         if(!field("", *value))
00581         {
00582           return false;
00583         }
00584         references[type][ref] = make_reference(value);
00585       }
00586       return endReference();
00587     }
00588 
00597     template <typename Ptr>
00598     bool reference(const QString& name, const QString& type, Ptr& value, Model* model)
00599     {
00600       int ref = startReference(name, type, (char*)(&*value) - (char*)0);
00601       if(ref < 0)
00602         return false;
00603       if(!find_reference(type, ref, value))
00604       {
00605         if(reader())
00606           value = create_object(value);
00607         if(!field("", *value, model))
00608         {
00609           return false;
00610         }
00611         references[type][ref] = make_reference(value);
00612       }
00613       return endReference();
00614     }
00615 
00621     virtual bool checkNextField(const QString& name) = 0;
00622 
00626     QString lastErrorString() const { return last_error_string; }
00627 
00633     int lastError() const { return last_error; }
00634 
00640     virtual void setLastError(int error, const QString& error_str) { if(last_error == NO__ERROR) { last_error = error; last_error_string = error_str; } }
00641 
00645     virtual void clearLastError() { last_error = NO__ERROR; last_error_string = QString(); }
00646 
00653     int version() const { return version_number; }
00654 
00658     const QString& fileVersion() const { return file_version; }
00659 
00663     virtual QString filename() const = 0;
00664 
00665   protected:
00666 
00667     template <typename Ptr>
00668     bool find_reference(const QString& type, int ref, Ptr& value)
00669     {
00670       ref_map_type::iterator found1 = references.find(type);
00671       if(found1 == references.end())
00672         return false;
00673       ref_map& typed_ref = found1->second;
00674       ref_map::iterator found = typed_ref.find(ref);
00675       if(found == typed_ref.end())
00676         return false;
00677       RealReference<Ptr> *r = dynamic_cast<RealReference<Ptr>*>(found->second.ptr);
00678       if(r)
00679         value = r->value;
00680       else
00681         return false;
00682       return true;
00683     }
00684 
00685     QString last_error_string;
00686 
00687     int last_error;
00688 
00689     QString file_version;
00690 
00691     int version_number;
00692   };
00693 
00702   template <typename T>
00703   bool serialization(VVEStorage& storage, T& value)
00704   {
00705     return value.serialize(storage);
00706   }
00707 
00730   int versionNumber(const QString& file_version);
00731 }
00732 
00733 #endif // VVELIB_STORAGE_STORAGE_H
00734 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:52 2013 for VVE by  doxygen 1.6.3