/*
 * This file was generated automatically by xsubpp version 1.9508 from the 
 * contents of BIO.xs. Do not edit this file, edit BIO.xs instead.
 *
 *	ANY CHANGES MADE HERE WILL BE LOST! 
 *
 */

#line 1 "BIO.xs"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "BIO.h"

static int nid = 1;
static int bid = 0;

typedef struct encstr {
	void * cipher;
	unsigned char key[EVP_MAX_KEY_LENGTH];
	unsigned char iv[EVP_MAX_IV_LENGTH];
} encstr;

typedef struct biostr {
    BIO * bio;
	struct biostr * next;
    int buflen;
    int freed;
	int id;
	struct encstr * enc;
} biostr;

typedef biostr * Crypt_OpenSSL_BIO;


Crypt_OpenSSL_BIO
init_BIO(int type, int buflen)
{
	Crypt_OpenSSL_BIO bio;

	if (New(nid++, (void*)bio, sizeof(biostr), Crypt_OpenSSL_BIO) == NULL)
		noAlloc();

	bio->next = NULL;
	bio->buflen = (buflen ? buflen : BUFLEN);
	bio->freed = 0;
	bio->id = bid++;

    if (New(nid++, (void*)bio->enc, sizeof(encstr), encstr *) == NULL)
        noAlloc();

	bio->enc->cipher = EVP_enc_null();
	memset(bio->enc->key, 0, sizeof(unsigned char));
    memset(bio->enc->iv, 0, sizeof(unsigned char));

	switch (type){
		case BIO_TYPE_NONE:			bio->bio = BIO_new(BIO_S_NULL); break;
		case BIO_TYPE_MEM:			bio->bio = BIO_new(BIO_S_MEM); break;
		case BIO_TYPE_FILE:			bio->bio = BIO_new(BIO_S_FILE); break;
		case BIO_TYPE_FD:			bio->bio = BIO_new(BIO_S_FD); break;
		case BIO_TYPE_SOCKET:		bio->bio = BIO_new(BIO_S_SOCKET); break;
		case BIO_TYPE_NULL:			bio->bio = BIO_new(BIO_S_NULL); break;
		case BIO_TYPE_MD:			bio->bio = BIO_new(BIO_F_MD); break;
		case BIO_TYPE_BUFFER:		bio->bio = BIO_new(BIO_F_BUFFER); break;
		case BIO_TYPE_CIPHER:		bio->bio = BIO_new(BIO_F_CIPHER); break;
		case BIO_TYPE_BASE64:		bio->bio = BIO_new(BIO_F_BASE64); break;
		case BIO_TYPE_CONNECT:		bio->bio = BIO_new(BIO_S_CONNECT); break;
		case BIO_TYPE_ACCEPT:		bio->bio = BIO_new(BIO_S_ACCEPT); break;
		case BIO_TYPE_NULL_FILTER:	bio->bio = BIO_new(BIO_F_NULL); break;
		case BIO_TYPE_BIO:			bio->bio = BIO_new(BIO_S_BIO); break;
		default:  					bio->bio = BIO_new(BIO_S_NULL); break;
	}

	return bio; 
}


int
set_BIO(Crypt_OpenSSL_BIO bio, int type)
{
    int ret;

    switch (type){
        case BIO_TYPE_NONE:         ret = BIO_set(bio->bio, BIO_S_NULL); break;
        case BIO_TYPE_MEM:          ret = BIO_set(bio->bio, BIO_S_MEM); break;
        case BIO_TYPE_FILE:         ret = BIO_set(bio->bio, BIO_S_FILE); break;
        case BIO_TYPE_FD:           ret = BIO_set(bio->bio, BIO_S_FD); break;
        case BIO_TYPE_SOCKET:       ret = BIO_set(bio->bio, BIO_S_SOCKET); break;
        case BIO_TYPE_NULL:         ret = BIO_set(bio->bio, BIO_S_NULL); break;
        case BIO_TYPE_MD:           ret = BIO_set(bio->bio, BIO_F_MD); break;
        case BIO_TYPE_BUFFER:       ret = BIO_set(bio->bio, BIO_F_BUFFER); break;
        case BIO_TYPE_CIPHER:       ret = BIO_set(bio->bio, BIO_F_CIPHER); break;
        case BIO_TYPE_BASE64:       ret = BIO_set(bio->bio, BIO_F_BASE64); break;
        case BIO_TYPE_CONNECT:      ret = BIO_set(bio->bio, BIO_S_CONNECT); break;
        case BIO_TYPE_ACCEPT:       ret = BIO_set(bio->bio, BIO_S_ACCEPT); break;
        case BIO_TYPE_NULL_FILTER:  ret = BIO_set(bio->bio, BIO_F_NULL); break;
        case BIO_TYPE_BIO:          ret = BIO_set(bio->bio, BIO_S_BIO); break;
        default:                    ret = BIO_set(bio->bio, BIO_S_NULL); break;
    }

    return ret;
}


int 
look_for_sink(Crypt_OpenSSL_BIO bio)
{
	int ret = 0;
	Crypt_OpenSSL_BIO btmp = bio;

	do {
		if (btmp->bio->method->type & BIO_TYPE_SOURCE_SINK)
		{
			ret = 1;
			break;
		}

		btmp = btmp->next;
		if (btmp == NULL) break;
	} while (btmp);

	return ret;
}


SV *
read_data(Crypt_OpenSSL_BIO bio, char *type)
{
    char *data;
	SV *result;
	int i = 0;
	int total = 0;
	STRLEN len;

    if (New(0, data, bio->buflen+1, char) == NULL)
        noAlloc();

	memset(data, 0, bio->buflen+1);
	result = sv_2mortal(NEWSV(0, bio->buflen));
	SvPOK_on(result);

	if (type == "read")
	{
		while ( (i = BIO_read(bio->bio, data, bio->buflen)) > 0){
			total += i;
			len = SvCUR(result);

			if ((len > 0) && (total > len))
			{
				SvGROW(result, total - len);
			}

			sv_catpv(result, data);
			memset(data, 0, bio->buflen+1);
		}
	}
	else
	{
        while ( (i = BIO_gets(bio->bio, data, bio->buflen)) > 0){
            total += i;
            len = SvCUR(result);

            if ((len > 0) && (total > len))
            {
                SvGROW(result, total - len);
            }

            sv_catpv(result, data);
            memset(data, 0, bio->buflen+1);
        }
	}

	Safefree(data);
	return result;
}


int
write_data(Crypt_OpenSSL_BIO bio, char* data, char *type)
{
    // Filter BIOs require a source/sink in order to
    // read/write. If none is present return flag

    if (look_for_sink(bio) == 0)
        return BIO_FLAGS_NO_SINK;

	if (type == "write")
 		return BIO_write(bio->bio, data, strlen(data));
	else
		return BIO_puts(bio->bio, data);
}


#line 195 "BIO.c"
XS(XS_Crypt__OpenSSL__BIO_new)
{
    dXSARGS;
    if (items < 2 || items > 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::new(CLASS, type, buflen = BUFLEN)");
    SP -= items;
    {
	char *	CLASS = (char *)SvPV(ST(0),PL_na);
	int	type = (int)SvIV(ST(1));
	int	buflen;

	if (items < 3)
	    buflen = BUFLEN;
	else {
	    buflen = (int)SvIV(ST(2));
	}
#line 195 "BIO.xs"
{
	Crypt_OpenSSL_BIO bio;
    bio = init_BIO(type, buflen); 

    XPUSHs(sv_setref_pv(sv_newmortal(),
                   PACKAGE_NAME, (void *)bio));
	XSRETURN(1);
}
#line 221 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_DESTROY)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::DESTROY(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 209 "BIO.xs"
{
	if (!self->freed)
    	BIO_vfree(self->bio);

	Safefree(self);
	XSRETURN_YES;
}
#line 250 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_buflen)
{
    dXSARGS;
    if (items < 1 || items > 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::buflen(self, buflen = 0)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	buflen;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 2)
	    buflen = 0;
	else {
	    buflen = (int)SvIV(ST(1));
	}
#line 230 "BIO.xs"
{
	if (buflen > 0)
	{
		self->buflen = buflen;
		XSRETURN_YES;
	}	
	else
	{
		XSRETURN_IV(self->buflen);
	}
}
#line 290 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_next)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::next(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 264 "BIO.xs"
{
    XPUSHs(sv_setref_pv(sv_newmortal(),
                   PACKAGE_NAME, (Crypt_OpenSSL_BIO)self->next));
	XSRETURN(1);
}
#line 317 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_push)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::push(self, bio)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	Crypt_OpenSSL_BIO	bio;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

                if (sv_derived_from(ST(1), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(1)));
                bio = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("bio is not of type Crypt::OpenSSL::BIO");
#line 282 "BIO.xs"
{
	self->next = bio;
	self->bio = BIO_push(self->bio, bio->bio);
	XSRETURN_YES;
}
#line 352 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_pop)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::pop(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 301 "BIO.xs"
{
	BIO_pop(self->bio);
	XSRETURN_YES;
}
#line 378 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_read)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::read(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 315 "BIO.xs"
{
	XPUSHs(read_data(self, "read"));
	XSRETURN(1);
}
#line 404 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_gets)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::gets(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 325 "BIO.xs"
{
    XPUSHs(read_data(self, "gets"));
    XSRETURN(1);
}
#line 430 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_write)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::write(self, data)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char *	data = (char *)SvPV(ST(1),PL_na);

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 336 "BIO.xs"
{
	XSRETURN_IV(write_data(self, data, "write"));
}
#line 456 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_puts)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::puts(self, data)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char *	data = (char *)SvPV(ST(1),PL_na);

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 346 "BIO.xs"
{
    XSRETURN_IV(write_data(self, data, "puts"));
}
#line 482 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_flush)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::flush(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 359 "BIO.xs"
{
	XSRETURN_IV(BIO_flush(self->bio));
}
#line 507 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_free)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::free(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 375 "BIO.xs"
{
	self->freed = 1;
	XSRETURN_IV(BIO_free(self->bio));
}
#line 533 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_vfree)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::vfree(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 385 "BIO.xs"
{
	self->freed = 1;
	BIO_vfree(self->bio);
	XSRETURN_YES;
}
#line 560 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_free_all)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::free_all(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 396 "BIO.xs"
{
	Crypt_OpenSSL_BIO btmp = self; 

	do {
		if (btmp == NULL) break;
		btmp->freed = BIO_free(btmp->bio);
		btmp = btmp->next;
	} while (btmp);

	XSRETURN_YES;
}
#line 593 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set(self, type)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	type = (int)SvIV(ST(1));

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 418 "BIO.xs"
{
	XSRETURN_IV(set_BIO(self, type));
}
#line 619 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_type)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::type(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 433 "BIO.xs"
{
	XSRETURN_IV(self->bio->method->type);
}
#line 644 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_reset)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::reset(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 447 "BIO.xs"
{
	XSRETURN_IV(BIO_reset(self->bio));
}
#line 669 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_eof)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::eof(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 460 "BIO.xs"
{
	XSRETURN_IV(BIO_eof(self->bio));
}
#line 694 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_seek)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::seek(self, offset)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	offset = (int)SvIV(ST(1));

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 475 "BIO.xs"
{
	if (self->bio->method->type != BIO_TYPE_FILE &&  
        self->bio->method->type != BIO_TYPE_FD)
			XSRETURN_NO;

	XSRETURN_IV(BIO_seek(self->bio, offset));
}
#line 724 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_tell)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::tell(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 493 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_FILE &&
        self->bio->method->type != BIO_TYPE_FD)
            XSRETURN_NO;

	XSRETURN_IV(BIO_tell(self->bio));
}
#line 753 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_close)
{
    dXSARGS;
    if (items < 1 || items > 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::close(self, flag = -1)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	flag;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 2)
	    flag = -1;
	else {
	    flag = (int)SvIV(ST(1));
	}
#line 511 "BIO.xs"
{
	if (flag == -1)
		XSRETURN_IV(BIO_get_close(self->bio));
	else
		XSRETURN_IV(BIO_set_close(self->bio, (long)flag));
}
#line 788 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_read_pending)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::read_pending(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 528 "BIO.xs"
{
	XSRETURN_IV(BIO_ctrl_pending(self->bio));
}
#line 813 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_write_pending)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::write_pending(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 542 "BIO.xs"
{
	XSRETURN_IV(BIO_ctrl_wpending(self->bio));
}
#line 838 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_should_retry)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::should_retry(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 556 "BIO.xs"
{
	XSRETURN_IV(BIO_should_retry(self->bio));
}
#line 863 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_should_write)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::should_write(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 565 "BIO.xs"
{
    XSRETURN_IV(BIO_should_write(self->bio));
}
#line 888 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_should_read)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::should_read(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 574 "BIO.xs"
{
    XSRETURN_IV(BIO_should_read(self->bio));
}
#line 913 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_should_io_special)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::should_io_special(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 583 "BIO.xs"
{
    XSRETURN_IV(BIO_should_io_special(self->bio));
}
#line 938 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_retry_type)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::retry_type(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 592 "BIO.xs"
{
    XSRETURN_IV(BIO_retry_type(self->bio));
}
#line 963 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_get_retry_reason)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::get_retry_reason(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 601 "BIO.xs"
{
	XSRETURN_IV(BIO_get_retry_reason(self->bio));
}
#line 988 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set_fd)
{
    dXSARGS;
    if (items < 2 || items > 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set_fd(self, fd, c = BIO_CLOSE)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	fd = (int)SvIV(ST(1));
	int	c;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 3)
	    c = BIO_CLOSE;
	else {
	    c = (int)SvIV(ST(2));
	}
#line 621 "BIO.xs"
{
	if (c != BIO_CLOSE && c != BIO_NOCLOSE)
		c = BIO_CLOSE;

	// Both file and socket types use this so we just 
	// look to see if the BIO is a descriptor
	if (!(self->bio->method->type & BIO_TYPE_DESCRIPTOR))
		XSRETURN_NO;

	XSRETURN_IV(BIO_set_fd(self->bio, fd, c));
}
#line 1029 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_get_fd)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::get_fd(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 638 "BIO.xs"
{
    // Both file and socket types use this so we just
    // look to see if the BIO is a descriptor
    if (!(self->bio->method->type & BIO_TYPE_DESCRIPTOR))
        XSRETURN_NO;

	XSRETURN_IV(BIO_get_fd(self->bio, NULL));
}
#line 1059 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_new_fd)
{
    dXSARGS;
    if (items < 2 || items > 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::new_fd(self, fd, flag = BIO_CLOSE)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	fd = (int)SvIV(ST(1));
	int	flag;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 3)
	    flag = BIO_CLOSE;
	else {
	    flag = (int)SvIV(ST(2));
	}
#line 654 "BIO.xs"
{
    if (!(self->bio->method->type & BIO_TYPE_DESCRIPTOR))
        XSRETURN_NO;

	if (flag != BIO_CLOSE && flag != BIO_NOCLOSE)
		flag = BIO_CLOSE;

	if ( BIO_new_fd(fd, flag) == NULL)
		XSRETURN_NO;

	self->bio = BIO_new_fd(fd, flag);
	XSRETURN_YES;
}
#line 1102 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set_fp)
{
    dXSARGS;
    if (items < 2 || items > 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set_fp(self, fp, c = BIO_CLOSE)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	fp = (int)SvIV(ST(1));
	int	c;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 3)
	    c = BIO_CLOSE;
	else {
	    c = (int)SvIV(ST(2));
	}
#line 679 "BIO.xs"
{
    if (c != BIO_CLOSE && c != BIO_NOCLOSE)
        c = BIO_CLOSE;

    if (self->bio->method->type != BIO_TYPE_FILE)
        XSRETURN_NO;

    BIO_set_fp(self->bio, fp, c);
    XSRETURN_YES;
}
#line 1142 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_get_fp)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::get_fp(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 695 "BIO.xs"
{
    char *c;

    if (self->bio->method->type != BIO_TYPE_FILE)
        XSRETURN_NO;

    XSRETURN_IV(BIO_get_fp(self->bio, c));
}
#line 1172 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_change_file)
{
    dXSARGS;
    if (items != 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::change_file(self, file, perms)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char *	file = (char *)SvPV(ST(1),PL_na);
	char *	perms = (char *)SvPV(ST(2),PL_na);

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 711 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_FILE)
        XSRETURN_NO;

	if (perms == "read")
		XSRETURN_IV(BIO_read_filename(self->bio, file));
	else if (perms == "write")
		XSRETURN_IV(BIO_write_filename(self->bio, file));
	else if (perms == "append")
		XSRETURN_IV(BIO_append_filename(self->bio, file));
	else if (perms == "rw")
		XSRETURN_IV(BIO_rw_filename(self->bio, file));
	else
		XSRETURN_NO;
}
#line 1211 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_new_file)
{
    dXSARGS;
    if (items < 2 || items > 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::new_file(self, filename, mode = \"a+\")");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char*	filename = (char *)SvPV(ST(1),PL_na);
	char*	mode;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 3)
	    mode = "a+";
	else {
	    mode = (char *)SvPV(ST(2),PL_na);
	}
#line 734 "BIO.xs"
{
	if (self->bio->method->type != BIO_TYPE_FILE)
		XSRETURN_NO;

	self->bio = BIO_new_file(filename, mode);
	XSRETURN_YES; 
}
#line 1248 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_new_fp)
{
    dXSARGS;
    if (items < 2 || items > 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::new_fp(self, stream, flags = BIO_NOCLOSE)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	FILE*	stream = IoIFP(sv_2io(ST(1)));
	int	flags;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 3)
	    flags = BIO_NOCLOSE;
	else {
	    flags = (int)SvIV(ST(2));
	}
#line 749 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_FILE)
        XSRETURN_NO;

	self->bio = BIO_new_fp(stream, flags);
	XSRETURN_YES;
}
#line 1285 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_new_socket)
{
    dXSARGS;
    if (items < 2 || items > 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::new_socket(self, sock, flag = BIO_CLOSE)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	sock = (int)SvIV(ST(1));
	int	flag;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 3)
	    flag = BIO_CLOSE;
	else {
	    flag = (int)SvIV(ST(2));
	}
#line 768 "BIO.xs"
{
	if (self->bio->method->type != BIO_TYPE_SOCKET)
		XSRETURN_NO;

	if (flag != BIO_NOCLOSE && flag != BIO_CLOSE)
		flag = BIO_CLOSE;

	self->bio = BIO_new_socket(sock, flag);
	XSRETURN_YES;
}
#line 1325 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set_cipher)
{
    dXSARGS;
    if (items < 2 || items > 5)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set_cipher(self, cipher, key = NULL, iv = \"INEEDNIV\", flag = 1)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	cipher = (int)SvIV(ST(1));
	unsigned char*	key;
	unsigned char*	iv;
	int	flag;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 3)
	    key = NULL;
	else {
	    key = (unsigned char *)SvPV(ST(2),PL_na);
	}

	if (items < 4)
	    iv = "INEEDNIV";
	else {
	    iv = (unsigned char *)SvPV(ST(3),PL_na);
	}

	if (items < 5)
	    flag = 1;
	else {
	    flag = (int)SvIV(ST(4));
	}
#line 792 "BIO.xs"
{
	void * function;

	switch (cipher){
		case EVP_NULL:				function = EVP_enc_null(); break;

		case EVP_DES_CBC:			function = EVP_des_cbc(); break;
		case EVP_DES_ECB:			function = EVP_des_ecb(); break;
		case EVP_DES_CFB:			function = EVP_des_cfb(); break;
		case EVP_DES_OFB:			function = EVP_des_ofb(); break;

		case EVP_DES_EDE_CBC:		function = EVP_des_ede_cbc(); break;
		case EVP_DES_EDE:			function = EVP_des_ede(); break;
		case EVP_DES_EDE_CFB:		function = EVP_des_ede_cfb(); break;
		case EVP_DES_EDE_OFB:		function = EVP_des_ede_ofb(); break;

		case EVP_DES_EDE3_CBC:		function = EVP_des_ede3_cbc(); break;
		case EVP_DES_EDE3:			function = EVP_des_ede3(); break;
		case EVP_DES_EDE3_CFB:		function = EVP_des_ede3_cfb(); break;
		case EVP_DES_EDE3_OFB:		function = EVP_des_ede3_ofb(); break;
		case EVP_DESX_CBC:			function = EVP_desx_cbc(); break;

		case EVP_RC4:				function = EVP_rc4(); break;

		case EVP_IDEA_CBC:			function = EVP_idea_cbc(); break;
		case EVP_IDEA_ECB:			function = EVP_idea_ecb(); break;
		case EVP_IDEA_CFB:			function = EVP_idea_cfb(); break;
		case EVP_IDEA_OFB:			function = EVP_idea_ofb(); break;

		case EVP_RC2_CBC:			function = EVP_rc2_cbc(); break;
		case EVP_RC2_ECB:			function = EVP_rc2_ecb(); break;
		case EVP_RC2_CFB:			function = EVP_rc2_cfb(); break;
		case EVP_RC2_OFB:			function = EVP_rc2_ofb(); break;

		case EVP_BF_CBC:			function = EVP_bf_cbc(); break;
		case EVP_BF_ECB:			function = EVP_bf_ecb(); break;
		case EVP_BF_CFB:			function = EVP_bf_cfb(); break;
		case EVP_BF_OFB:			function = EVP_bf_ofb(); break;

		case EVP_CAST5_CBC:			function = EVP_cast5_cbc(); break;
		case EVP_CAST5_ECB:			function = EVP_cast5_ecb(); break;
		case EVP_CAST5_CFB:			function = EVP_cast5_cfb(); break;
		case EVP_CAST5_OFB:			function = EVP_cast5_ofb(); break;

		case EVP_RC5_32_12_16_CBC:	function = EVP_rc5_32_12_16_cbc(); break;
		case EVP_RC5_32_12_16_ECB:	function = EVP_rc5_32_12_16_ecb(); break;
        case EVP_RC5_32_12_16_CFB:  function = EVP_rc5_32_12_16_cfb(); break;
        case EVP_RC5_32_12_16_OFB:  function = EVP_rc5_32_12_16_ofb(); break;

		default:					function = EVP_enc_null(); break;
	}

	self->enc->cipher = function;

	if (key != NULL)
		memcpy(self->enc->key, key, EVP_MAX_KEY_LENGTH);

	if (iv != NULL)
		memcpy(self->enc->iv, iv, EVP_MAX_IV_LENGTH);

	// These ciphers do not use IV so we just zero it out, 
	// or maybe I screwed something up which is entirely 
	// possible.
	if (cipher == EVP_DES_EDE3_OFB || cipher == EVP_RC2_CFB)
		memset(self->enc->iv, 0, sizeof(unsigned char));

	// Not sure why this doesn't take an 8-byte key, 
	// but this works so until I figure it out... 
	if (cipher == EVP_DES_ECB && strlen(key) > 4){
		memset(self->enc->key, 0, EVP_MAX_KEY_LENGTH);
		memcpy(self->enc->key, key, 4);
	}


	BIO_set_cipher(self->bio, self->enc->cipher, self->enc->key, self->enc->iv, flag);
	XSRETURN_YES;
}
#line 1446 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_encrypt)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::encrypt(self, data)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char *	data = (char *)SvPV(ST(1),PL_na);

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 883 "BIO.xs"
{
 	if (self->enc->cipher == NULL)
		croak("Encryption BIO must be set up via set_cipher()\n");

    BIO_set_cipher(self->bio, self->enc->cipher, self->enc->key, self->enc->iv, 1);
	XSRETURN_IV(write_data(self, data, "write"));
}
#line 1476 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_decrypt)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::decrypt(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 896 "BIO.xs"
{
     if (self->enc->cipher == NULL)
        croak("Encryption BIO must be set up via set_cipher()\n");

    BIO_set_cipher(self->bio, self->enc->cipher, self->enc->key, self->enc->iv, 0);

	XPUSHs(read_data(self, "read"));
    XSRETURN(1);
}
#line 1507 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_get_cipher_status)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::get_cipher_status(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 917 "BIO.xs"
{
	if (self->bio->method->type != BIO_TYPE_CIPHER)
		XSRETURN_NO;

	XSRETURN_IV(BIO_get_cipher_status(self->bio));
}
#line 1535 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set_flags)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set_flags(self, flags)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	flags = (int)SvIV(ST(1));

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 934 "BIO.xs"
{
	BIO_set_flags(self->bio, flags);
	XSRETURN_YES;
}
#line 1562 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_get_flags)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::get_flags(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 943 "BIO.xs"
{
	int flags = BIO_get_flags(self->bio);

	if (flags)
		XSRETURN_IV(BIO_get_flags(self->bio));
	else
		XSRETURN_IV(0);
}
#line 1592 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set_mem_eof_return)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set_mem_eof_return(self, flag)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	flag = (int)SvIV(ST(1));

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 962 "BIO.xs"
{
	if (self->bio->method->type != BIO_TYPE_MEM)
		XSRETURN_NO;

	BIO_set_mem_eof_return(self->bio, flag);
	XSRETURN_YES;
}
#line 1622 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set_read_only)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set_read_only(self, data)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char *	data = (char *)SvPV(ST(1),PL_na);

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 980 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_MEM)
        XSRETURN_NO;

	self->bio = BIO_new_mem_buf((void *)data, strlen(data));
	XSRETURN_YES;
}
#line 1652 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_get_num_lines)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::get_num_lines(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 997 "BIO.xs"
{
	if (self->bio->method->type != BIO_TYPE_BUFFER)
		XSRETURN_NO;

	XSRETURN_IV(BIO_get_buffer_num_lines(self->bio));
}
#line 1680 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set_size)
{
    dXSARGS;
    if (items < 2 || items > 3)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set_size(self, size, type = NULL)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	size = (int)SvIV(ST(1));
	char *	type;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 3)
	    type = NULL;
	else {
	    type = (char *)SvPV(ST(2),PL_na);
	}
#line 1011 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_BUFFER)
        XSRETURN_NO;

	if (type == NULL)
		XSRETURN_IV(BIO_set_buffer_size(self->bio, size));
	else if (type == "read")
		XSRETURN_IV(BIO_set_read_buffer_size(self->bio, size));
	else if (type == "write")
		XSRETURN_IV(BIO_set_write_buffer_size(self->bio, size));
	else
		XSRETURN_NO;
}
#line 1723 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_set_md)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::set_md(self, type)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	type = (int)SvIV(ST(1));

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 1035 "BIO.xs"
{
	void * function;

	if (self->bio->method->type != BIO_TYPE_MD)
        XSRETURN_NO;

	switch (type){
		case EVP_MD2:		function = EVP_md2(); break;
		case EVP_MD5:		function = EVP_md5(); break;
		case EVP_MDC2:		function = EVP_mdc2(); break;
		case EVP_SHA:		function = EVP_sha(); break;
		case EVP_SHA1:		function = EVP_sha1(); break;
	}

	if (function == NULL)
		croak("Incorrect digest method");

	XSRETURN_IV(BIO_set_md(self->bio, function));
}
#line 1765 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_read_md)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::read_md(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 1065 "BIO.xs"
{
    char *md, *temp;
    unsigned char mbuf[EVP_MAX_MD_SIZE];
    int i, len;

    if (New(0, md, self->buflen+1, char) == NULL)
        noAlloc();

    if (New(0, temp, self->buflen+1, char) == NULL)
        noAlloc();

    memset(md, 0, self->buflen+1);
    memset(temp, 0, self->buflen+1);

    len = BIO_gets(self->bio, mbuf, EVP_MAX_MD_SIZE);

    for (i = 0; i < len; i++)
    {
        sprintf(md, "%02X", mbuf[i]);
        strcat(temp, md);
    }

    XPUSHs(sv_2mortal(newSVpvn(temp, strlen(temp))));

    Safefree(md);
    Safefree(temp);

    XSRETURN(1);
}
#line 1816 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_hostname)
{
    dXSARGS;
    if (items < 1 || items > 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::hostname(self, name = NULL)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char*	name;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 2)
	    name = NULL;
	else {
	    name = (char *)SvPV(ST(1),PL_na);
	}
#line 1105 "BIO.xs"
{
	if (self->bio->method->type != BIO_TYPE_CONNECT)
		XSRETURN_NO;

	if (name == NULL)
		XSRETURN_PV(BIO_get_conn_hostname(self->bio));

	XSRETURN_IV(BIO_set_conn_hostname(self->bio, name));
}
#line 1854 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_port)
{
    dXSARGS;
    if (items < 1 || items > 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::port(self, port = NULL)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char*	port;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 2)
	    port = NULL;
	else {
	    port = (char *)SvPV(ST(1),PL_na);
	}
#line 1125 "BIO.xs"
{
    if (self->bio->method->type == BIO_TYPE_CONNECT)
	{
    	if (port == NULL)
        	XSRETURN_PV(BIO_get_conn_port(self->bio));

    	XSRETURN_IV(BIO_set_conn_port(self->bio, port));
	}
	else if (self->bio->method->type == BIO_TYPE_ACCEPT)
	{
        if (port == NULL)
            XSRETURN_PV(BIO_get_accept_port(self->bio));

        XSRETURN_IV(BIO_set_accept_port(self->bio, port));
	}
	else
	{
		XSRETURN_NO;
	}
}
#line 1903 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_ip)
{
    dXSARGS;
    if (items < 1 || items > 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::ip(self, ip = NULL)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char*	ip;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 2)
	    ip = NULL;
	else {
	    ip = (char *)SvPV(ST(1),PL_na);
	}
#line 1157 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_CONNECT)
        XSRETURN_NO;

	XSRETURN_NO;
}
#line 1938 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_nbio)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::nbio(self, n)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	n = (int)SvIV(ST(1));

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 1174 "BIO.xs"
{
    if (self->bio->method->type == BIO_TYPE_CONNECT)
		XSRETURN_IV(BIO_set_nbio(self->bio, n));
	else if (self->bio->method->type == BIO_TYPE_ACCEPT)
		XSRETURN_IV(BIO_set_nbio_accept(self->bio, n));
	else
		XSRETURN_NO;
}
#line 1969 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_do_connect)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::do_connect(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 1188 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_CONNECT)
        XSRETURN_NO;

	XSRETURN_IV(BIO_do_connect(self->bio));
}
#line 1997 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_new_connect)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::new_connect(self, loc)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char*	loc = (char *)SvPV(ST(1),PL_na);

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 1201 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_CONNECT)
        XSRETURN_NO;

	self->bio = BIO_new_connect(loc);
	XSRETURN_YES;
}
#line 2027 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_new_accept)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::new_accept(self, host)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	char*	host = (char *)SvPV(ST(1),PL_na);

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 1219 "BIO.xs"
{
	if (self->bio->method->type != BIO_TYPE_ACCEPT)
		XSRETURN_NO;

	self->bio = BIO_new_accept(host);
	XSRETURN_YES;
}
#line 2057 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_accept_bios)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::accept_bios(self, bio)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	Crypt_OpenSSL_BIO	bio;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

                if (sv_derived_from(ST(1), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(1)));
                bio = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("bio is not of type Crypt::OpenSSL::BIO");
#line 1237 "BIO.xs"
{
	XSRETURN_NO;

    if (self->bio->method->type != BIO_TYPE_ACCEPT)
        XSRETURN_NO;

	XSRETURN_IV(BIO_set_accept_bios(self->bio, bio->bio));
}
#line 2095 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_bind_mode)
{
    dXSARGS;
    if (items < 1 || items > 2)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::bind_mode(self, mode = -9)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;
	int	mode;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");

	if (items < 2)
	    mode = -9;
	else {
	    mode = (int)SvIV(ST(1));
	}
#line 1252 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_ACCEPT)
        XSRETURN_NO;

	if (mode == -9)
		XSRETURN_IV(BIO_get_bind_mode(self->bio, NULL));
	else
		XSRETURN_IV(BIO_set_bind_mode(self->bio, mode));
}
#line 2133 "BIO.c"
	PUTBACK;
	return;
    }
}

XS(XS_Crypt__OpenSSL__BIO_do_accept)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Crypt::OpenSSL::BIO::do_accept(self)");
    SP -= items;
    {
	Crypt_OpenSSL_BIO	self;

                if (sv_derived_from(ST(0), "Crypt::OpenSSL::BIO")) {
                        IV tmp = SvIV((SV*)SvRV(ST(0)));
                self = (Crypt_OpenSSL_BIO) tmp;
                }
                else
               	    croak("self is not of type Crypt::OpenSSL::BIO");
#line 1267 "BIO.xs"
{
    if (self->bio->method->type != BIO_TYPE_ACCEPT)
        XSRETURN_NO;

	XSRETURN_IV(BIO_do_accept(self->bio));
}
#line 2161 "BIO.c"
	PUTBACK;
	return;
    }
}

#ifdef __cplusplus
extern "C"
#endif
XS(boot_Crypt__OpenSSL__BIO)
{
    dXSARGS;
    char* file = __FILE__;

    XS_VERSION_BOOTCHECK ;

        newXS("Crypt::OpenSSL::BIO::new", XS_Crypt__OpenSSL__BIO_new, file);
        newXS("Crypt::OpenSSL::BIO::DESTROY", XS_Crypt__OpenSSL__BIO_DESTROY, file);
        newXS("Crypt::OpenSSL::BIO::buflen", XS_Crypt__OpenSSL__BIO_buflen, file);
        newXS("Crypt::OpenSSL::BIO::next", XS_Crypt__OpenSSL__BIO_next, file);
        newXS("Crypt::OpenSSL::BIO::push", XS_Crypt__OpenSSL__BIO_push, file);
        newXS("Crypt::OpenSSL::BIO::pop", XS_Crypt__OpenSSL__BIO_pop, file);
        newXS("Crypt::OpenSSL::BIO::read", XS_Crypt__OpenSSL__BIO_read, file);
        newXS("Crypt::OpenSSL::BIO::gets", XS_Crypt__OpenSSL__BIO_gets, file);
        newXS("Crypt::OpenSSL::BIO::write", XS_Crypt__OpenSSL__BIO_write, file);
        newXS("Crypt::OpenSSL::BIO::puts", XS_Crypt__OpenSSL__BIO_puts, file);
        newXS("Crypt::OpenSSL::BIO::flush", XS_Crypt__OpenSSL__BIO_flush, file);
        newXS("Crypt::OpenSSL::BIO::free", XS_Crypt__OpenSSL__BIO_free, file);
        newXS("Crypt::OpenSSL::BIO::vfree", XS_Crypt__OpenSSL__BIO_vfree, file);
        newXS("Crypt::OpenSSL::BIO::free_all", XS_Crypt__OpenSSL__BIO_free_all, file);
        newXS("Crypt::OpenSSL::BIO::set", XS_Crypt__OpenSSL__BIO_set, file);
        newXS("Crypt::OpenSSL::BIO::type", XS_Crypt__OpenSSL__BIO_type, file);
        newXS("Crypt::OpenSSL::BIO::reset", XS_Crypt__OpenSSL__BIO_reset, file);
        newXS("Crypt::OpenSSL::BIO::eof", XS_Crypt__OpenSSL__BIO_eof, file);
        newXS("Crypt::OpenSSL::BIO::seek", XS_Crypt__OpenSSL__BIO_seek, file);
        newXS("Crypt::OpenSSL::BIO::tell", XS_Crypt__OpenSSL__BIO_tell, file);
        newXS("Crypt::OpenSSL::BIO::close", XS_Crypt__OpenSSL__BIO_close, file);
        newXS("Crypt::OpenSSL::BIO::read_pending", XS_Crypt__OpenSSL__BIO_read_pending, file);
        newXS("Crypt::OpenSSL::BIO::write_pending", XS_Crypt__OpenSSL__BIO_write_pending, file);
        newXS("Crypt::OpenSSL::BIO::should_retry", XS_Crypt__OpenSSL__BIO_should_retry, file);
        newXS("Crypt::OpenSSL::BIO::should_write", XS_Crypt__OpenSSL__BIO_should_write, file);
        newXS("Crypt::OpenSSL::BIO::should_read", XS_Crypt__OpenSSL__BIO_should_read, file);
        newXS("Crypt::OpenSSL::BIO::should_io_special", XS_Crypt__OpenSSL__BIO_should_io_special, file);
        newXS("Crypt::OpenSSL::BIO::retry_type", XS_Crypt__OpenSSL__BIO_retry_type, file);
        newXS("Crypt::OpenSSL::BIO::get_retry_reason", XS_Crypt__OpenSSL__BIO_get_retry_reason, file);
        newXS("Crypt::OpenSSL::BIO::set_fd", XS_Crypt__OpenSSL__BIO_set_fd, file);
        newXS("Crypt::OpenSSL::BIO::get_fd", XS_Crypt__OpenSSL__BIO_get_fd, file);
        newXS("Crypt::OpenSSL::BIO::new_fd", XS_Crypt__OpenSSL__BIO_new_fd, file);
        newXS("Crypt::OpenSSL::BIO::set_fp", XS_Crypt__OpenSSL__BIO_set_fp, file);
        newXS("Crypt::OpenSSL::BIO::get_fp", XS_Crypt__OpenSSL__BIO_get_fp, file);
        newXS("Crypt::OpenSSL::BIO::change_file", XS_Crypt__OpenSSL__BIO_change_file, file);
        newXS("Crypt::OpenSSL::BIO::new_file", XS_Crypt__OpenSSL__BIO_new_file, file);
        newXS("Crypt::OpenSSL::BIO::new_fp", XS_Crypt__OpenSSL__BIO_new_fp, file);
        newXS("Crypt::OpenSSL::BIO::new_socket", XS_Crypt__OpenSSL__BIO_new_socket, file);
        newXS("Crypt::OpenSSL::BIO::set_cipher", XS_Crypt__OpenSSL__BIO_set_cipher, file);
        newXS("Crypt::OpenSSL::BIO::encrypt", XS_Crypt__OpenSSL__BIO_encrypt, file);
        newXS("Crypt::OpenSSL::BIO::decrypt", XS_Crypt__OpenSSL__BIO_decrypt, file);
        newXS("Crypt::OpenSSL::BIO::get_cipher_status", XS_Crypt__OpenSSL__BIO_get_cipher_status, file);
        newXS("Crypt::OpenSSL::BIO::set_flags", XS_Crypt__OpenSSL__BIO_set_flags, file);
        newXS("Crypt::OpenSSL::BIO::get_flags", XS_Crypt__OpenSSL__BIO_get_flags, file);
        newXS("Crypt::OpenSSL::BIO::set_mem_eof_return", XS_Crypt__OpenSSL__BIO_set_mem_eof_return, file);
        newXS("Crypt::OpenSSL::BIO::set_read_only", XS_Crypt__OpenSSL__BIO_set_read_only, file);
        newXS("Crypt::OpenSSL::BIO::get_num_lines", XS_Crypt__OpenSSL__BIO_get_num_lines, file);
        newXS("Crypt::OpenSSL::BIO::set_size", XS_Crypt__OpenSSL__BIO_set_size, file);
        newXS("Crypt::OpenSSL::BIO::set_md", XS_Crypt__OpenSSL__BIO_set_md, file);
        newXS("Crypt::OpenSSL::BIO::read_md", XS_Crypt__OpenSSL__BIO_read_md, file);
        newXS("Crypt::OpenSSL::BIO::hostname", XS_Crypt__OpenSSL__BIO_hostname, file);
        newXS("Crypt::OpenSSL::BIO::port", XS_Crypt__OpenSSL__BIO_port, file);
        newXS("Crypt::OpenSSL::BIO::ip", XS_Crypt__OpenSSL__BIO_ip, file);
        newXS("Crypt::OpenSSL::BIO::nbio", XS_Crypt__OpenSSL__BIO_nbio, file);
        newXS("Crypt::OpenSSL::BIO::do_connect", XS_Crypt__OpenSSL__BIO_do_connect, file);
        newXS("Crypt::OpenSSL::BIO::new_connect", XS_Crypt__OpenSSL__BIO_new_connect, file);
        newXS("Crypt::OpenSSL::BIO::new_accept", XS_Crypt__OpenSSL__BIO_new_accept, file);
        newXS("Crypt::OpenSSL::BIO::accept_bios", XS_Crypt__OpenSSL__BIO_accept_bios, file);
        newXS("Crypt::OpenSSL::BIO::bind_mode", XS_Crypt__OpenSSL__BIO_bind_mode, file);
        newXS("Crypt::OpenSSL::BIO::do_accept", XS_Crypt__OpenSSL__BIO_do_accept, file);
    XSRETURN_YES;
}

