001package org.apache.commons.ssl.util;
002
003import java.io.IOException;
004import java.io.InputStream;
005
006/**
007 * @author Julius Davies
008 * @author 23-Dec-2007
009 */
010public class ReadLine {
011
012    final InputStream in;
013    final byte[] bytes = new byte[8192];
014    int pos = 0;
015    int avail = 0;
016
017    public ReadLine(InputStream in) { this.in = in; }
018
019    public String next() throws IOException { return next(1); }
020
021    public String next(int lines) throws IOException {
022        if (lines < 1) {
023            lines = 1;
024        }
025        StringBuffer buf = new StringBuffer(128 * lines);
026        if (avail <= 0 || pos >= avail) {
027            pos = 0;
028            avail = in.read(bytes);
029        }
030        while (avail >= 0) {
031            while (pos < avail) {
032                char c = (char) bytes[pos++];
033                switch (c) {
034                    case '\n':
035                    case '\r':
036                        lines--;
037                        if (lines < 1 && buf.length() > 0) {
038                            return buf.toString();
039                        }
040                        break;
041                    default:
042                        buf.append(c);
043                        break;
044                }
045            }
046            pos = 0;
047            avail = in.read(bytes);
048        }
049        return buf.length() > 0 ? buf.toString() : null;
050    }
051
052    public byte[] nextAsBytes() throws IOException { return nextAsBytes(1); }
053
054    public byte[] nextAsBytes(int lines) throws IOException {
055        if (lines < 1) {
056            lines = 1;
057        }
058        byte[] buf = new byte[8192];
059        int bufPos = 0;
060        if (avail <= 0 || pos >= avail) {
061            pos = 0;
062            avail = in.read(bytes);
063        }
064        while (avail >= 0) {
065            while (pos < avail) {
066                byte b = bytes[pos++];
067                switch (b) {
068                    case '\n':
069                    case '\r':
070                        lines--;
071                        if (lines == 0 && bufPos > 0) {
072                            return buf;
073                        }
074                        break;
075                    default:
076                        if (bufPos >= buf.length) {
077                            byte[] moreBuff = new byte[buf.length * 2];
078                            System.arraycopy(buf, 0, moreBuff, 0, buf.length);
079                            buf = moreBuff;
080                        }
081                        buf[bufPos++] = b;
082                        break;
083                }
084            }
085            pos = 0;
086            avail = in.read(bytes);
087        }
088        return bufPos > 0 ? buf : null;
089    }
090
091}