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
00019 class MetaData
00020 {
00021 public:
00022 typedef std::set<std::string> Values;
00023 typedef std::map<std::string, Values> Map;
00024 private:
00025 Map m_values;
00026 public:
00028 bool include(std::string const& key) const;
00029
00033 Map const& get() const;
00034
00038 void set(std::string const& key, std::string const& value);
00039
00044 void add(std::string const& key, Values const& value);
00045
00049 void add(std::string const& key, std::string const& value);
00050
00053 void clear(std::string const& key);
00054
00057 void clear();
00058
00061 Values get(std::string const& key) const;
00062
00066 void merge(MetaData const& metadata);
00067 };
00068
00070 class Type
00071 {
00072 public:
00073
00074 enum Category
00075 {
00076 NullType = 0,
00077 Array ,
00078 Pointer,
00079 Numeric,
00080 Enum ,
00081 Compound,
00082 Opaque,
00083 Container,
00084 NumberOfValidCategories
00085 };
00086
00087 private:
00088 std::string m_name;
00089
00090 size_t m_size;
00091 Category m_category;
00092
00094
00095 MetaData* m_metadata;
00096
00098 static bool isValidIdentifier(const std::string& identifier);
00099
00100 Type& operator = (Type const& type);
00101
00102 protected:
00103
00104
00105 Type(const std::string& name, size_t size, Category category);
00106
00107 public:
00108 virtual ~Type();
00109 Type(Type const& type);
00110
00113 void setName (const std::string& name);
00118 void setSize (size_t size);
00120 std::string getName() const;
00122 std::string getBasename() const;
00124 std::string getNamespace() const;
00126 size_t getSize() const;
00128 Category getCategory() const;
00130 bool isNull() const;
00131
00137 virtual std::set<Type const*> dependsOn() const = 0;
00138
00145 virtual void modifiedDependencyAliases(Registry& registry) const;
00146
00147 bool operator == (Type const& with) const;
00148 bool operator != (Type const& with) const;
00149
00154 bool isSame(Type const& other) const;
00155
00159 bool canCastTo(Type const& to) const;
00160
00165 Type const& merge(Registry& registry) const;
00166
00168 typedef std::map<Type const*, Type const*> RecursionStack;
00169
00176 virtual Type const& merge(Registry& registry, RecursionStack& stack) const;
00177
00186 virtual bool resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00187
00190 virtual unsigned int getTrailingPadding() const;
00191
00194 MetaData& getMetaData() const;
00195
00198 MetaData::Values getMetaData(std::string const& key) const;
00199
00202 virtual void mergeMetaData(Type const& other) const;
00203
00204 protected:
00223 virtual bool do_compare(Type const& other, bool equality, std::map<Type const*, Type const*>& stack) const;
00224
00230 bool rec_compare(Type const& left, Type const& right, bool equality, RecursionStack& stack) const;
00231
00239 Type const* try_merge(Registry& registry, RecursionStack& stack) const;
00240
00248 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const = 0;
00249
00251 virtual bool do_resize(Registry& into, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00252 };
00253
00254 class NullType : public Type
00255 {
00256 public:
00257 NullType(std::string const& name) : Type(name, 0, Type::NullType ) {}
00258 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00259
00260 private:
00261 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const { return new NullType(*this); }
00262 };
00263
00268 class OpaqueType : public Type
00269 {
00270 public:
00271 OpaqueType(std::string const& name, size_t size) : Type(name, size, Type::Opaque) {}
00272 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00273 virtual bool do_compare(Type const& other, bool equality, std::map<Type const*, Type const*>& stack) const;
00274 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const { return new OpaqueType(*this); }
00275 };
00276
00278 class Numeric : public Type
00279 {
00280 public:
00281 enum NumericCategory
00282 {
00283 SInt = Type::NumberOfValidCategories,
00284 UInt,
00285 Float,
00286 NumberOfValidCategories
00287
00288 };
00289
00291 NumericCategory getNumericCategory() const;
00292
00293 public:
00295 Numeric(const std::string& name, size_t size, NumericCategory category);
00296
00297 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00298
00299 private:
00300 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00301 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00302 NumericCategory m_category;
00303 };
00304
00306 class Enum : public Type
00307 {
00308 public:
00309 typedef int integral_type;
00310 typedef std::map<std::string, int> ValueMap;
00311
00312 class AlreadyExists : public std::runtime_error
00313 {
00314 public:
00315 AlreadyExists(Type const& type, std::string const& name);
00316 };
00317 class SymbolNotFound : public std::runtime_error
00318 {
00319 public:
00320 SymbolNotFound(Type const& type, std::string const& name);
00321 };
00322 class ValueNotFound : public std::runtime_error
00323 {
00324 public:
00325 ValueNotFound(Type const& type, int value);
00326 };
00327
00328 Enum(const std::string& name, Enum::integral_type initial_value = 0);
00330 void add(std::string const& name, int value);
00333 integral_type get(std::string const& name) const;
00336 std::string get(integral_type value) const;
00337
00339 std::list<std::string> names() const;
00341 ValueMap const& values() const;
00342
00343 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00344
00347 Enum::integral_type getNextValue() const;
00348
00349 private:
00350 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00351 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00352 integral_type m_last_value;
00353 ValueMap m_values;
00354 };
00355
00357 class Field
00358 {
00359 friend class Compound;
00360
00361 std::string m_name;
00362 const Type& m_type;
00363 size_t m_offset;
00364 MetaData* m_metadata;
00365
00366 private:
00367 Field& operator = (Field const& field);
00368 protected:
00369 void setOffset(size_t offset);
00370
00371 public:
00372 Field(const std::string& name, Type const& base_type);
00373 Field(Field const& field);
00374 ~Field();
00375
00377 std::string getName() const;
00379 const Type& getType() const;
00382 size_t getOffset() const;
00383
00384 bool operator == (Field const& field) const;
00385
00386 MetaData& getMetaData() const;
00387 MetaData::Values getMetaData(std::string const& key) const;
00388 void mergeMetaData(Field const& field) const;
00389 };
00390
00393 class Compound : public Type
00394 {
00395 public:
00396 typedef std::list<Field> FieldList;
00397
00398 public:
00399 Compound(std::string const& name);
00400
00402 FieldList const& getFields() const;
00405 Field const* getField(const std::string& name) const;
00407 Field const& addField(const Field& field, size_t offset);
00409 Field const& addField(const std::string& name, const Type& type, size_t offset);
00410
00413 unsigned int getTrailingPadding() const;
00414
00415 virtual std::set<Type const*> dependsOn() const;
00416
00420 void mergeMetaData(Type const& other) const;
00421
00422 private:
00423 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00424 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00425 bool do_resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00426 FieldList m_fields;
00427 };
00428
00430 class Indirect : public Type
00431 {
00432 public:
00433 static const int ValidIDs = Type::Pointer | Type::Array;
00434
00435 public:
00436
00437 Indirect(std::string const& name, size_t size, Category category, Type const& on);
00438
00439 void modifiedDependencyAliases(Registry& registry) const;
00440
00441 Type const& getIndirection() const;
00442 virtual std::set<Type const*> dependsOn() const;
00443
00444 virtual Type const& merge(Registry& registry, RecursionStack& stack) const;
00445
00446 protected:
00447 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00448 virtual bool do_resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00449
00456 virtual std::string getIndirectTypeName(std::string const& inside_name) const = 0;
00457
00458 private:
00459 Type const& m_indirection;
00460 };
00461
00465 class Array : public Indirect
00466 {
00467 public:
00468
00469 Array(Type const& of, size_t dimension);
00470 size_t getDimension() const;
00471 static std::string getArrayName(std::string const& base, size_t new_dim);
00472
00473 protected:
00474 virtual std::string getIndirectTypeName(std::string const& inside_name) const;
00475
00476 private:
00477 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00478 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00479 virtual bool do_resize(Registry& into, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00480 size_t m_dimension;
00481 };
00482
00484 class Pointer : public Indirect
00485 {
00486 public:
00487 Pointer(Type const& on);
00488 static std::string getPointerName(std::string const& base);
00489
00490 protected:
00491 virtual std::string getIndirectTypeName(std::string const& inside_name) const;
00492
00493 private:
00494 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00495 };
00496
00497 struct UnknownContainer : public std::runtime_error
00498 {
00499 UnknownContainer(std::string const& name)
00500 : std::runtime_error("unknown container " + name) {}
00501 };
00502
00503 class ValueVisitor;
00504 class Value;
00505
00507 class Container : public Indirect
00508 {
00509 std::string m_kind;
00510
00511
00512 protected:
00513 struct DeleteIfPredicate
00514 {
00515 virtual bool should_delete(Value const& v) = 0;
00516 };
00517
00518 virtual void delete_if_impl(void* ptr, DeleteIfPredicate& pred) const = 0;
00519
00520 private:
00521 template<typename Pred>
00522 struct PredicateWrapper : public DeleteIfPredicate
00523 {
00524 Pred pred;
00525
00526 PredicateWrapper(Pred pred)
00527 : pred(pred) {}
00528
00529 virtual bool should_delete(Value const& v)
00530 {
00531 return pred(v);
00532 };
00533 };
00534
00535
00536 public:
00537 typedef std::vector<size_t> MarshalOps;
00538
00539 Container(std::string const& kind, std::string const& name, size_t size, Type const& of);
00540
00541 std::string kind() const;
00542 virtual void init(void* ptr) const = 0;
00543 virtual void destroy(void* ptr) const = 0;
00544 virtual bool visit(void* ptr, ValueVisitor& visitor) const = 0;
00545
00551 virtual bool isRandomAccess() const;
00552
00561 virtual Typelib::Value getElement(void* ptr, int idx) const;
00562
00571 virtual void setElement(void* ptr, int idx, Typelib::Value value) const;
00572
00575 virtual void clear(void* ptr) const = 0;
00576
00579 virtual void push(void* ptr, Value v) const = 0;
00580
00585 virtual bool erase(void* ptr, Value v) const = 0;
00586
00592 virtual bool compare(void* ptr, void* other) const = 0;
00593
00597 virtual void copy(void* dst, void* src) const = 0;
00598
00603 virtual long getNaturalSize() const = 0;
00604
00605 template<typename Pred>
00606 void delete_if(void* ptr, Pred pred) const
00607 {
00608 PredicateWrapper<Pred> predicate(pred);
00609 delete_if_impl(ptr, predicate);
00610 }
00611
00612 virtual size_t getElementCount(void const* ptr) const = 0;
00613
00631 virtual MarshalOps::const_iterator dump(
00632 void const* container_ptr, size_t element_count,
00633 OutputStream& stream,
00634 MarshalOps::const_iterator const begin, MarshalOps::const_iterator const end) const = 0;
00635
00652 virtual MarshalOps::const_iterator load(
00653 void* container_ptr, size_t element_count,
00654 InputStream& stream,
00655 MarshalOps::const_iterator const begin, MarshalOps::const_iterator const end) const = 0;
00656
00657 typedef Container const& (*ContainerFactory)(Registry& r, std::list<Type const*> const& base_type);
00658 typedef std::map<std::string, ContainerFactory> AvailableContainers;
00659
00660 static const AvailableContainers& availableContainers();
00661 static void registerContainer(std::string const& name, ContainerFactory factory);
00662 static Container const& createContainer(Registry& r, std::string const& name, Type const& on);
00663 static Container const& createContainer(Registry& r, std::string const& name, std::list<Type const*> const& on);
00664
00665 protected:
00666 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00667 virtual ContainerFactory getFactory() const = 0;
00668 Type* do_merge(Registry& registry, RecursionStack& stack) const;
00669
00670 private:
00671 static AvailableContainers s_available_containers;
00672 };
00673
00674 struct TypeException : public std::runtime_error
00675 {
00676 TypeException(std::string const& msg) : std::runtime_error(msg) { }
00677 };
00678
00679 struct BadCategory : public TypeException
00680 {
00681 Type::Category const found;
00682 Type::Category const expected;
00683
00684 BadCategory(Type::Category found, Type::Category expected);
00685 };
00686
00687 struct NullTypeFound : public TypeException
00688 {
00689 NullTypeFound();
00690 NullTypeFound(Type const& type);
00691 };
00692 };
00693
00694 #endif
00695