void SetParameters( void* obj, const ClassAccessors& accessors, const ParameterBox& paramBox) { // we can choose to iterate through the parameters in either way: // either by iterating through the accessors in "accessors" and pulling // values from the parameter box... // or by iterating through the parameters in "paramBox" and pushing those // values in. // We have to consider array cases -- perhaps it easier to go through the // parameters in the parameter box for (auto i=paramBox.Begin(); !i.IsEnd(); ++i) { const auto nameStart = i.Name(); const auto nameEnd = XlStringEnd(nameStart); auto arrayBracket = std::find(nameStart, nameEnd, '['); if (arrayBracket == nameEnd) { accessors.TryOpaqueSet( obj, Hash64(nameStart, nameEnd), i.RawValue(), i.Type(), false); } else { auto arrayIndex = XlAtoUI32((const char*)(arrayBracket+1)); accessors.TryOpaqueSet( obj, Hash64(nameStart, arrayBracket), arrayIndex, i.RawValue(), i.Type(), false); } } }
void AccessorDeserialize( Formatter& formatter, void* obj, const ClassAccessors& props) { using Blob = Formatter::Blob; using CharType = Formatter::value_type; auto charTypeCat = ImpliedTyping::TypeOf<CharType>()._type; for (;;) { switch (formatter.PeekNext()) { case Blob::AttributeName: { typename Formatter::InteriorSection name, value; if (!formatter.TryAttribute(name, value)) Throw(FormatException("Error in begin element", formatter.GetLocation())); auto arrayBracket = std::find(name._start, name._end, '['); if (arrayBracket == name._end) { if (!props.TryOpaqueSet( obj, Hash64(name._start, name._end), value._start, ImpliedTyping::TypeDesc(charTypeCat, uint16(value._end - value._start)), true)) { LogWarning << "Failure while assigning property during deserialization -- " << Conversion::Convert<std::string>(std::basic_string<CharType>(name._start, name._end)); } } else { auto arrayIndex = XlAtoUI32((const char*)(arrayBracket+1)); if (!props.TryOpaqueSet( obj, Hash64(name._start, arrayBracket), arrayIndex, value._start, ImpliedTyping::TypeDesc(charTypeCat, uint16(value._end - value._start)), true)) { LogWarning << "Failure while assigning array property during deserialization -- " << Conversion::Convert<std::string>(std::basic_string<CharType>(name._start, name._end)); } } } break; case Blob::EndElement: case Blob::None: return; case Blob::BeginElement: { typename Formatter::InteriorSection eleName; if (!formatter.TryBeginElement(eleName)) Throw(FormatException("Error in begin element", formatter.GetLocation())); auto created = props.TryCreateChild(obj, Hash64(eleName._start, eleName._end)); if (created.first) { AccessorDeserialize(formatter, created.first, *created.second); } else { LogWarning << "Couldn't find a match for element name during deserialization -- " << Conversion::Convert<std::string>(std::basic_string<CharType>(eleName._start, eleName._end)); formatter.SkipElement(); } if (!formatter.TryEndElement()) Throw(FormatException("Expecting end element", formatter.GetLocation())); break; } } } }