public synchronized String encode(byte[] input, int start, int end) {
   mBuilder.clear();
   for (int i = start; i < end; i++) {
     byte atom = input[i];
     if (isConvert(atom)) {
       encodeAtPersent(atom);
     } else {
       mBuilder.append(atom);
     }
   }
   return new String(mBuilder.getBuffer(), 0, mBuilder.length());
 }
 @Override
 public void encode(OutputStream output) throws IOException {
   // 2
   output.write(
       ByteArrayBuilder.parseShort(
           HtunAttribute.UNKNOWN_ATTRIBUTE, ByteArrayBuilder.BYTEORDER_BIG_ENDIAN));
   // length 2*type size
   int length = mTypes.size() * 2;
   output.write(ByteArrayBuilder.parseShort(2, ByteArrayBuilder.BYTEORDER_BIG_ENDIAN));
   // value
   for (Integer type : mTypes) {
     output.write(ByteArrayBuilder.parseShort(type, ByteArrayBuilder.BYTEORDER_BIG_ENDIAN));
   }
 }
  public synchronized byte[] decode(byte[] input) throws IOException {
    mBuilder.clear();

    int len = input.length;
    for (int i = 0; i < len; ) {
      byte atom = input[i];
      if (atom != '%') {
        mBuilder.append(atom);
        i += 1;
      } else {
        mBuilder.append(convertChar2Byte(input, i));
        i += 3;
      }
    }

    byte[] output = new byte[mBuilder.length()];
    System.arraycopy(mBuilder.getBuffer(), 0, output, 0, output.length);
    return output;
  }
 private void encodeAtPersent(byte atom) {
   mBuilder.append((byte) '%');
   mBuilder.append(sEncodeMap[(0xF0 & atom) >> 4]);
   mBuilder.append(sEncodeMap[atom & 0xF]);
 }