/* * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package build.tools.dtdbuilder; import javax.swing.text.html.parser.*; import java.io.IOException; import java.io.FileInputStream; import java.io.InputStream; import java.io.Reader; import java.io.InputStreamReader; import java.io.CharArrayReader; import java.io.FilterReader; import java.util.Stack; import java.net.URL; /** * A stream for reading HTML files. This stream takes care * of \r\n conversions and parameter entity expansion. * * @see DTD * @see DTDParser * @author Arthur van Hoff * @author Steven B. Byrne */ public final class DTDInputStream extends FilterReader implements DTDConstants { public DTD dtd; public Stack stack = new Stack<>(); public char str[] = new char[64]; public int replace = 0; public int ln = 1; public int ch; /** * Create the stream. */ public DTDInputStream(InputStream in, DTD dtd) throws IOException { super(new InputStreamReader(in)); this.dtd = dtd; this.ch = in.read(); } /** * Error */ public void error(String msg) { System.out.println("line " + ln + ": dtd input error: " + msg); } /** * Push a single character */ public void push(int ch) throws IOException { char data[] = {(char)ch}; push(new CharArrayReader(data)); } /** * Push an array of bytes. */ public void push(char data[]) throws IOException { if (data.length > 0) { push(new CharArrayReader(data)); } } /** * Push an entire input stream */ void push(Reader in) throws IOException { stack.push(Integer.valueOf(ln)); stack.push(Integer.valueOf(ch)); stack.push(this.in); this.in = in; ch = in.read(); } /** * Read a character from the input. Automatically pop * a stream of the stack if the EOF is reached. Also replaces * parameter entities. * [60] 350:22 */ @SuppressWarnings("fallthrough") public int read() throws IOException { switch (ch) { case '%': { ch = in.read(); if (replace > 0) { return '%'; } int pos = 0; while (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) || (ch == '.') || (ch == '-')) { str[pos++] = (char)ch; ch = in.read(); } if (pos == 0) { return '%'; } String nm = new String(str, 0, pos); Entity ent = dtd.getEntity(nm); if (ent == null) { error("undefined entity reference: " + nm); return read(); } // Skip ; or RE switch (ch) { case '\r': ln++; /* fall through */ case ';': ch = in.read(); break; case '\n': ln++; if ((ch = in.read()) == '\r') { ch = in.read(); } break; } // Push the entity. try { push(getEntityInputReader(ent)); } catch (Exception e) { error("entity data not found: " + ent + ", " + ent.getString()); } return read(); } case '\n': ln++; if ((ch = in.read()) == '\r') { ch = in.read(); } return '\n'; case '\r': ln++; ch = in.read(); return '\n'; case -1: if (stack.size() > 0) { in = (Reader)stack.pop(); ch = ((Integer)stack.pop()).intValue(); ln = ((Integer)stack.pop()).intValue(); return read(); } return -1; default: int c = ch; ch = in.read(); return c; } } /** * Return the data as a stream. */ private Reader getEntityInputReader(Entity ent) throws IOException { if ((ent.type & Entity.PUBLIC) != 0) { // InputStream is = DTDBuilder.mapping.get(ent.getString()).openStream(); // return new InputStreamReader(is); String path = DTDBuilder.mapping.get(ent.getString()); return new InputStreamReader(new FileInputStream(path)); } if ((ent.type & Entity.SYSTEM) != 0) { //InputStream is = new URL(DTDBuilder.mapping.base, ent.getString()).openStream(); String path = DTDBuilder.mapping.baseStr + ent.getString(); return new InputStreamReader(new FileInputStream(path)); } return new CharArrayReader(ent.data); } }