/******************************************************************************* * Copyright (c) 2009, 2010 Fraunhofer IWU and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Fraunhofer IWU - initial API and implementation *******************************************************************************/ package net.enilink.komma.model.base; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ReaderInputStream extends InputStream { private static final Pattern XML_HEADER = Pattern .compile("<\\?xml\\s+(?:version\\s*=\\s*\"[^\"]*\"\\s+)encoding\\s*=\\s*\"\\s*([^\\s\"]*)\"\\s*\\?>"); public static String getEncoding(String xmlString) { Matcher matcher = XML_HEADER.matcher(xmlString); return matcher.lookingAt() ? matcher.group(1) : null; } public static String getEncoding(Reader xmlReader) { try { xmlReader.mark(100); char[] buffer = new char[100]; int length = xmlReader.read(buffer); if (length > -1) { Matcher matcher = XML_HEADER.matcher(new String(buffer, 0, length)); return matcher.lookingAt() ? matcher.group(1) : null; } else { return null; } } catch (IOException exception) { return null; } finally { try { xmlReader.reset(); } catch (IOException exception) { // Ignore. } } } protected String encoding; protected Reader reader; protected Buffer buffer; public ReaderInputStream(Reader reader, String encoding) { this.reader = reader; this.encoding = encoding; } public ReaderInputStream(Reader xmlReader) { this.reader = xmlReader.markSupported() ? xmlReader : new BufferedReader(xmlReader); this.encoding = getEncoding(this.reader); } public ReaderInputStream(String string, String encoding) { this(new StringReader(string), encoding); } public ReaderInputStream(String xmlString) { this(new StringReader(xmlString), getEncoding(xmlString)); } @Override public int read() throws IOException { if (buffer == null) { buffer = new Buffer(100); } return buffer.read(); } public Reader asReader() { return reader; } public String getEncoding() { return encoding; } @Override public void close() throws IOException { super.close(); reader.close(); } @Override public void reset() throws IOException { super.reset(); reader.reset(); } protected class Buffer extends ByteArrayOutputStream { protected int index; protected char[] characters; protected OutputStreamWriter writer; public Buffer(int size) throws IOException { super(size); characters = new char[size]; writer = new OutputStreamWriter(this, encoding); } public int read() throws IOException { if (index < count) { return buf[index++]; } else { index = 0; reset(); int readCount = reader.read(characters); if (readCount < 0) { return -1; } else { writer.write(characters, 0, readCount); writer.flush(); return buf[index++]; } } } } }