public ObjectIterator(InternalObject[] objects, int startPosition = 0) { this.currentPosition = startPosition; this.objects = objects; if (objects.Length > 0) this.currentObject = objects[0]; }
public void MoveNext() { if (currentObject == null) { return; } currentIndex++; currentPosition += currentObject.Length; isAtElementEnd = false; while (currentIndex >= objects.Length && listStack.Count > 0) { objects = listStack.Pop(); currentIndex = indexStack.Pop(); if (this.StopAtElementEnd) { isAtElementEnd = true; break; } else { currentIndex++; } } currentObject = (currentIndex < objects.Length ? objects[currentIndex] : null); }
public InternalObject SetStartRelativeToParent(int newStartRelativeToParent) { if (newStartRelativeToParent == StartRelativeToParent) return this; InternalObject obj = (InternalObject)MemberwiseClone(); obj.StartRelativeToParent = newStartRelativeToParent; return obj; }
InternalObjectFrame BeginInternalObject(InternalObject internalObject, int beginLocation) { internalObject.StartRelativeToParent = beginLocation - internalObjectStartPosition; var frame = new InternalObjectFrame(internalObject, internalObjectStartPosition); internalObjectStartPosition = CurrentLocation; return(frame); }
public ObjectIterator(InternalObject[] objects, int startPosition = 0) { this.currentPosition = startPosition; this.objects = objects; if (objects.Length > 0) { this.currentObject = objects[0]; } }
public void MoveInto() { if (isAtElementEnd || !(currentObject is InternalElement)) { MoveNext(); } else { listStack.Push(objects); indexStack.Push(currentIndex); objects = currentObject.NestedObjects; currentIndex = 0; currentObject = objects[0]; } }
public void MoveNext() { if (currentObject == null) return; currentIndex++; currentPosition += currentObject.Length; isAtElementEnd = false; while (currentIndex >= objects.Length && listStack.Count > 0) { objects = listStack.Pop(); currentIndex = indexStack.Pop(); if (this.StopAtElementEnd) { isAtElementEnd = true; break; } else { currentIndex++; } } currentObject = (currentIndex < objects.Length ? objects[currentIndex] : null); }
public List<InternalObject> ReadAllObjectsIncremental(InternalObject[] oldObjects, List<UnchangedSegment> reuseMap, CancellationToken cancellationToken) { ObjectIterator oldObjectIterator = new ObjectIterator(oldObjects); int reuseMapIndex = 0; while (reuseMapIndex < reuseMap.Count) { var reuseEntry = reuseMap[reuseMapIndex]; while (this.CurrentLocation < reuseEntry.NewOffset) { cancellationToken.ThrowIfCancellationRequested(); ReadObject(); } if (this.CurrentLocation >= reuseEntry.NewOffset + reuseEntry.Length) { reuseMapIndex++; continue; } Debug.Assert(reuseEntry.NewOffset <= this.CurrentLocation && this.CurrentLocation < reuseEntry.NewOffset + reuseEntry.Length); // reuse the nodes within this reuseEntry starting at oldOffset: int oldOffset = this.CurrentLocation - reuseEntry.NewOffset + reuseEntry.OldOffset; // seek to oldOffset in the oldObjects array: oldObjectIterator.SkipTo(oldOffset); if (oldObjectIterator.CurrentPosition == oldOffset) { // reuse old objects within this reuse entry: int reuseEnd = reuseEntry.OldOffset + reuseEntry.Length; while (oldObjectIterator.CurrentObject != null && oldObjectIterator.CurrentPosition + oldObjectIterator.CurrentObject.LengthTouched < reuseEnd) { StoreObject(oldObjectIterator.CurrentObject); Skip(oldObjectIterator.CurrentObject.Length); oldObjectIterator.MoveNext(); } reuseMapIndex++; // go to next re-use map } else { // We are in a region where old objects are available, but aren't aligned correctly. // Don't skip this reuse entry, and read a single object so that we can re-align ReadObject(); } } while (HasMoreData()) { cancellationToken.ThrowIfCancellationRequested(); ReadObject(); } return objects; }
void ProcessObject(InternalObject obj, int indentationLevel, ConfigurationList oldConfigurations, ref ConfigurationList newConfigurations) { newConfigurations.Clear(); InternalTag tag = obj as InternalTag; for (int i = 0; i < oldConfigurations.count; i++) { Configuration c = oldConfigurations.configurations[i]; if (c.Cost == InfiniteCost) { continue; } if (tag != null && tag.IsStartTag) { // Push start tag newConfigurations.Add( c.OpenTags.Push(tag.Name, indentationLevel), c.Document.Push(obj), c.Cost ); } else if (tag != null && tag.IsEndTag) { // We can ignore this end tag newConfigurations.Add( c.OpenTags, c.Document.Push(StartTagPlaceholder).Push(obj), c.Cost + IgnoreEndTagCost ); // We can match this end tag with one of the currently open tags var openTags = c.OpenTags; var documentWithInsertedEndTags = c.Document; uint newCost = c.Cost; while (!openTags.IsEmpty) { uint matchCost = 0; if (openTags.IndentationLevel >= 0 && indentationLevel >= 0) { matchCost += (uint)Math.Abs(openTags.IndentationLevel - indentationLevel); } if (openTags.Name != tag.Name) { matchCost += MismatchedNameCost; } newConfigurations.Add( openTags.Pop(), documentWithInsertedEndTags.Push(obj), newCost + matchCost ); newCost += MissingEndTagCost; openTags = openTags.Pop(); documentWithInsertedEndTags = documentWithInsertedEndTags.Push(EndTagPlaceholder); } } else { newConfigurations.Add( c.OpenTags, c.Document.Push(obj), c.Cost ); } } }
InternalObjectFrame BeginInternalObject(InternalObject internalObject) { return(BeginInternalObject(internalObject, this.CurrentLocation)); }
void StoreObject(InternalObject obj) { objects.Add(obj); // Now combine properly-nested elements: if (elementNameStack == null) { return; // parsing tag soup } InternalTag tag = obj as InternalTag; if (tag == null) { return; } if (tag.IsEmptyTag) { // the tag is its own element objects[objects.Count - 1] = new InternalElement(tag) { Length = tag.Length, LengthTouched = tag.LengthTouched, IsPropertyNested = true, StartRelativeToParent = tag.StartRelativeToParent, NestedObjects = new [] { tag.SetStartRelativeToParent(0) } }; } else if (tag.IsStartTag) { elementNameStack.Push(tag.Name); } else if (tag.IsEndTag && elementNameStack.Count > 0) { // Now look for the start element: int startIndex = objects.Count - 2; bool ok = false; string expectedName = elementNameStack.Pop(); if (tag.Name == expectedName) { while (startIndex > 0) { var startTag = objects[startIndex] as InternalTag; if (startTag != null) { if (startTag.IsStartTag) { ok = (startTag.Name == expectedName); break; } else if (startTag.IsEndTag) { break; } } startIndex--; } } if (ok) { // We found a correct nesting, let's create an element: InternalObject[] nestedObjects = new InternalObject[objects.Count - startIndex]; int oldStartRelativeToParent = objects[startIndex].StartRelativeToParent; int pos = 0; int maxLengthTouched = 0; for (int i = 0; i < nestedObjects.Length; i++) { nestedObjects[i] = objects[startIndex + i].SetStartRelativeToParent(pos); maxLengthTouched = Math.Max(maxLengthTouched, pos + nestedObjects[i].LengthTouched); pos += nestedObjects[i].Length; } objects.RemoveRange(startIndex, nestedObjects.Length); objects.Add( new InternalElement((InternalTag)nestedObjects[0]) { HasEndTag = true, IsPropertyNested = true, Length = pos, LengthTouched = maxLengthTouched, StartRelativeToParent = oldStartRelativeToParent, NestedObjects = nestedObjects }); } else { // Mismatched name - the nesting isn't properly; // clear the whole stack so that none of the currently open elements are closed as properly-nested. elementNameStack.Clear(); } } }
public InternalObjectFrame(InternalObject internalObject, int parentStartPosition) { this.InternalObject = internalObject; this.ParentStartPosition = parentStartPosition; }
internal AXmlObject(AXmlObject parent, int startOffset, InternalObject internalObject) { this.parent = parent; this.startOffset = startOffset; this.internalObject = internalObject; }
internal IncrementalParserState(int textLength, ITextSourceVersion version, InternalObject[] objects) { this.TextLength = textLength; this.Version = version; this.Objects = objects; }
void ProcessObject(InternalObject obj, int indentationLevel, ConfigurationList oldConfigurations, ref ConfigurationList newConfigurations) { newConfigurations.Clear(); InternalTag tag = obj as InternalTag; for (int i = 0; i < oldConfigurations.count; i++) { Configuration c = oldConfigurations.configurations[i]; if (c.Cost == InfiniteCost) continue; if (tag != null && tag.IsStartTag) { // Push start tag newConfigurations.Add( c.OpenTags.Push(tag.Name, indentationLevel), c.Document.Push(obj), c.Cost ); } else if (tag != null && tag.IsEndTag) { // We can ignore this end tag newConfigurations.Add( c.OpenTags, c.Document.Push(StartTagPlaceholder).Push(obj), c.Cost + IgnoreEndTagCost ); // We can match this end tag with one of the currently open tags var openTags = c.OpenTags; var documentWithInsertedEndTags = c.Document; uint newCost = c.Cost; while (!openTags.IsEmpty) { uint matchCost = 0; if (openTags.IndentationLevel >= 0 && indentationLevel >= 0) matchCost += (uint)Math.Abs(openTags.IndentationLevel - indentationLevel); if (openTags.Name != tag.Name) matchCost += MismatchedNameCost; newConfigurations.Add( openTags.Pop(), documentWithInsertedEndTags.Push(obj), newCost + matchCost ); newCost += MissingEndTagCost; openTags = openTags.Pop(); documentWithInsertedEndTags = documentWithInsertedEndTags.Push(EndTagPlaceholder); } } else { newConfigurations.Add( c.OpenTags, c.Document.Push(obj), c.Cost ); } } }
internal AXmlReader(InternalObject[] objects, int startPosition = 0, Func<int, TextLocation> offsetToTextLocation = null) { this.offsetToTextLocation = offsetToTextLocation; objectIterator = new ObjectIterator(objects, startPosition); objectIterator.StopAtElementEnd = true; }
InternalObjectFrame BeginInternalObject(InternalObject internalObject, int beginLocation) { internalObject.StartRelativeToParent = beginLocation - internalObjectStartPosition; var frame = new InternalObjectFrame(internalObject, internalObjectStartPosition); internalObjectStartPosition = CurrentLocation; return frame; }
InternalObjectFrame BeginInternalObject(InternalObject internalObject) { return BeginInternalObject(internalObject, this.CurrentLocation); }
void StoreObject(InternalObject obj) { objects.Add(obj); // Now combine properly-nested elements: if (elementNameStack == null) return; // parsing tag soup InternalTag tag = obj as InternalTag; if (tag == null) return; if (tag.IsEmptyTag) { // the tag is its own element objects[objects.Count - 1] = new InternalElement(tag) { Length = tag.Length, LengthTouched = tag.LengthTouched, IsPropertyNested = true, StartRelativeToParent = tag.StartRelativeToParent, NestedObjects = new [] { tag.SetStartRelativeToParent(0) } }; } else if (tag.IsStartTag) { elementNameStack.Push(tag.Name); } else if (tag.IsEndTag && elementNameStack.Count > 0) { // Now look for the start element: int startIndex = objects.Count - 2; bool ok = false; string expectedName = elementNameStack.Pop(); if (tag.Name == expectedName) { while (startIndex > 0) { var startTag = objects[startIndex] as InternalTag; if (startTag != null) { if (startTag.IsStartTag) { ok = (startTag.Name == expectedName); break; } else if (startTag.IsEndTag) { break; } } startIndex--; } } if (ok) { // We found a correct nesting, let's create an element: InternalObject[] nestedObjects = new InternalObject[objects.Count - startIndex]; int oldStartRelativeToParent = objects[startIndex].StartRelativeToParent; int pos = 0; int maxLengthTouched = 0; for (int i = 0; i < nestedObjects.Length; i++) { nestedObjects[i] = objects[startIndex + i].SetStartRelativeToParent(pos); maxLengthTouched = Math.Max(maxLengthTouched, pos + nestedObjects[i].LengthTouched); pos += nestedObjects[i].Length; } objects.RemoveRange(startIndex, nestedObjects.Length); objects.Add( new InternalElement((InternalTag)nestedObjects[0]) { HasEndTag = true, IsPropertyNested = true, Length = pos, LengthTouched = maxLengthTouched, StartRelativeToParent = oldStartRelativeToParent, NestedObjects = nestedObjects }); } else { // Mismatched name - the nesting isn't properly; // clear the whole stack so that none of the currently open elements are closed as properly-nested. elementNameStack.Clear(); } } }