Headers.java 9.61 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.commons.lang.time.FastDateFormat
 */
package com.adobe.granite.httpcache.api;

import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import org.apache.commons.lang.time.FastDateFormat;

public class Headers {
    private final List<Entry> entries = new ArrayList<Entry>(16);
    private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
    private static final FastDateFormat RFC1123 = FastDateFormat.getInstance((String)"EEE, dd MMM yyyy HH:mm:ss z", (TimeZone)GMT, (Locale)Locale.US);

    public String getHeader(String name) {
        for (int i = 0; i < this.entries.size(); ++i) {
            Entry e = this.entries.get(i);
            if (!e.name.equalsIgnoreCase(name)) continue;
            return e.getString();
        }
        return null;
    }

    public String[] getHeaders(String name) {
        ArrayList<String> values = null;
        for (int i = 0; i < this.entries.size(); ++i) {
            Entry e = this.entries.get(i);
            if (!e.name.equalsIgnoreCase(name)) continue;
            if (values == null) {
                values = new ArrayList<String>();
            }
            values.add(e.getString());
        }
        if (values != null) {
            String[] result = new String[values.size()];
            return values.toArray(result);
        }
        return null;
    }

    public long getDateHeader(String name) {
        for (int i = 0; i < this.entries.size(); ++i) {
            Entry e = this.entries.get(i);
            if (!e.name.equalsIgnoreCase(name)) continue;
            return e.getLong();
        }
        return -1;
    }

    public int getIntHeader(String name) {
        for (int i = 0; i < this.entries.size(); ++i) {
            Entry e = this.entries.get(i);
            if (!e.name.equalsIgnoreCase(name)) continue;
            return e.getInt();
        }
        return 0;
    }

    public void setHeader(String name, String value) {
        if (value == null) {
            for (int i = 0; i < this.entries.size(); ++i) {
                if (!this.entries.get((int)i).name.equalsIgnoreCase(name)) continue;
                this.entries.remove(i);
            }
            return;
        }
        this.setHeader(new Entry(name, value));
    }

    public void setHeader(String name, long value) {
        this.setHeader(new Entry(name, value));
    }

    public void setHeader(String name, int value) {
        this.setHeader(new Entry(name, value));
    }

    private void setHeader(Entry e) {
        for (int i = 0; i < this.entries.size(); ++i) {
            if (!this.entries.get((int)i).name.equalsIgnoreCase(e.name)) continue;
            this.entries.set(i, e);
            return;
        }
        this.entries.add(e);
    }

    public void addHeader(String name, String value) {
        this.entries.add(new Entry(name, value));
    }

    public void addHeader(String name, long value) {
        this.entries.add(new Entry(name, value));
    }

    public void addHeader(String name, int value) {
        this.entries.add(new Entry(name, value));
    }

    public Entry[] getEntries() {
        Entry[] result = new Entry[this.entries.size()];
        this.entries.toArray(result);
        return result;
    }

    public void save(OutputStream out) throws IOException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream(256);
        Headers.writeShort(bout, this.entries.size());
        block5 : for (int i = 0; i < this.entries.size(); ++i) {
            Entry e = this.entries.get(i);
            Headers.writeString(bout, e.name);
            switch (e.type) {
                case STRING: {
                    bout.write(83);
                    Headers.writeString(bout, e.getString());
                    continue block5;
                }
                case LONG: {
                    bout.write(76);
                    Headers.writeLong(bout, e.getLong());
                    continue block5;
                }
                case INT: {
                    bout.write(73);
                    Headers.writeInt(bout, e.getInt());
                    continue block5;
                }
                default: {
                    throw new InternalError("Illegal type: " + (Object)((Object)e.type));
                }
            }
        }
        out.write(bout.toByteArray());
    }

    private static void writeShort(OutputStream out, int n) throws IOException {
        if (n > 65535) {
            throw new IOException("Number too big to be saved as short: " + n);
        }
        out.write(n >>> 8 & 255);
        out.write(n >>> 0 & 255);
    }

    private static void writeString(OutputStream out, String s) throws IOException {
        byte[] b = s.getBytes("8859_1");
        Headers.writeShort(out, b.length);
        out.write(b);
    }

    private static void writeInt(OutputStream out, int n) throws IOException {
        out.write(n >>> 24 & 255);
        out.write(n >>> 16 & 255);
        out.write(n >>> 8 & 255);
        out.write(n >>> 0 & 255);
    }

    private static void writeLong(OutputStream out, long l) throws IOException {
        Headers.writeInt(out, (int)(l >>> 32));
        Headers.writeInt(out, (int)l & -1);
    }

    public void load(InputStream in) throws IOException {
        int count = Headers.readUnsignedShort(in);
        block5 : for (int i = 0; i < count; ++i) {
            String name = Headers.readString(in);
            char ch = (char)in.read();
            switch (ch) {
                case 'S': {
                    this.addHeader(name, Headers.readString(in));
                    continue block5;
                }
                case 'L': {
                    this.addHeader(name, Headers.readLong(in));
                    continue block5;
                }
                case 'I': {
                    this.addHeader(name, Headers.readInt(in));
                    continue block5;
                }
                default: {
                    throw new InternalError("Illegal type: " + ch);
                }
            }
        }
    }

    private static int readUnsignedShort(InputStream in) throws IOException {
        int ch2;
        int ch1 = in.read();
        if ((ch1 | (ch2 = in.read())) < 0) {
            throw new EOFException();
        }
        return (ch1 << 8) + (ch2 << 0);
    }

    private static int readInt(InputStream in) throws IOException {
        int ch4;
        int ch3;
        int ch2;
        int ch1 = in.read();
        if ((ch1 | (ch2 = in.read()) | (ch3 = in.read()) | (ch4 = in.read())) < 0) {
            throw new EOFException();
        }
        return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0);
    }

    private static long readLong(InputStream in) throws IOException {
        long h = (long)Headers.readInt(in) & 0xFFFFFFFFL;
        long l = (long)Headers.readInt(in) & 0xFFFFFFFFL;
        return h << 32 | l;
    }

    private static String readString(InputStream in) throws IOException {
        int len;
        byte[] b = new byte[Headers.readUnsignedShort(in)];
        for (int off = 0; off < b.length; off += len) {
            len = in.read(b, off, b.length - off);
            if (len != -1) continue;
            throw new EOFException();
        }
        return new String(b, "8859_1");
    }

    public String toString() {
        StringBuilder s = new StringBuilder(256);
        for (Entry e : this.entries) {
            s.append(e.toString());
            s.append("\r\n");
        }
        return s.toString();
    }

    public static class Entry {
        final String name;
        final Type type;
        private String s;
        private long l;
        private int i;

        Entry(String name, String value) {
            this.type = Type.STRING;
            this.name = name;
            this.s = value;
        }

        Entry(String name, long value) {
            this.type = Type.LONG;
            this.name = name;
            this.l = value;
        }

        Entry(String name, int value) {
            this.type = Type.INT;
            this.name = name;
            this.i = value;
        }

        public String getString() {
            switch (this.type) {
                case STRING: {
                    return this.s;
                }
                case LONG: {
                    return RFC1123.format(this.l);
                }
                case INT: {
                    return String.valueOf(this.i);
                }
            }
            throw new InternalError("Illegal type: " + (Object)((Object)this.type));
        }

        public long getLong() {
            if (this.type == Type.LONG) {
                return this.l;
            }
            return -1;
        }

        public int getInt() {
            if (this.type == Type.INT) {
                return this.i;
            }
            return 0;
        }

        public Type getType() {
            return this.type;
        }

        public String getName() {
            return this.name;
        }

        public String toString() {
            StringBuilder s = new StringBuilder(32);
            s.append(this.name);
            s.append(": ");
            s.append(this.getString());
            return s.toString();
        }

        /*
         * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
         */
        public static enum Type {
            STRING,
            LONG,
            INT;
            

            private Type() {
            }
        }

    }

}