001/**
002 * Java Web Archive Toolkit - Software to read and validate ARC, WARC
003 * and GZip files. (http://jwat.org/)
004 * Copyright 2011-2012 Netarkivet.dk (http://netarkivet.dk/)
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.jwat.common;
019
020import java.io.ByteArrayOutputStream;
021import java.io.IOException;
022import java.io.InputStream;
023import java.util.LinkedList;
024import java.util.List;
025
026/**
027 * Depending on the parsing mode either a line or a header entry
028 * pair(name, value) is returned. Any problem(s) reading the (header)line
029 * is reported in the bfErrors field.
030 *
031 * @author nicl
032 */
033public class HeaderLine {
034
035    /** Read line initial size. */
036    public static final int READLINE_INITIAL_SIZE = 128;
037
038    /** Normal line parsed. */
039    public static final byte HLT_LINE = 1;
040
041    /** Header line parsed. */
042    public static final byte HLT_HEADERLINE = 2;
043
044    /** Type of the parsed line. */
045    public byte type = 0;
046
047    /** Header name. */
048    public String name;
049
050    /** Header value. */
051    public String value;
052
053    /** The raw line if no colon is present. */
054    public String line;
055
056    /** The original byte stream. */
057    public byte[] raw;
058
059    /** Bit field of errors encountered while attempting to read a line. */
060    public int bfErrors;
061
062    /** List of additional headers with the same name. */
063    public List<HeaderLine> lines = new LinkedList<HeaderLine>();
064
065    /**
066     * Read a single line into a header line.
067     * @param in inputstream
068     * @return single string line
069     * @throws IOException if an I/O error occurs while reading line
070     */
071    public static HeaderLine readLine(InputStream in) throws IOException {
072        StringBuffer sb = new StringBuffer(READLINE_INITIAL_SIZE);
073        ByteArrayOutputStream out = new ByteArrayOutputStream(READLINE_INITIAL_SIZE);
074        int b;
075        while (true) {
076            b = in.read();
077            if (b == -1) {
078                return null;    //Unexpected EOF
079            }
080            out.write(b);
081            if (b == '\n'){
082                break;
083            }
084            if (b != '\r') {
085                sb.append((char) b);
086            }
087        }
088        HeaderLine headerLine = new HeaderLine();
089        headerLine.line = sb.toString();
090        headerLine.raw = out.toByteArray();
091        return headerLine;
092    }
093
094}