/*--------------------------------------------------------------------------------
	HEAP LIBRARY
--------------------------------------------------------------------------------*/

#ifndef _NWHEAP_H_
#define _NWHEAP_H_

extern "C" {

#include <stdio.h>
#include <string.h>
#include <shinobi.h>

/*------------------------------------------------------------------------------*/

#define HL_ALIGN			(0x20)				/* アラインサイズ			*/
#define HL_ALIGN_N			(0xffffffe0)		/* アラインサイズ			*/
#define HL_HEADER_SIZE		(0x20)				/* ヘッダのサイズ			*/

#define HL_ERROR			(0x00000000)
#define HL_USED				(0x00000001)
#define HL_TOPOFLIST		(0x00000002)
#define HL_ENDOFLIST		(0x00000003)

typedef enum {
	HL_ERROR_INIT	= 0	,						/* 初期化されていない		*/
	HL_ERROR_DUP_INIT	,						/* 二重に初期化した			*/
	HL_ERROR_LEAK		,						/* メモリリーク				*/
	HL_ERROR_BREAK		,						/* メモリが破壊されている	*/
	HL_ERROR_MEMORY		,						/* メモリ不足				*/
	HL_ERROR_IVALID		,						/* 不正なパラメータ			*/
	HL_ERROR_POINTER	,						/* ポインタが不正			*/
	HL_ERROR_NOBEGIN	,						/* BEGINしてないのにEND		*/
	HL_ERROR_MISMATCH	,						/* MallocとFree回数の不一致	*/
	HL_WARNING_COUNT	,						/* 確保と開放回数が不一致	*/
	HL_WARNING_HOLE		,						/* メモリホールが発生		*/
	HL_BREAK_POINT		 						/* ブレークポイント			*/
} HLSTATUS;

typedef enum {
	HL_INIT			= 0	,
	HL_EXIT				,
	HL_MALLOCSTAT		,
	HL_MALLOC			,
	HL_CALLOC			,
	HL_REALLOC			,
	HL_FREE				,
	HL_BEGINCHECK		,
	HL_ENDCHECK			,
	HL_DUMP
} HLCOMMAND;

/*------------------------------------------------------------------------------*/

typedef struct _TAG_HEADER_ {
	unsigned long		nFlag;					/* フラグ					*/
	unsigned long		nSize;					/* ブロックサイズ(ヘッダ含)	*/
	struct _TAG_HEADER_	*pNext;					/* 次ポインタ				*/
	struct _TAG_HEADER_	*pBack;					/* 前ポインタ				*/
	unsigned long		nCount;					/* Checkのカウント			*/
	unsigned long		nAlloc;					/* Mallocのカウント			*/
	unsigned long		nFree;					/* Freeのカウント			*/
	unsigned long		PR;						/* PRレジスタ(CALL元)		*/
} *HEAPHANDLE;

typedef void (*HLCALLBACKFUNC)( HLCOMMAND eComd, HLSTATUS eStat, HEAPHANDLE pHandle );

typedef struct _TAG_GLOBAL_ {
	unsigned long		nSize;					/* 構造体のサイズ			*/
	unsigned long		nStat;					/* ステータス				*/
	unsigned long		nCount;					/* チェックカウンター		*/
	unsigned long		nAlloc;					/* Mallocした回数			*/
	unsigned long		nFree;					/* Freeした回数				*/
	HLCALLBACKFUNC		pFunc;					/* コールバックアドレス		*/
	HEAPHANDLE			pHandle;				/* メモリハンドル			*/
	unsigned long		pad;
} HEAPGLOBAL;

/*------------------------------------------------------------------------------*/

void hlHeapInit( void *pHeapStart, unsigned long nHeapSize, HLCALLBACKFUNC pFunc );
void hlHeapExit( void );
void hlMallocStat( unsigned long *nFreeSize, unsigned long *nBiggestSize );

void *hlMalloc( unsigned long nSize );
void *hlMalloc_( unsigned long nSize );
void hlFree( void *pMem );
void *hlRealloc( void *op, unsigned long nSize );
void *hlRealloc_( void *op, unsigned long nSize );
void *hlCalloc( size_t nObj, size_t nSize );
void *hlCalloc_( size_t nObj, size_t nSize );

void hlBeginCheck( void );
void hlEndCheck( void );
void hlHeapDump( void );

char *hlComdToStr( HLCOMMAND eComd );
char *hlStatToStr( HLSTATUS eStat );

static void* operator new( size_t size )
{
	return hlMalloc( size );
}
static void operator delete( void *p )
{
	hlFree( p );
}
/*------------------------------------------------------------------------------*/

}
#endif
