code: public static String dumpString(byte[] frame, int offset, int length, boolean ascii) {
      if ((frame == null)|| (length == 0)) return null;
      // Main formatting is performed in buf. asciibuf is used to hold the
      // ascii translation. asciibuf is appended to buf before a new line is started
      StringBuffer buf = new StringBuffer();
      StringBuffer asciibuf = new StringBuffer();
      buf.append("Length=").append(length);
      for (int i = 0; i < length; i++) {
        if (i%32 == 0) {
          if (ascii) {
            buf.append(asciibuf);
            asciibuf.setLength(0);
            asciibuf.append("\n").append(pad(0)).append("   ");
          }
          buf.append("\n").append(pad(offset+i)).append(offset+i).append(": ");
        }
        else if (i%16 == 0) {
          buf.append("  ");
          if (ascii) asciibuf.append("  ");
        }
        else if (i%4 == 0) {
          buf.append(" ");
          if (ascii) asciibuf.append(" ");
        }
        buf.append(digits[(frame[offset+i] >>> 4) & 0x0f]);
        buf.append(digits[frame[offset+i] & 0x0f]);
        if (ascii) {
          if (frame[offset+i]>=0x20 && ((frame[offset+i] & 0x80) == 0)) {
            asciibuf.append(' ').append((char)frame[offset+i]);
          }
          else {
            asciibuf.append(" .");
          }
        }
      }
      if (ascii) buf.append(asciibuf);
      return buf.toString();
    }
docs: Create a formatted "dump" of a sequence of bytes with ascii translation, if specified.
  Performs simple ascii translation. No DBCS translations.
  
  @param  frame    the byte array containing the bytes to be formatted
  @param  offset   the offset of the first byte to format
  @param  length   the number of bytes to format
  @param  ascii    if true, include ascii translation
  @return a String containing the formatted dump.