package net.contrapunctus.rngzip; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.Stack; import net.contrapunctus.rngzip.io.RNGZOutputInterface; import net.contrapunctus.rngzip.util.ErrorReporter; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; public abstract class Compressor extends DefaultHandler { protected ErrorReporter err; protected Locator loc; protected CompositeState state; protected Stack<String> elts; protected Stack<Map<Integer,String>> atts; private static final boolean DEBUG = System.getProperty("DEBUG_Compressor") != null; private static final PrintWriter dbg = new PrintWriter(System.err, true); public Compressor(ErrorReporter _err, RNGZOutputInterface out) { err = _err; state = new SequentialStates(out); elts = new Stack<String>(); atts = new Stack<Map<Integer,String>>(); } protected abstract SingletonState initialState(); public void setDocumentLocator(Locator _loc) { loc = _loc; } protected void die(Exception exn) throws SAXParseException { err.fatalError(new SAXParseException(exn.getMessage(), loc, exn)); } public abstract int encodeName(String ns, String lname); public void startDocument() { state.initialize(initialState()); elts.clear(); atts.clear(); atts.push(null); } public void endDocument() throws SAXParseException { if(DEBUG) { trace("END document"); } try { state = state.end(null); } catch(IOException exn) { die(exn); } catch(IllegalStateException exn) { die(exn); } } public void startElement(String ns, String lname, String qname, Attributes attr) throws SAXParseException { if(DEBUG) { trace("START "+qname); } HashMap<Integer,String> attm = new HashMap<Integer,String>(); for(int i = 0; i < attr.getLength(); i++) { attm.put(encodeName(attr.getURI(i), attr.getLocalName(i)), attr.getValue(i)); } elts.push(qname); atts.push(attm); try { state = state.start(encodeName(ns, lname), attm); } catch(IOException exn) { die(exn); } catch(IllegalStateException exn) { die(exn); } } public void endElement(String ns, String lname, String qname) throws SAXParseException { if(DEBUG) { trace("END "+qname); } assert qname == elts.peek(); atts.pop(); try { state = state.end(atts.peek()); } catch(IOException exn) { die(exn); } catch(IllegalStateException exn) { die(exn); } elts.pop(); } public void characters(char[] ch, int start, int length) throws SAXParseException { if(DEBUG) { trace("CHARS"); } try { state = state.chars(ch, start, length); } catch(IOException exn) { die(exn); } catch(IllegalStateException exn) { die(exn); } } protected void trace(String msg) { state.show(dbg); dbg.print(" <> "); dbg.println(msg); } }