docs: public String readString(final int strStart, final boolean replaceSlashWithDot, final boolean stripLSemicolon)
              throws IOException {
          final int utfLen = readUnsignedShort(strStart);
          final int utfStart = strStart + 2;
          final int bufferUnderrunBytes = Math.max(0, utfStart + utfLen - used);
          if (bufferUnderrunBytes > 0) {
              readMore(bufferUnderrunBytes);
          }
          final char[] chars = new char[utfLen];
          int c, c2, c3, c4;
          int byteIdx = 0;
          int charIdx = 0;
          for (; byteIdx < utfLen; byteIdx++) {
              c = buf[utfStart + byteIdx] & 0xff;
              if (c > 127) {
                  break;
              }
              chars[charIdx++] = (char) (replaceSlashWithDot && c == '/' ? '.' : c);
          }
          while (byteIdx < utfLen) {
              c = buf[utfStart + byteIdx] & 0xff;
              switch (c >> 4) {
              case 0:
              case 1:
              case 2:
              case 3:
              case 4:
              case 5:
              case 6:
              case 7:
                  byteIdx++;
                  chars[charIdx++] = (char) (replaceSlashWithDot && c == '/' ? '.' : c);
                  break;
              case 12:
              case 13:
                  byteIdx += 2;
                  if (byteIdx > utfLen) {
                      throw new IOException("Bad modified UTF8");
                  }
                  c2 = buf[utfStart + byteIdx - 1];
                  if ((c2 & 0xc0) != 0x80) {
                      throw new IOException("Bad modified UTF8");
                  }
                  c4 = ((c & 0x1f) << 6) | (c2 & 0x3f);
                  chars[charIdx++] = (char) (replaceSlashWithDot && c4 == '/' ? '.' : c4);
                  break;
              case 14:
                  byteIdx += 3;
                  if (byteIdx > utfLen) {
                      throw new IOException("Bad modified UTF8");
                  }
                  c2 = buf[utfStart + byteIdx - 2];
                  c3 = buf[utfStart + byteIdx - 1];
                  if ((c2 & 0xc0) != 0x80 || (c3 & 0xc0) != 0x80) {
                      throw new IOException("Bad modified UTF8");
                  }
                  c4 = ((c & 0x0f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f);
                  chars[charIdx++] = (char) (replaceSlashWithDot && c4 == '/' ? '.' : c4);
                  break;
              default:
                  throw new IOException("Bad modified UTF8");
              }
          }
          if (charIdx == utfLen && !stripLSemicolon) {
              return new String(chars);
          } else {
              if (stripLSemicolon) {
                  if (charIdx < 2 || chars[0] != 'L' || chars[charIdx - 1] != ';') {
                      throw new IOException("Expected string to start with 'L' and end with ';', got \""
                              + new String(chars) + "\"");
                  }
                  return new String(chars, 1, charIdx - 2);
              } else {
                  return new String(chars, 0, charIdx);
              }
          }
      }