001    /*
002     * Copyright (c) 2007 Henri Sivonen
003     *
004     * Permission is hereby granted, free of charge, to any person obtaining a 
005     * copy of this software and associated documentation files (the "Software"), 
006     * to deal in the Software without restriction, including without limitation 
007     * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
008     * and/or sell copies of the Software, and to permit persons to whom the 
009     * Software is furnished to do so, subject to the following conditions:
010     *
011     * The above copyright notice and this permission notice shall be included in 
012     * all copies or substantial portions of the Software.
013     *
014     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
015     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
016     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
017     * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
018     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
019     * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
020     * DEALINGS IN THE SOFTWARE.
021     */
022    
023    package nu.validator.htmlparser.test;
024    
025    import java.io.IOException;
026    import java.io.InputStream;
027    
028    public class UntilHashInputStream extends InputStream {
029    
030        private final StringBuilder builder = new StringBuilder();
031        
032        private final InputStream delegate;
033    
034        private int buffer = -1;
035        
036        private boolean closed = false;
037    
038        /**
039         * @param delegate
040         * @throws IOException 
041         */
042        public UntilHashInputStream(final InputStream delegate) throws IOException {
043            this.delegate = delegate;
044            this.buffer = delegate.read();
045            if (buffer == '#') {
046                closed = true;
047            }
048        }
049    
050        public int read() throws IOException {
051            if (closed) {
052                return -1;
053            }
054            int rv = buffer;
055            buffer = delegate.read();
056            if (buffer == '#' && rv == '\n') {
057                // end of stream
058                closed = true;
059                return -1;
060            } else {
061                if (rv >= 0x20 && rv < 0x80) {
062                    builder.append(((char)rv));
063                } else {
064                    builder.append("0x");
065                    builder.append(Integer.toHexString(rv));
066                }
067                return rv;
068            }
069        }
070    
071        /**
072         * @see java.io.InputStream#close()
073         */
074        @Override
075        public void close() throws IOException {
076            super.close();
077            if (closed) {
078                return;
079            }
080            for (;;) {
081                int b = delegate.read();
082                if (b == 0x23 || b == -1) {
083                    break;
084                }
085            }
086            closed = true;
087        }
088    
089        /**
090         * @see java.lang.Object#toString()
091         */
092        @Override
093        public String toString() {
094            return builder.toString();
095        }
096    
097    }