diff options
Diffstat (limited to 'libxsde/xsde/cxx/serializer')
-rw-r--r-- | libxsde/xsde/cxx/serializer/genx/document.cxx | 2 | ||||
-rw-r--r-- | libxsde/xsde/cxx/serializer/substitution-map-callback.hxx | 26 | ||||
-rw-r--r-- | libxsde/xsde/cxx/serializer/substitution-map.cxx | 133 | ||||
-rw-r--r-- | libxsde/xsde/cxx/serializer/substitution-map.hxx | 23 | ||||
-rw-r--r-- | libxsde/xsde/cxx/serializer/substitution-map.ixx | 13 |
5 files changed, 136 insertions, 61 deletions
diff --git a/libxsde/xsde/cxx/serializer/genx/document.cxx b/libxsde/xsde/cxx/serializer/genx/document.cxx index 4c634a4..e8cacc0 100644 --- a/libxsde/xsde/cxx/serializer/genx/document.cxx +++ b/libxsde/xsde/cxx/serializer/genx/document.cxx @@ -514,7 +514,7 @@ namespace xsde // Call to check sets ns and n if successful. // if (strcmp (dt, root_static_type_) == 0 || - substitution_map_instance ().check (ns, n, dt)) + substitution_map_instance ().check (ns, n, dt, 0)) dt = 0; } diff --git a/libxsde/xsde/cxx/serializer/substitution-map-callback.hxx b/libxsde/xsde/cxx/serializer/substitution-map-callback.hxx new file mode 100644 index 0000000..c29a00d --- /dev/null +++ b/libxsde/xsde/cxx/serializer/substitution-map-callback.hxx @@ -0,0 +1,26 @@ +// file : xsde/cxx/serializer/substitution-map-callback.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSDE_CXX_SERIALIZER_SUBSTITUTION_MAP_CALLBACK_HXX +#define XSDE_CXX_SERIALIZER_SUBSTITUTION_MAP_CALLBACK_HXX + +namespace xsde +{ + namespace cxx + { + namespace serializer + { + void + serializer_smap_callback ( + bool (*callback) ( + const char* type, + const void* obj, + const char*& ns, + const char*& name)); + } + } +} + +#endif // XSDE_CXX_SERIALIZER_SUBSTITUTION_MAP_CALLBACK_HXX diff --git a/libxsde/xsde/cxx/serializer/substitution-map.cxx b/libxsde/xsde/cxx/serializer/substitution-map.cxx index 28f01b5..dc73fd2 100644 --- a/libxsde/xsde/cxx/serializer/substitution-map.cxx +++ b/libxsde/xsde/cxx/serializer/substitution-map.cxx @@ -17,6 +17,7 @@ #endif #include <xsde/cxx/serializer/substitution-map.hxx> +#include <xsde/cxx/serializer/substitution-map-callback.hxx> #include <xsde/cxx/serializer/substitution-map-load.hxx> namespace xsde @@ -103,8 +104,19 @@ namespace xsde bool substitution_map:: check_ (const char*& ns, const char*& name, - const char* type) const + const char* type, + const void* obj, + bool top) const { + // Call the callback first to allow the user to provide a custom + // substitution group mapping. + // + if (top && callback_ != 0) + { + if (callback_ (type, obj, ns, name)) + return true; + } + size_t h = hash (name); if (ns) @@ -115,70 +127,70 @@ namespace xsde const bucket* p = find (h); - if (p == 0) - return false; - - // Search for the entry in the bucket. - // - const size_t el_size = sizeof (element) + sizeof (hashmap*); - const char* b = reinterpret_cast<const char*> (p) + sizeof (bucket); - const char* e = b + p->size_ * el_size; - - size_t nl = ns ? strlen (name) : 0; - - for (; b < e; b += el_size) + if (p != 0) { - const element* e = reinterpret_cast<const element*> (b); + // Search for the entry in the bucket. + // + const size_t el_size = sizeof (element) + sizeof (hashmap*); + const char* b = reinterpret_cast<const char*> (p) + sizeof (bucket); + const char* e = b + p->size_ * el_size; + + size_t nl = ns ? strlen (name) : 0; - if (e->hash_ == h) + for (; b < e; b += el_size) { - if (ns == 0) - { - if (strcmp (e->key_, name) == 0) - break; - } - else + const element* e = reinterpret_cast<const element*> (b); + + if (e->hash_ == h) { - if (strncmp (e->key_, name, nl) == 0 && - e->key_[nl] == ' ' && - strcmp (e->key_ + nl + 1, ns) == 0) - break; + if (ns == 0) + { + if (strcmp (e->key_, name) == 0) + break; + } + else + { + if (strncmp (e->key_, name, nl) == 0 && + e->key_[nl] == ' ' && + strcmp (e->key_ + nl + 1, ns) == 0) + break; + } } } - } - if (b == e) - return false; - - const hashmap* map = *reinterpret_cast<const hashmap* const*> ( - b + sizeof (element)); + if (b != e) + { + const hashmap* map = *reinterpret_cast<const hashmap* const*> ( + b + sizeof (element)); - // See if we have a direct substitution. - // - if (const value* v = static_cast<const value*> (map->find (type))) - { - ns = v->ns_; - name = v->name_; - return true; - } + // See if we have a direct substitution. + // + if (const value* v = static_cast<const value*> (map->find (type))) + { + ns = v->ns_; + name = v->name_; + return true; + } - // Otherwise we have to iterate over possible substitutions and - // see if any of them can in turn be substituted with something - // that we can use. - // - for (const_iterator i (map->begin ()), end (map->end ()); - i != end; ++i) - { - const value* v = static_cast<const value*> (*i); + // Otherwise we have to iterate over possible substitutions and + // see if any of them can in turn be substituted with something + // that we can use. + // + for (const_iterator i (map->begin ()), end (map->end ()); + i != end; ++i) + { + const value* v = static_cast<const value*> (*i); - const char* tns = v->ns_; - const char* tn = v->name_; + const char* tns = v->ns_; + const char* tn = v->name_; - if (check_ (tns, tn, type)) - { - ns = tns; - name = tn; - return true; + if (check_ (tns, tn, type, obj, false)) + { + ns = tns; + name = tn; + return true; + } + } } } @@ -264,7 +276,20 @@ namespace xsde #endif } + // Callback. // + void + serializer_smap_callback ( + bool (*callback) ( + const char* type, + const void* obj, + const char*& ns, + const char*& name)) + { + substitution_map_instance ().callback (callback); + } + + // Load. // size_t serializer_smap_elements () diff --git a/libxsde/xsde/cxx/serializer/substitution-map.hxx b/libxsde/xsde/cxx/serializer/substitution-map.hxx index ae16f4c..e36c481 100644 --- a/libxsde/xsde/cxx/serializer/substitution-map.hxx +++ b/libxsde/xsde/cxx/serializer/substitution-map.hxx @@ -30,21 +30,34 @@ namespace xsde const char* member_name, const char* member_type); + typedef bool (*callback_func) ( + const char* type, + const void* obj, + const char*& ns, + const char*& name); + + void + callback (callback_func); + // Check whether there is a substitution available for this // root element with the specified type. If so, return true // and override namespace and name (ns is 0 if there is no - // namespace). + // namespace). The obj argument is an opaque pointer to the + // instance being serialized or 0 if there is none. // bool check (const char*& ns, const char*& name, - const char* type) const; + const char* type, + const void* obj) const; private: bool check_ (const char*& ns, const char*& name, - const char* type) const; + const char* type, + const void* obj, + bool top) const; private: struct value @@ -52,6 +65,9 @@ namespace xsde const char* ns_; const char* name_; }; + + private: + callback_func callback_; }; @@ -85,4 +101,3 @@ namespace xsde #include <xsde/cxx/serializer/substitution-map.ixx> #endif // XSDE_CXX_SERIALIZER_SUBSTITUTION_MAP_HXX - diff --git a/libxsde/xsde/cxx/serializer/substitution-map.ixx b/libxsde/xsde/cxx/serializer/substitution-map.ixx index 6622e33..6dbd951 100644 --- a/libxsde/xsde/cxx/serializer/substitution-map.ixx +++ b/libxsde/xsde/cxx/serializer/substitution-map.ixx @@ -15,12 +15,21 @@ namespace xsde { } + inline void substitution_map:: + callback (callback_func c) + { + callback_ = c; + } + inline bool substitution_map:: check (const char*& ns, const char*& name, - const char* type) const + const char* type, + const void* obj) const { - return empty () ? false : check_ (ns, name, type); + return !empty () || callback_ != 0 + ? check_ (ns, name, type, obj, true) + : false; } inline substitution_map& |