text:
package com.bt.pi.core.application.watcher.task;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

import com.bt.pi.core.conf.Property;
import com.bt.pi.core.continuation.UpdateResolvingPiContinuation;
import com.bt.pi.core.dht.DhtClientFactory;
import com.bt.pi.core.dht.DhtWriter;
import com.bt.pi.core.entity.TaskProcessingQueue;
import com.bt.pi.core.id.PId;

/*
 * A Spring bean to help with managing TaskProcessingQueues
 */
@Component
public class TaskProcessingQueueHelper {
    protected static final int DEFAULT_REMAINING_RETRIES = -1;
    private static final String QUEUE_STATE_S = "queue state: %s";
    private static final Log LOG = LogFactory.getLog(TaskProcessingQueueHelper.class);
    private static final String DEFAULT_QUEUE_SIZE_WARNING_THRESHOLD = "100";
    private DhtClientFactory dhtClientFactory;
    private int queueSizeWarningThreshold = Integer.parseInt(DEFAULT_QUEUE_SIZE_WARNING_THRESHOLD);

    public TaskProcessingQueueHelper() {
        this.dhtClientFactory = null;
    }

    @Property(key = "queue.size.warning.threshold", defaultValue = DEFAULT_QUEUE_SIZE_WARNING_THRESHOLD)
    public void setQueueSizeWarningThreshold(int value) {
        this.queueSizeWarningThreshold = value;
    }

    public void addUrlToQueue(final PId queueId, final String url) {
        addUrlToQueue(queueId, url, DEFAULT_REMAINING_RETRIES, null);
    }

    public void addUrlToQueue(final PId queueId, final String url, TaskProcessingQueueContinuation continuation) {
        addUrlToQueue(queueId, url, DEFAULT_REMAINING_RETRIES, continuation);
    }

    public void addUrlToQueue(final PId queueId, final String url, final int remainingRetries) {
        addUrlToQueue(queueId, url, remainingRetries, null);
    }

    public void addUrlToQueue(final PId queueId, final String url, final int remainingRetries, final TaskProcessingQueueContinuation continuation) {
        LOG.debug(String.format("addUrlToQueue(%s, %s, %s, %s)", queueId, url, remainingRetries, continuation));
        DhtWriter writer = dhtClientFactory.createWriter();
        writer.update(queueId, new UpdateResolvingPiContinuation<TaskProcessingQueue>() {
            @Override
            public TaskProcessingQueue update(TaskProcessingQueue existingEntity, TaskProcessingQueue requestedEntity) {
                if (null == existingEntity) {
                    LOG.warn(String.format("cannot add %s to non-existent queue %s", url, queueId.toStringFull()));
                    return null;
                }
                if (existingEntity.add(url, remainingRetries)) {
                    if (existingEntity.size() > queueSizeWarningThreshold) {
                        LOG.warn(String.format("queue %s has exceeded %d entries, size is now %d", queueId.toStringFull(), queueSizeWarningThreshold, existingEntity.size()));
                    }
                    return existingEntity;
                }
                return null;
            }

            @Override
            public void handleResult(TaskProcessingQueue result) {
                LOG.debug(String.format(QUEUE_STATE_S, result));
                if (null != continuation)
                    continuation.receiveResult(url, null);
            }
        });
    }

    public void removeUrlFromQueue(final PId queueId, final String url) {
        LOG.debug(String.format("removeUrlFromQueue(%s, %s)", queueId, url));
        DhtWriter writer = dhtClientFactory.createWriter();
        writer.update(queueId, new UpdateResolvingPiContinuation<TaskProcessingQueue>() {
            @Override
            public TaskProcessingQueue update(TaskProcessingQueue existingEntity, TaskProcessingQueue requestedEntity) {
                if (null == existingEntity) {
                    LOG.warn(String.format("cannot remove %s from non-existent queue %s", url, queueId.toStringFull()));
                    return null;
                }
                if (existingEntity.remove(url))
                    return existingEntity;
                return null;
            }

            @Override
            public void handleResult(TaskProcessingQueue result) {
                LOG.debug(String.format(QUEUE_STATE_S, result));
            }
        });
    }

    public void setNodeIdOnUrl(final PId queueId, final String url, final String nodeId) {
        setNodeIdOnUrl(queueId, url, nodeId, null);
    }

    public void setNodeIdOnUrl(final PId queueId, final String url, final String nodeId, final TaskProcessingQueueContinuation continuation) {
        LOG.debug(String.format("setNodeIdOnUrl(%s, %s, %s, %s)", queueId, url, nodeId, continuation));
        DhtWriter writer = dhtClientFactory.createWriter();
        writer.update(queueId, new UpdateResolvingPiContinuation<TaskProcessingQueue>() {
            @Override
            public TaskProcessingQueue update(TaskProcessingQueue existingEntity, TaskProcessingQueue requestedEntity) {
                if (null == existingEntity) {
                    LOG.warn(String.format("cannot update %s on non-existent queue %s", url, queueId));
                    return null;
                }
                existingEntity.setOwnerNodeIdForUrl(url, nodeId);
                return existingEntity;
            }

            @Override
            public void handleResult(TaskProcessingQueue result) {
                LOG.debug(String.format(QUEUE_STATE_S, result));
                if (null != continuation)
                    continuation.receiveResult(url, nodeId);
            }
        });
    }

    @Resource
    public void setDhtClientFactory(DhtClientFactory aDhtClientFactory) {
        this.dhtClientFactory = aDhtClientFactory;
    }
}


text:
package org.jivesoftware.sparkimpl.certificates;

import java.awt.HeadlessException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.stream.Collectors;

import javax.naming.InvalidNameException;
import javax.net.ssl.X509TrustManager;

import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.jivesoftware.spark.util.log.Log;

/**
 * This trust manager wrap around SparkExceptionsTrustManager. In case when SparkExceptionsTrustManager fail then this
 * TrustManager will provide certificates from TRUSTED KeyStore which are checked against data validity, revocation,
 * acceptance of self-signed certificates and basic constraints.
 *
 *
 * @author Pawel Scibiorsk
 *
 */
public class SparkTrustManager extends GeneralTrustManager implements X509TrustManager {

    static X509Certificate[] lastFailedChain;

    private final boolean checkCRL;
    private final boolean checkOCSP;
    private final boolean acceptExpired;
    private final boolean acceptNotValidYet;
    private final boolean acceptRevoked;
    private final boolean acceptSelfSigned;
    private final boolean allowSoftFail;

    private CertStore crlStore;
    private final X509TrustManager exceptionsTrustManager;
    private KeyStore trustStore;
    private KeyStore displayedCaCerts;
    private final Collection<X509CRL> crlCollection = new ArrayList<>();

    public SparkTrustManager() {
        exceptionsTrustManager = new SparkExceptionsTrustManager();
        checkCRL = localPref.isCheckCRL();
        checkOCSP = localPref.isCheckOCSP();
        acceptExpired = localPref.isAcceptExpired();
        acceptNotValidYet = localPref.isAcceptNotValidYet();
        acceptRevoked = localPref.isAcceptRevoked();
        acceptSelfSigned = localPref.isAcceptSelfSigned();
        allowSoftFail = localPref.isAllowSoftFail();

        loadKeyStores();
    }

    public static X509TrustManager[] getTrustManagerList() {
        return new X509TrustManager[] { new SparkTrustManager() };
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) {
        throw new UnsupportedOperationException("This implementation cannot be used to validate client-provided certificate chains.");
    }

    public static X509Certificate[] getLastFailedChain()
    {
        return lastFailedChain;
    }

    public void addChain( X509Certificate[] chain ) {
        certControll.addChain(chain);
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        try {
            doTheChecks(chain, authType);
            lastFailedChain = null;
        } catch (CertPathValidatorException e) {
            lastFailedChain = chain;
            throw new CertificateException(e);
        }
    }

    /**
     * Do chain validity checks
     * @param chain with certificates from server
     * @param authType
     * @throws CertificateException
     * @throws CertPathValidatorException
     */
    private void doTheChecks(X509Certificate[] chain, String authType) throws CertificateException, CertPathValidatorException {
        try {
            // first check if certificate is accepted as as certificate from exceptions list, exceptionsTrustManager
            // will make use of chain provided by exceptions KeyStore
            exceptionsTrustManager.checkServerTrusted(chain, authType);
        } catch (CertificateException ex) {
            // in case when certificate isn't on exceptions list then make use of this Trust Manager
            // validate chain by date (expired/not valid yet)
            checkDateValidity(chain);

            // check if certificate isn't self signed, self signed certificate still have to be in TrustStore to be
            // accepted
            if (!isSelfSigned(chain)) {
                // validate certificate path
                try {
                    validatePath(chain);

                } catch (NoSuchAlgorithmException | KeyStoreException | InvalidAlgorithmParameterException | CertPathValidatorException e) {
                    Log.error("Validating path failed", e);
                    throw new CertPathValidatorException("Certificate path validation failed", e);

                }
            } else if (isSelfSigned(chain) && !acceptSelfSigned) {
                // Self Signed certificate while it isn't accepted
                throw new CertificateException("Self Signed certificate");

            } else if (isSelfSigned(chain) && acceptSelfSigned) {
                // check if certificate is in Keystore and check CRL, but do not validate path as certificate is Self
                // Signed important reminder: hostname validation must be also turned off to accept self signed
                // certificate
                List<X509Certificate> certList = new ArrayList<>(Arrays.asList(getAcceptedIssuers()));
                if (!certList.contains(chain[0])) {
                    throw new CertPathValidatorException("Certificate not in the TrustStore");
                }
                try {
                    loadCRL(chain);
                    for (X509CRL crl : crlCollection) {
                        if (crl.isRevoked(chain[0])) {
                            throw new CertificateException("Certificate is revoked");
                        }
                    }
                } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | CRLException | IOException e) {
                    Log.warning("Couldn't load CRL");
                }
            } else {
                throw new CertificateException("Certificate chain cannot be trusted");
            }
        }
    }

    /**
     * Return true if the certificate chain contain only one Self Signed certificate
     */
    public static boolean isSelfSigned(X509Certificate[] chain) {
        return chain[0].getIssuerX500Principal().getName().equals(chain[0].getSubjectX500Principal().getName())
                && chain.length == 1;
    }

    /**
     * Returns true if a certificate is a 'root' certificate, by verifying that its issuer matches its subject, and the
     * subject of the certificate is a CA (by checking the Basic Constraints).
     *
     * @param cert The certificate to check
     * @return 'true' if the certificate is a root certificate, otherwise false.
     */
    public static boolean isRootCACertificate( final X509Certificate cert ) {
        return cert.getIssuerX500Principal().getName().equals(cert.getSubjectX500Principal().getName()) && cert.getBasicConstraints() > -1;
    }

    /**
     * Verifies if Spark's trust stores recognize the issuer of at least one of the certificates in the chain.
     *
     * @param chain The chain to verify
     * @return false if none of the issuers are present in any of the trust stores of Spark.
     */
    public boolean containsTrustAnchorFor(X509Certificate[] chain) {
        final Collection<String> allAcceptedIssuers = Arrays.stream(getAcceptedIssuers())
            .map(x509Certificate -> x509Certificate.getSubjectDN().getName())
            .collect(Collectors.toSet());
        return Arrays.stream(chain).anyMatch( cert -> allAcceptedIssuers.contains( cert.getIssuerDN().getName()) );
    }

    /**
     * Validate certificate path
     *
     * Note that the provided chain cannot be a self-signed certificate. This method assumes a CA-signed chain is
     * provided.
     *
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws InvalidAlgorithmParameterException
     * @throws CertPathValidatorException
     * @throws CertificateException
     */
    private void validatePath(X509Certificate[] chain)
            throws NoSuchAlgorithmException, KeyStoreException, InvalidAlgorithmParameterException,
            CertPathValidatorException, CertificateException
    {
        if (isSelfSigned(chain)) {
            throw new IllegalArgumentException("Method cannot be used with self-signed certificate.");
        }

        // The certificate representing the {@link TrustAnchor TrustAnchor} should not be included in the certification
        // path. If it does, certain validation (like OCSP) might give unexpected results/fail. SPARK-2188
        final List<X509Certificate> certificates = Arrays.stream(chain)
            .filter( cert -> !isRootCACertificate(cert))
            .collect(Collectors.toList());

        // Construct a certPath entity that represents the chain that is to be validated. Does not include the trust anchor.
        final CertPath certPath = CertificateFactory.getInstance("X.509").generateCertPath(certificates);

        // SPARK-2185: Ensure that what we validate is not empty.
        if ( certPath.getCertificates().isEmpty() ) {
            throw new CertificateException("Unable to build a certificate path from the provided chain.");
        }

        // PKIX algorithm is defined in rfc3280
        CertPathValidator certPathValidator = CertPathValidator.getInstance("PKIX");
        CertPathBuilder certPathBuilder = CertPathBuilder.getInstance("PKIX");

        // Selects the target to be validated. This is the end-entity/leaf certificate, typically the first in the chain.
        X509CertSelector toBeValidated = new X509CertSelector();
        toBeValidated.setCertificate((X509Certificate) certPath.getCertificates().get(0));

        // create parameters using trustStore as source of Trust Anchors and using X509CertSelector
        PKIXBuilderParameters parameters = new PKIXBuilderParameters(allStore, toBeValidated);

        // will use PKIXRevocationChecker (or nothing if revocation mechanisms are
        // disabled) instead of the default revocation checker
        parameters.setRevocationEnabled(false);

        // if revoked certificates aren't accepted, but no revocation checks then only
        // certificates from blacklist will be rejected
        if (!acceptRevoked) {

            // OCSP checking is done according to Java PKI Programmer's Guide, PKIXRevocationChecker was added in Java 8:
            // https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html#PKIXRevocationChecker
            PKIXRevocationChecker checker = (PKIXRevocationChecker) certPathBuilder.getRevocationChecker();

            EnumSet<PKIXRevocationChecker.Option> checkerOptions = EnumSet.noneOf(PKIXRevocationChecker.Option.class);
            // if soft fail isn't enabled then OCSP or CRL must pass validation, in case
            // when any of them cannot be validated verification will fail, if soft fail
            // is enabled then in case of network issues revocation checking is omitted
            if (allowSoftFail) {
                checkerOptions.add(PKIXRevocationChecker.Option.SOFT_FAIL);
            }
            // check OCSP, CRL serve as backup
            if (checkOCSP && checkCRL) {
                checker.setOptions(checkerOptions);
                parameters.addCertPathChecker(checker);
            } else if (!checkOCSP && checkCRL) {
                // check only CRL, if CRL fail then there is no fallback to OCSP
                checkerOptions.add(PKIXRevocationChecker.Option.PREFER_CRLS);
                checkerOptions.add(PKIXRevocationChecker.Option.NO_FALLBACK);
                checker.setOptions(checkerOptions);
                parameters.addCertPathChecker(checker);
            }

        }

        try {
            PKIXCertPathValidatorResult validationResult = (PKIXCertPathValidatorResult) certPathValidator
                    .validate(certPath, parameters);
            X509Certificate trustAnchor = validationResult.getTrustAnchor().getTrustedCert();

            if (trustAnchor == null) {
                throw new CertificateException("certificate path failed: Trusted CA is NULL");
            }
            checkBasicConstraints(certPath, trustAnchor);
        } catch (CertificateRevokedException e) {
            Log.warning("Certificate was revoked", e);
            for (Certificate c : certPath.getCertificates()) {
                X509Certificate cert = (X509Certificate) c;
                for (X509CRL crl : crlCollection) {
                    if (crl.isRevoked(cert)) {
                        try {
                            addToBlackList(cert);
                        } catch (HeadlessException | InvalidNameException e1) {
                            Log.error("Couldn't move to the blacklist", e1);
                        }
                        break;
                    }
                }
            }
            throw new CertificateException("Certificate was revoked");
        } catch (CertPathValidatorException e) {
            String no_OCSP_Responder_error = "Certificate does not specify OCSP responder";
            // Spark can be configured to disregard some of the issues that can pop up through validation.
            if ( e.getReason() == CertPathValidatorException.BasicReason.EXPIRED && acceptExpired ) {
                Log.debug("Chain validation detected expiry, but Spark is configured to allow this. Not failing validation.");
            } else if ( e.getReason() == CertPathValidatorException.BasicReason.NOT_YET_VALID && acceptNotValidYet ) {
                Log.debug("Chain validation detected not-yet-valid, but Spark is configured to allow this. Not failing validation.");
            } else if (e.getReason() == CertPathValidatorException.BasicReason.UNSPECIFIED && e.getMessage().equals(no_OCSP_Responder_error)) {
                Log.debug(no_OCSP_Responder_error);
            } else {
                // When Spark is not configured to ignore the validation issue, rethrow the original exception.
                throw e;
            }
        }
    }

    /**
     * check time date validity of certificates
     *
     * @throws CertificateException
     */
    private void checkDateValidity(X509Certificate[] chain) throws CertificateException {

        for (X509Certificate cert : chain) {
            // expiration check
            try {
                cert.checkValidity();
            } catch (CertificateExpiredException e) {
                Log.warning("Certificate is expired " + cert.getSubjectX500Principal().getName(), e);
                if (!acceptExpired) {
                    throw new CertificateException("Certificate is expired");
                }
            } catch (CertificateNotYetValidException e) {
                Log.warning("Certificate is not valid yet " + cert.getSubjectX500Principal().getName(), e);
                if (!acceptNotValidYet) {
                    throw new CertificateException("Certificate is not valid yet");
                }
            }

        }
    }

    /**
     * Checks the validity of the BasicConstraints extension of each certificate in the chain.
     *
     * Each certificate is assumed to have a BasicConstraints extension, with the exception of the leaf (end-entity)
     * certificate, which _can_ have a certificate.
     *
     * All non-leaf certificates must have the cA field set to 'true'.
     *
     * The pathLen is valid: it defines the maximum amount of intermediate certificates between the CA and the leaf
     * certificate. The leaf certificate itself is not included in the count (eg: a value of 'one' would allow for a
     * chain length of three: the leaf, one intermediate, and the root (where the value of 'one' is defined).
     *
     * This method assumes that the provided chain is in order, where the first chain is the end-entity / leaf certificate.
     *
     * The trust anchor / root CA should not be part of the certPath chain.
     *
     * @param chain The certificate chain, possibly incomplete.
     * @param trustAnchor the root CA certificate.
     * @throws CertificateException When the BasicConstraint verification fails.
     */
    private void checkBasicConstraints(CertPath chain, X509Certificate trustAnchor) throws CertificateException {
        // Intentionally skipping over the first certificate, which is the end-entity certificate.
        for (int i = 1; i<chain.getCertificates().size(); i++)
        {
            final X509Certificate cert = (X509Certificate) chain.getCertificates().get(i);
            // The amount of certificates between the current certificate and the end-entity certificate cannot
            // exceed the value of pathLenConstraint (if the CA flag is not set, -1 will be returned)
            final int pathLenConstraint = cert.getBasicConstraints();
            final int certsSeparatingThisCertFromEndEntity = i - 1;
            if (certsSeparatingThisCertFromEndEntity > pathLenConstraint) {
                throw new CertificateException("Certificate number " + i + " in the chain failed the BasicConstraints check: "
                    + (pathLenConstraint == -1 ? "CA flag not set" : "pathLenConstraint to small (was: " +pathLenConstraint+ " needed:" + certsSeparatingThisCertFromEndEntity+")"));
            }
        }

        // Explicitly check the trustAnchor (as it should not be in the chain)
        final int pathLenConstraint = trustAnchor.getBasicConstraints();
        final int certsSeparatingThisCertFromEndEntity = chain.getCertificates().size() - 1;
        if (certsSeparatingThisCertFromEndEntity > pathLenConstraint) {
            throw new CertificateException("Trust anchor of the chain failed the BasicConstraints check: "
                + (pathLenConstraint == -1 ? "CA flag not set" : "pathLenConstraint to small (was: " + pathLenConstraint + " needed:" + certsSeparatingThisCertFromEndEntity + ")"));
        }
    }

    /**
     * loads truststores and potentially (depending on settings) blacklist
     */
    @Override
    protected void loadKeyStores() {
        certControll.loadKeyStores();
        trustStore = certControll.openKeyStore(CertificateController.TRUSTED);
        displayedCaCerts = certControll.openCacertsKeyStore();

        try {
            loadAllStore();
        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException
                | HeadlessException e) {
            Log.error("Cannot create allStore KeyStore");
        }

        try {
            addKeyStoreContentToAllStore(trustStore);
        } catch (HeadlessException | KeyStoreException | InvalidNameException e) {
            Log.error("Cannot add trustStore content to allStore", e);
        }
        try {
            addKeyStoreContentToAllStore(displayedCaCerts);
        } catch (HeadlessException | KeyStoreException | InvalidNameException e) {
            Log.error("Cannot add displayedCaCerts to the allStore", e);
        }

    }

    public Collection<X509CRL> loadCRL(X509Certificate[] chain) throws IOException, InvalidAlgorithmParameterException,
            NoSuchAlgorithmException, CRLException {

        // for each certificate in chain
        for (X509Certificate cert : chain) {
            if (cert.getExtensionValue(Extension.cRLDistributionPoints.getId()) != null) {
                ASN1Primitive primitive = JcaX509ExtensionUtils
                        .parseExtensionValue(cert.getExtensionValue(Extension.cRLDistributionPoints.getId()));
                // extract distribution point extension
                CRLDistPoint distPoint = CRLDistPoint.getInstance(primitive);
                DistributionPoint[] dp = distPoint.getDistributionPoints();
                // each distribution point extension can hold number of distribution points
                for (DistributionPoint d : dp) {
                    DistributionPointName dpName = d.getDistributionPoint();
                    // Look for URIs in fullName
                    if (dpName != null && dpName.getType() == DistributionPointName.FULL_NAME) {
                        GeneralName[] genNames = GeneralNames.getInstance(dpName.getName()).getNames();
                        // Look for an URI
                        for (GeneralName genName : genNames) {
                            // extract url
                            URL url = new URL(genName.getName().toString());
                            try {
                                // download from Internet to the collection
                                crlCollection.add(downloadCRL(url));
                            } catch (CertificateException | CRLException e) {
                                throw new CRLException("Couldn't download CRL");
                            }
                        }
                    }
                }
            } else {
                Log.warning("Certificate " + cert.getSubjectX500Principal().getName() + " have no CRLs");
            }
            // parameters for cert store is collection type, using collection with crl create parameters
            CollectionCertStoreParameters params = new CollectionCertStoreParameters(crlCollection);
            // this parameters are next used for creation of certificate store with crls
            crlStore = CertStore.getInstance("Collection", params);
        }
        return crlCollection;
    }

    /**
     * Move certificate to the blacklist of the revoked certificates.
     *
     * @param cert certificate which is meant to move into blacklist
     * @throws KeyStoreException
     * @throws InvalidNameException
     * @throws HeadlessException
     */
    private void addToBlackList(X509Certificate cert) throws KeyStoreException,
        HeadlessException, InvalidNameException {
        certControll.addCertificateToBlackList(cert);
    }

    /**
     * Downloads a CRL from given URL
     *
     * @param url the web address with given CRL
     * @throws IOException
     * @throws CertificateException
     * @throws CRLException
     */
    private X509CRL downloadCRL(URL url) throws IOException, CertificateException, CRLException {

        try (InputStream crlStream = url.openStream()) {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            return (X509CRL) cf.generateCRL(crlStream);
        }
    }

}

redpajama_set_name: RedPajamaGithub


text:
#pragma once

template <typename T>
class Singleton
{
public:
    static void _create();
    static inline T &get()
    {
        if (d_instance == nullptr)
            _create();
        return *d_instance;
    }
private:
    static T *d_instance;
};


text:
package com.lessomall.bidding.ui.bidding;

import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.LinearLayout;

import com.lessomall.bidding.LessoApplication;
import com.lessomall.bidding.R;
import com.lessomall.bidding.activity.BaseActivity;
import com.lessomall.bidding.activity.OtherActivity;
import com.lessomall.bidding.common.Constant;

/**
 * Created by meisl on 2015/9/8.
 */
public class LogoutDialog extends Dialog {

    private String TAG = "com.lessomall.bidding.ui.bidding.LogoutDialog";

    private Context context;

    public LogoutDialog(Context context) {

        super(context);

        this.context = context;

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        init();
    }

    private void init() {

        LayoutInflater inflater = LayoutInflater.from(context);
        LinearLayout dialog = (LinearLayout) inflater.inflate(R.layout.dialog_logout, null);

        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        setContentView(dialog, params);
        getWindow().getAttributes().width = ViewGroup.LayoutParams.MATCH_PARENT;

        LinearLayout logout_layout = (LinearLayout) findViewById(R.id.logout_layout);
        logout_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SharedPreferences sp = context.getSharedPreferences(
                        context.getString(R.string.app_name), Context.MODE_PRIVATE);

                SharedPreferences.Editor editor = sp.edit();
                editor.remove(Constant.LESSO_BIDDING_USERPASSWORD);
                editor.commit();

                ((LessoApplication) ((OtherActivity) context).getApplication()).setUser(null);

                ((BaseActivity) context).reLogin();
            }
        });

        LinearLayout cancel_layout = (LinearLayout) findViewById(R.id.cancel_layout);
        cancel_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dismiss();
            }
        });

    }

}


text:
$( document ).ready( function() {

	var MySubviewClass = Backbone.View.extend( {
		initialize: function(options) {
			this.renderText = options["rendertext"]
		},
		render: function() {
			this.$el.html(this.renderText)
		}
	})

	module( "Subview assignment",
		{
			teardown: function() {
				itemViewInstance.remove()
			}
		}
	)

	test( "Subviews are rendered as parent is rendered", function() {
		var MyItemViewClass = Backbone.View.extend( {
			el: "#container",
			initialize: function() {
				Backbone.AssignSubviews.add(this)
				this.subview1 = new MySubviewClass({ rendertext: "rendered subview 1" })
				this.subview2 = new MySubviewClass({ rendertext: "rendered second subview" })
				this.render()
			},
			render: function() {
				this.$el.html("

")
				this.assign({ "#subview1" : this.subview1,
					      "#subview2" : this.subview2 })
			}
		})

		itemViewInstance = new MyItemViewClass()

		equal( $("#subview1").html(), "rendered subview 1", "subview is rendered")
		equal( $("#subview2").html(), "rendered second subview", "subview is rendered")

	})

	test( "Subviews are rendered on reassignment", function() {
		var MyItemViewClass = Backbone.View.extend( {
			el: "#container",
			initialize: function() {
				Backbone.AssignSubviews.add(this)
				this.subview1 = new MySubviewClass({ rendertext: "rendered subview 1" })
				this.subview2 = new MySubviewClass({ rendertext: "rendered second subview" })
				this.render()
			},
			render: function() {
				this.$el.html("

")
				this.assign({ "#subview1" : this.subview1,
					      "#subview2" : this.subview2 })
			}
		})

		itemViewInstance = new MyItemViewClass()

		itemViewInstance.assign("#subview1", itemViewInstance.subview2)
		itemViewInstance.assign("#subview2", itemViewInstance.subview1)

		equal( $("#subview1").html(), "rendered second subview", "subview is rendered")
		equal( $("#subview2").html(), "rendered subview 1", "subview is rendered")
	})

})


text:
from .SSD300 import SSD300
from .ssd_utils import make_prior_boxes


text:
ACCEPTED

#### According to
International Plant Names Index

#### Published in
null

#### Original name
Pterocactus kuntzei K.Schum.

### Remarks
null


text:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/start_daemon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:text="@string/btn_start_daemon"/>

    <Button
        android:id="@+id/stop_daemon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:text="@string/btn_stop_daemon"/>

    <Button
        android:id="@+id/goto_sleep"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:text="@string/btn_goto_sleep"/>

    <Button
        android:id="@+id/reboot"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:text="@string/btn_reboot"/>

    <Button
        android:id="@+id/list_services"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:text="@string/btn_list_services"/>

    <Button
        android:id="@+id/test_raw_invoking"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:text="@string/btn_test_raw_invoking"/>
</LinearLayout>


text:
//
//  OGImageProcessing.m
//
//  Created by Art Gillespie on 11/29/12.
//  Copyright (c) 2012 Origami Labs, Inc.. All rights reserved.
//

#import "OGImageProcessing.h"
#import <Accelerate/Accelerate.h>

NSString * const OGImageProcessingErrorDomain = @"OGImageProcessingErrorDomain";

/*
 * Return the size that aspect fits `from` into `to`
 */
CGSize OGAspectFit(CGSize from, CGSize to) {
    NSCParameterAssert(0.f != from.width);
    NSCParameterAssert(0.f != from.height);
    NSCParameterAssert(0.f != to.width);
    NSCParameterAssert(0.f != to.height);

    if (CGSizeEqualToSize(from, to)) {
        return to;
    }
    CGFloat r1 = from.width / from.height;
    CGFloat r2 = to.width / to.height;
    if (r2 > r1) {
        return CGSizeMake(ceilf(from.width * to.height/from.height), ceilf(to.height));
    } else {
        return CGSizeMake(ceilf(to.width), ceilf(from.height * (to.width / from.width)));
    }
    return CGSizeZero;
}

CGSize OGAspectFill(CGSize from, CGSize to, CGPoint *offset) {
    NSCParameterAssert(0.f != from.width);
    NSCParameterAssert(0.f != from.height);
    NSCParameterAssert(0.f != to.width);
    NSCParameterAssert(0.f != to.height);
    NSCParameterAssert(nil != offset);
    offset->x = 0.f;
    offset->y = 0.f;
    CGFloat sRatio = from.width / from.height;
    CGFloat dRatio = to.width / to.height;
    CGFloat ratio = (dRatio <= sRatio) ? to.height / from.height : to.width / from.width;
    CGSize ret = CGSizeMake(roundf(from.width * ratio), roundf(from.height * ratio));
    if (ret.width > to.width) {
        offset->x = floorf(ret.width / 2.f - to.width / 2.f);
    }
    if (ret.height > to.height) {
        offset->y = floorf(ret.height / 2.f - to.height / 2.f);
    }
    return ret;
}

void OGClearVImageBuffer(vImage_Buffer *buffer) {
    Pixel_8888 c = {0, 0, 0, 0};
    vImageBufferFill_ARGB8888(buffer, c, 0);
}

/*
 * Don't forget to free buffer->data.
 */
OSStatus UIImageToVImageBuffer(UIImage *image, vImage_Buffer *buffer, CGImageAlphaInfo alphaInfo) {
    OSStatus err = noErr;
    CGImageRef cgImage = image.CGImage;
    size_t width = CGImageGetWidth(cgImage);
    size_t height = CGImageGetHeight(cgImage);
    //
    // If the image orientation isn't Up or Down, we create the buffer in the
    // target orientation's dimensions (i.e., the resulting buffer *does* have 'Up' orientation)
    //
    if (UIImageOrientationRight == image.imageOrientation ||
        UIImageOrientationLeft == image.imageOrientation ||
        UIImageOrientationRightMirrored == image.imageOrientation ||
        UIImageOrientationLeftMirrored == image.imageOrientation) {
        size_t nh = width;
        width = height;
        height = nh;
    }
    buffer->data = malloc(width * height * 4);
    buffer->width = width;
    buffer->height = height;
    buffer->rowBytes = width * 4;
    OGClearVImageBuffer(buffer);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(buffer->data,
                                             buffer->width,
                                             buffer->height, 8,
                                             buffer->rowBytes, colorSpace, alphaInfo);
    if (UIImageOrientationRight == image.imageOrientation) {
        CGContextRotateCTM(ctx, -M_PI/2.f);
        CGContextTranslateCTM(ctx, -(CGFloat)height, 0.f);
    } else if (UIImageOrientationLeft == image.imageOrientation) {
        CGContextRotateCTM(ctx, M_PI/2.f);
        CGContextTranslateCTM(ctx, 0.f, -(CGFloat)width);
    }
    CGContextDrawImage(ctx, CGRectMake(0.f, 0.f, CGImageGetWidth(cgImage), CGImageGetHeight(cgImage)), cgImage);
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    return err;
}

CGImageRef VImageBufferToCGImage(vImage_Buffer *buffer, CGFloat scale, CGImageAlphaInfo alphaInfo) {
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreateWithData(buffer->data,
                                                     buffer->width,
                                                     buffer->height,
                                                     8, buffer->rowBytes, colorSpace, alphaInfo, NULL, NULL);
    CGImageRef theImage = CGBitmapContextCreateImage(ctx);
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    return theImage;
}

#pragma mark -

@implementation OGImageProcessing {
    dispatch_queue_t _imageProcessingQueue;
    // key -> __OGImage, value -> NSArray of id<OGImageProcessingDelegate>
    NSMutableDictionary *_delegates;
    // mediate access to _delegates;
    dispatch_queue_t _delegateSerialQueue;
}

+ (OGImageProcessing *)shared {
    static OGImageProcessing *shared = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[OGImageProcessing alloc] init];
    });
    return shared;
}

- (id)init
{
    self = [super init];
    if (self) {
        _imageProcessingQueue = dispatch_queue_create("com.origamilabs.imageProcessing", DISPATCH_QUEUE_CONCURRENT);
        _delegates = [NSMutableDictionary dictionaryWithCapacity:10];
        _delegateSerialQueue = dispatch_queue_create("com.origamilabs.imageProcessing.delegateSerialization", DISPATCH_QUEUE_SERIAL);
    }
    return self;
}

- (void)scaleImage:(__OGImage *)image toSize:(CGSize)size cornerRadius:(CGFloat)cornerRadius delegate:(id<OGImageProcessingDelegate>)delegate {
    [self scaleImage:image toSize:size cornerRadius:cornerRadius method:OGImageProcessingScale_AspectFit delegate:delegate];
}

- (void)scaleImage:(__OGImage *)image toSize:(CGSize)size cornerRadius:(CGFloat)cornerRadius method:(OGImageProcessingScaleMethod)method delegate:(id<OGImageProcessingDelegate>)delegate {
    NSString *lsnrKey = [NSString stringWithFormat:@"%p.%@.%f", image, NSStringFromCGSize(size), cornerRadius];
    dispatch_async(_delegateSerialQueue, ^{
        NSMutableArray *lsnrs = _delegates[lsnrKey];
        if (nil != lsnrs) {
            // we already have a queued block for this combination, so
            // just register our delegate and return
            [lsnrs addObject:delegate];
            return;
        }
        // we didn't already have a queued block for this combination, so create
        // the delegate array, add our delegate to it, set it using the combination's key
        // and queue the processing operation for it
        lsnrs = [NSMutableArray arrayWithObject:delegate];
        [_delegates setValue:lsnrs forKey:lsnrKey];
        dispatch_async(_imageProcessingQueue, ^{
            CGFloat scale = [UIScreen mainScreen].scale;
            CGSize newSize = CGSizeZero;
            CGPoint offset = CGPointZero;
            CGSize fromSize = image.size;
            fromSize.width *= image.scale;
            fromSize.height *= image.scale;
            CGSize toSize = size;
            toSize.width *= scale;
            toSize.height *= scale;
            // if the two sizes are the same, I mean, come on
            if (CGSizeEqualToSize(fromSize, toSize) && 0.f == cornerRadius) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self notifyDelegatesForKey:lsnrKey withImage:image error:nil];
                });
                return;
            }

            CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image.CGImage);
            if (kCGImageAlphaNone == alphaInfo) {
                // kCGImageAlphaNone w/8-bit channels not supported
                alphaInfo = kCGImageAlphaNoneSkipLast;
            }
            if (0.f < cornerRadius) {
                alphaInfo = kCGImageAlphaPremultipliedFirst;
            }

            if (OGImageProcessingScale_AspectFit == method) {
                newSize = OGAspectFit(image.size, size);
            } else {
                newSize = OGAspectFill(image.size, size, &offset);
            }
            newSize.width *= scale;
            newSize.height *= scale;
            offset.x *= scale;
            offset.y *= scale;

            vImage_Buffer vBuffer;
            OSStatus err = UIImageToVImageBuffer(image, &vBuffer, alphaInfo);
            if (noErr != err) {
                NSError *error = [NSError errorWithDomain:OGImageProcessingErrorDomain
                                                     code:err userInfo:@{NSLocalizedDescriptionKey : @"Error converting UIImage to vImage"}];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self notifyDelegatesForKey:lsnrKey withImage:nil error:error];
                });
                return;
            }
            vImage_Buffer dBuffer;
            dBuffer.width = newSize.width;
            dBuffer.height = newSize.height;
            dBuffer.rowBytes = newSize.width * 4;
            CGFloat xHeight = 0.f;
            if (0.f < offset.x) {
                xHeight = 1;
            }
            dBuffer.data = malloc(newSize.width * (newSize.height + xHeight) * 4);
            OGClearVImageBuffer(&dBuffer);
            vImage_Error vErr = vImageScale_ARGB8888(&vBuffer, &dBuffer, NULL, kvImageNoFlags);
            if (kvImageNoError != vErr) {
                free(dBuffer.data);
                NSError *error = [NSError errorWithDomain:OGImageProcessingErrorDomain
                                                     code:err userInfo:@{NSLocalizedDescriptionKey : @"Error scaling image"}];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self notifyDelegatesForKey:lsnrKey withImage:nil error:error];
                });
                return;
            }

            void *origDataPtr = dBuffer.data;

            if (OGImageProcessingScale_AspectFill == method) {
                if (0.f < offset.x) {
                    dBuffer.data = dBuffer.data + ((int)offset.x * 4);
                    dBuffer.width = toSize.width;
                } else if (0.f < offset.y) {
                    int row_offset = (int)offset.y;
                    row_offset *= dBuffer.rowBytes;
                    dBuffer.data = dBuffer.data + row_offset;
                    dBuffer.height = toSize.height;
                }
            }
            CGImageRef cgImage = VImageBufferToCGImage(&dBuffer, [UIScreen mainScreen].scale, alphaInfo);
            __OGImage *scaledImage = [[__OGImage alloc] initWithCGImage:cgImage type:image.originalFileType info:image.originalFileProperties alphaInfo:alphaInfo scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
            CGImageRelease(cgImage);
            free(vBuffer.data);
            free(origDataPtr);
            if (0.f < cornerRadius) {
                scaledImage = [self applyCornerRadius:cornerRadius toImage:scaledImage];
            }

            // notify the interested delegates
            [self notifyDelegatesForKey:lsnrKey withImage:scaledImage error:nil];
        });
    });
}

- (void)notifyDelegatesForKey:(NSString *)key withImage:(__OGImage *)image error:(NSError *)error {
    __block NSMutableArray *lsnrs;
    dispatch_sync(_delegateSerialQueue, ^{
        lsnrs = _delegates[key];
        [_delegates removeObjectForKey:key];
    });
    __weak OGImageProcessing *weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        for (id<OGImageProcessingDelegate> delegate in lsnrs) {
            if (nil != error) {
                [delegate imageProcessingFailed:self error:error];
            } else {
                [delegate imageProcessing:weakSelf didProcessImage:image];
            }
        }
    });
}

- (__OGImage *)applyCornerRadius:(CGFloat)cornerRadius toImage:(__OGImage *)origImage {
    if (0.f == cornerRadius)
        return origImage;
    CGSize _size = origImage.size;
    float _cornerRadius = cornerRadius;
    // If we're on a retina display, make sure everything is @2x
    if ([[UIScreen mainScreen] scale] > 1.f) {
        _size.width *= origImage.scale;
        _size.height *= origImage.scale;
        _cornerRadius *= origImage.scale;
    }

    // Lots of weird math
    uint32_t bitsPerComponent = 8;
    uint32_t numberOfComponents = 4;
    uint32_t dataSize = _size.height * _size.width * (numberOfComponents * bitsPerComponent) / 8;
    uint8_t *data = (uint8_t *)malloc(dataSize);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    bzero(data, dataSize);

    CGImageAlphaInfo alphaInfo = kCGImageAlphaPremultipliedLast;
    CGContextRef context = CGBitmapContextCreate(data, _size.width, _size.height, bitsPerComponent,
                                                 _size.width * (bitsPerComponent * numberOfComponents) / 8, colorSpace,
                                                 alphaInfo);

    // Let's round the corners, if desired
    if (_cornerRadius != 0.0) {
        CGContextSaveGState(context);
        CGContextMoveToPoint(context, 0.f, _cornerRadius);
        CGContextAddArc(context, _cornerRadius, _cornerRadius, _cornerRadius, M_PI, 1.5 * M_PI, 0);
        CGContextAddLineToPoint(context, _size.width - _cornerRadius, 0.f);
        CGContextAddArc(context, _size.width - _cornerRadius, _cornerRadius, _cornerRadius, 1.5 * M_PI, 0.f, 0);
        CGContextAddLineToPoint(context, _size.width, _size.height - _cornerRadius);
        CGContextAddArc(context, _size.width - _cornerRadius, _size.height - _cornerRadius, _cornerRadius, 0.f, 0.5 * M_PI, 0);
        CGContextAddLineToPoint(context, _cornerRadius, _size.height);
        CGContextAddArc(context, _cornerRadius, _size.height - _cornerRadius, _cornerRadius, 0.5 * M_PI, M_PI, 0);
        CGContextAddLineToPoint(context, 0.f, _cornerRadius);
        CGContextSaveGState(context);
        CGContextClip(context);
    }

    // Create a fresh image from the context
    CGContextDrawImage(context, CGRectMake(0.f, 0.f, _size.width, _size.height), [origImage CGImage]);
    if (_cornerRadius != 0.0)
        CGContextRestoreGState(context);
    CGImageRef image = CGBitmapContextCreateImage(context);
    __OGImage *ret = [[__OGImage alloc] initWithCGImage:image type:@"public.png" info:origImage.originalFileProperties alphaInfo:alphaInfo scale:origImage.scale orientation:origImage.imageOrientation];
    if (image)
        CFRelease(image);

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(data);
    context = NULL;
    return ret;
}

@end


text:
<?php

namespace AvoRed\Review\Database\Contracts;

use Illuminate\Support\Collection as SupportCollection;
use Illuminate\Database\Eloquent\Collection;
use AvoRed\Review\Database\Models\ProductReview;
use Illuminate\Contracts\Pagination\Paginator;

interface ProductReviewModelInterface
{
    /**
     * Create ProductReview Resource into a database.
     * @param array $data
     * @return \AvoRed\Review\Database\Models\ProductReview $review
     */
    public function create(array $data) : ProductReview;

    /**
     * Find ProductReview Resource into a database.
     * @param int $id
     * @return \AvoRed\Review\Database\Models\ProductReview $review
     */
    public function find(int $id) : ProductReview;

    /**
     * Delete ProductReview Resource from a database.
     * @param int $id
     * @return int
     */
    public function delete(int $id) : int;

    /**
     * Get All ProductReview from the database.
     * @return \Illuminate\Database\Eloquent\Collection $reviews
     */
    public function all() : Collection;

    /**
     * Get All ProductReview from the database by given Product Id.
     * @param int $productId
     * @param int $perPage
     * @return \Illuminate\Support\Collection $reviews
     */
    public function getAllReviewsByProductId(int $productId) : Paginator;
}


text:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var request = require('request');

var config = require('./config');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

var path = require('path');
var fs = require('fs');
var Services = [];

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

module.exports = app;

// Load Services
var servicesPath = path.join(__dirname, 'services');
fs.readdirSync(servicesPath).forEach(function (file) {
  if (path.extname(file) === '.js') {
    Services.push(require(path.join(servicesPath, file)));
  }
});

// Run Services
Services.forEach(function (service) {
  service.setup(config);
});

function shutdown() {
  Services.forEach(function (service) {
    service.shutdown();
  });

  process.exit();
}

process.on('SIGINT', shutdown);


text:
/*
 * The source code included in this files was separated from mbfilter.c
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 4 Dec 2002. The file
 * mbfilter.c is included in this package .
 *
 */

#ifndef MBFL_MBFILTER_ASCII_H
#define MBFL_MBFILTER_ASCII_H

#include "mbfilter.h"

extern const mbfl_encoding mbfl_encoding_ascii;
extern const struct mbfl_identify_vtbl vtbl_identify_ascii;
extern const struct mbfl_convert_vtbl vtbl_ascii_wchar;
extern const struct mbfl_convert_vtbl vtbl_wchar_ascii;

int mbfl_filt_conv_ascii_wchar(int c, mbfl_convert_filter *filter);
int mbfl_filt_conv_wchar_ascii(int c, mbfl_convert_filter *filter);

#endif /* MBFL_MBFILTER_ASCII_H */