$search
00001 #ifndef __TYPELIB_TYPEMODEL_HH__ 00002 #define __TYPELIB_TYPEMODEL_HH__ 00003 00004 #include <string> 00005 #include <list> 00006 #include <map> 00007 #include <set> 00008 #include <vector> 00009 #include <stdint.h> 00010 #include <stdexcept> 00011 00012 namespace Typelib 00013 { 00014 struct OutputStream; 00015 struct InputStream; 00016 00017 class Registry; 00018 00020 class Type 00021 { 00022 public: 00023 00024 enum Category 00025 { 00026 NullType = 0, 00027 Array , 00028 Pointer, 00029 Numeric, 00030 Enum , 00031 Compound, 00032 Opaque, 00033 Container 00034 }; 00035 static const int ValidCategories = Compound + 1; 00036 00037 private: 00038 std::string m_name; 00039 00040 size_t m_size; 00041 Category m_category; 00042 00044 static bool isValidIdentifier(const std::string& identifier); 00045 00046 protected: 00047 00048 // Creates a basic type from \c name, \c size and \c category 00049 Type(const std::string& name, size_t size, Category category); 00050 00051 public: 00052 virtual ~Type(); 00053 00056 void setName (const std::string& name); 00061 void setSize (size_t size); 00063 std::string getName() const; 00065 std::string getBasename() const; 00067 std::string getNamespace() const; 00069 size_t getSize() const; 00071 Category getCategory() const; 00073 bool isNull() const; 00074 00080 virtual std::set<Type const*> dependsOn() const = 0; 00081 00088 virtual void modifiedDependencyAliases(Registry& registry) const; 00089 00090 bool operator == (Type const& with) const; 00091 bool operator != (Type const& with) const; 00092 00097 bool isSame(Type const& other) const; 00098 00102 bool canCastTo(Type const& to) const; 00103 00108 Type const& merge(Registry& registry) const; 00109 00111 typedef std::map<Type const*, Type const*> RecursionStack; 00112 00119 virtual Type const& merge(Registry& registry, RecursionStack& stack) const; 00120 00129 virtual bool resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes); 00130 00133 virtual unsigned int getTrailingPadding() const; 00134 00135 protected: 00154 virtual bool do_compare(Type const& other, bool equality, std::map<Type const*, Type const*>& stack) const; 00155 00161 bool rec_compare(Type const& left, Type const& right, bool equality, RecursionStack& stack) const; 00162 00170 Type const* try_merge(Registry& registry, RecursionStack& stack) const; 00171 00179 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const = 0; 00180 00182 virtual bool do_resize(Registry& into, std::map<std::string, std::pair<size_t, size_t> >& new_sizes); 00183 }; 00184 00185 class NullType : public Type 00186 { 00187 public: 00188 NullType(std::string const& name) : Type(name, 0, Type::NullType ) {} 00189 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); } 00190 00191 private: 00192 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const { return new NullType(*this); } 00193 }; 00194 00199 class OpaqueType : public Type 00200 { 00201 public: 00202 OpaqueType(std::string const& name, size_t size) : Type(name, size, Type::Opaque) {} 00203 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); } 00204 virtual bool do_compare(Type const& other, bool equality, std::map<Type const*, Type const*>& stack) const; 00205 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const { return new OpaqueType(*this); } 00206 }; 00207 00209 class Numeric : public Type 00210 { 00211 public: 00212 enum NumericCategory 00213 { 00214 SInt = Type::ValidCategories, 00215 UInt, 00216 Float 00217 }; 00218 static const int ValidCategories = Float + 1; 00219 00221 NumericCategory getNumericCategory() const; 00222 00223 public: 00225 Numeric(const std::string& name, size_t size, NumericCategory category); 00226 00227 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); } 00228 00229 private: 00230 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const; 00231 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const; 00232 NumericCategory m_category; 00233 }; 00234 00236 class Enum : public Type 00237 { 00238 public: 00239 typedef int integral_type; 00240 typedef std::map<std::string, int> ValueMap; 00241 00242 class AlreadyExists : public std::runtime_error 00243 { 00244 public: 00245 AlreadyExists(Type const& type, std::string const& name); 00246 }; 00247 class SymbolNotFound : public std::runtime_error 00248 { 00249 public: 00250 SymbolNotFound(Type const& type, std::string const& name); 00251 }; 00252 class ValueNotFound : public std::runtime_error 00253 { 00254 public: 00255 ValueNotFound(Type const& type, int value); 00256 }; 00257 00258 Enum(const std::string& name, Enum::integral_type initial_value = 0); 00260 void add(std::string const& name, int value); 00263 integral_type get(std::string const& name) const; 00266 std::string get(integral_type value) const; 00267 00269 std::list<std::string> names() const; 00271 ValueMap const& values() const; 00272 00273 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); } 00274 00277 Enum::integral_type getNextValue() const; 00278 00279 private: 00280 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const; 00281 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const; 00282 integral_type m_last_value; 00283 ValueMap m_values; 00284 }; 00285 00287 class Field 00288 { 00289 friend class Compound; 00290 00291 std::string m_name; 00292 const Type& m_type; 00293 size_t m_offset; 00294 00295 protected: 00296 void setOffset(size_t offset); 00297 00298 public: 00299 Field(const std::string& name, Type const& base_type); 00300 00302 std::string getName() const; 00304 const Type& getType() const; 00307 size_t getOffset() const; 00308 00309 bool operator == (Field const& field) const; 00310 }; 00311 00314 class Compound : public Type 00315 { 00316 public: 00317 typedef std::list<Field> FieldList; 00318 00319 public: 00320 Compound(std::string const& name); 00321 00323 FieldList const& getFields() const; 00326 Field const* getField(const std::string& name) const; 00328 void addField(const Field& field, size_t offset); 00330 void addField(const std::string& name, const Type& type, size_t offset); 00331 00334 unsigned int getTrailingPadding() const; 00335 00336 virtual std::set<Type const*> dependsOn() const; 00337 00338 private: 00339 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const; 00340 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const; 00341 bool do_resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes); 00342 FieldList m_fields; 00343 }; 00344 00346 class Indirect : public Type 00347 { 00348 public: 00349 static const int ValidIDs = Type::Pointer | Type::Array; 00350 00351 public: 00352 00353 Indirect(std::string const& name, size_t size, Category category, Type const& on); 00354 00355 void modifiedDependencyAliases(Registry& registry) const; 00356 00357 Type const& getIndirection() const; 00358 virtual std::set<Type const*> dependsOn() const; 00359 00360 virtual Type const& merge(Registry& registry, RecursionStack& stack) const; 00361 00362 protected: 00363 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const; 00364 virtual bool do_resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes); 00365 00372 virtual std::string getIndirectTypeName(std::string const& inside_name) const = 0; 00373 00374 private: 00375 Type const& m_indirection; 00376 }; 00377 00381 class Array : public Indirect 00382 { 00383 public: 00384 00385 Array(Type const& of, size_t dimension); 00386 size_t getDimension() const; 00387 static std::string getArrayName(std::string const& base, size_t new_dim); 00388 00389 protected: 00390 virtual std::string getIndirectTypeName(std::string const& inside_name) const; 00391 00392 private: 00393 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const; 00394 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const; 00395 virtual bool do_resize(Registry& into, std::map<std::string, std::pair<size_t, size_t> >& new_sizes); 00396 size_t m_dimension; 00397 }; 00398 00400 class Pointer : public Indirect 00401 { 00402 public: 00403 Pointer(Type const& on); 00404 static std::string getPointerName(std::string const& base); 00405 00406 protected: 00407 virtual std::string getIndirectTypeName(std::string const& inside_name) const; 00408 00409 private: 00410 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const; 00411 }; 00412 00413 struct UnknownContainer : public std::runtime_error 00414 { 00415 UnknownContainer(std::string const& name) 00416 : std::runtime_error("unknown container " + name) {} 00417 }; 00418 00419 class ValueVisitor; 00420 class Value; 00421 00423 class Container : public Indirect 00424 { 00425 std::string m_kind; 00426 00427 00428 protected: 00429 struct DeleteIfPredicate 00430 { 00431 virtual bool should_delete(Value const& v) = 0; 00432 }; 00433 00434 virtual void delete_if_impl(void* ptr, DeleteIfPredicate& pred) const = 0; 00435 00436 private: 00437 template<typename Pred> 00438 struct PredicateWrapper : public DeleteIfPredicate 00439 { 00440 Pred pred; 00441 00442 PredicateWrapper(Pred pred) 00443 : pred(pred) {} 00444 00445 virtual bool should_delete(Value const& v) 00446 { 00447 return pred(v); 00448 }; 00449 }; 00450 00451 00452 public: 00453 typedef std::vector<size_t> MarshalOps; 00454 00455 Container(std::string const& kind, std::string const& name, size_t size, Type const& of); 00456 00457 std::string kind() const; 00458 virtual void init(void* ptr) const = 0; 00459 virtual void destroy(void* ptr) const = 0; 00460 virtual bool visit(void* ptr, ValueVisitor& visitor) const = 0; 00461 00467 virtual bool isRandomAccess() const; 00468 00477 virtual Typelib::Value getElement(void* ptr, int idx) const; 00478 00487 virtual void setElement(void* ptr, int idx, Typelib::Value value) const; 00488 00491 virtual void clear(void* ptr) const = 0; 00492 00495 virtual void push(void* ptr, Value v) const = 0; 00496 00501 virtual bool erase(void* ptr, Value v) const = 0; 00502 00508 virtual bool compare(void* ptr, void* other) const = 0; 00509 00513 virtual void copy(void* dst, void* src) const = 0; 00514 00519 virtual long getNaturalSize() const = 0; 00520 00521 template<typename Pred> 00522 void delete_if(void* ptr, Pred pred) const 00523 { 00524 PredicateWrapper<Pred> predicate(pred); 00525 delete_if_impl(ptr, predicate); 00526 } 00527 00528 virtual size_t getElementCount(void const* ptr) const = 0; 00529 00547 virtual MarshalOps::const_iterator dump( 00548 void const* container_ptr, size_t element_count, 00549 OutputStream& stream, 00550 MarshalOps::const_iterator const begin, MarshalOps::const_iterator const end) const = 0; 00551 00568 virtual MarshalOps::const_iterator load( 00569 void* container_ptr, size_t element_count, 00570 InputStream& stream, 00571 MarshalOps::const_iterator const begin, MarshalOps::const_iterator const end) const = 0; 00572 00573 typedef Container const& (*ContainerFactory)(Registry& r, std::list<Type const*> const& base_type); 00574 typedef std::map<std::string, ContainerFactory> AvailableContainers; 00575 00576 static AvailableContainers availableContainers(); 00577 static void registerContainer(std::string const& name, ContainerFactory factory); 00578 static Container const& createContainer(Registry& r, std::string const& name, Type const& on); 00579 static Container const& createContainer(Registry& r, std::string const& name, std::list<Type const*> const& on); 00580 00581 protected: 00582 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const; 00583 virtual ContainerFactory getFactory() const = 0; 00584 Type* do_merge(Registry& registry, RecursionStack& stack) const; 00585 00586 private: 00587 static AvailableContainers* s_available_containers; 00588 }; 00589 00590 struct TypeException : public std::runtime_error 00591 { 00592 TypeException(std::string const& msg) : std::runtime_error(msg) { } 00593 }; 00594 00595 struct BadCategory : public TypeException 00596 { 00597 Type::Category const found; 00598 int const expected; 00599 00600 BadCategory(Type::Category found, int expected); 00601 }; 00602 00603 struct NullTypeFound : public TypeException 00604 { 00605 NullTypeFound(); 00606 }; 00607 }; 00608 00609 #endif 00610