private boolean[] decodeBooleanArray(int len, TCDataInput input) throws IOException {
   final boolean[] rv = new boolean[len];
   for (int i = 0, n = rv.length; i < n; i++) {
     rv[i] = input.readBoolean();
   }
   return rv;
 }
  @Override
  public Object decode(TCDataInput input, ObjectStringSerializer serializer)
      throws IOException, ClassNotFoundException {
    final byte type = input.readByte();

    switch (type) {
      case TYPE_ID_ENUM:
        return readEnum(input, type, serializer);
      case TYPE_ID_ENUM_HOLDER:
        return readEnum(input, type, serializer);
      case TYPE_ID_JAVA_LANG_CLASS:
        return readClass(input, type, serializer);
      case TYPE_ID_JAVA_LANG_CLASS_HOLDER:
        return readClass(input, type, serializer);
      case TYPE_ID_BOOLEAN:
        return Boolean.valueOf(input.readBoolean());
      case TYPE_ID_BYTE:
        return Byte.valueOf(input.readByte());
      case TYPE_ID_CHAR:
        return Character.valueOf(input.readChar());
      case TYPE_ID_DOUBLE:
        return Double.valueOf(input.readDouble());
      case TYPE_ID_FLOAT:
        return Float.valueOf(input.readFloat());
      case TYPE_ID_INT:
        return Integer.valueOf(input.readInt());
      case TYPE_ID_LONG:
        return Long.valueOf(input.readLong());
      case TYPE_ID_SHORT:
        return Short.valueOf(input.readShort());
      case TYPE_ID_STRING:
        return readString(input, type, serializer);
      case TYPE_ID_STRING_COMPRESSED:
        return readCompressedString(input);
      case TYPE_ID_STRING_BYTES:
        return readString(input, type, serializer);
      case TYPE_ID_REFERENCE:
        return new ObjectID(input.readLong());
      case TYPE_ID_ARRAY:
        return decodeArray(input);
      default:
        throw Assert.failure("Illegal type (" + type + ")");
    }

    // unreachable
  }