/*
 * MessagePack for C deflate buffer implementation
 *
 * Copyright (C) 2010 FURUHASHI Sadayuki
 *
 *    Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *    http://www.boost.org/LICENSE_1_0.txt)
 */
#ifndef MSGPACK_ZBUFFER_H
#define MSGPACK_ZBUFFER_H

#include "sysdep.h"
#include <stdlib.h>
#include <string.h>
#include <zlib.h>

#ifdef __cplusplus
extern "C" {
#endif


/**
 * @defgroup msgpack_zbuffer Compressed buffer
 * @ingroup msgpack_buffer
 * @{
 */

typedef struct msgpack_zbuffer {
    z_stream stream;
    char* data;
    size_t init_size;
} msgpack_zbuffer;

#ifndef MSGPACK_ZBUFFER_INIT_SIZE
#define MSGPACK_ZBUFFER_INIT_SIZE 8192
#endif

static inline bool msgpack_zbuffer_init(
    msgpack_zbuffer* zbuf, int level, size_t init_size);
static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf);

static inline msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size);
static inline void msgpack_zbuffer_free(msgpack_zbuffer* zbuf);

static inline char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf);

static inline const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf);
static inline size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf);

static inline bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf);
static inline void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf);
static inline char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf);


#ifndef MSGPACK_ZBUFFER_RESERVE_SIZE
#define MSGPACK_ZBUFFER_RESERVE_SIZE 512
#endif

static inline int msgpack_zbuffer_write(void* data, const char* buf, size_t len);

static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf);


static inline bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
        int level, size_t init_size)
{
    memset(zbuf, 0, sizeof(msgpack_zbuffer));
    zbuf->init_size = init_size;
    if(deflateInit(&zbuf->stream, level) != Z_OK) {
        free(zbuf->data);
        return false;
    }
    return true;
}

static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf)
{
    deflateEnd(&zbuf->stream);
    free(zbuf->data);
}

static inline msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size)
{
    msgpack_zbuffer* zbuf = (msgpack_zbuffer*)malloc(sizeof(msgpack_zbuffer));
    if (zbuf == NULL) return NULL;
    if(!msgpack_zbuffer_init(zbuf, level, init_size)) {
        free(zbuf);
        return NULL;
    }
    return zbuf;
}

static inline void msgpack_zbuffer_free(msgpack_zbuffer* zbuf)
{
    if(zbuf == NULL) { return; }
    msgpack_zbuffer_destroy(zbuf);
    free(zbuf);
}

static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf)
{
    size_t used = (char*)zbuf->stream.next_out - zbuf->data;
    size_t csize = used + zbuf->stream.avail_out;
    size_t nsize = (csize == 0) ? zbuf->init_size : csize * 2;

    char* tmp = (char*)realloc(zbuf->data, nsize);
    if(tmp == NULL) {
        return false;
    }

    zbuf->data = tmp;
    zbuf->stream.next_out  = (Bytef*)(tmp + used);
    zbuf->stream.avail_out = nsize - used;

    return true;
}

static inline int msgpack_zbuffer_write(void* data, const char* buf, size_t len)
{
    msgpack_zbuffer* zbuf = (msgpack_zbuffer*)data;

    zbuf->stream.next_in = (Bytef*)buf;
    zbuf->stream.avail_in = len;

    while(zbuf->stream.avail_in > 0) {
        if(zbuf->stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
            if(!msgpack_zbuffer_expand(zbuf)) {
                return -1;
            }
        }

        if(deflate(&zbuf->stream, Z_NO_FLUSH) != Z_OK) {
            return -1;
        }
    }

    return 0;
}

static inline char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf)
{
    while(true) {
        switch(deflate(&zbuf->stream, Z_FINISH)) {
        case Z_STREAM_END:
            return zbuf->data;
        case Z_OK:
            if(!msgpack_zbuffer_expand(zbuf)) {
                return NULL;
            }
            break;
        default:
            return NULL;
        }
    }
}

static inline const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf)
{
    return zbuf->data;
}

static inline size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf)
{
    return (char*)zbuf->stream.next_out - zbuf->data;
}

static inline void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf)
{
    zbuf->stream.avail_out += (char*)zbuf->stream.next_out - zbuf->data;
    zbuf->stream.next_out = (Bytef*)zbuf->data;
}

static inline bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf)
{
    if(deflateReset(&zbuf->stream) != Z_OK) {
        return false;
    }
    msgpack_zbuffer_reset_buffer(zbuf);
    return true;
}

static inline char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf)
{
    char* tmp = zbuf->data;
    zbuf->data = NULL;
    zbuf->stream.next_out = NULL;
    zbuf->stream.avail_out = 0;
    return tmp;
}

/** @} */


#ifdef __cplusplus
}
#endif

#endif /* msgpack/zbuffer.h */

