~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
ļ»æ// Copyright (c) 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
 
 
19
 
using System;
20
 
using System.Collections.Generic;
21
 
 
22
 
namespace ICSharpCode.NRefactory.Editor
23
 
{
24
 
        /// <summary>
25
 
        /// Read-only implementation of <see cref="IDocument"/>.
26
 
        /// </summary>
27
 
        [Serializable]
28
 
        public sealed class ReadOnlyDocument : IDocument
29
 
        {
30
 
                readonly ITextSource textSource;
31
 
                int[] lines;
32
 
                
33
 
                static readonly char[] newline = { '\r', '\n' };
34
 
                
35
 
                /// <summary>
36
 
                /// Creates a new ReadOnlyDocument from the given text source.
37
 
                /// </summary>
38
 
                public ReadOnlyDocument(ITextSource textSource)
39
 
                {
40
 
                        if (textSource == null)
41
 
                                throw new ArgumentNullException("textSource");
42
 
                        // ensure that underlying buffer is immutable
43
 
                        this.textSource = textSource.CreateSnapshot();
44
 
                        List<int> lines = new List<int>();
45
 
                        lines.Add(0);
46
 
                        int offset = 0;
47
 
                        int textLength = textSource.TextLength;
48
 
                        while ((offset = textSource.IndexOfAny(newline, offset, textLength - offset)) >= 0) {
49
 
                                offset++;
50
 
                                if (textSource.GetCharAt(offset - 1) == '\r' && offset < textLength && textSource.GetCharAt(offset) == '\n') {
51
 
                                        offset++;
52
 
                                }
53
 
                                lines.Add(offset);
54
 
                        }
55
 
                        this.lines = lines.ToArray();
56
 
                }
57
 
                
58
 
                /// <summary>
59
 
                /// Creates a new ReadOnlyDocument from the given string.
60
 
                /// </summary>
61
 
                public ReadOnlyDocument(string text)
62
 
                        : this(new StringTextSource(text))
63
 
                {
64
 
                }
65
 
                
66
 
                /// <inheritdoc/>
67
 
                public IDocumentLine GetLineByNumber(int lineNumber)
68
 
                {
69
 
                        if (lineNumber < 1 || lineNumber > lines.Length)
70
 
                                throw new ArgumentOutOfRangeException("lineNumber", lineNumber, "Value must be between 1 and " + lines.Length);
71
 
                        return new ReadOnlyDocumentLine(this, lineNumber);
72
 
                }
73
 
                
74
 
                sealed class ReadOnlyDocumentLine : IDocumentLine
75
 
                {
76
 
                        readonly ReadOnlyDocument doc;
77
 
                        readonly int lineNumber;
78
 
                        readonly int offset, endOffset;
79
 
                        
80
 
                        public ReadOnlyDocumentLine(ReadOnlyDocument doc, int lineNumber)
81
 
                        {
82
 
                                this.doc = doc;
83
 
                                this.lineNumber = lineNumber;
84
 
                                this.offset = doc.GetStartOffset(lineNumber);
85
 
                                this.endOffset = doc.GetEndOffset(lineNumber);
86
 
                        }
87
 
                        
88
 
                        public override int GetHashCode()
89
 
                        {
90
 
                                return doc.GetHashCode() ^ lineNumber;
91
 
                        }
92
 
                        
93
 
                        public override bool Equals(object obj)
94
 
                        {
95
 
                                ReadOnlyDocumentLine other = obj as ReadOnlyDocumentLine;
96
 
                                return other != null && doc == other.doc && lineNumber == other.lineNumber;
97
 
                        }
98
 
                        
99
 
                        public int Offset {
100
 
                                get { return offset; }
101
 
                        }
102
 
                        
103
 
                        public int Length {
104
 
                                get { return endOffset - offset; }
105
 
                        }
106
 
                        
107
 
                        public int EndOffset {
108
 
                                get { return endOffset; }
109
 
                        }
110
 
                        
111
 
                        public int TotalLength {
112
 
                                get {
113
 
                                        return doc.GetTotalEndOffset(lineNumber) - offset;
114
 
                                }
115
 
                        }
116
 
                        
117
 
                        public int DelimiterLength {
118
 
                                get {
119
 
                                        return doc.GetTotalEndOffset(lineNumber) - endOffset;
120
 
                                }
121
 
                        }
122
 
                        
123
 
                        public int LineNumber {
124
 
                                get { return lineNumber; }
125
 
                        }
126
 
                        
127
 
                        public IDocumentLine PreviousLine {
128
 
                                get {
129
 
                                        if (lineNumber == 1)
130
 
                                                return null;
131
 
                                        else
132
 
                                                return new ReadOnlyDocumentLine(doc, lineNumber - 1);
133
 
                                }
134
 
                        }
135
 
                        
136
 
                        public IDocumentLine NextLine {
137
 
                                get {
138
 
                                        if (lineNumber == doc.LineCount)
139
 
                                                return null;
140
 
                                        else
141
 
                                                return new ReadOnlyDocumentLine(doc, lineNumber + 1);
142
 
                                }
143
 
                        }
144
 
                        
145
 
                        public bool IsDeleted {
146
 
                                get { return false; }
147
 
                        }
148
 
                }
149
 
                
150
 
                int GetStartOffset(int lineNumber)
151
 
                {
152
 
                        return lines[lineNumber-1];
153
 
                }
154
 
                
155
 
                int GetTotalEndOffset(int lineNumber)
156
 
                {
157
 
                        return lineNumber < lines.Length ? lines[lineNumber] : textSource.TextLength;
158
 
                }
159
 
                
160
 
                int GetEndOffset(int lineNumber)
161
 
                {
162
 
                        if (lineNumber == lines.Length)
163
 
                                return textSource.TextLength;
164
 
                        int off = lines[lineNumber] - 1;
165
 
                        if (off > 0 && textSource.GetCharAt(off - 1) == '\r' && textSource.GetCharAt(off) == '\n')
166
 
                                off--;
167
 
                        return off;
168
 
                }
169
 
                
170
 
                /// <inheritdoc/>
171
 
                public IDocumentLine GetLineByOffset(int offset)
172
 
                {
173
 
                        return GetLineByNumber(GetLineNumberForOffset(offset));
174
 
                }
175
 
                
176
 
                int GetLineNumberForOffset(int offset)
177
 
                {
178
 
                        int r = Array.BinarySearch(lines, offset);
179
 
                        return r < 0 ? ~r : r + 1;
180
 
                }
181
 
                
182
 
                /// <inheritdoc/>
183
 
                public int GetOffset(int line, int column)
184
 
                {
185
 
                        if (line < 1 || line > lines.Length)
186
 
                                throw new ArgumentOutOfRangeException("line", line, "Value must be between 1 and " + lines.Length);
187
 
                        int lineStart = GetStartOffset(line);
188
 
                        if (column <= 1)
189
 
                                return lineStart;
190
 
                        int lineEnd = GetEndOffset(line);
191
 
                        if (column - 1 >= lineEnd - lineStart)
192
 
                                return lineEnd;
193
 
                        return lineStart + column - 1;
194
 
                }
195
 
                
196
 
                /// <inheritdoc/>
197
 
                public int GetOffset(TextLocation location)
198
 
                {
199
 
                        return GetOffset(location.Line, location.Column);
200
 
                }
201
 
                
202
 
                /// <inheritdoc/>
203
 
                public TextLocation GetLocation(int offset)
204
 
                {
205
 
                        if (offset < 0 || offset > textSource.TextLength)
206
 
                                throw new ArgumentOutOfRangeException("offset", offset, "Value must be between 0 and " + textSource.TextLength);
207
 
                        int line = GetLineNumberForOffset(offset);
208
 
                        return new TextLocation(line, offset-GetStartOffset(line)+1);
209
 
                }
210
 
                
211
 
                /// <inheritdoc/>
212
 
                public string Text {
213
 
                        get { return textSource.Text; }
214
 
                        set {
215
 
                                throw new NotSupportedException();
216
 
                        }
217
 
                }
218
 
                
219
 
                /// <inheritdoc/>
220
 
                public int LineCount {
221
 
                        get { return lines.Length; }
222
 
                }
223
 
                
224
 
                /// <inheritdoc/>
225
 
                public ITextSourceVersion Version {
226
 
                        get { return textSource.Version; }
227
 
                }
228
 
                
229
 
                /// <inheritdoc/>
230
 
                public int TextLength {
231
 
                        get { return textSource.TextLength; }
232
 
                }
233
 
                
234
 
                event EventHandler<TextChangeEventArgs> IDocument.TextChanging { add {} remove {} }
235
 
                
236
 
                event EventHandler<TextChangeEventArgs> IDocument.TextChanged { add {} remove {} }
237
 
                
238
 
                event EventHandler IDocument.ChangeCompleted { add {} remove {} }
239
 
                
240
 
                void IDocument.Insert(int offset, string text)
241
 
                {
242
 
                        throw new NotSupportedException();
243
 
                }
244
 
                
245
 
                void IDocument.Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType)
246
 
                {
247
 
                        throw new NotSupportedException();
248
 
                }
249
 
                
250
 
                void IDocument.Remove(int offset, int length)
251
 
                {
252
 
                        throw new NotSupportedException();
253
 
                }
254
 
                
255
 
                void IDocument.Replace(int offset, int length, string newText)
256
 
                {
257
 
                        throw new NotSupportedException();
258
 
                }
259
 
                
260
 
                void IDocument.StartUndoableAction()
261
 
                {
262
 
                }
263
 
                
264
 
                void IDocument.EndUndoableAction()
265
 
                {
266
 
                }
267
 
                
268
 
                IDisposable IDocument.OpenUndoGroup()
269
 
                {
270
 
                        return null;
271
 
                }
272
 
                
273
 
                /// <inheritdoc/>
274
 
                public ITextAnchor CreateAnchor(int offset)
275
 
                {
276
 
                        return new ReadOnlyDocumentTextAnchor(GetLocation(offset), offset);
277
 
                }
278
 
                
279
 
                sealed class ReadOnlyDocumentTextAnchor : ITextAnchor
280
 
                {
281
 
                        readonly TextLocation location;
282
 
                        readonly int offset;
283
 
                        
284
 
                        public ReadOnlyDocumentTextAnchor(TextLocation location, int offset)
285
 
                        {
286
 
                                this.location = location;
287
 
                                this.offset = offset;
288
 
                        }
289
 
                        
290
 
                        public event EventHandler Deleted { add {} remove {} }
291
 
                        
292
 
                        public TextLocation Location {
293
 
                                get { return location; }
294
 
                        }
295
 
                        
296
 
                        public int Offset {
297
 
                                get { return offset; }
298
 
                        }
299
 
                        
300
 
                        public AnchorMovementType MovementType { get; set; }
301
 
                        
302
 
                        public bool SurviveDeletion { get; set; }
303
 
                        
304
 
                        public bool IsDeleted {
305
 
                                get { return false; }
306
 
                        }
307
 
                        
308
 
                        public int Line {
309
 
                                get { return location.Line; }
310
 
                        }
311
 
                        
312
 
                        public int Column {
313
 
                                get { return location.Column; }
314
 
                        }
315
 
                }
316
 
                
317
 
                /// <inheritdoc/>
318
 
                public ITextSource CreateSnapshot()
319
 
                {
320
 
                        return textSource; // textBuffer is immutable
321
 
                }
322
 
                
323
 
                /// <inheritdoc/>
324
 
                public ITextSource CreateSnapshot(int offset, int length)
325
 
                {
326
 
                        return textSource.CreateSnapshot(offset, length);
327
 
                }
328
 
                
329
 
                /// <inheritdoc/>
330
 
                public IDocument CreateDocumentSnapshot()
331
 
                {
332
 
                        return this; // ReadOnlyDocument is immutable
333
 
                }
334
 
                
335
 
                /// <inheritdoc/>
336
 
                public System.IO.TextReader CreateReader()
337
 
                {
338
 
                        return textSource.CreateReader();
339
 
                }
340
 
                
341
 
                /// <inheritdoc/>
342
 
                public System.IO.TextReader CreateReader(int offset, int length)
343
 
                {
344
 
                        return textSource.CreateReader(offset, length);
345
 
                }
346
 
                
347
 
                /// <inheritdoc/>
348
 
                public char GetCharAt(int offset)
349
 
                {
350
 
                        return textSource.GetCharAt(offset);
351
 
                }
352
 
                
353
 
                /// <inheritdoc/>
354
 
                public string GetText(int offset, int length)
355
 
                {
356
 
                        return textSource.GetText(offset, length);
357
 
                }
358
 
                
359
 
                /// <inheritdoc/>
360
 
                public string GetText(ISegment segment)
361
 
                {
362
 
                        return textSource.GetText(segment);
363
 
                }
364
 
                
365
 
                /// <inheritdoc/>
366
 
                public int IndexOf(char c, int startIndex, int count)
367
 
                {
368
 
                        return textSource.IndexOf(c, startIndex, count);
369
 
                }
370
 
                
371
 
                /// <inheritdoc/>
372
 
                public int IndexOfAny(char[] anyOf, int startIndex, int count)
373
 
                {
374
 
                        return textSource.IndexOfAny(anyOf, startIndex, count);
375
 
                }
376
 
                
377
 
                /// <inheritdoc/>
378
 
                public int IndexOf(string searchText, int startIndex, int count, StringComparison comparisonType)
379
 
                {
380
 
                        return textSource.IndexOf(searchText, startIndex, count, comparisonType);
381
 
                }
382
 
                
383
 
                /// <inheritdoc/>
384
 
                public int LastIndexOf(char c, int startIndex, int count)
385
 
                {
386
 
                        return textSource.LastIndexOf(c, startIndex, count);
387
 
                }
388
 
                
389
 
                /// <inheritdoc/>
390
 
                public int LastIndexOf(string searchText, int startIndex, int count, StringComparison comparisonType)
391
 
                {
392
 
                        return textSource.LastIndexOf(searchText, startIndex, count, comparisonType);
393
 
                }
394
 
                
395
 
                object IServiceProvider.GetService(Type serviceType)
396
 
                {
397
 
                        return null;
398
 
                }
399
 
        }
400
 
}