10d4feee6275f08268863fa28ead05283625c96f
[phpeclipse.git] /
1 /*
2  * Copyright (c) 2002-2004 Widespace, OU 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  *     Igor Malinin - initial contribution
10  *
11  * $Id: AbstractDocumentProvider.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
12  */
13
14 package net.sourceforge.phpeclipse.xml.ui.internal.text;
15
16 import java.io.BufferedInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19
20 import net.sourceforge.phpeclipse.ui.editor.I18NDocumentProvider;
21
22 import org.eclipse.jface.text.rules.IWhitespaceDetector;
23
24 /**
25  * 
26  * 
27  * @author Igor Malinin
28  */
29 public abstract class AbstractDocumentProvider extends I18NDocumentProvider {
30         protected IWhitespaceDetector detector = new WhitespaceDetector();
31
32         /*
33          * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getDefaultEncoding()
34          */
35         public String getDefaultEncoding() {
36                 return "UTF-8";
37         }
38
39         public String getDeclaredEncoding(InputStream in) throws IOException {
40                 if (!in.markSupported()) {
41                         in = new BufferedInputStream(in, 512);
42                 }
43
44                 in.mark(512);
45                 String encoding = super.getDeclaredEncoding(in);
46                 if (encoding != null) {
47                         return encoding;
48                 }
49
50                 in.reset();
51
52                 // check Prolog-Start <?xml
53                 if (!skipXMLDecl(in)) {
54                         return null;
55                 }
56
57                 // detect 'encoding'
58                 skipEncoding(in);
59
60                 // read encoding
61                 int delimiter;
62
63                 while (true) {
64                         int ch = in.read();
65                         if (ch < 0) {
66                                 return null;
67                         }
68
69                         if (detector.isWhitespace((char) ch)) {
70                                 continue;
71                         }
72
73                         if (ch == '"' || ch == '\'') {
74                                 delimiter = ch;
75                                 break;
76                         }
77
78                         return null;
79                 }
80
81                 StringBuffer buf = new StringBuffer();
82
83                 while (true) {
84                         int ch = in.read();
85                         if (ch < 0) {
86                                 return null;
87                         }
88
89                         if (ch == delimiter) {
90                                 break;
91                         }
92
93                         buf.append((char) ch);
94                 }
95
96                 return buf.toString();
97         }
98
99         private boolean skipXMLDecl(InputStream in) throws IOException {
100                 int ch = in.read();
101                 if (ch != '<') {
102                         return false;
103                 }
104
105                 ch = in.read();
106                 if (ch != '?') {
107                         return false;
108                 }
109
110                 ch = in.read();
111                 if (ch != 'x') {
112                         return false;
113                 }
114
115                 ch = in.read();
116                 if (ch != 'm') {
117                         return false;
118                 }
119
120                 ch = in.read();
121                 if (ch != 'l') {
122                         return false;
123                 }
124
125                 return true;
126         }
127
128         private boolean skipEncoding(InputStream in) throws IOException {
129                 int ch = in.read();
130
131                 boolean whitespace = false;
132
133                 while (true) {
134                         if (ch < 0) {
135                                 return false;
136                         }
137
138                         if (detector.isWhitespace((char) ch)) {
139                                 ch = in.read();
140                                 whitespace = true;
141                                 continue;
142                         }
143
144                         if (ch == '?' || ch == '<') {
145                                 return false;
146                         }
147
148                         if (ch != 'e') {
149                                 ch = in.read();
150                                 whitespace = false;
151                                 continue;
152                         }
153
154                         if (!whitespace) {
155                                 ch = in.read();
156                                 continue;
157                         }
158
159                         if ((ch = in.read()) == 'n' && (ch = in.read()) == 'c'
160                                         && (ch = in.read()) == 'o' && (ch = in.read()) == 'd'
161                                         && (ch = in.read()) == 'i' && (ch = in.read()) == 'n'
162                                         && (ch = in.read()) == 'g') {
163                                 break;
164                         }
165
166                         whitespace = false;
167                 }
168
169                 // '='
170                 while (true) {
171                         ch = in.read();
172                         if (ch < 0) {
173                                 return false;
174                         }
175
176                         if (detector.isWhitespace((char) ch)) {
177                                 continue;
178                         }
179
180                         if (ch == '=') {
181                                 break;
182                         }
183
184                         return false;
185                 }
186
187                 return true;
188         }
189 }