Collection<? extends T> generateItems(InputStream inStream)
                throws ParsingException {
            if (inStream == null) {
                throw new ParsingException("inStream == null");
            }

            final boolean markable = inStream.markSupported();
            if (markable) {
                inStream.mark(PUSHBACK_SIZE);
            }

            /* Attempt to see if this is a PKCS#7 bag. */
            final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE);
            try {
                final byte[] buffer = new byte[PKCS7_MARKER.length];

                final int len = pbis.read(buffer);
                if (len < 0) {
                    // No need to reset here. The stream was empty or EOF so we return an empty
                    // list, making it mutable for consistency with the other code paths.
                    return new ArrayList<>();
                }
                pbis.unread(buffer, 0, len);

                if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
                    return fromPkcs7PemInputStream(pbis);
                }

                if (isMaybePkcs7(buffer)) {
                    return fromPkcs7DerInputStream(pbis);
                }
            } catch (Exception e) {
                if (markable) {
                    try {
                        inStream.reset();
                    } catch (IOException ignored) {
                        // If resetting the stream fails, there's not much we can do
                    }
                }
                throw new ParsingException(e);
            }

            /*
             * It wasn't, so just try to keep grabbing certificates until we
             * can't anymore.
             */
            final List<T> coll = new ArrayList<T>();
            T c;
            do {
                /*
                 * If this stream supports marking, try to mark here in case
                 * there is an error during certificate generation.
                 */
                if (markable) {
                    inStream.mark(PUSHBACK_SIZE);
                }

                try {
                    c = generateItem(pbis);
                    coll.add(c);
                } catch (ParsingException e) {
                    /*
                     * If this stream supports marking, attempt to reset it to
                     * the mark before the failure.
                     */
                    if (markable) {
                        try {
                            inStream.reset();
                        } catch (IOException ignored) {
                            // If resetting the stream fails, there's not much we can do
                        }
                    }

                    c = null;
                }
            } while (c != null);

            return coll;
        }
The code for X509 Certificates and CRL is pretty much the same. We use
this abstract class to share the code between them. This makes it ugly,
but it's already written in this language anyway.
common/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java