public static Codec getCodec()

in src/main/java/org/apache/commons/compress/harmony/pack200/CodecEncoding.java [90:178]


    public static Codec getCodec(final int value, final InputStream in, final Codec defaultCodec) throws IOException, Pack200Exception {
        // Sanity check to make sure that no-one has changed
        // the canonical codecs, which would really cause havoc
        if (canonicalCodec.length != 116) {
            throw new Error("Canonical encodings have been incorrectly modified");
        }
        if (value < 0) {
            throw new IllegalArgumentException("Encoding cannot be less than zero");
        }
        if (value == 0) {
            return defaultCodec;
        }
        if (value <= 115) {
            return canonicalCodec[value];
        }
        if (value == 116) {
            int code = in.read();
            if (code == -1) {
                throw new EOFException("End of buffer read whilst trying to decode codec");
            }
            final int d = code & 0x01;
            final int s = code >> 1 & 0x03;
            final int b = (code >> 3 & 0x07) + 1; // this might result in an invalid
            // number, but it's checked in the
            // Codec constructor
            code = in.read();
            if (code == -1) {
                throw new EOFException("End of buffer read whilst trying to decode codec");
            }
            final int h = code + 1;
            // This handles the special cases for invalid combinations of data.
            return new BHSDCodec(b, h, s, d);
        }
        if (value >= 117 && value <= 140) { // Run codec
            final int offset = value - 117;
            final int kx = offset & 3;
            final boolean kbflag = (offset >> 2 & 1) == 1;
            final boolean adef = (offset >> 3 & 1) == 1;
            final boolean bdef = (offset >> 4 & 1) == 1;
            // If both A and B use the default encoding, what's the point of
            // having a run of default values followed by default values
            if (adef && bdef) {
                throw new Pack200Exception("ADef and BDef should never both be true");
            }
            final int kb = kbflag ? in.read() : 3;
            final int k = (kb + 1) * (int) Math.pow(16, kx);
            final Codec aCodec;
            final Codec bCodec;
            if (adef) {
                aCodec = defaultCodec;
            } else {
                aCodec = getCodec(in.read(), in, defaultCodec);
            }
            if (bdef) {
                bCodec = defaultCodec;
            } else {
                bCodec = getCodec(in.read(), in, defaultCodec);
            }
            return new RunCodec(k, aCodec, bCodec);
        }
        if (value < 141 || value > 188) {
            throw new Pack200Exception("Invalid codec encoding byte (" + value + ") found");
        }
        final int offset = value - 141;
        final boolean fdef = (offset & 1) == 1;
        final boolean udef = (offset >> 1 & 1) == 1;
        final int tdefl = offset >> 2;
        final boolean tdef = tdefl != 0;
        // From section 6.7.3 of spec
        final int[] tdefToL = { 0, 4, 8, 16, 32, 64, 128, 192, 224, 240, 248, 252 };
        final int l = tdefToL[tdefl];
        // NOTE: Do not re-factor this to bring out uCodec; the order in
        // which
        // they are read from the stream is important
        if (tdef) {
            final Codec fCodec = fdef ? defaultCodec : getCodec(in.read(), in, defaultCodec);
            final Codec uCodec = udef ? defaultCodec : getCodec(in.read(), in, defaultCodec);
            // Unfortunately, if tdef, then tCodec depends both on l and
            // also on k, the
            // number of items read from the fCodec. So we don't know in
            // advance what
            // the codec will be.
            return new PopulationCodec(fCodec, l, uCodec);
        }
        final Codec fCodec = fdef ? defaultCodec : getCodec(in.read(), in, defaultCodec);
        final Codec tCodec = getCodec(in.read(), in, defaultCodec);
        final Codec uCodec = udef ? defaultCodec : getCodec(in.read(), in, defaultCodec);
        return new PopulationCodec(fCodec, tCodec, uCodec);
    }