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