/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"
#include <tools/stream.hxx>
#include <tools/tenccvt.hxx>
#include <basic/sbx.hxx>
#include "sb.hxx"
#include <string.h>		// memset() etc
#include "image.hxx"
#include <codegen.hxx>
SbiImage::SbiImage()
{
	pStringOff = NULL;
	pStrings   = NULL;
	pCode  	   = NULL;
	pLegacyPCode  	   = NULL;
	nFlags	   = 0;
	nStrings   = 0;
	nStringSize= 0;
	nCodeSize  = 0;
	nLegacyCodeSize  =
	nDimBase   = 0;
	bInit	   =
	bError	   = sal_False;
    bFirstInit = sal_True;
	eCharSet   = gsl_getSystemTextEncoding();
}

SbiImage::~SbiImage()
{
	Clear();
}

void SbiImage::Clear()
{
	delete[] pStringOff;
	delete[] pStrings;
	delete[] pCode;
	ReleaseLegacyBuffer();
	pStringOff = NULL;
	pStrings   = NULL;
	pCode  	   = NULL;
	nFlags	   = 0;
	nStrings   = 0;
	nStringSize= 0;
	nLegacyCodeSize  = 0;
	nCodeSize  = 0;
	eCharSet   = gsl_getSystemTextEncoding();
	nDimBase   = 0;
	bError	   = sal_False;
}

/**************************************************************************
*
*    Service-Routines for Load/Store
*
**************************************************************************/

sal_Bool SbiGood( SvStream& r )
{
	return sal_Bool( !r.IsEof() && r.GetError() == SVSTREAM_OK );
}

// Open Record
sal_uIntPtr SbiOpenRecord( SvStream& r, sal_uInt16 nSignature, sal_uInt16 nElem )
{
	sal_uIntPtr nPos = r.Tell();
	r << nSignature << (sal_Int32) 0 << nElem;
	return nPos;
}

// Close Record
void SbiCloseRecord( SvStream& r, sal_uIntPtr nOff )
{
	sal_uIntPtr nPos = r.Tell();
	r.Seek( nOff + 2 );
	r << (sal_Int32) ( nPos - nOff - 8 );
	r.Seek( nPos );
}

/**************************************************************************
*
*    Load/Store
*
**************************************************************************/

// If the version number does not find, binary parts are omitted, but not
// source, comments and name
sal_Bool SbiImage::Load( SvStream& r )
{
	sal_uInt32 nVersion = 0;        // Versionsnumber
	return Load( r, nVersion );
}
sal_Bool SbiImage::Load( SvStream& r, sal_uInt32& nVersion )
{

	sal_uInt16 nSign, nCount;
	sal_uInt32 nLen, nOff;

	Clear();
	// Read Master-Record
	r >> nSign >> nLen >> nCount;
	sal_uIntPtr nLast = r.Tell() + nLen;
	sal_uInt32 nCharSet;               // System charset
	sal_uInt32 lDimBase;
	sal_uInt16 nReserved1;
	sal_uInt32 nReserved2;
	sal_uInt32 nReserved3;
	sal_Bool bBadVer = sal_False;
	if( nSign == B_MODULE )
	{
		r >> nVersion >> nCharSet >> lDimBase
		  >> nFlags >> nReserved1 >> nReserved2 >> nReserved3;
		eCharSet = (CharSet) nCharSet;
        eCharSet = GetSOLoadTextEncoding( eCharSet );
		bBadVer  = sal_Bool( nVersion > B_CURVERSION );
		nDimBase = (sal_uInt16) lDimBase;
	}

	bool bLegacy = ( nVersion < B_EXT_IMG_VERSION );

	sal_uIntPtr nNext;
	while( ( nNext = r.Tell() ) < nLast )
	{
		short i;

		r >> nSign >> nLen >> nCount;
		nNext += nLen + 8;
		if( r.GetError() == SVSTREAM_OK )
		  switch( nSign )
		{
			case B_NAME:
				r.ReadByteString( aName, eCharSet );
				//r >> aName;
				break;
			case B_COMMENT:
				r.ReadByteString( aComment, eCharSet );
				//r >> aComment;
				break;
			case B_SOURCE:
            {
                String aTmp;
				r.ReadByteString( aTmp, eCharSet );
                aOUSource = aTmp;
				//r >> aSource;
				break;
            }
#ifdef EXTENDED_BINARY_MODULES
			case B_EXTSOURCE:
            {
				for( sal_uInt16 j = 0 ; j < nCount ; j++ )
				{
					String aTmp;
					r.ReadByteString( aTmp, eCharSet );
	                aOUSource += aTmp;
				}
				break;
            }
#endif
			case B_PCODE:
				if( bBadVer ) break;
				pCode = new char[ nLen ];
				nCodeSize = nLen;
				r.Read( pCode, nCodeSize );
				if ( bLegacy )
				{
					ReleaseLegacyBuffer(); // release any previously held buffer
					nLegacyCodeSize = (sal_uInt16) nCodeSize;
					pLegacyPCode = pCode;

					PCodeBuffConvertor< sal_uInt16, sal_uInt32 > aLegacyToNew( (sal_uInt8*)pLegacyPCode, nLegacyCodeSize );
					aLegacyToNew.convert();
					pCode = (char*)aLegacyToNew.GetBuffer();
					nCodeSize = aLegacyToNew.GetSize();
					// we don't release the legacy buffer
					// right now, that's because the module
					// needs it to fix up the method
					// nStart members. When that is done
					// the module can release the buffer
					// or it can wait until this routine
					// is called again or when this class						// destructs all of which will trigger
					// release of the buffer.
				}
				break;
			case B_PUBLICS:
			case B_POOLDIR:
			case B_SYMPOOL:
			case B_LINERANGES:
				break;
			case B_STRINGPOOL:
				if( bBadVer ) break;
				MakeStrings( nCount );
				for( i = 0; i < nStrings && SbiGood( r ); i++ )
				{
					r >> nOff;
					pStringOff[ i ] = (sal_uInt16) nOff;
				}
				r >> nLen;
				if( SbiGood( r ) )
				{
					delete [] pStrings;
					pStrings = new sal_Unicode[ nLen ];
					nStringSize = (sal_uInt16) nLen;

					char* pByteStrings = new char[ nLen ];
					r.Read( pByteStrings, nStringSize );
					for( short j = 0; j < nStrings; j++ )
					{
						sal_uInt16 nOff2 = (sal_uInt16) pStringOff[ j ];
						String aStr( pByteStrings + nOff2, eCharSet );
						memcpy( pStrings + nOff2, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( sal_Unicode ) );
					}
					delete[] pByteStrings;
				} break;
			case B_MODEND:
				goto done;
			default:
				break;
		}
		else
			break;
		r.Seek( nNext );
	}
done:
	r.Seek( nLast );
	//if( eCharSet != ::GetSystemCharSet() )
		//ConvertStrings();
	if( !SbiGood( r ) )
		bError = sal_True;
	return sal_Bool( !bError );
}

sal_Bool SbiImage::Save( SvStream& r, sal_uInt32 nVer )
{
	bool bLegacy = ( nVer < B_EXT_IMG_VERSION );

	// detect if old code exceeds legacy limits
	// if so, then disallow save
	if ( bLegacy && ExceedsLegacyLimits() )
	{
		SbiImage aEmptyImg;
		aEmptyImg.aName = aName;
		aEmptyImg.Save( r, B_LEGACYVERSION );
		return sal_True;
	}
	// First of all the header
	sal_uIntPtr nStart = SbiOpenRecord( r, B_MODULE, 1 );
	sal_uIntPtr nPos;

    eCharSet = GetSOStoreTextEncoding( eCharSet );
	if ( bLegacy )
		r << (sal_Int32) B_LEGACYVERSION;
	else
		r << (sal_Int32) B_CURVERSION;
	r  << (sal_Int32) eCharSet
	  << (sal_Int32) nDimBase
	  << (sal_Int16) nFlags
	  << (sal_Int16) 0
	  << (sal_Int32) 0
	  << (sal_Int32) 0;

	// Name?
	if( aName.Len() && SbiGood( r ) )
	{
		nPos = SbiOpenRecord( r, B_NAME, 1 );
		r.WriteByteString( aName, eCharSet );
		//r << aName;
		SbiCloseRecord( r, nPos );
	}
	// Comment?
	if( aComment.Len() && SbiGood( r ) )
	{
		nPos = SbiOpenRecord( r, B_COMMENT, 1 );
		r.WriteByteString( aComment, eCharSet );
		//r << aComment;
		SbiCloseRecord( r, nPos );
	}
	// Source?
	if( !aOUSource.isEmpty() && SbiGood( r ) )
	{
		nPos = SbiOpenRecord( r, B_SOURCE, 1 );
        String aTmp;
        sal_Int32 nLen = aOUSource.getLength();
		const sal_Int32 nMaxUnitSize = STRING_MAXLEN - 1;
        if( nLen > STRING_MAXLEN )
            aTmp = aOUSource.copy( 0, nMaxUnitSize );
        else
            aTmp = aOUSource;
		r.WriteByteString( aTmp, eCharSet );
		//r << aSource;
		SbiCloseRecord( r, nPos );

#ifdef EXTENDED_BINARY_MODULES
        if( nLen > STRING_MAXLEN )
		{
			sal_Int32 nRemainingLen = nLen - nMaxUnitSize;
			sal_uInt16 nUnitCount = sal_uInt16( (nRemainingLen + nMaxUnitSize - 1) / nMaxUnitSize );
			nPos = SbiOpenRecord( r, B_EXTSOURCE, nUnitCount );
			for( sal_uInt16 i = 0 ; i < nUnitCount ; i++ )
			{
				sal_Int32 nCopyLen =
					(nRemainingLen > nMaxUnitSize) ? nMaxUnitSize : nRemainingLen;
				String aTmp2 = aOUSource.copy( (i+1) * nMaxUnitSize, nCopyLen );
				nRemainingLen -= nCopyLen;
				r.WriteByteString( aTmp2, eCharSet );
			}
			SbiCloseRecord( r, nPos );
		}
#endif
	}
	// Binary data?
	if( pCode && SbiGood( r ) )
	{
		nPos = SbiOpenRecord( r, B_PCODE, 1 );
		if ( bLegacy )
		{
			ReleaseLegacyBuffer(); // release any previously held buffer
			PCodeBuffConvertor< sal_uInt32, sal_uInt16 > aNewToLegacy( (sal_uInt8*)pCode, nCodeSize );
			aNewToLegacy.convert();
			pLegacyPCode = (char*)aNewToLegacy.GetBuffer();
			nLegacyCodeSize = aNewToLegacy.GetSize();
		        r.Write( pLegacyPCode, nLegacyCodeSize );
		}
		else
			r.Write( pCode, nCodeSize );
		SbiCloseRecord( r, nPos );
	}
	// String-Pool?
	if( nStrings )
	{
		nPos = SbiOpenRecord( r, B_STRINGPOOL, nStrings );
		// For every String:
		//	sal_uInt32 Offset of the Strings in the Stringblock
		short i;

		for( i = 0; i < nStrings && SbiGood( r ); i++ )
			r << (sal_uInt32) pStringOff[ i ];

		// Then the String-Block
		char* pByteStrings = new char[ nStringSize ];
		for( i = 0; i < nStrings; i++ )
		{
			sal_uInt16 nOff = (sal_uInt16) pStringOff[ i ];
			ByteString aStr( pStrings + nOff, eCharSet );
			memcpy( pByteStrings + nOff, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( char ) );
		}
		r << (sal_uInt32) nStringSize;
		r.Write( pByteStrings, nStringSize );

		delete[] pByteStrings;
		SbiCloseRecord( r, nPos );
	}
	// Set overall length
	SbiCloseRecord( r, nStart );
	if( !SbiGood( r ) )
		bError = sal_True;
	return sal_Bool( !bError );
}

/**************************************************************************
*
*    Routines called by the compiler
*
**************************************************************************/

void SbiImage::MakeStrings( short nSize )
{
	nStrings = 0;
	nStringIdx = 0;
	nStringOff = 0;
	nStringSize = 1024;
	pStrings = new sal_Unicode[ nStringSize ];
	pStringOff = new sal_uInt32[ nSize ];
	if( pStrings && pStringOff )
	{
		nStrings = nSize;
		memset( pStringOff, 0, nSize * sizeof( sal_uInt32 ) );
		memset( pStrings, 0, nStringSize * sizeof( sal_Unicode ) );
	}
	else
		bError = sal_True;
}

// Hinzufuegen eines Strings an den StringPool. Der String-Puffer
// waechst dynamisch in 1K-Schritten
// Add a string to StringPool. The String buffer is dynamically
// growing in 1K-Steps
void SbiImage::AddString( const String& r )
{
	if( nStringIdx >= nStrings )
		bError = sal_True;
	if( !bError )
	{
		xub_StrLen  len = r.Len() + 1;
		sal_uInt32 needed = nStringOff + len;
		if( needed > 0xFFFFFF00L )
			bError = sal_True;	// out of mem!
		else if( needed > nStringSize )
		{
            sal_uInt32 nNewLen = needed + 1024;
            nNewLen &= 0xFFFFFC00;  // trim to 1K border
			if( nNewLen > 0xFFFFFF00L )
				nNewLen = 0xFFFFFF00L;
			sal_Unicode* p = NULL;
			if( (p = new sal_Unicode[ nNewLen ]) != NULL )
			{
				memcpy( p, pStrings, nStringSize * sizeof( sal_Unicode ) );
				delete[] pStrings;
				pStrings = p;
				nStringSize = sal::static_int_cast< sal_uInt16 >(nNewLen);
			}
			else
				bError = sal_True;
		}
		if( !bError )
		{
			pStringOff[ nStringIdx++ ] = nStringOff;
			//ByteString aByteStr( r, eCharSet );
			memcpy( pStrings + nStringOff, r.GetBuffer(), len * sizeof( sal_Unicode ) );
			nStringOff = nStringOff + len;
			// Last String? The update the size of the buffer
			if( nStringIdx >= nStrings )
				nStringSize = nStringOff;
		}
	}
}

// Add code block
// The block was fetched by the compiler from class SbBuffer and
// is already created with new. Additionally it contains all Integers
// in Big Endian format, so can be directly read/written.
void SbiImage::AddCode( char* p, sal_uInt32 s )
{
	pCode = p;
	nCodeSize = s;
}

// Add user type
void SbiImage::AddType(SbxObject* pObject)
{
	if( !rTypes.Is() )
		rTypes = new SbxArray;
	SbxObject *pCopyObject = new SbxObject(*pObject);
	rTypes->Insert (pCopyObject,rTypes->Count());
}

void SbiImage::AddEnum(SbxObject* pObject) // Register enum type
{
	if( !rEnums.Is() )
		rEnums = new SbxArray;
	rEnums->Insert( pObject, rEnums->Count() );
}


/**************************************************************************
*
*    Accessing the image
*
**************************************************************************/

// Note: IDs start with 1
String SbiImage::GetString( short nId ) const
{
	if( nId && nId <= nStrings )
	{
		sal_uInt32 nOff = pStringOff[ nId - 1 ];
		sal_Unicode* pStr = pStrings + nOff;

		// #i42467: Special treatment for vbNullChar
		if( *pStr == 0 )
		{
			sal_uInt32 nNextOff = (nId < nStrings) ? pStringOff[ nId ] : nStringOff;
			sal_uInt32 nLen = nNextOff - nOff - 1;
			if( nLen == 1 )
			{
				// Force length 1 and make char 0 afterwards
				String aNullCharStr( String::CreateFromAscii( " " ) );
				aNullCharStr.SetChar( 0, 0 );
				return aNullCharStr;
			}
		}
		else
		{
			String aStr( pStr );
			return aStr;
		}
	}
	return String();
}

const SbxObject* SbiImage::FindType (String aTypeName) const
{
	return rTypes.Is() ? (SbxObject*)rTypes->Find(aTypeName,SbxCLASS_OBJECT) : NULL;
}

sal_uInt16 SbiImage::CalcLegacyOffset( sal_Int32 nOffset )
{
	return SbiCodeGen::calcLegacyOffSet( (sal_uInt8*)pCode, nOffset ) ;
}

sal_uInt32 SbiImage::CalcNewOffset( sal_Int16 nOffset )
{
	return SbiCodeGen::calcNewOffSet( (sal_uInt8*)pLegacyPCode, nOffset ) ;
}

void  SbiImage::ReleaseLegacyBuffer()
{
	delete[] pLegacyPCode;
	pLegacyPCode = NULL;
	nLegacyCodeSize = 0;
}

sal_Bool SbiImage::ExceedsLegacyLimits()
{
	if ( ( nStringSize > 0xFF00L ) || ( CalcLegacyOffset( nCodeSize ) > 0xFF00L ) )
		return sal_True;
	return sal_False;
}
