mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-19 09:42:11 +03:00
Importing Processing rev. 5503 (1.0.3).
This commit is contained in:
626
core/src/processing/xml/StdXMLReader.java
Normal file
626
core/src/processing/xml/StdXMLReader.java
Normal file
@ -0,0 +1,626 @@
|
||||
/* StdXMLReader.java NanoXML/Java
|
||||
*
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2002/01/04 21:03:28 $
|
||||
* $Name: RELEASE_2_2_1 $
|
||||
*
|
||||
* This file is part of NanoXML 2 for Java.
|
||||
* Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from the
|
||||
* use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
package processing.xml;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
//import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.PushbackReader;
|
||||
import java.io.PushbackInputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Stack;
|
||||
|
||||
|
||||
/**
|
||||
* StdXMLReader reads the data to be parsed.
|
||||
*
|
||||
* @author Marc De Scheemaecker
|
||||
* @version $Name: RELEASE_2_2_1 $, $Revision: 1.4 $
|
||||
*/
|
||||
public class StdXMLReader
|
||||
{
|
||||
|
||||
/**
|
||||
* A stacked reader.
|
||||
*
|
||||
* @author Marc De Scheemaecker
|
||||
* @version $Name: RELEASE_2_2_1 $, $Revision: 1.4 $
|
||||
*/
|
||||
private class StackedReader
|
||||
{
|
||||
|
||||
PushbackReader pbReader;
|
||||
|
||||
LineNumberReader lineReader;
|
||||
|
||||
URL systemId;
|
||||
|
||||
String publicId;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The stack of readers.
|
||||
*/
|
||||
private Stack<StackedReader> readers;
|
||||
|
||||
|
||||
/**
|
||||
* The current push-back reader.
|
||||
*/
|
||||
private StackedReader currentReader;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new reader using a string as input.
|
||||
*
|
||||
* @param str the string containing the XML data
|
||||
*/
|
||||
public static StdXMLReader stringReader(String str)
|
||||
{
|
||||
return new StdXMLReader(new StringReader(str));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new reader using a file as input.
|
||||
*
|
||||
* @param filename the name of the file containing the XML data
|
||||
*
|
||||
* @throws java.io.FileNotFoundException
|
||||
* if the file could not be found
|
||||
* @throws java.io.IOException
|
||||
* if an I/O error occurred
|
||||
*/
|
||||
public static StdXMLReader fileReader(String filename)
|
||||
throws FileNotFoundException,
|
||||
IOException
|
||||
{
|
||||
StdXMLReader r = new StdXMLReader(new FileInputStream(filename));
|
||||
r.setSystemID(filename);
|
||||
|
||||
for (int i = 0; i < r.readers.size(); i++) {
|
||||
StackedReader sr = (StackedReader) r.readers.elementAt(i);
|
||||
sr.systemId = r.currentReader.systemId;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the reader from a system and public ID.
|
||||
*
|
||||
* @param publicID the public ID which may be null.
|
||||
* @param systemID the non-null system ID.
|
||||
*
|
||||
* @throws MalformedURLException
|
||||
* if the system ID does not contain a valid URL
|
||||
* @throws FileNotFoundException
|
||||
* if the system ID refers to a local file which does not exist
|
||||
* @throws IOException
|
||||
* if an error occurred opening the stream
|
||||
*/
|
||||
public StdXMLReader(String publicID,
|
||||
String systemID)
|
||||
throws MalformedURLException,
|
||||
FileNotFoundException,
|
||||
IOException
|
||||
{
|
||||
URL systemIDasURL = null;
|
||||
|
||||
try {
|
||||
systemIDasURL = new URL(systemID);
|
||||
} catch (MalformedURLException e) {
|
||||
systemID = "file:" + systemID;
|
||||
|
||||
try {
|
||||
systemIDasURL = new URL(systemID);
|
||||
} catch (MalformedURLException e2) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
this.currentReader = new StackedReader();
|
||||
this.readers = new Stack<StackedReader>();
|
||||
Reader reader = this.openStream(publicID, systemIDasURL.toString());
|
||||
this.currentReader.lineReader = new LineNumberReader(reader);
|
||||
this.currentReader.pbReader
|
||||
= new PushbackReader(this.currentReader.lineReader, 2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the XML reader.
|
||||
*
|
||||
* @param reader the input for the XML data.
|
||||
*/
|
||||
public StdXMLReader(Reader reader)
|
||||
{
|
||||
this.currentReader = new StackedReader();
|
||||
this.readers = new Stack<StackedReader>();
|
||||
this.currentReader.lineReader = new LineNumberReader(reader);
|
||||
this.currentReader.pbReader
|
||||
= new PushbackReader(this.currentReader.lineReader, 2);
|
||||
this.currentReader.publicId = "";
|
||||
|
||||
try {
|
||||
this.currentReader.systemId = new URL("file:.");
|
||||
} catch (MalformedURLException e) {
|
||||
// never happens
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cleans up the object when it's destroyed.
|
||||
*/
|
||||
protected void finalize()
|
||||
throws Throwable
|
||||
{
|
||||
this.currentReader.lineReader = null;
|
||||
this.currentReader.pbReader = null;
|
||||
this.currentReader.systemId = null;
|
||||
this.currentReader.publicId = null;
|
||||
this.currentReader = null;
|
||||
this.readers.clear();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scans the encoding from an <?xml...?> tag.
|
||||
*
|
||||
* @param str the first tag in the XML data.
|
||||
*
|
||||
* @return the encoding, or null if no encoding has been specified.
|
||||
*/
|
||||
protected String getEncoding(String str)
|
||||
{
|
||||
if (! str.startsWith("<?xml")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int index = 5;
|
||||
|
||||
while (index < str.length()) {
|
||||
StringBuffer key = new StringBuffer();
|
||||
|
||||
while ((index < str.length()) && (str.charAt(index) <= ' ')) {
|
||||
index++;
|
||||
}
|
||||
|
||||
while ((index < str.length())
|
||||
&& (str.charAt(index) >= 'a')
|
||||
&& (str.charAt(index) <= 'z')) {
|
||||
key.append(str.charAt(index));
|
||||
index++;
|
||||
}
|
||||
|
||||
while ((index < str.length()) && (str.charAt(index) <= ' ')) {
|
||||
index++;
|
||||
}
|
||||
|
||||
if ((index >= str.length()) || (str.charAt(index) != '=')) {
|
||||
break;
|
||||
}
|
||||
|
||||
while ((index < str.length()) && (str.charAt(index) != '\'')
|
||||
&& (str.charAt(index) != '"')) {
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index >= str.length()) {
|
||||
break;
|
||||
}
|
||||
|
||||
char delimiter = str.charAt(index);
|
||||
index++;
|
||||
int index2 = str.indexOf(delimiter, index);
|
||||
|
||||
if (index2 < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (key.toString().equals("encoding")) {
|
||||
return str.substring(index, index2);
|
||||
}
|
||||
|
||||
index = index2 + 1;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a stream to a reader while detecting the encoding.
|
||||
*
|
||||
* @param stream the input for the XML data.
|
||||
* @param charsRead buffer where to put characters that have been read
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
* if an I/O error occurred
|
||||
*/
|
||||
protected Reader stream2reader(InputStream stream,
|
||||
StringBuffer charsRead)
|
||||
throws IOException
|
||||
{
|
||||
PushbackInputStream pbstream = new PushbackInputStream(stream);
|
||||
int b = pbstream.read();
|
||||
|
||||
switch (b) {
|
||||
case 0x00:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
pbstream.unread(b);
|
||||
return new InputStreamReader(pbstream, "UTF-16");
|
||||
|
||||
case 0xEF:
|
||||
for (int i = 0; i < 2; i++) {
|
||||
pbstream.read();
|
||||
}
|
||||
|
||||
return new InputStreamReader(pbstream, "UTF-8");
|
||||
|
||||
case 0x3C:
|
||||
b = pbstream.read();
|
||||
charsRead.append('<');
|
||||
|
||||
while ((b > 0) && (b != 0x3E)) {
|
||||
charsRead.append((char) b);
|
||||
b = pbstream.read();
|
||||
}
|
||||
|
||||
if (b > 0) {
|
||||
charsRead.append((char) b);
|
||||
}
|
||||
|
||||
String encoding = this.getEncoding(charsRead.toString());
|
||||
|
||||
if (encoding == null) {
|
||||
return new InputStreamReader(pbstream, "UTF-8");
|
||||
}
|
||||
|
||||
charsRead.setLength(0);
|
||||
|
||||
try {
|
||||
return new InputStreamReader(pbstream, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return new InputStreamReader(pbstream, "UTF-8");
|
||||
}
|
||||
|
||||
default:
|
||||
charsRead.append((char) b);
|
||||
return new InputStreamReader(pbstream, "UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the XML reader.
|
||||
*
|
||||
* @param stream the input for the XML data.
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
* if an I/O error occurred
|
||||
*/
|
||||
public StdXMLReader(InputStream stream)
|
||||
throws IOException
|
||||
{
|
||||
// unused?
|
||||
//PushbackInputStream pbstream = new PushbackInputStream(stream);
|
||||
StringBuffer charsRead = new StringBuffer();
|
||||
Reader reader = this.stream2reader(stream, charsRead);
|
||||
this.currentReader = new StackedReader();
|
||||
this.readers = new Stack<StackedReader>();
|
||||
this.currentReader.lineReader = new LineNumberReader(reader);
|
||||
this.currentReader.pbReader
|
||||
= new PushbackReader(this.currentReader.lineReader, 2);
|
||||
this.currentReader.publicId = "";
|
||||
|
||||
try {
|
||||
this.currentReader.systemId = new URL("file:.");
|
||||
} catch (MalformedURLException e) {
|
||||
// never happens
|
||||
}
|
||||
|
||||
this.startNewStream(new StringReader(charsRead.toString()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads a character.
|
||||
*
|
||||
* @return the character
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
* if no character could be read
|
||||
*/
|
||||
public char read()
|
||||
throws IOException
|
||||
{
|
||||
int ch = this.currentReader.pbReader.read();
|
||||
|
||||
while (ch < 0) {
|
||||
if (this.readers.empty()) {
|
||||
throw new IOException("Unexpected EOF");
|
||||
}
|
||||
|
||||
this.currentReader.pbReader.close();
|
||||
this.currentReader = (StackedReader) this.readers.pop();
|
||||
ch = this.currentReader.pbReader.read();
|
||||
}
|
||||
|
||||
return (char) ch;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the current stream has no more characters left to be
|
||||
* read.
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
* if an I/O error occurred
|
||||
*/
|
||||
public boolean atEOFOfCurrentStream()
|
||||
throws IOException
|
||||
{
|
||||
int ch = this.currentReader.pbReader.read();
|
||||
|
||||
if (ch < 0) {
|
||||
return true;
|
||||
} else {
|
||||
this.currentReader.pbReader.unread(ch);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if there are no more characters left to be read.
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
* if an I/O error occurred
|
||||
*/
|
||||
public boolean atEOF()
|
||||
throws IOException
|
||||
{
|
||||
int ch = this.currentReader.pbReader.read();
|
||||
|
||||
while (ch < 0) {
|
||||
if (this.readers.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.currentReader.pbReader.close();
|
||||
this.currentReader = (StackedReader) this.readers.pop();
|
||||
ch = this.currentReader.pbReader.read();
|
||||
}
|
||||
|
||||
this.currentReader.pbReader.unread(ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pushes the last character read back to the stream.
|
||||
*
|
||||
* @param ch the character to push back.
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
* if an I/O error occurred
|
||||
*/
|
||||
public void unread(char ch)
|
||||
throws IOException
|
||||
{
|
||||
this.currentReader.pbReader.unread(ch);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Opens a stream from a public and system ID.
|
||||
*
|
||||
* @param publicID the public ID, which may be null
|
||||
* @param systemID the system ID, which is never null
|
||||
*
|
||||
* @throws java.net.MalformedURLException
|
||||
* if the system ID does not contain a valid URL
|
||||
* @throws java.io.FileNotFoundException
|
||||
* if the system ID refers to a local file which does not exist
|
||||
* @throws java.io.IOException
|
||||
* if an error occurred opening the stream
|
||||
*/
|
||||
public Reader openStream(String publicID,
|
||||
String systemID)
|
||||
throws MalformedURLException,
|
||||
FileNotFoundException,
|
||||
IOException
|
||||
{
|
||||
URL url = new URL(this.currentReader.systemId, systemID);
|
||||
|
||||
if (url.getRef() != null) {
|
||||
String ref = url.getRef();
|
||||
|
||||
if (url.getFile().length() > 0) {
|
||||
url = new URL(url.getProtocol(), url.getHost(), url.getPort(),
|
||||
url.getFile());
|
||||
url = new URL("jar:" + url + '!' + ref);
|
||||
} else {
|
||||
url = StdXMLReader.class.getResource(ref);
|
||||
}
|
||||
}
|
||||
|
||||
this.currentReader.publicId = publicID;
|
||||
this.currentReader.systemId = url;
|
||||
StringBuffer charsRead = new StringBuffer();
|
||||
Reader reader = this.stream2reader(url.openStream(), charsRead);
|
||||
|
||||
if (charsRead.length() == 0) {
|
||||
return reader;
|
||||
}
|
||||
|
||||
String charsReadStr = charsRead.toString();
|
||||
PushbackReader pbreader = new PushbackReader(reader,
|
||||
charsReadStr.length());
|
||||
|
||||
for (int i = charsReadStr.length() - 1; i >= 0; i--) {
|
||||
pbreader.unread(charsReadStr.charAt(i));
|
||||
}
|
||||
|
||||
return pbreader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts a new stream from a Java reader. The new stream is used
|
||||
* temporary to read data from. If that stream is exhausted, control
|
||||
* returns to the parent stream.
|
||||
*
|
||||
* @param reader the non-null reader to read the new data from
|
||||
*/
|
||||
public void startNewStream(Reader reader)
|
||||
{
|
||||
this.startNewStream(reader, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts a new stream from a Java reader. The new stream is used
|
||||
* temporary to read data from. If that stream is exhausted, control
|
||||
* returns to the parent stream.
|
||||
*
|
||||
* @param reader the non-null reader to read the new data from
|
||||
* @param isInternalEntity true if the reader is produced by resolving
|
||||
* an internal entity
|
||||
*/
|
||||
public void startNewStream(Reader reader,
|
||||
boolean isInternalEntity)
|
||||
{
|
||||
StackedReader oldReader = this.currentReader;
|
||||
this.readers.push(this.currentReader);
|
||||
this.currentReader = new StackedReader();
|
||||
|
||||
if (isInternalEntity) {
|
||||
this.currentReader.lineReader = null;
|
||||
this.currentReader.pbReader = new PushbackReader(reader, 2);
|
||||
} else {
|
||||
this.currentReader.lineReader = new LineNumberReader(reader);
|
||||
this.currentReader.pbReader
|
||||
= new PushbackReader(this.currentReader.lineReader, 2);
|
||||
}
|
||||
|
||||
this.currentReader.systemId = oldReader.systemId;
|
||||
this.currentReader.publicId = oldReader.publicId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current "level" of the stream on the stack of streams.
|
||||
*/
|
||||
public int getStreamLevel()
|
||||
{
|
||||
return this.readers.size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the line number of the data in the current stream.
|
||||
*/
|
||||
public int getLineNr()
|
||||
{
|
||||
if (this.currentReader.lineReader == null) {
|
||||
StackedReader sr = (StackedReader) this.readers.peek();
|
||||
|
||||
if (sr.lineReader == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return sr.lineReader.getLineNumber() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return this.currentReader.lineReader.getLineNumber() + 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the system ID of the current stream.
|
||||
*
|
||||
* @param systemID the system ID
|
||||
*
|
||||
* @throws java.net.MalformedURLException
|
||||
* if the system ID does not contain a valid URL
|
||||
*/
|
||||
public void setSystemID(String systemID)
|
||||
throws MalformedURLException
|
||||
{
|
||||
this.currentReader.systemId = new URL(this.currentReader.systemId,
|
||||
systemID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the public ID of the current stream.
|
||||
*
|
||||
* @param publicID the public ID
|
||||
*/
|
||||
public void setPublicID(String publicID)
|
||||
{
|
||||
this.currentReader.publicId = publicID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current system ID.
|
||||
*/
|
||||
public String getSystemID()
|
||||
{
|
||||
return this.currentReader.systemId.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current public ID.
|
||||
*/
|
||||
public String getPublicID()
|
||||
{
|
||||
return this.currentReader.publicId;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user