/* $Id$ */
/* 
 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#ifndef __PJPP_POOL_HPP__
#define __PJPP_POOL_HPP__

#include <pj/pool.h>

class Pj_Pool;
class Pj_Caching_Pool;

//
// Base class for all Pjlib objects
//
class Pj_Object
{
public:
    void *operator new(unsigned int class_size, Pj_Pool *pool);
    void *operator new(unsigned int class_size, Pj_Pool &pool);

    void operator delete(void*)
    {
    }

    void operator delete(void*, Pj_Pool*)
    {
    }

    void operator delete(void*, Pj_Pool&)
    {
    }

    //
    // Inline implementations at the end of this file.
    //

private:
    // Can not use normal new operator; must use pool.
    // e.g.:
    //   obj = new(pool) Pj_The_Object(pool, ...);
    //
    void *operator new(unsigned int)
    {}
};


//
// Pool.
//
class Pj_Pool : public Pj_Object
{
public:
    //
    // Default constructor, initializes internal pool to NULL.
    // Application must call attach() some time later.
    //
    Pj_Pool()
        : p_(NULL)
    {
    }

    //
    // Create pool.
    //
    Pj_Pool(Pj_Caching_Pool &caching_pool,
            pj_size_t initial_size, 
            pj_size_t increment_size, 
            const char *name = NULL, 
            pj_pool_callback *callback = NULL);

    //
    // Construct from existing pool.
    //
    explicit Pj_Pool(pj_pool_t *pool)
        : p_(pool)
    {
    }

    //
    // Attach existing pool.
    //
    void attach(pj_pool_t *pool)
    {
        p_ = pool;
    }

    //
    // Destructor.
    //
    // Release pool back to factory. Remember: if you delete pool, then 
    // make sure that all objects that have been allocated from this pool
    // have been properly destroyed.
    //
    // This is where C++ is trickier than plain C!!
    //
    ~Pj_Pool()
    {
        if (p_)
	    pj_pool_release(p_);
    }

    //
    // Get name.
    //
    const char *getobjname() const
    {
	return pj_pool_getobjname(p_);
    }

    //
    // You can cast Pj_Pool to pj_pool_t*
    //
    operator pj_pool_t*()
    {
	return p_;
    }

    //
    // Get pjlib compatible pool object.
    //
    pj_pool_t *pool_()
    {
	return p_;
    }

    //
    // Get pjlib compatible pool object.
    //
    const pj_pool_t *pool_() const
    {
	return p_;
    }

    //
    // Get pjlib compatible pool object.
    //
    pj_pool_t *pj_pool_t_()
    {
	return p_;
    }

    //
    // Reset pool.
    //
    void reset()
    {
	pj_pool_reset(p_);
    }

    //
    // Get current capacity.
    //
    pj_size_t get_capacity()
    {
	pj_pool_get_capacity(p_);
    }

    //
    // Get current total bytes allocated from the pool.
    //
    pj_size_t get_used_size()
    {
	pj_pool_get_used_size(p_);
    }

    //
    // Allocate.
    //
    void *alloc(pj_size_t size)
    {
	return pj_pool_alloc(p_, size);
    }

    //
    // Allocate elements and zero fill the memory.
    //
    void *calloc(pj_size_t count, pj_size_t elem)
    {
	return pj_pool_calloc(p_, count, elem);
    }

    //
    // Allocate and zero fill memory.
    //
    void *zalloc(pj_size_t size)
    {
        return pj_pool_zalloc(p_, size);
    }

private:
    pj_pool_t *p_;
};


//
// Caching pool.
//
class Pj_Caching_Pool
{
public:
    //
    // Construct caching pool.
    //
    Pj_Caching_Pool( pj_size_t cache_capacity = 0,
	             const pj_pool_factory_policy *pol=&pj_pool_factory_default_policy)
    {
	pj_caching_pool_init(&cp_, pol, cache_capacity);
    }

    //
    // Destroy caching pool.
    //
    ~Pj_Caching_Pool()
    {
	pj_caching_pool_destroy(&cp_);
    }

    //
    // Create pool.
    //
    pj_pool_t *create_pool( pj_size_t initial_size, 
                            pj_size_t increment_size, 
                            const char *name = NULL, 
                            pj_pool_callback *callback = NULL)
    {
	return (pj_pool_t*)(*cp_.factory.create_pool)(&cp_.factory, name, 
                                                     initial_size, 
                                                     increment_size, 
                                                     callback);
    }

private:
    pj_caching_pool cp_;
};

//
// Inlines for Pj_Object
//
inline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool *pool)
{
    return pool->alloc(class_size);
}
inline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool &pool)
{
    return pool.alloc(class_size);
}

//
// Inlines for Pj_Pool
//
inline Pj_Pool::Pj_Pool( Pj_Caching_Pool &caching_pool,
                         pj_size_t initial_size, 
                         pj_size_t increment_size, 
                         const char *name, 
                         pj_pool_callback *callback)
{
    p_ = caching_pool.create_pool(initial_size, increment_size, name,
                                  callback);
}


#endif	/* __PJPP_POOL_HPP__ */

