/*	Roast+ License

//	### C compilable ###

//	Safe系関数 (バッファオーバーラン防止)
//		- バッファを越えようとした場合は、納まり切らなかった文字列を切り捨てます。
*/
#ifndef __SFJP_OPENMGL_roast_bufsafe_H__
#define __SFJP_OPENMGL_roast_bufsafe_H__

#include <stdio.h>
#include <string.h>
#include "roast_common.h"
#include "roast_str.h"


/*////////////////////////////////////////////////////////////////*/

/*	文字列バッファの最後を\0にする。 */
#define ROAST_STR_ZTERM(STR,BUFSIZE)		STR[BUFSIZE-1] = '\0'
#define ROAST_STR_ZERO_TERM(STR,BUFSIZE)	ROAST_STR_ZTERM(STR,BUFSIZE)	/*	alias to ROAST_STR_ZTERM */


/*////////////////////////////////////////////////////////////////*/

/*	strcpyのセーフ版 */
#define roast_safe_strcpy(dest,src,dest_memsize)		\
	(ROAST_STR_ZTERM(dest,dest_memsize),				\
	strncpy( dest, src, dest_memsize-1 ))

#define roast_safe_strcat(dest,src,dest_memsize)		\
	(ROAST_STR_ZTERM(dest,dest_memsize),				\
	dest_memsize-1 - strlen(dest) >= 0 ?				\
		strncat( dest, src, dest_memsize-1 - strlen(dest) ) : dest)

/*#define roast_safe_strcat(dest,src,dest_memsize)		\
	ROAST_STR_ZTERM(dest,dest_memsize),					\
	int copy_size = dest_memsize-1 - strlen(dest),		\
	if ( copy_size < 0 )								\
		copy_size = 0,									\
	strncat( dest, src, copy_size )*/

#define roast_safe_strccpy(dest,src,c,dest_memsize)		\
	(ROAST_STR_ZTERM(dest,dest_memsize),				\
	roast_strcncpy( dest, src, c, dest_memsize-1 ))


/*	Auto Sizeof */
#define ROAST_SAFE_STRCPY_AS(DEST,SRC)		roast_safe_strcpy(DEST,SRC,sizeof(DEST))
#define ROAST_SAFE_STRCAT_AS(DEST,SRC)		roast_safe_strcat(DEST,SRC,sizeof(DEST))
#define ROAST_SAFE_STRCCPY_AS(DEST,SRC,C)	roast_safe_strccpy(DEST,SRC,C,sizeof(DEST))


/*////////////////////////////////////////////////////////////////*/


/*  安全な delete, delete[], Release()  */
#define ROAST_SAFE_DELETE(p)			{ if ( p != NULL ) { delete p; p=NULL; }}
#define ROAST_SAFE_DELETE_ARY(p)		{ if ( p != NULL ) { delete []p; p=NULL; }}
#define ROAST_SAFE_DELETE_ARRAY(p)		{ if ( p != NULL ) { delete []p; p=NULL; }}
#define ROAST_SAFE_FREE(p)				{ if ( p != NULL ) { free(p); p=NULL; }}
#define ROAST_SAFE_RELEASE(p)			{ if ( p != NULL ) { (p)->Release(); (p)=NULL; }}


/*#define ROAST_SAFE_NEW(p)				{ if ( p != NULL ) { delete p; p=NULL; }}*/


/*//////////////////////////////////////////////////////////////////////*/
/*//////////////////////////////////////////////////////////////////////*/
/*//////////////////////////////////////////////////////////////////////*/
/*//////////////////////////////////////////////////////////////////////*/
/*//////////////////////////////////////////////////////////////////////*/



#ifdef ROAST_WIN32

	/*///////////////////////////////////////////////////////////////////
	//
	//	VCの_snprintfはC99のsnprintfと挙動が違うので、これを準拠させる
	//
	/////////////////////////////////////////////////////////////////////*/

	__ROAST_EXTERN_C_START
	
	int roast_vc_vsnprintf_conformed_c99(
		char *str, size_t size, const char *format, va_list ap );
	
	int roast_vc_snprintf_conformed_c99(
		char *str, size_t size, const char *format, ... );
	
	__ROAST_EXTERN_C_END

	#define roast_vsnprintf roast_vc_vsnprintf_conformed_c99
	#define roast_snprintf roast_vc_snprintf_conformed_c99

#else /* UNIX/Linux */

	#define roast_vsnprintf vsnprintf
	#define roast_snprintf snprintf

#endif

/*

//	snprintf を roast_snprintf にしちゃう
//	（※ _ROAST_NOT_SNPRINTF_REPLACES をdefineする事に回避可能）

#ifndef _ROAST_NOT_SNPRINTF_REPLACES
	#define vsnprintf roast_vsnprintf
	#define snprintf roast_snprintf
#endif//_ROAST_NOT_SNPRINTF_REPLACES

*/

/*////////////////////////////////////////////////////////////////*/

#ifdef _ROAST_REMOVE_MACRO_NS

	#define STR_ZTERM				ROAST_STR_ZTERM
	#define STR_ZERO_TERM			ROAST_STR_ZERO_TERM
	
	#define safe_strcpy				roast_safe_strcpy
	#define safe_strcat				roast_safe_strcat
	#define safe_strccpy			roast_safe_strccpy
	
	#define SAFE_STRCPY_AS			ROAST_SAFE_STRCPY_AS
	#define SAFE_STRCAT_AS			ROAST_SAFE_STRCAT_AS
	#define SAFE_STRCCPY_AS			ROAST_SAFE_STRCCPY_AS

/*
	#define STR_ZTERM(DEST,SRC)					ROAST_STR_ZTERM(DEST,SRC)
	#define STR_ZERO_TERM(DEST,SRC)				ROAST_STR_ZERO_TERM(DEST,SRC)
	
	#define safe_strcpy(DEST,SRC,BUFSIZE)		roast_safe_strcpy(DEST,SRC,BUFSIZE)
	#define safe_strcat(DEST,SRC,BUFSIZE)		roast_safe_strcat(DEST,SRC,BUFSIZE)
	#define safe_strccpy(DEST,SRC,C,BUFSIZE)	roast_safe_strccpy(DEST,SRC,C,BUFSIZE)
	
	#define SAFE_STRCPY_AS(DEST,SRC)			ROAST_SAFE_STRCPY_AS(DEST,SRC)
	#define SAFE_STRCAT_AS(DEST,SRC)			ROAST_SAFE_STRCAT_AS(DEST,SRC)
	#define SAFE_STRCCPY_AS(DEST,SRC,C)			ROAST_SAFE_STRCCPY_AS(DEST,SRC,C)
*/

	#ifndef _ROAST_NOT_SNPRINTF_REPLACES
		#define vsnprintf roast_vsnprintf
		#define snprintf roast_snprintf
	#endif/*_ROAST_NOT_SNPRINTF_REPLACES*/
	
	
	
	#ifndef SAFE_DELETE
		#define SAFE_DELETE			ROAST_SAFE_DELETE
	#endif
	
	#ifndef SAFE_DELETE_ARY
		#define SAFE_DELETE_ARY		ROAST_SAFE_DELETE_ARY
	#endif
	
	#ifndef SAFE_DELETE_ARRAY
		#define SAFE_DELETE_ARRAY	ROAST_SAFE_DELETE_ARRAY
	#endif
	
	#ifndef SAFE_RELEASE
		#define SAFE_RELEASE		ROAST_SAFE_RELEASE
	#endif

#endif

/*
namespace roast{
}
*/

#endif/*__SFJP_OPENMGL_roast_bufsafe_H__*/
