virtual void attribute(const str& name, const variant value) { schema_item itm; if (!obj_->resolve(name, itm)) assert(false); //ought to be mutable //this tries to fix an importand design flaw of the mutant/xml reader... fault to deduce arrays variant val = value; if (itm.type) { int options = itm.type->options(); if (options & TYPE_ITERATED) { schema* vtype = value.get_schema(); if (!vtype || !(vtype->options() & TYPE_ITERATED)) { return; //just bail if whats being assigned to an array is not } } } if (!itm.set) { assert(false); //same } itm.set->set(obj_, value); }
void base_write_archive::write( Writer w, const str& name, variant& v) { schema* type = true_type(v); void* this_ = v.get_pointer(); //3 use cases: //- we know the type as attibuted (ints, strings, things like that) // note the implementor is free to define its custom types // //- we are saving an iterable type // //- or we are saving an object, these seem to be reasonable assumptions. if (attributed_type(type)) { assert(!name.empty()); w->attribute(name, v); } else { size_t type_options = type->options(); if (type_options & TYPE_ITERATED) { iterable iter(v); iterator it = iter.begin(); iterator nd = iter.end(); WriteIterator wit = w->create_iterator(name, iter.iterated_type()); for(; it != nd; ++it) { variant iv = *it; Writer iw = wit->next(iv); if (iw) write(iw, "", iv); } } else { Writer writer_ = name.empty()? w : w->create_node(name); schema* otype = v.get_schema(); assert(otype); size_t oopt = otype->options(); if (oopt & TYPE_NON_INSTANTIABLE) { assert(type != otype); assert(types_); str class_id = types_->type_name(type); assert( !class_id.empty() ); w->attribute("class", class_id); } //collect what we're saving schema_collector sc; type->visit(&sc); schema_collector::container::iterator it = sc.begin(); schema_collector::container::iterator nd = sc.end(); for(; it != nd; it++) { schema_item& item = it->second; if (item.flags & CONST) continue; if (item.flags & TRANSIENT) continue; if (item.get) { variant value = item.get->get(this_); write(writer_, it->first, value); } } } } }