Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.Xml-5.5.0/IncrementalParserState.cs @ 12515

Last change on this file since 12515 was 11804, checked in by jkarder, 10 years ago

#2077:

  • added fancy xml documentation
  • fixed configurations and plattforms
File size: 4.4 KB
Line 
1// Copyright (c) 2009-2013 AlphaSierraPapa for the SharpDevelop Team
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4// software and associated documentation files (the "Software"), to deal in the Software
5// without restriction, including without limitation the rights to use, copy, modify, merge,
6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7// to whom the Software is furnished to do so, subject to the following conditions:
8//
9// The above copyright notice and this permission notice shall be included in all copies or
10// substantial portions of the Software.
11//
12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17// DEALINGS IN THE SOFTWARE.
18
19using System;
20using System.Collections.Generic;
21using System.Diagnostics;
22using ICSharpCode.NRefactory.Editor;
23
24namespace ICSharpCode.NRefactory.Xml
25{
26  /// <summary>
27  /// Encapsulates the state of the incremental tag soup parser.
28  /// </summary>
29  public class IncrementalParserState
30  {
31    internal readonly int TextLength;
32    internal readonly ITextSourceVersion Version;
33    internal readonly InternalObject[] Objects;
34   
35    internal IncrementalParserState(int textLength, ITextSourceVersion version, InternalObject[] objects)
36    {
37      this.TextLength = textLength;
38      this.Version = version;
39      this.Objects = objects;
40    }
41   
42    internal List<UnchangedSegment> GetReuseMapTo(ITextSourceVersion newVersion)
43    {
44      ITextSourceVersion oldVersion = this.Version;
45      if (oldVersion == null || newVersion == null)
46        return null;
47      if (!oldVersion.BelongsToSameDocumentAs(newVersion))
48        return null;
49      List<UnchangedSegment> reuseMap = new List<UnchangedSegment>();
50      reuseMap.Add(new UnchangedSegment(0, 0, this.TextLength));
51      foreach (var change in oldVersion.GetChangesTo(newVersion)) {
52        bool needsSegmentRemoval = false;
53        for (int i = 0; i < reuseMap.Count; i++) {
54          UnchangedSegment segment = reuseMap[i];
55          if (segment.NewOffset + segment.Length <= change.Offset) {
56            // change is completely after this segment
57            continue;
58          }
59          if (change.Offset + change.RemovalLength <= segment.NewOffset) {
60            // change is completely before this segment
61            segment.NewOffset += change.InsertionLength - change.RemovalLength;
62            reuseMap[i] = segment;
63            continue;
64          }
65          // Change is overlapping segment.
66          // Split segment into two parts: the part before change, and the part after change.
67          var segmentBefore = new UnchangedSegment(segment.OldOffset, segment.NewOffset, change.Offset - segment.NewOffset);
68          Debug.Assert(segmentBefore.Length < segment.Length);
69         
70          int lengthAtEnd = segment.NewOffset + segment.Length - (change.Offset + change.RemovalLength);
71          var segmentAfter = new UnchangedSegment(
72            segment.OldOffset + segment.Length - lengthAtEnd,
73            change.Offset + change.InsertionLength,
74            lengthAtEnd);
75          Debug.Assert(segmentAfter.Length < segment.Length);
76          Debug.Assert(segmentBefore.Length + segmentAfter.Length <= segment.Length);
77          Debug.Assert(segmentBefore.NewOffset + segmentBefore.Length <= segmentAfter.NewOffset);
78          Debug.Assert(segmentBefore.OldOffset + segmentBefore.Length <= segmentAfter.OldOffset);
79          if (segmentBefore.Length > 0 && segmentAfter.Length > 0) {
80            reuseMap[i] = segmentBefore;
81            reuseMap.Insert(++i, segmentAfter);
82          } else if (segmentBefore.Length > 0) {
83            reuseMap[i] = segmentBefore;
84          } else {
85            reuseMap[i] = segmentAfter;
86            if (segmentAfter.Length <= 0)
87              needsSegmentRemoval = true;
88          }
89        }
90        if (needsSegmentRemoval)
91          reuseMap.RemoveAll(s => s.Length <= 0);
92      }
93      return reuseMap;
94    }
95  }
96 
97  struct UnchangedSegment
98  {
99    public int OldOffset;
100    public int NewOffset;
101    public int Length;
102   
103    public UnchangedSegment(int oldOffset, int newOffset, int length)
104    {
105      this.OldOffset = oldOffset;
106      this.NewOffset = newOffset;
107      this.Length = length;
108    }
109   
110    public override string ToString()
111    {
112      return string.Format("[UnchangedSegment OldOffset={0}, NewOffset={1}, Length={2}]", OldOffset, NewOffset, Length);
113    }
114  }
115}
Note: See TracBrowser for help on using the repository browser.