Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.AvalonEdit/5.0.1/AvalonEdit-5.0.1/Document/TextSourceVersionProvider.cs

Last change on this file was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 4.4 KB
Line 
1// Copyright (c) 2014 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 System.Linq;
23using ICSharpCode.AvalonEdit.Utils;
24
25namespace ICSharpCode.AvalonEdit.Document
26{
27  #if !NREFACTORY
28  /// <summary>
29  /// Provides ITextSourceVersion instances.
30  /// </summary>
31  public class TextSourceVersionProvider
32  {
33    Version currentVersion;
34   
35    /// <summary>
36    /// Creates a new TextSourceVersionProvider instance.
37    /// </summary>
38    public TextSourceVersionProvider()
39    {
40      this.currentVersion = new Version(this);
41    }
42   
43    /// <summary>
44    /// Gets the current version.
45    /// </summary>
46    public ITextSourceVersion CurrentVersion {
47      get { return currentVersion; }
48    }
49   
50    /// <summary>
51    /// Replaces the current version with a new version.
52    /// </summary>
53    /// <param name="change">Change from current version to new version</param>
54    public void AppendChange(TextChangeEventArgs change)
55    {
56      if (change == null)
57        throw new ArgumentNullException("change");
58      currentVersion.change = change;
59      currentVersion.next = new Version(currentVersion);
60      currentVersion = currentVersion.next;
61    }
62   
63    [DebuggerDisplay("Version #{id}")]
64    sealed class Version : ITextSourceVersion
65    {
66      // Reference back to the provider.
67      // Used to determine if two checkpoints belong to the same document.
68      readonly TextSourceVersionProvider provider;
69      // ID used for CompareAge()
70      readonly int id;
71     
72      // the change from this version to the next version
73      internal TextChangeEventArgs change;
74      internal Version next;
75     
76      internal Version(TextSourceVersionProvider provider)
77      {
78        this.provider = provider;
79      }
80     
81      internal Version(Version prev)
82      {
83        this.provider = prev.provider;
84        this.id = unchecked( prev.id + 1 );
85      }
86     
87      public bool BelongsToSameDocumentAs(ITextSourceVersion other)
88      {
89        Version o = other as Version;
90        return o != null && provider == o.provider;
91      }
92     
93      public int CompareAge(ITextSourceVersion other)
94      {
95        if (other == null)
96          throw new ArgumentNullException("other");
97        Version o = other as Version;
98        if (o == null || provider != o.provider)
99          throw new ArgumentException("Versions do not belong to the same document.");
100        // We will allow overflows, but assume that the maximum distance between checkpoints is 2^31-1.
101        // This is guaranteed on x86 because so many checkpoints don't fit into memory.
102        return Math.Sign(unchecked( this.id - o.id ));
103      }
104     
105      public IEnumerable<TextChangeEventArgs> GetChangesTo(ITextSourceVersion other)
106      {
107        int result = CompareAge(other);
108        Version o = (Version)other;
109        if (result < 0)
110          return GetForwardChanges(o);
111        else if (result > 0)
112          return o.GetForwardChanges(this).Reverse().Select(change => change.Invert());
113        else
114          return Empty<TextChangeEventArgs>.Array;
115      }
116     
117      IEnumerable<TextChangeEventArgs> GetForwardChanges(Version other)
118      {
119        // Return changes from this(inclusive) to other(exclusive).
120        for (Version node = this; node != other; node = node.next) {
121          yield return node.change;
122        }
123      }
124     
125      public int MoveOffsetTo(ITextSourceVersion other, int oldOffset, AnchorMovementType movement)
126      {
127        int offset = oldOffset;
128        foreach (var e in GetChangesTo(other)) {
129          offset = e.GetNewOffset(offset, movement);
130        }
131        return offset;
132      }
133    }
134  }
135  #endif
136}
Note: See TracBrowser for help on using the repository browser.