aboutsummaryrefslogtreecommitdiff
path: root/libxsde/xsde/cxx/serializer/substitution-map.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-10-18 11:17:51 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-10-18 11:17:51 +0200
commitd80d096ee8743fd6f7382d274272b0b6d7faf9bf (patch)
treed0f0bee1e645cb2b86b6837ac0db8a7d2821e533 /libxsde/xsde/cxx/serializer/substitution-map.cxx
parent0e4637025fa8d1b4234b0512561d31f0dd023843 (diff)
Support for schema evolution using substitution groups
New examples: hybrid/evolution/ignore and hybrid/evolution/passthrough.
Diffstat (limited to 'libxsde/xsde/cxx/serializer/substitution-map.cxx')
-rw-r--r--libxsde/xsde/cxx/serializer/substitution-map.cxx133
1 files changed, 79 insertions, 54 deletions
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 ()