Example #1
0
        Document<Formatter>::Document(Formatter& formatter)
    {
        _elements.reserve(32);
        _attributes.reserve(64);
        _firstRootAttribute = ~0u;

            // Parse the input formatter, building a tree
            // of elements and a list of attributes.
            // We can start with several top-level elements
        unsigned lastEle = ~0u;
        unsigned lastAttrib = ~0u;
        for (;;) {
            switch (formatter.PeekNext()) {
            case Formatter::Blob::AttributeName:
                {
                    Formatter::InteriorSection name, value;
                    if (formatter.TryAttribute(name, value)) {
                        _attributes.push_back(AttributeDesc{name, value, ~0u});
                        if (lastAttrib != ~0u) {
                            _attributes[lastAttrib]._nextSibling = unsigned(_attributes.size()-1);
                        } else {
                            _firstRootAttribute = unsigned(_attributes.size()-1);
                        }
                        lastAttrib = unsigned(_attributes.size()-1);
                    }
                }
                continue;

            case Formatter::Blob::BeginElement:
                {
                    auto newEle = ParseElement(formatter);
                    if (newEle == ~0u) break;
                    if (lastEle != ~0u) _elements[lastEle]._nextSibling = newEle;
                    lastEle = newEle;
                }
                continue;

            default:
                break;
            }

            break;
        }
        
        //      Sometimes we serialize in some elements as a "Document"
        //      In these cases, there may be more data in the file...
        // if (formatter.PeekNext() != Formatter::Blob::None)
        //     Throw(FormatException(
        //         "Unexpected trailing characters in StreamDOM", formatter.GetLocation()));
    }
Example #2
0
        unsigned Document<Formatter>::ParseElement(Formatter& formatter)
    {
        Formatter::InteriorSection section;
        if (!formatter.TryBeginElement(section))
            return ~0u;

        unsigned e = ~0u;
        {
            ElementDesc newElement;
            newElement._name = section;
            newElement._firstAttribute = ~0u;
            newElement._firstChild = ~0u;
            newElement._nextSibling = ~0u;
            _elements.push_back(newElement);
            e = (unsigned)_elements.size()-1;
        }

        auto lastChild = ~0u;
        auto lastAttribute = ~0u;
        for (;;) {
            auto next = formatter.PeekNext();
            if (next == Formatter::Blob::BeginElement) {
                auto newElement = ParseElement(formatter);
                if (lastChild == ~0u) {
                    _elements[e]._firstChild = newElement;
                } else {
                    _elements[lastChild]._nextSibling = newElement;
                }
                lastChild = newElement;
            } else if (next == Formatter::Blob::AttributeName) {
                Formatter::InteriorSection name;
                Formatter::InteriorSection value;
                if (!formatter.TryAttribute(name, value))
                    Throw(FormatException(
                        "Error while reading attribute in StreamDOM", formatter.GetLocation()));

                AttributeDesc attrib;
                attrib._name = name;
                attrib._value = value;
                attrib._nextSibling = ~0u;
                _attributes.push_back(attrib);
                auto a = (unsigned)_attributes.size()-1;
                if (lastAttribute == ~0u) {
                    _elements[e]._firstAttribute = a;
                } else {
                    _attributes[lastAttribute]._nextSibling = a;
                }
                lastAttribute = a;
            } else if (next == Formatter::Blob::EndElement) {
                break;
            } else {
                Throw(FormatException(
                    StringMeld<128>() << "Got unexpected blob type (" << unsigned(next) << ") while parsing element in StreamDOM",
                    formatter.GetLocation()));
            }
        }

        if (!formatter.TryEndElement()) 
            Throw(FormatException(
                "Expected end element in StreamDOM", formatter.GetLocation()));

        return e;
    }
Example #3
0
        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;
                }
            }
        }
    }