/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sfx2_newhdl.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/27 19:05:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <vos/mutex.hxx>
#pragma hdrstop

#if defined( WIN ) || defined( WNT )
#include <tools/svwin.h>				// GetFreeSpace()
#endif

#if defined( MAC )
#include <mac_start.h>
#include <Memory.h>						// FreeMem()
#include <mac_end.h>
#endif

#include "newhdl.hxx"
#include "sfxresid.hxx"
#include "bastyp.hrc"
#include "topfrm.hxx"
namespace binfilter {

using namespace vos;

// STATIC DATA -----------------------------------------------------------

#define WARN_MEM_SIZE       (200L*1024L)
#define EXCEPT_MEM_SIZE     (300L*1024L)
#define SAVE_MEM_SIZE       (1000L*1024L)

// Static member
SfxNewHdl* SfxNewHdl::pInstance = NULL;

// -----------------------------------------------------------------------
//	F"ur die vielen Plattformem ein _GetFreeMem()

#if defined( WIN ) || defined( WNT )
long    _GetFreeMem()	{ return GetFreeSpace(0); }
#endif
#if defined( MAC )
long    _GetFreeMem()   { return FreeMem(); }
#endif
#if defined( OS2 )
long    _GetFreeMem()   { DBG_ERRORFILE( "Kein _GetFreeMem()" ); return 0; }
#endif
#if defined( UNX )
long    _GetFreeMem()   { DBG_ERRORFILE( "Kein _GetFreeMem()" ); return 0; }
#endif

//--------------------------------------------------------------------

/*?*/ void SfxNewHdl::MemoryWarning()
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

//--------------------------------------------------------------------

} 
namespace binfilter {//STRIP009

/*?*/ void SfxNewHdl::MemoryError()
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

// -----------------------------------------------------------------------

/*N*/ SfxNewHdl::SfxNewHdl()

/*	[Beschreibung]

	Konstruktor der Klasse SfxNewHdl.
	Die beiden MemoryBuffer werden f"ur den Notfall alloziert und der
	new-Handler wird installiert..

*/
/*N*/ 	: pWarnMem(0)
/*N*/ 	, pExceptMem(0)
/*N*/ 	, aMemWarningString( SfxResId(MSG_MEM_WARN) )
/*N*/ 	, aMemExceptionString( SfxResId( STR_MEMEXCEPTION ) )
/*N*/ {
/*N*/ }

// -----------------------------------------------------------------------

/*N*/ SfxNewHdl::~SfxNewHdl()

/*	[Beschreibung]

	Destruktor der Klasse SfxNewHdl.
	Die beiden MemoryBuffer werden freigegeben und der new-Handler
	wird deinstalliert.

*/
/*N*/ {
/*N*/ 	FlushWarnMem();
/*N*/ 	FlushExceptMem();
/*N*/ }

/*N*/ SfxNewHdl* SfxNewHdl::Get()
/*N*/ {
/*N*/ 	return pInstance;
/*N*/ }

/*N*/ SfxNewHdl* SfxNewHdl::GetOrCreate()
/*N*/ {
/*N*/ 	NAMESPACE_VOS( OGuard ) aGuard( NAMESPACE_VOS(OMutex)::getGlobalMutex() );
/*N*/ 	if ( !pInstance )
/*N*/ 		pInstance = new SfxNewHdl;
/*N*/ 	return pInstance;
/*N*/ }

/*N*/ void SfxNewHdl::Delete()
/*N*/ {
/*N*/ 	NAMESPACE_VOS( OGuard ) aGuard( NAMESPACE_VOS(OMutex)::getGlobalMutex() );
/*N*/ 	DELETEZ( pInstance );
/*N*/ }

// -----------------------------------------------------------------------

/*N*/ BOOL SfxNewHdl::TryAllocBuffer()
/*	[Beschreibung]

	Gfs. wird versucht, den Buffer f"ur das WarningLevel zu reallozieren.

*/
/*N*/ {
/*N*/ //	fprintf (stderr, "%s\n", "TryAllocBuffer" );
/*N*/ 
/*N*/ 	if(!pWarnMem)
/*N*/ 	{
/*?*/ 		const ULONG nFree = _GetFreeMem();
/*?*/ 		if ( nFree >= WARN_MEM_SIZE + SAVE_MEM_SIZE )
/*?*/ #ifndef MAC
/*?*/ 		{
/*?*/ //            fprintf (stderr, "%s\n", "Reallocating" );
/*?*/ 			pWarnMem = new char[WARN_MEM_SIZE];
/*?*/ 		}
/*?*/ #else
/*?*/ 		{
/*?*/ 			Sysdepen::CallNewHandler( FALSE );
/*?*/ 			pWarnMem = (MAC_Ptr) NewHandleClear(WARN_MEM_SIZE);
/*?*/ 			if ( pWarnMem )
/*?*/ 			{
/*?*/ 				MoveHHi((Handle) pWarnMem);
/*?*/ 				HLock ((Handle) pWarnMem);
/*?*/ 			}
/*?*/ 			Sysdepen::CallNewHandler( TRUE );
/*N*/ 		}
/*N*/ #endif
/*N*/ 	}
/*N*/ 	return pWarnMem ? TRUE : FALSE;
/*N*/ }

// -----------------------------------------------------------------------

/*N*/ BOOL SfxNewHdl::FlushWarnMem()

/*	[Beschreibung]

	Freigabe Buffer f"ur das WarningLevel
*/
/*N*/ {
/*N*/ //	fprintf (stderr, "%s\n", "FlushWarnmem" );
/*N*/ 	if ( pWarnMem )
/*N*/ 	{
/*N*/ #ifndef MAC
/*N*/         delete [] pWarnMem;
/*N*/         pWarnMem = NULL;
/*N*/ #else
/*N*/ 	#ifdef DBG_UTIL
/*N*/ 		// Ist unser Handle immer noch NULL ?
/*N*/ 		if (memcmp(*((Handle) pWarnMem),
/*N*/ 				   *((Handle) pWarnMem)+ WARN_MEM_SIZE / 2,
/*N*/ 					 WARN_MEM_SIZE / 2) != 0)
/*N*/ 			DebugStr("\ppWarnMem wurde ueberschrieben");
/*N*/ 	#endif
/*N*/ 		DisposeHandle((Handle) pWarnMem);
/*N*/ 		pWarnMem = NULL;
/*N*/ #endif
/*N*/ 		return TRUE;
/*N*/ 	}
/*N*/ 	return FALSE;
/*N*/ }

// -----------------------------------------------------------------------

/*N*/ BOOL SfxNewHdl::FlushExceptMem()

/*	[Beschreibung]

	Freigabe Buffer f"ur das ErrorLevel
*/
/*N*/ {
/*N*/ //	fprintf (stderr, "%s\n", "FlushExceptMem" );
/*N*/ 
/*N*/ 	if ( pExceptMem )
/*N*/ 	{
/*N*/ #ifndef MAC
/*N*/         delete [] pExceptMem;
/*N*/         pExceptMem = NULL;
/*N*/ #else
/*N*/ 	#ifdef DBG_UTIL
/*N*/ 		// Ist unser Handle immer noch NULL ?
/*N*/ 		if (memcmp(*((Handle) pExceptMem),
/*N*/ 				   *((Handle) pExceptMem)+EXCEPT_MEM_SIZE / 2,
/*N*/ 					 EXCEPT_MEM_SIZE / 2) != 0)
/*N*/ 			DebugStr("\ppExceptMem wurde ueberschrieben");
/*N*/ 	#endif
/*N*/ 		DisposeHandle((Handle) pExceptMem);
/*N*/ 		pExceptMem = NULL;
/*N*/ #endif
/*N*/ 		return TRUE;
/*N*/ 	}
/*N*/ 	return FALSE;
/*N*/ }

// -----------------------------------------------------------------------

/*N*/ IMPL_LINK( SfxNewHdl, InitMem_Impl, void *, pvoid )
/*N*/ {
/*N*/ #ifndef MAC
/*N*/ 	pWarnMem 	= new char [WARN_MEM_SIZE];
/*N*/ 	pExceptMem 	= new char [EXCEPT_MEM_SIZE];
/*N*/ #else
/*N*/ 	Sysdepen::CallNewHandler( FALSE );
/*N*/ 	pExceptMem = (MAC_Ptr) NewHandleClear(EXCEPT_MEM_SIZE);
/*N*/ 	if ( pExceptMem )
/*N*/ 	{
/*N*/ 		MoveHHi((Handle) pExceptMem);
/*N*/ 		HLock ((Handle) pExceptMem);
/*N*/ 	}
/*N*/ 	pWarnMem = (MAC_Ptr) NewHandleClear(WARN_MEM_SIZE);
/*N*/ 	if ( pWarnMem )
/*N*/ 	{
/*N*/ 		MoveHHi((Handle) pWarnMem);
/*N*/ 		HLock ((Handle) pWarnMem);
/*N*/ 	}
/*N*/ 	Sysdepen::CallNewHandler( TRUE );
/*N*/ #endif
/*N*/ 	return 0;
/*N*/ }


}
