| ofs | hex dump | ascii |
|---|
| 0000 | 50 4b 03 04 0a 00 00 00 08 00 4f 4f fd 4c 3a be 4b a0 46 08 00 00 2a 1f 00 00 20 00 00 00 54 61 | PK........OO.L:.K.F...*.......Ta |
| 0020 | 6e 67 6f 2e 50 50 43 2e 53 79 6e 63 68 72 6f 6e 69 7a 61 74 69 6f 6e 2e 63 73 70 72 6f 6a d5 59 | ngo.PPC.Synchronization.csproj.Y |
| 0040 | eb 6e db 38 16 fe bf c0 be 83 61 14 e8 14 a8 ee 94 2c cd 38 1e 38 ce 65 82 49 3a 46 9c b4 f3 c3 | .n.8......a......,.8.8.e.I:F.... |
| 0060 | c0 82 22 29 47 5b 49 54 25 2a 8d b7 33 4f b6 3f f6 91 f6 15 f6 50 96 64 c9 76 6c b7 0d 30 58 b4 | ..")G[IT%*..3O.?.....P.d.vl..0X. |
| 0080 | 70 24 f2 f0 5c be 73 e1 21 f5 df 7f ff 67 f8 f3 53 1c f5 1e 59 96 87 3c 39 e9 1b aa de ef b1 84 | p$..\.s.!....g..S...Y..<9....... |
| 00a0 | 70 1a 26 8b 93 7e 21 02 c5 ed ff 3c fa fb df 86 d3 8c ff 93 11 d1 bb e3 3c ca df 37 f4 b6 5c 00 | p.&..~!....<............<..7..\. |
| 00c0 | 2c 92 fc a4 ff 20 44 fa a3 a6 e5 e4 81 c5 38 57 e3 90 64 3c e7 81 50 09 8f 35 ca 1e 59 c4 53 96 | ,.....D.......8W..d<..P..5..Y.S. |
| 00e0 | 69 71 ee 17 61 44 35 53 d7 ad 3e b0 ee f5 86 57 71 ca 33 d1 ab 64 9c f4 5f fd 70 33 3b 95 44 e7 | iq..aD5S..>....Wq.3..d.._.p3;.D. |
| 0100 | 4f 82 25 52 54 3e c5 e2 e1 cd bc 99 68 ab f1 66 7e d3 88 9a f0 38 e6 89 9a 66 3c cd fb bd 09 4f | O.%RT>......h..f~....8...f<....O |
| 0120 | 68 28 4a 4d cf 9f c2 5c e4 3f bc 7e 19 d6 af df f4 7b da 4a 77 50 1a ac 12 cb cb 8c 17 69 39 04 | h(JM...\.?.~.....{.JwP.......i9. |
| 0140 | 83 20 38 08 17 45 86 a5 f0 b6 1a 3d 50 a0 33 f9 e6 75 ef e4 a4 f7 fa 75 af 3f 3a 63 7e b1 18 6a | ..8..E.....=P.3..u.....u.?:c~..j |
| 0160 | 9d e9 9a e1 34 c2 22 e0 59 bc c9 ab 1e 6f b1 19 27 cb c9 f4 7e a8 d5 53 0d 8b 15 ba 97 45 48 47 | ....4.".Y....o..'...~..S.....EHG |
| 0180 | 5f 5e 2d e0 8f f1 ea 4f 20 6b 0d 57 94 bf 15 22 2d c4 dd 32 65 a3 28 f4 33 9c 2d 87 5a 6b ac a2 | _^-....O.k.W..."-..2e.(.3.-.Zk.. |
| 01a0 | ba e5 5c bc c3 31 cb 53 4c d8 e8 55 8e 03 96 ae 78 25 30 fa 6a a8 75 09 aa 55 e3 3c 67 b1 1f 2d | ..\..1.SL..U....x%0.j.u..U.<g..- |
| 01c0 | e5 c4 ae 45 9d f9 6a cd 1d ce 16 4c 5c 64 30 f4 99 67 1f 2b df 8c 1e 91 ea 0c b5 67 26 ab a5 17 | ...E..j....L\d0..g.+.......g&... |
| 01e0 | 61 c4 c6 51 b8 48 62 96 88 91 6d 98 43 ad 3b d4 05 47 da 27 91 c8 47 5f 1c 9d 12 d7 b0 90 c2 7c | a..Q.Hb...m.C.;..G.'..G_.......| |
| 0200 | 6c 2b c8 f2 5d c5 27 c4 53 7c 1f f9 c4 70 88 69 23 f7 cf 9f be 5c 8c cf 75 74 3e d1 15 4b 37 2e | l+..].'.S|...p.i#....\..ut>..K7. |
| 0220 | 14 c3 38 b3 94 d3 0b 74 aa e8 fa 44 47 17 03 ef fc e2 74 b2 46 79 cd bf 92 fb 01 67 09 a4 da b5 | ..8....t...DG.....t.Fy.....g.... |
| 0240 | cc 8e 11 1a 6a 9d f7 32 be b4 ed 00 eb c6 dc fe f0 fa 63 2b 46 ca 30 fb 63 15 25 32 5e 2a 4d ca | ....j..2..........c+F.0.c.%2^*M. |
| 0260 | e1 d9 32 f6 21 fa 47 22 2b d8 50 eb 0c b5 c9 ca 30 08 8a 28 aa 68 da 61 f1 5b 2a c2 38 fc 17 cc | ..2.!.G"+.P.....0..(.h.a.[*.8... |
| 0280 | e3 28 07 26 cd 7b 27 b8 64 ce 8d 54 75 be fa 5f e6 dd bc 64 35 9f 4e 27 f3 3a dc 4a aa 46 70 10 | .(.&.{'.d..Tu.._...d5.N'.:.J.Fp. |
| 02a0 | 26 0c 8c cb 05 4e 44 3e 3a 3b 3f bd bf fc e9 ee 76 3c 39 97 5a 74 27 ab 35 e7 59 c6 b3 5b 26 8b | &....ND>:;?.....v<9.Zt'.5.Y..[&. |
| 02c0 | cb 08 c2 2c 4e c5 50 6b 8f fd 75 4e b8 65 11 c3 39 7b c6 0d 25 9e 29 f5 79 12 2d f7 41 bc 72 d3 | ...,N.Pk..uN.e..9{..%.).y.-.A.r. |
| 02e0 | f1 08 57 52 8f c6 f8 2f 44 f7 4a b0 b8 53 52 6f 59 c0 32 d8 9a 58 ef 2a 21 51 41 19 d4 f4 44 84 | ..WR..// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.AvalonEdit.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ICSharpCode.AvalonEdit.Document
{
/// <summary>
/// <para>A checkpoint that allows tracking changes to a TextDocument.</para>
/// <para>
/// Use <see cref="TextDocument.CreateSnapshot(out ChangeTrackingCheckpoint)"/> to create a checkpoint.
/// </para>
/// </summary>
/// <remarks>
/// <para>The <see cref="ChangeTrackingCheckpoint"/> class allows tracking document changes, even from background threads.</para>
/// <para>Once you have two checkpoints, you can call <see cref="ChangeTrackingCheckpoint.GetChangesTo"/> to retrieve the complete list
/// of document changes that happened between those versions of the document.</para>
/// </remarks>
public sealed class ChangeTrackingCheckpoint
{
// Object that is unique per document.
// Used to determine if two checkpoints belong to the same document.
// We don't use a reference to the document itself to allow the GC to reclaim the document memory
// even if there are still references to checkpoints.
readonly object documentIdentifier;
// 'value' is the change from the previous checkpoint to this checkpoint
// TODO: store the change in the older checkpoint instead - if only a reference to the
// newest document version exists, the GC should be able to collect all DocumentChangeEventArgs.
readonly DocumentChangeEventArgs value;
readonly int id;
ChangeTrackingCheckpoint next;
internal ChangeTrackingCheckpoint(object documentIdentifier)
{
this.documentIdentifier = documentIdentifier;
}
internal ChangeTrackingCheckpoint(object documentIdentifier, DocumentChangeEventArgs value, int id)
{
this.documentIdentifier = documentIdentifier;
this.value = value;
this.id = id;
}
internal ChangeTrackingCheckpoint Append(DocumentChangeEventArgs change)
{
Debug.Assert(this.next == null);
this.next = new ChangeTrackingCheckpoint(this.documentIdentifier, change, unchecked( this.id + 1 ));
return this.next;
}
/// <summary>
/// Creates a change tracking checkpoint for the specified document.
/// This method is thread-safe.
/// If you need a ChangeTrackingCheckpoint that's consistent with a snapshot of the document,
/// use <see cref="TextDocument.CreateSnapshot(out ChangeTrackingCheckpoint)"/>.
/// </summary>
public static ChangeTrackingCheckpoint Create(TextDocument document)
{
if (document == null)
throw new ArgumentNullException("document");
return document.CreateChangeTrackingCheckpoint();
}
/// <summary>
/// Gets whether this checkpoint belongs to the same document as the other checkpoint.
/// </summary>
public bool BelongsToSameDocumentAs(ChangeTrackingCheckpoint other)
{
if (other == null)
throw new ArgumentNullException("other");
return documentIdentifier == other.documentIdentifier;
}
/// <summary>
/// Compares the age of this checkpoint to the other checkpoint.
/// </summary>
/// <remarks>This method is thread-safe.</remarks>
/// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this checkpoint.</exception>
/// <returns>-1 if this checkpoint is older than <paramref name="other"/>.
/// 0 if <c>this</c>==<paramref name="other"/>.
/// 1 if this checkpoint is newer than <paramref name="other"/>.</returns>
public int CompareAge(ChangeTrackingCheckpoint other)
{
if (other == null)
throw new ArgumentNullException("other");
if (other.documentIdentifier != this.documentIdentifier)
throw new ArgumentException("Checkpoints do not belong to the same document.");
// We will allow overflows, but assume that the maximum distance between checkpoints is 2^31-1.
// This is guaranteed on x86 because so many checkpoints don't fit into memory.
return Math.Sign(unchecked( this.id - other.id ));
}
/// <summary>
/// Gets the changes from this checkpoint to the other checkpoint.
/// If 'other' is older than this checkpoint, reverse changes are calculated.
/// </summary>
/// <remarks>This method is thread-safe.</remarks>
/// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this checkpoint.</exception>
public IEnumerable<DocumentChangeEventArgs> GetChangesTo(ChangeTrackingCheckpoint other)
{
int result = CompareAge(other);
if (result < 0)
return GetForwardChanges(other);
else if (result > 0)
return other.GetForwardChanges(this).Reverse().Select(change => change.Invert());
else
return Empty<DocumentChangeEventArgs>.Array;
}
IEnumerable<DocumentChangeEventArgs> GetForwardChanges(ChangeTrackingCheckpoint other)
{
// Return changes from this(exclusive) to other(inclusive).
ChangeTrackingCheckpoint node = this;
do {
node = node.next;
yield return node.value;
} while (node != other);
}
/// <summary>
/// Calculates where the offset has moved in the other buffer version.
/// </summary>
/// <remarks>This method is thread-safe.</remarks>
/// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this checkpoint.</exception>
public int MoveOffsetTo(ChangeTrackingCheckpoint other, int oldOffset, AnchorMovementType movement)
{
int offset = oldOffset;
foreach (DocumentChangeEventArgs e in GetChangesTo(other)) {
offset = e.GetNewOffset(offset, movement);
}
return offset;
}
}
}
|