public Task Process(XenonHandler handler) { return(inner.Process(entry => { XenonRow[] rows = new XenonRow[1024]; int position = XenonScanner.NextOpening(entry, 0, name); while (position >= 0 && position < size) { XenonHierarchy hierarchy = new XenonHierarchy(rows); if (Handle(entry, hierarchy, ref position) == -1) { return; } handler.Handle(new XenonDocument(entry, hierarchy)); position = XenonScanner.NextOpening(entry, position, name); } })); }
public string ToString(XenonWhiteCharacter mode) { if (id > 0) { int length = hierarchy.GetLength(id); int position = hierarchy.GetPosition(id); StringBuilder builder = new StringBuilder(length); if (length < 0) { length = -length; } if (mode == XenonWhiteCharacter.Omit) { int next = XenonScanner.SkipWhiteCharactersForward(entry, position); length = length - (next - position); position = next; } if (length > 0) { int prev = XenonScanner.SkipWhiteCharactersBackward(entry, position + length - 1); length = length - (position + length - 1 - prev); } while (length > 0) { builder.Append(entry.GetCharacterAt(position, out int read)); position = position + read; length = length - read; } return(builder.ToString()); } return(null); }
private int Handle(BufferEntry entry, XenonHierarchy hierarchy, ref int position) { //Console.WriteLine($"el {position}"); byte value; bool self = false; if (entry.GetByteAt(position++) != '<') { return(-1); } int starting = position; if ((position = XenonScanner.NextElementName(entry, starting)) == -1) { return(-1); } // handle element start int previousId = 0; int owner = hierarchy.Add(starting, position - starting); if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if ((value = entry.GetByteAt(position)) == 0) { return(-1); } int append(int id) { if (previousId == 0) { hierarchy.SetFirst(owner, id); previousId = id; } else { hierarchy.SetNext(previousId, id); previousId = id; } return(id); } int addToHierarchy(int index, int length) { return(append(hierarchy.Add(index, length))); } int contentId = append(hierarchy.Add()); void setContent(int index, int length) { if (contentId != 0) { hierarchy.SetPosition(contentId, index); hierarchy.SetLength(contentId, length); contentId = 0; } else { addToHierarchy(index, length); } } while (value != '/' && value != '>') { starting = position; if ((position = XenonScanner.NextAttributeName(entry, starting)) == -1) { return(-1); } // handle attribute name int nameId = addToHierarchy(starting, position - starting); if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if (entry.GetByteAt(position++) != '=') { return(-1); } if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if (entry.GetByteAt(position++) != '"') { return(-1); } starting = position; if ((position = XenonScanner.NextAttributeValue(entry, starting)) == -1) { return(-1); } // handle attribute value int valueId = hierarchy.Add(starting, position - starting); hierarchy.SetFirst(nameId, valueId); if (entry.GetByteAt(position++) != '"') { return(-1); } if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if ((value = entry.GetByteAt(position)) == 0) { return(-1); } } if (value == '/') { if ((value = entry.GetByteAt(++position)) == 0) { return(-1); } self = true; } if (value != '>') { return(-1); } if (self == false) { position = position + 1; while (true) { starting = position; if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if (starting == position) { if ((value = entry.GetByteAt(position)) == 0) { return(-1); } if (value == '<') { if ((value = entry.GetByteAt(position + 1)) == 0) { return(-1); } if (value == '/') { starting = position + 2; if ((position = XenonScanner.NextElementName(entry, starting + 2)) == -1) { return(-1); } // handle element end if ((value = entry.GetByteAt(position)) != '>') { return(-1); } //Console.WriteLine($"cl {position}"); return(owner); } if ((starting = Handle(entry, hierarchy, ref position)) == -1) { return(-1); } append(starting); position++; continue; } } if ((position = XenonScanner.NextContent(entry, position)) == -1) { return(-1); } setContent(starting, position - starting); } } return(owner); }