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);
}