2010-10-12 15:53:47 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-07-17 12:30:48 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* 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 .
|
|
|
|
*/
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
#include <tools/stream.hxx>
|
2001-08-07 10:20:11 +00:00
|
|
|
#include <tools/tenccvt.hxx>
|
2007-06-27 13:18:06 +00:00
|
|
|
#include <basic/sbx.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
#include "sb.hxx"
|
|
|
|
#include <string.h> // memset() etc
|
|
|
|
#include "image.hxx"
|
2006-11-01 15:13:02 +00:00
|
|
|
#include <codegen.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiImage::SbiImage()
|
|
|
|
{
|
|
|
|
pStringOff = NULL;
|
|
|
|
pStrings = NULL;
|
|
|
|
pCode = NULL;
|
2006-11-01 15:13:02 +00:00
|
|
|
pLegacyPCode = NULL;
|
2006-11-03 06:39:47 +00:00
|
|
|
nFlags = 0;
|
|
|
|
nStrings = 0;
|
|
|
|
nStringSize= 0;
|
|
|
|
nCodeSize = 0;
|
2006-11-01 15:13:02 +00:00
|
|
|
nLegacyCodeSize =
|
2000-09-18 15:18:56 +00:00
|
|
|
nDimBase = 0;
|
|
|
|
bInit =
|
2012-08-12 09:07:20 +09:00
|
|
|
bError = false;
|
2012-08-15 09:44:54 +09:00
|
|
|
bFirstInit = true;
|
2011-11-24 12:06:54 +01:00
|
|
|
eCharSet = osl_getThreadTextEncoding();
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SbiImage::~SbiImage()
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SbiImage::Clear()
|
|
|
|
{
|
2003-03-18 15:28:40 +00:00
|
|
|
delete[] pStringOff;
|
|
|
|
delete[] pStrings;
|
|
|
|
delete[] pCode;
|
2006-11-01 15:13:02 +00:00
|
|
|
ReleaseLegacyBuffer();
|
2000-09-18 15:18:56 +00:00
|
|
|
pStringOff = NULL;
|
|
|
|
pStrings = NULL;
|
|
|
|
pCode = NULL;
|
2006-11-03 06:39:47 +00:00
|
|
|
nFlags = 0;
|
|
|
|
nStrings = 0;
|
|
|
|
nStringSize= 0;
|
2006-11-01 15:13:02 +00:00
|
|
|
nLegacyCodeSize = 0;
|
2000-09-18 15:18:56 +00:00
|
|
|
nCodeSize = 0;
|
2011-11-24 12:06:54 +01:00
|
|
|
eCharSet = osl_getThreadTextEncoding();
|
2000-09-18 15:18:56 +00:00
|
|
|
nDimBase = 0;
|
2012-08-12 09:07:20 +09:00
|
|
|
bError = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
*
|
2009-04-25 00:18:20 +00:00
|
|
|
* Service-Routines for Load/Store
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
|
|
|
**************************************************************************/
|
|
|
|
|
2012-08-15 09:44:54 +09:00
|
|
|
bool SbiGood( SvStream& r )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2012-08-15 09:44:54 +09:00
|
|
|
return !r.IsEof() && r.GetError() == SVSTREAM_OK;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2009-04-25 00:18:20 +00:00
|
|
|
// Open Record
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uIntPtr SbiOpenRecord( SvStream& r, sal_uInt16 nSignature, sal_uInt16 nElem )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uIntPtr nPos = r.Tell();
|
|
|
|
r << nSignature << (sal_Int32) 0 << nElem;
|
2000-09-18 15:18:56 +00:00
|
|
|
return nPos;
|
|
|
|
}
|
|
|
|
|
2009-04-25 00:18:20 +00:00
|
|
|
// Close Record
|
2011-01-10 14:40:57 +01:00
|
|
|
void SbiCloseRecord( SvStream& r, sal_uIntPtr nOff )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uIntPtr nPos = r.Tell();
|
2000-09-18 15:18:56 +00:00
|
|
|
r.Seek( nOff + 2 );
|
2011-01-10 14:40:57 +01:00
|
|
|
r << (sal_Int32) ( nPos - nOff - 8 );
|
2000-09-18 15:18:56 +00:00
|
|
|
r.Seek( nPos );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
*
|
2009-04-25 00:18:20 +00:00
|
|
|
* Load/Store
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
|
|
|
**************************************************************************/
|
|
|
|
|
2012-08-15 09:44:54 +09:00
|
|
|
bool SbiImage::Load( SvStream& r, sal_uInt32& nVersion )
|
2006-11-01 15:13:02 +00:00
|
|
|
{
|
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nSign, nCount;
|
|
|
|
sal_uInt32 nLen, nOff;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
Clear();
|
2009-04-25 00:18:20 +00:00
|
|
|
// Read Master-Record
|
2000-09-18 15:18:56 +00:00
|
|
|
r >> nSign >> nLen >> nCount;
|
2011-01-10 14:40:57 +01:00
|
|
|
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;
|
2000-09-18 15:18:56 +00:00
|
|
|
if( nSign == B_MODULE )
|
|
|
|
{
|
|
|
|
r >> nVersion >> nCharSet >> lDimBase
|
|
|
|
>> nFlags >> nReserved1 >> nReserved2 >> nReserved3;
|
|
|
|
eCharSet = (CharSet) nCharSet;
|
2001-08-07 10:20:11 +00:00
|
|
|
eCharSet = GetSOLoadTextEncoding( eCharSet );
|
2011-01-10 14:40:57 +01:00
|
|
|
bBadVer = sal_Bool( nVersion > B_CURVERSION );
|
|
|
|
nDimBase = (sal_uInt16) lDimBase;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2006-11-01 15:13:02 +00:00
|
|
|
bool bLegacy = ( nVersion < B_EXT_IMG_VERSION );
|
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uIntPtr nNext;
|
2000-09-18 15:18:56 +00:00
|
|
|
while( ( nNext = r.Tell() ) < nLast )
|
|
|
|
{
|
|
|
|
|
|
|
|
r >> nSign >> nLen >> nCount;
|
|
|
|
nNext += nLen + 8;
|
|
|
|
if( r.GetError() == SVSTREAM_OK )
|
|
|
|
switch( nSign )
|
|
|
|
{
|
|
|
|
case B_NAME:
|
2012-01-06 08:50:03 +00:00
|
|
|
aName = r.ReadUniOrByteString(eCharSet);
|
2000-09-18 15:18:56 +00:00
|
|
|
break;
|
|
|
|
case B_COMMENT:
|
2012-01-06 08:50:03 +00:00
|
|
|
aComment = r.ReadUniOrByteString(eCharSet );
|
2000-09-18 15:18:56 +00:00
|
|
|
break;
|
|
|
|
case B_SOURCE:
|
2003-04-23 15:55:53 +00:00
|
|
|
{
|
2012-01-06 08:50:03 +00:00
|
|
|
aOUSource = r.ReadUniOrByteString(eCharSet);
|
2000-09-18 15:18:56 +00:00
|
|
|
break;
|
2003-04-23 15:55:53 +00:00
|
|
|
}
|
2005-05-18 12:07:10 +00:00
|
|
|
case B_EXTSOURCE:
|
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
for( sal_uInt16 j = 0 ; j < nCount ; j++ )
|
2005-05-18 12:07:10 +00:00
|
|
|
{
|
2012-01-06 08:50:03 +00:00
|
|
|
String aTmp = r.ReadUniOrByteString(eCharSet);
|
2005-05-18 12:07:10 +00:00
|
|
|
aOUSource += aTmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
case B_PCODE:
|
|
|
|
if( bBadVer ) break;
|
|
|
|
pCode = new char[ nLen ];
|
2006-11-01 15:13:02 +00:00
|
|
|
nCodeSize = nLen;
|
2000-09-18 15:18:56 +00:00
|
|
|
r.Read( pCode, nCodeSize );
|
2006-11-01 15:13:02 +00:00
|
|
|
if ( bLegacy )
|
|
|
|
{
|
|
|
|
ReleaseLegacyBuffer(); // release any previously held buffer
|
2011-01-10 14:40:57 +01:00
|
|
|
nLegacyCodeSize = (sal_uInt16) nCodeSize;
|
2006-11-01 15:13:02 +00:00
|
|
|
pLegacyPCode = pCode;
|
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
PCodeBuffConvertor< sal_uInt16, sal_uInt32 > aLegacyToNew( (sal_uInt8*)pLegacyPCode, nLegacyCodeSize );
|
2006-11-01 15:13:02 +00:00
|
|
|
aLegacyToNew.convert();
|
|
|
|
pCode = (char*)aLegacyToNew.GetBuffer();
|
|
|
|
nCodeSize = aLegacyToNew.GetSize();
|
|
|
|
// we don't release the legacy buffer
|
|
|
|
// right now, thats 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.
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
break;
|
|
|
|
case B_PUBLICS:
|
|
|
|
case B_POOLDIR:
|
|
|
|
case B_SYMPOOL:
|
|
|
|
case B_LINERANGES:
|
|
|
|
break;
|
|
|
|
case B_STRINGPOOL:
|
|
|
|
if( bBadVer ) break;
|
|
|
|
MakeStrings( nCount );
|
2011-02-10 14:48:51 +01:00
|
|
|
short i;
|
2000-09-18 15:18:56 +00:00
|
|
|
for( i = 0; i < nStrings && SbiGood( r ); i++ )
|
|
|
|
{
|
|
|
|
r >> nOff;
|
2011-01-10 14:40:57 +01:00
|
|
|
pStringOff[ i ] = (sal_uInt16) nOff;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
r >> nLen;
|
|
|
|
if( SbiGood( r ) )
|
|
|
|
{
|
2003-05-22 10:01:17 +00:00
|
|
|
delete [] pStrings;
|
2000-09-18 15:18:56 +00:00
|
|
|
pStrings = new sal_Unicode[ nLen ];
|
2011-01-10 14:40:57 +01:00
|
|
|
nStringSize = (sal_uInt16) nLen;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
char* pByteStrings = new char[ nLen ];
|
|
|
|
r.Read( pByteStrings, nStringSize );
|
2006-06-19 16:39:15 +00:00
|
|
|
for( short j = 0; j < nStrings; j++ )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nOff2 = (sal_uInt16) pStringOff[ j ];
|
2006-06-19 16:39:15 +00:00
|
|
|
String aStr( pByteStrings + nOff2, eCharSet );
|
|
|
|
memcpy( pStrings + nOff2, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( sal_Unicode ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2003-03-18 15:28:40 +00:00
|
|
|
delete[] pByteStrings;
|
2000-09-18 15:18:56 +00:00
|
|
|
} break;
|
|
|
|
case B_MODEND:
|
|
|
|
goto done;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
r.Seek( nNext );
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
r.Seek( nLast );
|
|
|
|
if( !SbiGood( r ) )
|
2012-08-12 09:07:20 +09:00
|
|
|
bError = true;
|
2012-08-15 09:44:54 +09:00
|
|
|
return !bError;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2012-08-15 09:44:54 +09:00
|
|
|
bool SbiImage::Save( SvStream& r, sal_uInt32 nVer )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2006-11-01 15:13:02 +00:00
|
|
|
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 );
|
2012-08-15 09:44:54 +09:00
|
|
|
return true;
|
2006-11-01 15:13:02 +00:00
|
|
|
}
|
2009-04-25 00:18:20 +00:00
|
|
|
// First of all the header
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uIntPtr nStart = SbiOpenRecord( r, B_MODULE, 1 );
|
|
|
|
sal_uIntPtr nPos;
|
2001-08-07 10:20:11 +00:00
|
|
|
|
|
|
|
eCharSet = GetSOStoreTextEncoding( eCharSet );
|
2006-11-01 15:13:02 +00:00
|
|
|
if ( bLegacy )
|
2011-01-10 14:40:57 +01:00
|
|
|
r << (sal_Int32) B_LEGACYVERSION;
|
2006-11-01 15:13:02 +00:00
|
|
|
else
|
2011-01-10 14:40:57 +01:00
|
|
|
r << (sal_Int32) B_CURVERSION;
|
|
|
|
r << (sal_Int32) eCharSet
|
|
|
|
<< (sal_Int32) nDimBase
|
|
|
|
<< (sal_Int16) nFlags
|
|
|
|
<< (sal_Int16) 0
|
|
|
|
<< (sal_Int32) 0
|
|
|
|
<< (sal_Int32) 0;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
// Name?
|
|
|
|
if( aName.Len() && SbiGood( r ) )
|
|
|
|
{
|
|
|
|
nPos = SbiOpenRecord( r, B_NAME, 1 );
|
2011-12-21 10:45:54 +00:00
|
|
|
r.WriteUniOrByteString( aName, eCharSet );
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiCloseRecord( r, nPos );
|
|
|
|
}
|
2009-04-25 00:18:20 +00:00
|
|
|
// Comment?
|
2000-09-18 15:18:56 +00:00
|
|
|
if( aComment.Len() && SbiGood( r ) )
|
|
|
|
{
|
|
|
|
nPos = SbiOpenRecord( r, B_COMMENT, 1 );
|
2011-12-21 10:45:54 +00:00
|
|
|
r.WriteUniOrByteString( aComment, eCharSet );
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiCloseRecord( r, nPos );
|
|
|
|
}
|
|
|
|
// Source?
|
2011-12-10 13:35:14 -02:00
|
|
|
if( !aOUSource.isEmpty() && SbiGood( r ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
nPos = SbiOpenRecord( r, B_SOURCE, 1 );
|
2003-04-23 15:55:53 +00:00
|
|
|
String aTmp;
|
|
|
|
sal_Int32 nLen = aOUSource.getLength();
|
2005-05-18 12:07:10 +00:00
|
|
|
const sal_Int32 nMaxUnitSize = STRING_MAXLEN - 1;
|
2003-04-23 15:55:53 +00:00
|
|
|
if( nLen > STRING_MAXLEN )
|
2005-05-18 12:07:10 +00:00
|
|
|
aTmp = aOUSource.copy( 0, nMaxUnitSize );
|
2003-04-23 15:55:53 +00:00
|
|
|
else
|
|
|
|
aTmp = aOUSource;
|
2011-12-21 10:45:54 +00:00
|
|
|
r.WriteUniOrByteString( aTmp, eCharSet );
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiCloseRecord( r, nPos );
|
2005-05-18 12:07:10 +00:00
|
|
|
|
|
|
|
if( nLen > STRING_MAXLEN )
|
|
|
|
{
|
|
|
|
sal_Int32 nRemainingLen = nLen - nMaxUnitSize;
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nUnitCount = sal_uInt16( (nRemainingLen + nMaxUnitSize - 1) / nMaxUnitSize );
|
2005-05-18 12:07:10 +00:00
|
|
|
nPos = SbiOpenRecord( r, B_EXTSOURCE, nUnitCount );
|
2011-01-10 14:40:57 +01:00
|
|
|
for( sal_uInt16 i = 0 ; i < nUnitCount ; i++ )
|
2005-05-18 12:07:10 +00:00
|
|
|
{
|
|
|
|
sal_Int32 nCopyLen =
|
|
|
|
(nRemainingLen > nMaxUnitSize) ? nMaxUnitSize : nRemainingLen;
|
2006-06-19 16:39:15 +00:00
|
|
|
String aTmp2 = aOUSource.copy( (i+1) * nMaxUnitSize, nCopyLen );
|
2005-05-18 12:07:10 +00:00
|
|
|
nRemainingLen -= nCopyLen;
|
2011-12-21 10:45:54 +00:00
|
|
|
r.WriteUniOrByteString( aTmp2, eCharSet );
|
2005-05-18 12:07:10 +00:00
|
|
|
}
|
|
|
|
SbiCloseRecord( r, nPos );
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2009-04-25 00:18:20 +00:00
|
|
|
// Binary data?
|
2000-09-18 15:18:56 +00:00
|
|
|
if( pCode && SbiGood( r ) )
|
|
|
|
{
|
|
|
|
nPos = SbiOpenRecord( r, B_PCODE, 1 );
|
2006-11-01 15:13:02 +00:00
|
|
|
if ( bLegacy )
|
|
|
|
{
|
|
|
|
ReleaseLegacyBuffer(); // release any previously held buffer
|
2011-01-10 14:40:57 +01:00
|
|
|
PCodeBuffConvertor< sal_uInt32, sal_uInt16 > aNewToLegacy( (sal_uInt8*)pCode, nCodeSize );
|
2006-11-01 15:13:02 +00:00
|
|
|
aNewToLegacy.convert();
|
|
|
|
pLegacyPCode = (char*)aNewToLegacy.GetBuffer();
|
|
|
|
nLegacyCodeSize = aNewToLegacy.GetSize();
|
|
|
|
r.Write( pLegacyPCode, nLegacyCodeSize );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
r.Write( pCode, nCodeSize );
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiCloseRecord( r, nPos );
|
|
|
|
}
|
|
|
|
// String-Pool?
|
|
|
|
if( nStrings )
|
|
|
|
{
|
|
|
|
nPos = SbiOpenRecord( r, B_STRINGPOOL, nStrings );
|
2009-04-25 00:18:20 +00:00
|
|
|
// For every String:
|
2011-01-10 14:40:57 +01:00
|
|
|
// sal_uInt32 Offset of the Strings in the Stringblock
|
2003-12-01 15:26:51 +00:00
|
|
|
short i;
|
|
|
|
|
|
|
|
for( i = 0; i < nStrings && SbiGood( r ); i++ )
|
2011-01-10 14:40:57 +01:00
|
|
|
r << (sal_uInt32) pStringOff[ i ];
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2009-04-25 00:18:20 +00:00
|
|
|
// Then the String-Block
|
2000-09-18 15:18:56 +00:00
|
|
|
char* pByteStrings = new char[ nStringSize ];
|
|
|
|
for( i = 0; i < nStrings; i++ )
|
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nOff = (sal_uInt16) pStringOff[ i ];
|
2011-11-27 20:37:42 +00:00
|
|
|
rtl::OString aStr(rtl::OUStringToOString(rtl::OUString(pStrings + nOff), eCharSet));
|
|
|
|
memcpy( pByteStrings + nOff, aStr.getStr(), (aStr.getLength() + 1) * sizeof( char ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2011-01-10 14:40:57 +01:00
|
|
|
r << (sal_uInt32) nStringSize;
|
2000-09-18 15:18:56 +00:00
|
|
|
r.Write( pByteStrings, nStringSize );
|
2003-03-18 15:28:40 +00:00
|
|
|
|
|
|
|
delete[] pByteStrings;
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiCloseRecord( r, nPos );
|
|
|
|
}
|
2009-04-25 00:18:20 +00:00
|
|
|
// Set overall length
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiCloseRecord( r, nStart );
|
|
|
|
if( !SbiGood( r ) )
|
2012-08-12 09:07:20 +09:00
|
|
|
bError = true;
|
2012-08-15 09:44:54 +09:00
|
|
|
return !bError;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
*
|
2009-04-25 00:18:20 +00:00
|
|
|
* Routines called by the compiler
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
void SbiImage::MakeStrings( short nSize )
|
|
|
|
{
|
2006-11-03 06:39:47 +00:00
|
|
|
nStrings = 0;
|
|
|
|
nStringIdx = 0;
|
|
|
|
nStringOff = 0;
|
2000-09-18 15:18:56 +00:00
|
|
|
nStringSize = 1024;
|
|
|
|
pStrings = new sal_Unicode[ nStringSize ];
|
2011-01-10 14:40:57 +01:00
|
|
|
pStringOff = new sal_uInt32[ nSize ];
|
2000-09-18 15:18:56 +00:00
|
|
|
if( pStrings && pStringOff )
|
|
|
|
{
|
|
|
|
nStrings = nSize;
|
2011-01-10 14:40:57 +01:00
|
|
|
memset( pStringOff, 0, nSize * sizeof( sal_uInt32 ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
memset( pStrings, 0, nStringSize * sizeof( sal_Unicode ) );
|
|
|
|
}
|
|
|
|
else
|
2012-08-12 09:07:20 +09:00
|
|
|
bError = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2009-04-25 00:18:20 +00:00
|
|
|
// Add a string to StringPool. The String buffer is dynamically
|
|
|
|
// growing in 1K-Steps
|
2000-09-18 15:18:56 +00:00
|
|
|
void SbiImage::AddString( const String& r )
|
|
|
|
{
|
|
|
|
if( nStringIdx >= nStrings )
|
2012-08-12 09:07:20 +09:00
|
|
|
bError = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
if( !bError )
|
|
|
|
{
|
2006-11-01 15:13:02 +00:00
|
|
|
xub_StrLen len = r.Len() + 1;
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt32 needed = nStringOff + len;
|
2006-11-01 15:13:02 +00:00
|
|
|
if( needed > 0xFFFFFF00L )
|
2012-08-12 09:07:20 +09:00
|
|
|
bError = true; // out of mem!
|
2006-11-01 15:13:02 +00:00
|
|
|
else if( needed > nStringSize )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt32 nNewLen = needed + 1024;
|
2005-09-29 17:38:33 +00:00
|
|
|
nNewLen &= 0xFFFFFC00; // trim to 1K border
|
2006-11-01 15:13:02 +00:00
|
|
|
if( nNewLen > 0xFFFFFF00L )
|
|
|
|
nNewLen = 0xFFFFFF00L;
|
2005-09-29 17:38:33 +00:00
|
|
|
sal_Unicode* p = NULL;
|
|
|
|
if( (p = new sal_Unicode[ nNewLen ]) != NULL )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
memcpy( p, pStrings, nStringSize * sizeof( sal_Unicode ) );
|
2003-03-18 15:28:40 +00:00
|
|
|
delete[] pStrings;
|
2000-09-18 15:18:56 +00:00
|
|
|
pStrings = p;
|
2011-01-10 14:40:57 +01:00
|
|
|
nStringSize = sal::static_int_cast< sal_uInt16 >(nNewLen);
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
else
|
2012-08-12 09:07:20 +09:00
|
|
|
bError = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
if( !bError )
|
|
|
|
{
|
|
|
|
pStringOff[ nStringIdx++ ] = nStringOff;
|
|
|
|
memcpy( pStrings + nStringOff, r.GetBuffer(), len * sizeof( sal_Unicode ) );
|
2006-10-12 13:25:10 +00:00
|
|
|
nStringOff = nStringOff + len;
|
2009-04-25 00:18:20 +00:00
|
|
|
// Last String? The update the size of the buffer
|
2000-09-18 15:18:56 +00:00
|
|
|
if( nStringIdx >= nStrings )
|
|
|
|
nStringSize = nStringOff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-25 00:18:20 +00:00
|
|
|
// 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.
|
2011-01-10 14:40:57 +01:00
|
|
|
void SbiImage::AddCode( char* p, sal_uInt32 s )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
pCode = p;
|
|
|
|
nCodeSize = s;
|
|
|
|
}
|
|
|
|
|
2009-04-25 00:18:20 +00:00
|
|
|
// Add user type
|
|
|
|
void SbiImage::AddType(SbxObject* pObject)
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2004-11-15 15:34:02 +00:00
|
|
|
if( !rTypes.Is() )
|
|
|
|
rTypes = new SbxArray;
|
2000-09-18 15:18:56 +00:00
|
|
|
SbxObject *pCopyObject = new SbxObject(*pObject);
|
|
|
|
rTypes->Insert (pCopyObject,rTypes->Count());
|
|
|
|
}
|
|
|
|
|
2004-11-15 15:34:02 +00:00
|
|
|
void SbiImage::AddEnum(SbxObject* pObject) // Register enum type
|
|
|
|
{
|
|
|
|
if( !rEnums.Is() )
|
|
|
|
rEnums = new SbxArray;
|
|
|
|
rEnums->Insert( pObject, rEnums->Count() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
/**************************************************************************
|
|
|
|
*
|
2009-04-25 00:18:20 +00:00
|
|
|
* Accessing the image
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
|
|
|
**************************************************************************/
|
|
|
|
|
2009-04-25 00:18:20 +00:00
|
|
|
// Note: IDs start with 1
|
2000-09-18 15:18:56 +00:00
|
|
|
String SbiImage::GetString( short nId ) const
|
|
|
|
{
|
|
|
|
if( nId && nId <= nStrings )
|
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt32 nOff = pStringOff[ nId - 1 ];
|
2005-03-29 10:47:59 +00:00
|
|
|
sal_Unicode* pStr = pStrings + nOff;
|
|
|
|
|
|
|
|
// #i42467: Special treatment for vbNullChar
|
|
|
|
if( *pStr == 0 )
|
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt32 nNextOff = (nId < nStrings) ? pStringOff[ nId ] : nStringOff;
|
|
|
|
sal_uInt32 nLen = nNextOff - nOff - 1;
|
2005-03-29 10:47:59 +00:00
|
|
|
if( nLen == 1 )
|
|
|
|
{
|
|
|
|
// Force length 1 and make char 0 afterwards
|
2012-07-02 16:02:38 +01:00
|
|
|
String aNullCharStr( rtl::OUString(" ") );
|
2005-03-29 10:47:59 +00:00
|
|
|
aNullCharStr.SetChar( 0, 0 );
|
|
|
|
return aNullCharStr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2012-06-12 13:40:45 +01:00
|
|
|
return rtl::OUString(pStr);
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2012-06-12 13:40:45 +01:00
|
|
|
return rtl::OUString();
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const SbxObject* SbiImage::FindType (String aTypeName) const
|
|
|
|
{
|
2004-11-15 15:34:02 +00:00
|
|
|
return rTypes.Is() ? (SbxObject*)rTypes->Find(aTypeName,SbxCLASS_OBJECT) : NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 SbiImage::CalcLegacyOffset( sal_Int32 nOffset )
|
2006-11-01 15:13:02 +00:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
return SbiCodeGen::calcLegacyOffSet( (sal_uInt8*)pCode, nOffset ) ;
|
2006-11-01 15:13:02 +00:00
|
|
|
}
|
2009-04-25 00:18:20 +00:00
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt32 SbiImage::CalcNewOffset( sal_Int16 nOffset )
|
2006-11-01 15:13:02 +00:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
return SbiCodeGen::calcNewOffSet( (sal_uInt8*)pLegacyPCode, nOffset ) ;
|
2006-11-01 15:13:02 +00:00
|
|
|
}
|
|
|
|
|
2009-04-25 00:18:20 +00:00
|
|
|
void SbiImage::ReleaseLegacyBuffer()
|
2006-11-01 15:13:02 +00:00
|
|
|
{
|
|
|
|
delete[] pLegacyPCode;
|
|
|
|
pLegacyPCode = NULL;
|
|
|
|
nLegacyCodeSize = 0;
|
|
|
|
}
|
|
|
|
|
2012-08-15 09:44:54 +09:00
|
|
|
bool SbiImage::ExceedsLegacyLimits()
|
2006-11-01 15:13:02 +00:00
|
|
|
{
|
2012-08-15 09:44:54 +09:00
|
|
|
return ( nStringSize > 0xFF00L ) || ( CalcLegacyOffset( nCodeSize ) > 0xFF00L );
|
2006-11-01 15:13:02 +00:00
|
|
|
}
|
2010-10-12 15:53:47 +02:00
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|