icinga2/lib/base/stream_bio.cpp

122 lines
2.1 KiB
C++

#include "i2-base.h"
using namespace icinga;
int I2Stream_new(BIO *bi);
int I2Stream_free(BIO *bi);
int I2Stream_read(BIO *bi, char *out, int outl);
int I2Stream_write(BIO *bi, const char *in, int inl);
long I2Stream_ctrl(BIO *bi, int cmd, long num, void *ptr);
int I2Stream_gets(BIO *bi, char *buf, int size);
int I2Stream_puts(BIO *bi, const char *str);
#define BIO_TYPE_I2STREAM (99|0x0400|0x0100)
static BIO_METHOD I2Stream_method =
{
BIO_TYPE_I2STREAM,
"Icinga Stream",
I2Stream_write,
I2Stream_read,
NULL,
NULL,
I2Stream_ctrl,
I2Stream_new,
I2Stream_free,
NULL,
};
typedef struct I2Stream_bio_s
{
Stream::Ptr Stream;
boost::exception_ptr Exception;
} I2Stream_bio_t;
BIO_METHOD *BIO_s_I2Stream(void)
{
return &I2Stream_method;
}
BIO *icinga::BIO_new_I2Stream(const Stream::Ptr& stream)
{
BIO *bi = BIO_new(BIO_s_I2Stream());
if (bi == NULL)
return NULL;
I2Stream_bio_t *bp = (I2Stream_bio_t *)bi->ptr;
bp->Stream = stream;
return bi;
}
void icinga::I2Stream_check_exception(BIO *bi) {
I2Stream_bio_t *bp = (I2Stream_bio_t *)bi->ptr;
if (bp->Exception) {
boost::exception_ptr ptr = bp->Exception;
bp->Exception = boost::exception_ptr();
rethrow_exception(ptr);
}
}
static int I2Stream_new(BIO *bi)
{
bi->shutdown = 0;
bi->init = 1;
bi->num = -1;
bi->ptr = new I2Stream_bio_t;
return 1;
}
static int I2Stream_free(BIO *bi)
{
I2Stream_bio_t *bp = (I2Stream_bio_t *)bi->ptr;
delete bp;
return 1;
}
static int I2Stream_read(BIO *bi, char *out, int outl)
{
I2Stream_bio_t *bp = (I2Stream_bio_t *)bi->ptr;
size_t data_read;
BIO_clear_retry_flags(bi);
try {
data_read = bp->Stream->Read(out, outl);
} catch (...) {
bp->Exception = boost::current_exception();
return -1;
}
if (data_read == 0) {
BIO_set_retry_read(bi);
return -1;
}
return data_read;
}
static int I2Stream_write(BIO *bi, const char *in, int inl)
{
I2Stream_bio_t *bp = (I2Stream_bio_t *)bi->ptr;
bp->Stream->Write(in, inl);
return inl;
}
static long I2Stream_ctrl(BIO *bi, int cmd, long num, void *ptr)
{
switch (cmd) {
case BIO_CTRL_FLUSH:
return 1;
default:
return 0;
}
}