code: @SuppressWarnings("resource")
      private static BerDataValue readDataValue(InputStream input)
              throws BerDataValueFormatException {
          RecordingInputStream in = new RecordingInputStream(input);
  
          try {
              int firstIdentifierByte = in.read();
              if (firstIdentifierByte == -1) {
                  // End of input
                  return null;
              }
              int tagNumber = readTagNumber(in, firstIdentifierByte);
  
              int firstLengthByte = in.read();
              if (firstLengthByte == -1) {
                  throw new BerDataValueFormatException("Missing length");
              }
  
              boolean constructed = BerEncoding.isConstructed((byte) firstIdentifierByte);
              int contentsLength;
              int contentsOffsetInDataValue;
              if ((firstLengthByte & 0x80) == 0) {
                  // short form length
                  contentsLength = readShortFormLength(firstLengthByte);
                  contentsOffsetInDataValue = in.getReadByteCount();
                  skipDefiniteLengthContents(in, contentsLength);
              } else if ((firstLengthByte & 0xff) != 0x80) {
                  // long form length
                  contentsLength = readLongFormLength(in, firstLengthByte);
                  contentsOffsetInDataValue = in.getReadByteCount();
                  skipDefiniteLengthContents(in, contentsLength);
              } else {
                  // indefinite length
                  contentsOffsetInDataValue = in.getReadByteCount();
                  contentsLength =
                          constructed
                                  ? skipConstructedIndefiniteLengthContents(in)
                                  : skipPrimitiveIndefiniteLengthContents(in);
              }
  
              byte[] encoded = in.getReadBytes();
              ByteBuffer encodedContents =
                      ByteBuffer.wrap(encoded, contentsOffsetInDataValue, contentsLength);
              return new BerDataValue(
                      ByteBuffer.wrap(encoded),
                      encodedContents,
                      BerEncoding.getTagClass((byte) firstIdentifierByte),
                      constructed,
                      tagNumber);
          } catch (IOException e) {
              throw new BerDataValueFormatException("Failed to read data value", e);
          }
      }
docs: Returns the next data value or {@code null} if end of input has been reached.
  
  @throws BerDataValueFormatException if the value being read is malformed.