97a0edd679f90543e859645d80f069cce274c778
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / text / PHPPairMatcher.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 java.io.IOException;
9
10 import org.eclipse.jface.text.BadLocationException;
11 import org.eclipse.jface.text.IDocument;
12 import org.eclipse.jface.text.IRegion;
13 import org.eclipse.jface.text.Region;
14
15 /**
16  * Helper class for match pairs of characters.
17  */
18 public class PHPPairMatcher {
19         
20         
21         public static final int LEFT=      1;
22         public static final int RIGHT= 2;
23
24         
25         protected char[] fPairs;
26         protected IDocument fDocument;
27         protected int fOffset;
28         
29         protected int fStartPos;
30         protected int fEndPos;
31         protected int fAnchor;
32         
33         protected PHPCodeReader fReader= new PHPCodeReader();
34         
35         
36         public PHPPairMatcher(char[] pairs) {
37                 fPairs= pairs;
38         }
39         
40         public IRegion match(IDocument document, int offset) {
41
42                 fOffset= offset;
43
44                 if (fOffset < 0)
45                         return null;
46
47                 fDocument= document;
48
49                 if (matchPairsAt() && fStartPos != fEndPos)
50                         return new Region(fStartPos, fEndPos - fStartPos + 1);
51                         
52                 return null;
53         }
54         
55         public int getAnchor() {
56                 return fAnchor;
57         }
58         
59         public void dispose() {
60                 fDocument= null;
61                 if (fReader != null) {
62                         try {
63                                 fReader.close();
64                         } catch (IOException x) {
65                                 // ignore
66                         }
67                         fReader= null;
68                 }
69         }
70         
71         protected boolean matchPairsAt() {
72
73                 int i;
74                 int pairIndex1= fPairs.length;
75                 int pairIndex2= fPairs.length;
76
77                 fStartPos= -1;
78                 fEndPos= -1;
79
80                 // get the chars preceding and following the start position
81                 try {
82
83                         char prevChar= fDocument.getChar(Math.max(fOffset - 1, 0));
84                         char nextChar= fDocument.getChar(fOffset);
85
86                         // search for opening peer character next to the activation point
87                         for (i= 0; i < fPairs.length; i= i + 2) {
88                                 if (nextChar == fPairs[i]) {
89                                         fStartPos= fOffset;
90                                         pairIndex1= i;
91                                 } else if (prevChar == fPairs[i]) {
92                                         fStartPos= fOffset - 1;
93                                         pairIndex1= i;
94                                 }
95                         }
96                         
97                         // search for closing peer character next to the activation point
98                         for (i= 1; i < fPairs.length; i= i + 2) {
99                                 if (prevChar == fPairs[i]) {
100                                         fEndPos= fOffset - 1;
101                                         pairIndex2= i;
102                                 } else if (nextChar == fPairs[i]) {
103                                         fEndPos= fOffset;
104                                         pairIndex2= i;
105                                 }
106                         }
107
108                         if (fEndPos > -1) {
109                                 fAnchor= RIGHT;
110                                 fStartPos= searchForOpeningPeer(fEndPos, fPairs[pairIndex2 - 1], fPairs[pairIndex2], fDocument);
111                                 if (fStartPos > -1)
112                                         return true;
113                                 else
114                                         fEndPos= -1;
115                         }       else if (fStartPos > -1) {
116                                 fAnchor= LEFT;
117                                 fEndPos= searchForClosingPeer(fStartPos, fPairs[pairIndex1], fPairs[pairIndex1 + 1], fDocument);
118                                 if (fEndPos > -1)
119                                         return true;
120                                 else
121                                         fStartPos= -1;
122                         }
123
124                 } catch (BadLocationException x) {
125                 } catch (IOException x) {
126                 }
127
128                 return false;
129         }
130         
131         protected int searchForClosingPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException {
132                 
133                 fReader.configureForwardReader(document, offset + 1, document.getLength(), true, true);
134                 
135                 int stack= 1;
136                 int c= fReader.read();
137                 while (c != PHPCodeReader.EOF) {
138                         if (c == openingPeer && c != closingPeer)
139                                 stack++;
140                         else if (c == closingPeer)
141                                 stack--;
142                                 
143                         if (stack == 0)
144                                 return fReader.getOffset();
145                                 
146                         c= fReader.read();
147                 }
148                 
149                 return  -1;
150         }
151         
152         protected int searchForOpeningPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException {
153                 
154                 fReader.configureBackwardReader(document, offset, true, true);
155                 
156                 int stack= 1;
157                 int c= fReader.read();
158                 while (c != PHPCodeReader.EOF) {
159                         if (c == closingPeer && c != openingPeer)
160                                 stack++;
161                         else if (c == openingPeer)
162                                 stack--;
163                                 
164                         if (stack == 0)
165                                 return fReader.getOffset();
166                                 
167                         c= fReader.read();
168                 }
169                 
170                 return -1;
171         }
172 }