bugfix 1412408
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / text / BufferedDocumentScanner.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text;
12
13
14 import org.eclipse.jface.text.Assert;
15 import org.eclipse.jface.text.BadLocationException;
16 import org.eclipse.jface.text.IDocument;
17 import org.eclipse.jface.text.rules.ICharacterScanner;
18
19
20
21 /**
22  * A buffered document scanner. The buffer always contains a section
23  * of a fixed size of the document to be scanned.
24  */
25
26 public final class BufferedDocumentScanner implements ICharacterScanner {
27
28         /** The document being scanned. */
29         private IDocument fDocument;
30         /** The offset of the document range to scan. */
31         private int fRangeOffset;
32         /** The length of the document range to scan. */
33         private int fRangeLength;
34         /** The delimiters of the document. */
35         private char[][] fDelimiters;
36
37         /** The buffer. */
38         private final char[] fBuffer;
39         /** The offset of the buffer within the document. */
40         private int fBufferOffset;
41         /** The valid length of the buffer for access. */
42         private int fBufferLength;
43         /** The offset of the scanner within the buffer. */
44         private int fOffset;
45
46
47         /**
48          * Creates a new buffered document scanner.
49          * The buffer size is set to the given number of characters.
50          *
51          * @param size the buffer size
52          */
53         public BufferedDocumentScanner(int size) {
54                 Assert.isTrue(size >= 1);
55                 fBuffer= new char[size];
56         }
57
58         /**
59          * Fills the buffer with the contens of the document starting at the given offset.
60          *
61          * @param offset the document offset at which the buffer starts
62          */
63         private final void updateBuffer(int offset) {
64
65                 fBufferOffset= offset;
66
67                 if (fBufferOffset + fBuffer.length > fRangeOffset + fRangeLength)
68                         fBufferLength= fRangeLength - (fBufferOffset - fRangeOffset);
69                 else
70                         fBufferLength= fBuffer.length;
71
72                 try {
73                         final String content= fDocument.get(fBufferOffset, fBufferLength);
74                         if (content!=null) {
75                           content.getChars(0, fBufferLength, fBuffer, 0);
76                         }
77                 } catch (BadLocationException e) {
78                 }
79         }
80
81         /**
82          * Configures the scanner by providing access to the document range over which to scan.
83          *
84          * @param document the document to scan
85          * @param offset the offset of the document range to scan
86          * @param length the length of the document range to scan
87          */
88         public final void setRange(IDocument document, int offset, int length) {
89
90                 fDocument= document;
91                 fRangeOffset= offset;
92                 fRangeLength= length;
93
94                 String[] delimiters= document.getLegalLineDelimiters();
95                 fDelimiters= new char[delimiters.length][];
96                 for (int i= 0; i < delimiters.length; i++)
97                         fDelimiters[i]= delimiters[i].toCharArray();
98
99                 updateBuffer(offset);
100                 fOffset= 0;
101         }
102
103         /*
104          * @see ICharacterScanner#read()
105          */
106         public final int read() {
107
108                 if (fOffset == fBufferLength) {
109                         if (fBufferOffset + fBufferLength == fDocument.getLength())
110                                 return EOF;
111                         else {
112                                 updateBuffer(fBufferOffset + fBufferLength);
113                                 fOffset= 0;
114                         }
115                 }
116         try {
117                 return fBuffer[fOffset++];
118         } catch (ArrayIndexOutOfBoundsException e) {
119           System.out.println("Offset:"+fOffset);
120           System.out.println("Buffer:"+fBuffer.toString());
121           throw e;
122         }
123         }
124
125         /*
126          * @see ICharacterScanner#unread
127          */
128         public final void unread() {
129
130                 if (fOffset == 0) {
131                         if (fBufferOffset == fRangeOffset) {
132                                 // error: BOF
133                         } else {
134                                 updateBuffer(fBufferOffset - fBuffer.length);
135                                 fOffset= fBuffer.length - 1;
136                         }
137                 } else {
138                         --fOffset;
139                 }
140         }
141
142         /*
143          * @see ICharacterScanner#getColumn()
144          */
145         public final int getColumn() {
146
147                 try {
148                         final int offset= fBufferOffset + fOffset;
149                         final int line= fDocument.getLineOfOffset(offset);
150                         final int start= fDocument.getLineOffset(line);
151                         return offset - start;
152                 } catch (BadLocationException e) {
153                 }
154
155                 return -1;
156         }
157
158         /*
159          * @see ICharacterScanner#getLegalLineDelimiters()
160          */
161         public final char[][] getLegalLineDelimiters() {
162                 return fDelimiters;
163         }
164 }