/* $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_);
    }

    //
    // 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__ */

