code: private String readUTF(int index, final int utfLen, final char[] buf) {
          int endIndex = index + utfLen;
          byte[] b = this.b;
          int strLen = 0;
          int c, d, e;
          while (index < endIndex) {
              c = b[index++] & 0xFF;
              switch (c >> 4) {
                  case 0:
                  case 1:
                  case 2:
                  case 3:
                  case 4:
                  case 5:
                  case 6:
                  case 7:
                      // 0xxxxxxx
                      buf[strLen++] = (char) c;
                      break;
                  case 12:
                  case 13:
                      // 110x xxxx 10xx xxxx
                      d = b[index++];
                      buf[strLen++] = (char) (((c & 0x1F) << 6) | (d & 0x3F));
                      break;
                  default:
                      // 1110 xxxx 10xx xxxx 10xx xxxx
                      d = b[index++];
                      e = b[index++];
                      buf[strLen++] = (char) (((c & 0x0F) << 12)
                              | ((d & 0x3F) << 6) | (e & 0x3F));
                      break;
              }
          }
          return new String(buf, 0, strLen);
      }
docs: Reads UTF8 string in {@link #b b}.
  
  @param index start offset of the UTF8 string to be read.
  @param utfLen length of the UTF8 string to be read.
  @param buf buffer to be used to read the string. This buffer must be
  sufficiently large. It is not automatically resized.
  @return the String corresponding to the specified UTF8 string.