1 28 29 package net.n3.nanoxml; 30 31 import java.io.FileInputStream ; 32 import java.io.FileNotFoundException ; 33 import java.io.IOException ; 34 import java.io.InputStream ; 35 import java.io.InputStreamReader ; 36 import java.io.LineNumberReader ; 37 import java.io.PushbackInputStream ; 38 import java.io.PushbackReader ; 39 import java.io.Reader ; 40 import java.io.StringReader ; 41 import java.io.UnsupportedEncodingException ; 42 import java.net.MalformedURLException ; 43 import java.net.URL ; 44 import java.util.Stack ; 45 46 52 public class StdXMLReader implements IXMLReader 53 { 54 55 58 private Stack pbreaders; 59 60 63 private Stack linereaders; 64 65 68 private Stack systemIds; 69 70 73 private Stack publicIds; 74 75 78 private PushbackReader currentPbReader; 79 80 83 private LineNumberReader currentLineReader; 84 85 88 private URL currentSystemID; 89 90 93 private String currentPublicID; 94 95 100 public static IXMLReader stringReader(String str) 101 { 102 return new StdXMLReader(new StringReader (str)); 103 } 104 105 113 public static IXMLReader fileReader(String filename) throws FileNotFoundException , IOException 114 { 115 IXMLReader reader = new StdXMLReader(new FileInputStream (filename)); 116 reader.setSystemID(filename); 117 return reader; 118 } 119 120 130 public StdXMLReader(String publicID, String systemID) throws MalformedURLException , 131 FileNotFoundException , IOException 132 { 133 URL systemIDasURL = null; 134 135 try 136 { 137 systemIDasURL = new URL (systemID); 138 } 139 catch (MalformedURLException e) 140 { 141 systemID = "file:" + systemID; 142 143 try 144 { 145 systemIDasURL = new URL (systemID); 146 } 147 catch (MalformedURLException e2) 148 { 149 throw e; 150 } 151 } 152 153 Reader reader = this.openStream(publicID, systemIDasURL.toString()); 154 this.currentLineReader = new LineNumberReader (reader); 155 this.currentPbReader = new PushbackReader (this.currentLineReader, 2); 156 this.pbreaders = new Stack (); 157 this.linereaders = new Stack (); 158 this.publicIds = new Stack (); 159 this.systemIds = new Stack (); 160 this.currentPublicID = publicID; 161 this.currentSystemID = systemIDasURL; 162 } 163 164 169 public StdXMLReader(Reader reader) 170 { 171 this.currentLineReader = new LineNumberReader (reader); 172 this.currentPbReader = new PushbackReader (this.currentLineReader, 2); 173 this.pbreaders = new Stack (); 174 this.linereaders = new Stack (); 175 this.publicIds = new Stack (); 176 this.systemIds = new Stack (); 177 this.currentPublicID = ""; 178 179 try 180 { 181 this.currentSystemID = new URL ("file:."); 182 } 183 catch (MalformedURLException e) 184 { 185 } 187 } 188 189 192 protected void finalize() throws Throwable 193 { 194 this.currentLineReader = null; 195 this.currentPbReader = null; 196 this.pbreaders.clear(); 197 this.pbreaders = null; 198 this.linereaders.clear(); 199 this.linereaders = null; 200 this.publicIds.clear(); 201 this.publicIds = null; 202 this.systemIds.clear(); 203 this.systemIds = null; 204 this.currentPublicID = null; 205 super.finalize(); 206 } 207 208 215 protected String getEncoding(String str) 216 { 217 if (!str.startsWith("<?xml")) { return null; } 218 219 int index = 5; 220 221 while (index < str.length()) 222 { 223 StringBuffer key = new StringBuffer (); 224 225 while ((index < str.length()) && (str.charAt(index) <= ' ')) 226 { 227 index++; 228 } 229 230 while ((index < str.length()) && (str.charAt(index) >= 'a') 231 && (str.charAt(index) <= 'z')) 232 { 233 key.append(str.charAt(index)); 234 index++; 235 } 236 237 while ((index < str.length()) && (str.charAt(index) <= ' ')) 238 { 239 index++; 240 } 241 242 if ((index >= str.length()) || (str.charAt(index) != '=')) 243 { 244 break; 245 } 246 247 while ((index < str.length()) && (str.charAt(index) != '\'') 248 && (str.charAt(index) != '"')) 249 { 250 index++; 251 } 252 253 if (index >= str.length()) 254 { 255 break; 256 } 257 258 char delimiter = str.charAt(index); 259 index++; 260 int index2 = str.indexOf(delimiter, index); 261 262 if (index2 < 0) 263 { 264 break; 265 } 266 267 if ("encoding".equals(key.toString())) { return str.substring(index, index2); } 268 269 index = index2 + 1; 270 } 271 272 return null; 273 } 274 275 283 protected Reader stream2reader(InputStream stream, StringBuffer charsRead) throws IOException 284 { 285 PushbackInputStream pbstream = new PushbackInputStream (stream); 286 int b = pbstream.read(); 287 288 switch (b) 289 { 290 case 0x00: 291 case 0xFE: 292 case 0xFF: 293 pbstream.unread(b); 294 return new InputStreamReader (pbstream, "UTF-16"); 295 296 case 0xEF: 297 for (int i = 0; i < 2; i++) 298 { 299 pbstream.read(); 300 } 301 302 return new InputStreamReader (pbstream, "UTF-8"); 303 304 case 0x3C: 305 b = pbstream.read(); 306 charsRead.append('<'); 307 308 while ((b > 0) && (b != 0x3E)) 309 { 310 charsRead.append((char) b); 311 b = pbstream.read(); 312 } 313 314 if (b > 0) 315 { 316 charsRead.append((char) b); 317 } 318 319 String encoding = this.getEncoding(charsRead.toString()); 320 321 if (encoding == null) { return new InputStreamReader (pbstream, "UTF-8"); } 322 323 charsRead.setLength(0); 324 325 try 326 { 327 return new InputStreamReader (pbstream, encoding); 328 } 329 catch (UnsupportedEncodingException e) 330 { 331 return new InputStreamReader (pbstream, "UTF-8"); 332 } 333 334 default: 335 charsRead.append((char) b); 336 return new InputStreamReader (pbstream, "UTF-8"); 337 } 338 } 339 340 347 public StdXMLReader(InputStream stream) throws IOException 348 { 349 StringBuffer charsRead = new StringBuffer (); 350 Reader reader = this.stream2reader(stream, charsRead); 351 this.currentLineReader = new LineNumberReader (reader); 352 this.currentPbReader = new PushbackReader (this.currentLineReader, 2); 353 this.pbreaders = new Stack (); 354 this.linereaders = new Stack (); 355 this.publicIds = new Stack (); 356 this.systemIds = new Stack (); 357 this.currentPublicID = ""; 358 359 try 360 { 361 this.currentSystemID = new URL ("file:."); 362 } 363 catch (MalformedURLException e) 364 { 365 } 367 368 this.startNewStream(new StringReader (charsRead.toString())); 369 } 370 371 378 public char read() throws IOException 379 { 380 int ch = this.currentPbReader.read(); 381 382 while (ch < 0) 383 { 384 if (this.pbreaders.empty()) { throw new IOException ("Unexpected EOF"); } 385 386 this.currentPbReader.close(); 387 this.currentPbReader = (PushbackReader ) this.pbreaders.pop(); 388 this.currentLineReader = (LineNumberReader ) this.linereaders.pop(); 389 this.currentSystemID = (URL ) this.systemIds.pop(); 390 this.currentPublicID = (String ) this.publicIds.pop(); 391 ch = this.currentPbReader.read(); 392 } 393 394 if (ch == 0x0D) 395 { ch = this.currentPbReader.read(); 400 401 if (ch != 0x0A && ch > 0) 402 { this.currentPbReader.unread(ch); 404 } 405 return (char) 0x0A; } 407 408 return (char) ch; 409 } 410 411 416 public boolean atEOFOfCurrentStream() throws IOException 417 { 418 int ch = this.currentPbReader.read(); 419 420 if (ch < 0) 421 { 422 return true; 423 } 424 else 425 { 426 this.currentPbReader.unread(ch); 427 return false; 428 } 429 } 430 431 436 public boolean atEOF() throws IOException 437 { 438 int ch = this.currentPbReader.read(); 439 440 while (ch < 0) 441 { 442 if (this.pbreaders.empty()) { return true; } 443 444 this.currentPbReader.close(); 445 this.currentPbReader = (PushbackReader ) this.pbreaders.pop(); 446 this.currentLineReader = (LineNumberReader ) this.linereaders.pop(); 447 this.currentSystemID = (URL ) this.systemIds.pop(); 448 this.currentPublicID = (String ) this.publicIds.pop(); 449 ch = this.currentPbReader.read(); 450 } 451 452 this.currentPbReader.unread(ch); 453 return false; 454 } 455 456 461 public void unread(char ch) throws IOException 462 { 463 this.currentPbReader.unread(ch); 464 } 465 466 477 public Reader openStream(String publicID, String systemID) throws MalformedURLException , 478 FileNotFoundException , IOException 479 { 480 URL url = new URL (this.currentSystemID, systemID); 481 StringBuffer charsRead = new StringBuffer (); 482 Reader reader = this.stream2reader(url.openStream(), charsRead); 483 484 if (charsRead.length() == 0) { return reader; } 485 486 String charsReadStr = charsRead.toString(); 487 PushbackReader pbreader = new PushbackReader (reader, charsReadStr.length()); 488 for (int i = charsReadStr.length() - 1; i >= 0; i--) 489 { 490 pbreader.unread(charsReadStr.charAt(i)); 491 } 492 493 return pbreader; 494 } 495 496 502 public void startNewStream(Reader reader) 503 { 504 this.pbreaders.push(this.currentPbReader); 505 this.linereaders.push(this.currentLineReader); 506 this.systemIds.push(this.currentSystemID); 507 this.publicIds.push(this.currentPublicID); 508 this.currentLineReader = new LineNumberReader (reader); 509 this.currentPbReader = new PushbackReader (this.currentLineReader, 2); 510 } 511 512 515 public int getLineNr() 516 { 517 return this.currentLineReader.getLineNumber() + 1; 518 } 519 520 527 public void setSystemID(String systemID) throws MalformedURLException 528 { 529 this.currentSystemID = new URL (this.currentSystemID, systemID); 530 } 531 532 537 public void setPublicID(String publicID) 538 { 539 this.currentPublicID = publicID; 540 } 541 542 545 public String getSystemID() 546 { 547 return this.currentSystemID.toString(); 548 } 549 550 553 public String getPublicID() 554 { 555 return this.currentPublicID; 556 } 557 558 } 559 | Popular Tags |