sieve-binary-private.h [plain text]
#ifndef __SIEVE_BINARY_PRIVATE_H
#define __SIEVE_BINARY_PRIVATE_H
#include "sieve-common.h"
#include "sieve-binary.h"
#include "sieve-extensions.h"
#include <sys/stat.h>
struct sieve_binary_file {
pool_t pool;
const char *path;
struct sieve_instance *svinst;
struct stat st;
int fd;
off_t offset;
const void *(*load_data)
(struct sieve_binary_file *file, off_t *offset, size_t size);
buffer_t *(*load_buffer)
(struct sieve_binary_file *file, off_t *offset, size_t size);
};
bool sieve_binary_file_open
(struct sieve_binary_file *file, struct sieve_instance *svinst,
const char *path, enum sieve_error *error_r);
void sieve_binary_file_close(struct sieve_binary_file **file);
struct sieve_binary_extension_reg {
int index;
const struct sieve_extension *extension;
const struct sieve_binary_extension *binext;
void *context;
unsigned int block_id;
};
struct sieve_binary_block {
struct sieve_binary *sbin;
unsigned int id;
int ext_index;
buffer_t *data;
uoff_t offset;
};
struct sieve_binary {
pool_t pool;
int refcount;
struct sieve_instance *svinst;
struct sieve_script *script;
struct sieve_binary_file *file;
ARRAY_DEFINE(extensions, struct sieve_binary_extension_reg *);
ARRAY_DEFINE(extension_index, struct sieve_binary_extension_reg *);
ARRAY_DEFINE(linked_extensions, struct sieve_binary_extension_reg *);
const char *path;
ARRAY_DEFINE(blocks, struct sieve_binary_block *);
};
struct sieve_binary *sieve_binary_create
(struct sieve_instance *svinst, struct sieve_script *script);
static inline struct sieve_binary_block *sieve_binary_block_index
(struct sieve_binary *sbin, unsigned int id)
{
struct sieve_binary_block * const *sblock;
if ( id >= array_count(&sbin->blocks) )
return NULL;
sblock = array_idx(&sbin->blocks, id);
if ( *sblock == NULL ) {
return NULL;
}
return *sblock;
}
static inline size_t _sieve_binary_block_get_size
(const struct sieve_binary_block *sblock)
{
return buffer_get_used_size(sblock->data);
}
struct sieve_binary_block *sieve_binary_block_create_id
(struct sieve_binary *sbin, unsigned int id);
buffer_t *sieve_binary_block_get_buffer
(struct sieve_binary_block *sblock);
static inline struct sieve_binary_extension_reg *
sieve_binary_extension_create_reg
(struct sieve_binary *sbin, const struct sieve_extension *ext)
{
int index = array_count(&sbin->extensions);
struct sieve_binary_extension_reg *ereg;
if ( ext->id < 0 ) return NULL;
ereg = p_new(sbin->pool, struct sieve_binary_extension_reg, 1);
ereg->index = index;
ereg->extension = ext;
array_idx_set(&sbin->extensions, (unsigned int) index, &ereg);
array_idx_set(&sbin->extension_index, (unsigned int) ext->id, &ereg);
return ereg;
}
static inline struct sieve_binary_extension_reg *sieve_binary_extension_get_reg
(struct sieve_binary *sbin, const struct sieve_extension *ext, bool create)
{
struct sieve_binary_extension_reg *reg = NULL;
if ( ext->id >= 0 && ext->id < (int) array_count(&sbin->extension_index) ) {
struct sieve_binary_extension_reg * const *ereg =
array_idx(&sbin->extension_index, (unsigned int) ext->id);
reg = *ereg;
}
if ( reg == NULL && create )
return sieve_binary_extension_create_reg(sbin, ext);
return reg;
}
static inline int sieve_binary_extension_register
(struct sieve_binary *sbin, const struct sieve_extension *ext,
struct sieve_binary_extension_reg **reg_r)
{
struct sieve_binary_extension_reg *ereg;
if ( (ereg=sieve_binary_extension_get_reg(sbin, ext, FALSE)) == NULL ) {
ereg = sieve_binary_extension_create_reg(sbin, ext);
if ( ereg == NULL ) return -1;
array_append(&sbin->linked_extensions, &ereg, 1);
}
if ( reg_r != NULL ) *reg_r = ereg;
return ereg->index;
}
bool sieve_binary_load_block(struct sieve_binary_block *);
#endif