1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_basic.hxx" 30*cdf0e10cSrcweir #include <tools/stream.hxx> 31*cdf0e10cSrcweir #include <tools/tenccvt.hxx> 32*cdf0e10cSrcweir #include <basic/sbx.hxx> 33*cdf0e10cSrcweir #include "sb.hxx" 34*cdf0e10cSrcweir #include <string.h> // memset() etc 35*cdf0e10cSrcweir #include "image.hxx" 36*cdf0e10cSrcweir #include <codegen.hxx> 37*cdf0e10cSrcweir SbiImage::SbiImage() 38*cdf0e10cSrcweir { 39*cdf0e10cSrcweir pStringOff = NULL; 40*cdf0e10cSrcweir pStrings = NULL; 41*cdf0e10cSrcweir pCode = NULL; 42*cdf0e10cSrcweir pLegacyPCode = NULL; 43*cdf0e10cSrcweir nFlags = 0; 44*cdf0e10cSrcweir nStrings = 0; 45*cdf0e10cSrcweir nStringSize= 0; 46*cdf0e10cSrcweir nCodeSize = 0; 47*cdf0e10cSrcweir nLegacyCodeSize = 48*cdf0e10cSrcweir nDimBase = 0; 49*cdf0e10cSrcweir bInit = 50*cdf0e10cSrcweir bError = sal_False; 51*cdf0e10cSrcweir bFirstInit = sal_True; 52*cdf0e10cSrcweir eCharSet = gsl_getSystemTextEncoding(); 53*cdf0e10cSrcweir } 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir SbiImage::~SbiImage() 56*cdf0e10cSrcweir { 57*cdf0e10cSrcweir Clear(); 58*cdf0e10cSrcweir } 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir void SbiImage::Clear() 61*cdf0e10cSrcweir { 62*cdf0e10cSrcweir delete[] pStringOff; 63*cdf0e10cSrcweir delete[] pStrings; 64*cdf0e10cSrcweir delete[] pCode; 65*cdf0e10cSrcweir ReleaseLegacyBuffer(); 66*cdf0e10cSrcweir pStringOff = NULL; 67*cdf0e10cSrcweir pStrings = NULL; 68*cdf0e10cSrcweir pCode = NULL; 69*cdf0e10cSrcweir nFlags = 0; 70*cdf0e10cSrcweir nStrings = 0; 71*cdf0e10cSrcweir nStringSize= 0; 72*cdf0e10cSrcweir nLegacyCodeSize = 0; 73*cdf0e10cSrcweir nCodeSize = 0; 74*cdf0e10cSrcweir eCharSet = gsl_getSystemTextEncoding(); 75*cdf0e10cSrcweir nDimBase = 0; 76*cdf0e10cSrcweir bError = sal_False; 77*cdf0e10cSrcweir } 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir /************************************************************************** 80*cdf0e10cSrcweir * 81*cdf0e10cSrcweir * Service-Routines for Load/Store 82*cdf0e10cSrcweir * 83*cdf0e10cSrcweir **************************************************************************/ 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir sal_Bool SbiGood( SvStream& r ) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir return sal_Bool( !r.IsEof() && r.GetError() == SVSTREAM_OK ); 88*cdf0e10cSrcweir } 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir // Open Record 91*cdf0e10cSrcweir sal_uIntPtr SbiOpenRecord( SvStream& r, sal_uInt16 nSignature, sal_uInt16 nElem ) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir sal_uIntPtr nPos = r.Tell(); 94*cdf0e10cSrcweir r << nSignature << (sal_Int32) 0 << nElem; 95*cdf0e10cSrcweir return nPos; 96*cdf0e10cSrcweir } 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir // Close Record 99*cdf0e10cSrcweir void SbiCloseRecord( SvStream& r, sal_uIntPtr nOff ) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir sal_uIntPtr nPos = r.Tell(); 102*cdf0e10cSrcweir r.Seek( nOff + 2 ); 103*cdf0e10cSrcweir r << (sal_Int32) ( nPos - nOff - 8 ); 104*cdf0e10cSrcweir r.Seek( nPos ); 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir /************************************************************************** 108*cdf0e10cSrcweir * 109*cdf0e10cSrcweir * Load/Store 110*cdf0e10cSrcweir * 111*cdf0e10cSrcweir **************************************************************************/ 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir // If the version number does not find, binary parts are omitted, but not 114*cdf0e10cSrcweir // source, comments and name 115*cdf0e10cSrcweir sal_Bool SbiImage::Load( SvStream& r ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir sal_uInt32 nVersion = 0; // Versionsnumber 118*cdf0e10cSrcweir return Load( r, nVersion ); 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir sal_Bool SbiImage::Load( SvStream& r, sal_uInt32& nVersion ) 121*cdf0e10cSrcweir { 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir sal_uInt16 nSign, nCount; 124*cdf0e10cSrcweir sal_uInt32 nLen, nOff; 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir Clear(); 127*cdf0e10cSrcweir // Read Master-Record 128*cdf0e10cSrcweir r >> nSign >> nLen >> nCount; 129*cdf0e10cSrcweir sal_uIntPtr nLast = r.Tell() + nLen; 130*cdf0e10cSrcweir sal_uInt32 nCharSet; // System charset 131*cdf0e10cSrcweir sal_uInt32 lDimBase; 132*cdf0e10cSrcweir sal_uInt16 nReserved1; 133*cdf0e10cSrcweir sal_uInt32 nReserved2; 134*cdf0e10cSrcweir sal_uInt32 nReserved3; 135*cdf0e10cSrcweir sal_Bool bBadVer = sal_False; 136*cdf0e10cSrcweir if( nSign == B_MODULE ) 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir r >> nVersion >> nCharSet >> lDimBase 139*cdf0e10cSrcweir >> nFlags >> nReserved1 >> nReserved2 >> nReserved3; 140*cdf0e10cSrcweir eCharSet = (CharSet) nCharSet; 141*cdf0e10cSrcweir eCharSet = GetSOLoadTextEncoding( eCharSet ); 142*cdf0e10cSrcweir bBadVer = sal_Bool( nVersion > B_CURVERSION ); 143*cdf0e10cSrcweir nDimBase = (sal_uInt16) lDimBase; 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir bool bLegacy = ( nVersion < B_EXT_IMG_VERSION ); 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir sal_uIntPtr nNext; 149*cdf0e10cSrcweir while( ( nNext = r.Tell() ) < nLast ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir short i; 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir r >> nSign >> nLen >> nCount; 154*cdf0e10cSrcweir nNext += nLen + 8; 155*cdf0e10cSrcweir if( r.GetError() == SVSTREAM_OK ) 156*cdf0e10cSrcweir switch( nSign ) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir case B_NAME: 159*cdf0e10cSrcweir r.ReadByteString( aName, eCharSet ); 160*cdf0e10cSrcweir //r >> aName; 161*cdf0e10cSrcweir break; 162*cdf0e10cSrcweir case B_COMMENT: 163*cdf0e10cSrcweir r.ReadByteString( aComment, eCharSet ); 164*cdf0e10cSrcweir //r >> aComment; 165*cdf0e10cSrcweir break; 166*cdf0e10cSrcweir case B_SOURCE: 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir String aTmp; 169*cdf0e10cSrcweir r.ReadByteString( aTmp, eCharSet ); 170*cdf0e10cSrcweir aOUSource = aTmp; 171*cdf0e10cSrcweir //r >> aSource; 172*cdf0e10cSrcweir break; 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir #ifdef EXTENDED_BINARY_MODULES 175*cdf0e10cSrcweir case B_EXTSOURCE: 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir for( sal_uInt16 j = 0 ; j < nCount ; j++ ) 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir String aTmp; 180*cdf0e10cSrcweir r.ReadByteString( aTmp, eCharSet ); 181*cdf0e10cSrcweir aOUSource += aTmp; 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir break; 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir #endif 186*cdf0e10cSrcweir case B_PCODE: 187*cdf0e10cSrcweir if( bBadVer ) break; 188*cdf0e10cSrcweir pCode = new char[ nLen ]; 189*cdf0e10cSrcweir nCodeSize = nLen; 190*cdf0e10cSrcweir r.Read( pCode, nCodeSize ); 191*cdf0e10cSrcweir if ( bLegacy ) 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir ReleaseLegacyBuffer(); // release any previously held buffer 194*cdf0e10cSrcweir nLegacyCodeSize = (sal_uInt16) nCodeSize; 195*cdf0e10cSrcweir pLegacyPCode = pCode; 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir PCodeBuffConvertor< sal_uInt16, sal_uInt32 > aLegacyToNew( (sal_uInt8*)pLegacyPCode, nLegacyCodeSize ); 198*cdf0e10cSrcweir aLegacyToNew.convert(); 199*cdf0e10cSrcweir pCode = (char*)aLegacyToNew.GetBuffer(); 200*cdf0e10cSrcweir nCodeSize = aLegacyToNew.GetSize(); 201*cdf0e10cSrcweir // we don't release the legacy buffer 202*cdf0e10cSrcweir // right now, thats because the module 203*cdf0e10cSrcweir // needs it to fix up the method 204*cdf0e10cSrcweir // nStart members. When that is done 205*cdf0e10cSrcweir // the module can release the buffer 206*cdf0e10cSrcweir // or it can wait until this routine 207*cdf0e10cSrcweir // is called again or when this class // destructs all of which will trigger 208*cdf0e10cSrcweir // release of the buffer. 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir break; 211*cdf0e10cSrcweir case B_PUBLICS: 212*cdf0e10cSrcweir case B_POOLDIR: 213*cdf0e10cSrcweir case B_SYMPOOL: 214*cdf0e10cSrcweir case B_LINERANGES: 215*cdf0e10cSrcweir break; 216*cdf0e10cSrcweir case B_STRINGPOOL: 217*cdf0e10cSrcweir if( bBadVer ) break; 218*cdf0e10cSrcweir MakeStrings( nCount ); 219*cdf0e10cSrcweir for( i = 0; i < nStrings && SbiGood( r ); i++ ) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir r >> nOff; 222*cdf0e10cSrcweir pStringOff[ i ] = (sal_uInt16) nOff; 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir r >> nLen; 225*cdf0e10cSrcweir if( SbiGood( r ) ) 226*cdf0e10cSrcweir { 227*cdf0e10cSrcweir delete [] pStrings; 228*cdf0e10cSrcweir pStrings = new sal_Unicode[ nLen ]; 229*cdf0e10cSrcweir nStringSize = (sal_uInt16) nLen; 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir char* pByteStrings = new char[ nLen ]; 232*cdf0e10cSrcweir r.Read( pByteStrings, nStringSize ); 233*cdf0e10cSrcweir for( short j = 0; j < nStrings; j++ ) 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir sal_uInt16 nOff2 = (sal_uInt16) pStringOff[ j ]; 236*cdf0e10cSrcweir String aStr( pByteStrings + nOff2, eCharSet ); 237*cdf0e10cSrcweir memcpy( pStrings + nOff2, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( sal_Unicode ) ); 238*cdf0e10cSrcweir } 239*cdf0e10cSrcweir delete[] pByteStrings; 240*cdf0e10cSrcweir } break; 241*cdf0e10cSrcweir case B_MODEND: 242*cdf0e10cSrcweir goto done; 243*cdf0e10cSrcweir default: 244*cdf0e10cSrcweir break; 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir else 247*cdf0e10cSrcweir break; 248*cdf0e10cSrcweir r.Seek( nNext ); 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir done: 251*cdf0e10cSrcweir r.Seek( nLast ); 252*cdf0e10cSrcweir //if( eCharSet != ::GetSystemCharSet() ) 253*cdf0e10cSrcweir //ConvertStrings(); 254*cdf0e10cSrcweir if( !SbiGood( r ) ) 255*cdf0e10cSrcweir bError = sal_True; 256*cdf0e10cSrcweir return sal_Bool( !bError ); 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir sal_Bool SbiImage::Save( SvStream& r, sal_uInt32 nVer ) 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir bool bLegacy = ( nVer < B_EXT_IMG_VERSION ); 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir // detect if old code exceeds legacy limits 264*cdf0e10cSrcweir // if so, then disallow save 265*cdf0e10cSrcweir if ( bLegacy && ExceedsLegacyLimits() ) 266*cdf0e10cSrcweir { 267*cdf0e10cSrcweir SbiImage aEmptyImg; 268*cdf0e10cSrcweir aEmptyImg.aName = aName; 269*cdf0e10cSrcweir aEmptyImg.Save( r, B_LEGACYVERSION ); 270*cdf0e10cSrcweir return sal_True; 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir // First of all the header 273*cdf0e10cSrcweir sal_uIntPtr nStart = SbiOpenRecord( r, B_MODULE, 1 ); 274*cdf0e10cSrcweir sal_uIntPtr nPos; 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir eCharSet = GetSOStoreTextEncoding( eCharSet ); 277*cdf0e10cSrcweir if ( bLegacy ) 278*cdf0e10cSrcweir r << (sal_Int32) B_LEGACYVERSION; 279*cdf0e10cSrcweir else 280*cdf0e10cSrcweir r << (sal_Int32) B_CURVERSION; 281*cdf0e10cSrcweir r << (sal_Int32) eCharSet 282*cdf0e10cSrcweir << (sal_Int32) nDimBase 283*cdf0e10cSrcweir << (sal_Int16) nFlags 284*cdf0e10cSrcweir << (sal_Int16) 0 285*cdf0e10cSrcweir << (sal_Int32) 0 286*cdf0e10cSrcweir << (sal_Int32) 0; 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir // Name? 289*cdf0e10cSrcweir if( aName.Len() && SbiGood( r ) ) 290*cdf0e10cSrcweir { 291*cdf0e10cSrcweir nPos = SbiOpenRecord( r, B_NAME, 1 ); 292*cdf0e10cSrcweir r.WriteByteString( aName, eCharSet ); 293*cdf0e10cSrcweir //r << aName; 294*cdf0e10cSrcweir SbiCloseRecord( r, nPos ); 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir // Comment? 297*cdf0e10cSrcweir if( aComment.Len() && SbiGood( r ) ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir nPos = SbiOpenRecord( r, B_COMMENT, 1 ); 300*cdf0e10cSrcweir r.WriteByteString( aComment, eCharSet ); 301*cdf0e10cSrcweir //r << aComment; 302*cdf0e10cSrcweir SbiCloseRecord( r, nPos ); 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir // Source? 305*cdf0e10cSrcweir if( aOUSource.getLength() && SbiGood( r ) ) 306*cdf0e10cSrcweir { 307*cdf0e10cSrcweir nPos = SbiOpenRecord( r, B_SOURCE, 1 ); 308*cdf0e10cSrcweir String aTmp; 309*cdf0e10cSrcweir sal_Int32 nLen = aOUSource.getLength(); 310*cdf0e10cSrcweir const sal_Int32 nMaxUnitSize = STRING_MAXLEN - 1; 311*cdf0e10cSrcweir if( nLen > STRING_MAXLEN ) 312*cdf0e10cSrcweir aTmp = aOUSource.copy( 0, nMaxUnitSize ); 313*cdf0e10cSrcweir else 314*cdf0e10cSrcweir aTmp = aOUSource; 315*cdf0e10cSrcweir r.WriteByteString( aTmp, eCharSet ); 316*cdf0e10cSrcweir //r << aSource; 317*cdf0e10cSrcweir SbiCloseRecord( r, nPos ); 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir #ifdef EXTENDED_BINARY_MODULES 320*cdf0e10cSrcweir if( nLen > STRING_MAXLEN ) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir sal_Int32 nRemainingLen = nLen - nMaxUnitSize; 323*cdf0e10cSrcweir sal_uInt16 nUnitCount = sal_uInt16( (nRemainingLen + nMaxUnitSize - 1) / nMaxUnitSize ); 324*cdf0e10cSrcweir nPos = SbiOpenRecord( r, B_EXTSOURCE, nUnitCount ); 325*cdf0e10cSrcweir for( sal_uInt16 i = 0 ; i < nUnitCount ; i++ ) 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir sal_Int32 nCopyLen = 328*cdf0e10cSrcweir (nRemainingLen > nMaxUnitSize) ? nMaxUnitSize : nRemainingLen; 329*cdf0e10cSrcweir String aTmp2 = aOUSource.copy( (i+1) * nMaxUnitSize, nCopyLen ); 330*cdf0e10cSrcweir nRemainingLen -= nCopyLen; 331*cdf0e10cSrcweir r.WriteByteString( aTmp2, eCharSet ); 332*cdf0e10cSrcweir } 333*cdf0e10cSrcweir SbiCloseRecord( r, nPos ); 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir #endif 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir // Binary data? 338*cdf0e10cSrcweir if( pCode && SbiGood( r ) ) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir nPos = SbiOpenRecord( r, B_PCODE, 1 ); 341*cdf0e10cSrcweir if ( bLegacy ) 342*cdf0e10cSrcweir { 343*cdf0e10cSrcweir ReleaseLegacyBuffer(); // release any previously held buffer 344*cdf0e10cSrcweir PCodeBuffConvertor< sal_uInt32, sal_uInt16 > aNewToLegacy( (sal_uInt8*)pCode, nCodeSize ); 345*cdf0e10cSrcweir aNewToLegacy.convert(); 346*cdf0e10cSrcweir pLegacyPCode = (char*)aNewToLegacy.GetBuffer(); 347*cdf0e10cSrcweir nLegacyCodeSize = aNewToLegacy.GetSize(); 348*cdf0e10cSrcweir r.Write( pLegacyPCode, nLegacyCodeSize ); 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir else 351*cdf0e10cSrcweir r.Write( pCode, nCodeSize ); 352*cdf0e10cSrcweir SbiCloseRecord( r, nPos ); 353*cdf0e10cSrcweir } 354*cdf0e10cSrcweir // String-Pool? 355*cdf0e10cSrcweir if( nStrings ) 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir nPos = SbiOpenRecord( r, B_STRINGPOOL, nStrings ); 358*cdf0e10cSrcweir // For every String: 359*cdf0e10cSrcweir // sal_uInt32 Offset of the Strings in the Stringblock 360*cdf0e10cSrcweir short i; 361*cdf0e10cSrcweir 362*cdf0e10cSrcweir for( i = 0; i < nStrings && SbiGood( r ); i++ ) 363*cdf0e10cSrcweir r << (sal_uInt32) pStringOff[ i ]; 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir // Then the String-Block 366*cdf0e10cSrcweir char* pByteStrings = new char[ nStringSize ]; 367*cdf0e10cSrcweir for( i = 0; i < nStrings; i++ ) 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir sal_uInt16 nOff = (sal_uInt16) pStringOff[ i ]; 370*cdf0e10cSrcweir ByteString aStr( pStrings + nOff, eCharSet ); 371*cdf0e10cSrcweir memcpy( pByteStrings + nOff, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( char ) ); 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir r << (sal_uInt32) nStringSize; 374*cdf0e10cSrcweir r.Write( pByteStrings, nStringSize ); 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir delete[] pByteStrings; 377*cdf0e10cSrcweir SbiCloseRecord( r, nPos ); 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir // Set overall length 380*cdf0e10cSrcweir SbiCloseRecord( r, nStart ); 381*cdf0e10cSrcweir if( !SbiGood( r ) ) 382*cdf0e10cSrcweir bError = sal_True; 383*cdf0e10cSrcweir return sal_Bool( !bError ); 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir /************************************************************************** 387*cdf0e10cSrcweir * 388*cdf0e10cSrcweir * Routines called by the compiler 389*cdf0e10cSrcweir * 390*cdf0e10cSrcweir **************************************************************************/ 391*cdf0e10cSrcweir 392*cdf0e10cSrcweir void SbiImage::MakeStrings( short nSize ) 393*cdf0e10cSrcweir { 394*cdf0e10cSrcweir nStrings = 0; 395*cdf0e10cSrcweir nStringIdx = 0; 396*cdf0e10cSrcweir nStringOff = 0; 397*cdf0e10cSrcweir nStringSize = 1024; 398*cdf0e10cSrcweir pStrings = new sal_Unicode[ nStringSize ]; 399*cdf0e10cSrcweir pStringOff = new sal_uInt32[ nSize ]; 400*cdf0e10cSrcweir if( pStrings && pStringOff ) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir nStrings = nSize; 403*cdf0e10cSrcweir memset( pStringOff, 0, nSize * sizeof( sal_uInt32 ) ); 404*cdf0e10cSrcweir memset( pStrings, 0, nStringSize * sizeof( sal_Unicode ) ); 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir else 407*cdf0e10cSrcweir bError = sal_True; 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir // Hinzufuegen eines Strings an den StringPool. Der String-Puffer 411*cdf0e10cSrcweir // waechst dynamisch in 1K-Schritten 412*cdf0e10cSrcweir // Add a string to StringPool. The String buffer is dynamically 413*cdf0e10cSrcweir // growing in 1K-Steps 414*cdf0e10cSrcweir void SbiImage::AddString( const String& r ) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir if( nStringIdx >= nStrings ) 417*cdf0e10cSrcweir bError = sal_True; 418*cdf0e10cSrcweir if( !bError ) 419*cdf0e10cSrcweir { 420*cdf0e10cSrcweir xub_StrLen len = r.Len() + 1; 421*cdf0e10cSrcweir sal_uInt32 needed = nStringOff + len; 422*cdf0e10cSrcweir if( needed > 0xFFFFFF00L ) 423*cdf0e10cSrcweir bError = sal_True; // out of mem! 424*cdf0e10cSrcweir else if( needed > nStringSize ) 425*cdf0e10cSrcweir { 426*cdf0e10cSrcweir sal_uInt32 nNewLen = needed + 1024; 427*cdf0e10cSrcweir nNewLen &= 0xFFFFFC00; // trim to 1K border 428*cdf0e10cSrcweir if( nNewLen > 0xFFFFFF00L ) 429*cdf0e10cSrcweir nNewLen = 0xFFFFFF00L; 430*cdf0e10cSrcweir sal_Unicode* p = NULL; 431*cdf0e10cSrcweir if( (p = new sal_Unicode[ nNewLen ]) != NULL ) 432*cdf0e10cSrcweir { 433*cdf0e10cSrcweir memcpy( p, pStrings, nStringSize * sizeof( sal_Unicode ) ); 434*cdf0e10cSrcweir delete[] pStrings; 435*cdf0e10cSrcweir pStrings = p; 436*cdf0e10cSrcweir nStringSize = sal::static_int_cast< sal_uInt16 >(nNewLen); 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir else 439*cdf0e10cSrcweir bError = sal_True; 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir if( !bError ) 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir pStringOff[ nStringIdx++ ] = nStringOff; 444*cdf0e10cSrcweir //ByteString aByteStr( r, eCharSet ); 445*cdf0e10cSrcweir memcpy( pStrings + nStringOff, r.GetBuffer(), len * sizeof( sal_Unicode ) ); 446*cdf0e10cSrcweir nStringOff = nStringOff + len; 447*cdf0e10cSrcweir // Last String? The update the size of the buffer 448*cdf0e10cSrcweir if( nStringIdx >= nStrings ) 449*cdf0e10cSrcweir nStringSize = nStringOff; 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir // Add code block 455*cdf0e10cSrcweir // The block was fetched by the compiler from class SbBuffer and 456*cdf0e10cSrcweir // is already created with new. Additionally it contains all Integers 457*cdf0e10cSrcweir // in Big Endian format, so can be directly read/written. 458*cdf0e10cSrcweir void SbiImage::AddCode( char* p, sal_uInt32 s ) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir pCode = p; 461*cdf0e10cSrcweir nCodeSize = s; 462*cdf0e10cSrcweir } 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir // Add user type 465*cdf0e10cSrcweir void SbiImage::AddType(SbxObject* pObject) 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir if( !rTypes.Is() ) 468*cdf0e10cSrcweir rTypes = new SbxArray; 469*cdf0e10cSrcweir SbxObject *pCopyObject = new SbxObject(*pObject); 470*cdf0e10cSrcweir rTypes->Insert (pCopyObject,rTypes->Count()); 471*cdf0e10cSrcweir } 472*cdf0e10cSrcweir 473*cdf0e10cSrcweir void SbiImage::AddEnum(SbxObject* pObject) // Register enum type 474*cdf0e10cSrcweir { 475*cdf0e10cSrcweir if( !rEnums.Is() ) 476*cdf0e10cSrcweir rEnums = new SbxArray; 477*cdf0e10cSrcweir rEnums->Insert( pObject, rEnums->Count() ); 478*cdf0e10cSrcweir } 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir 481*cdf0e10cSrcweir /************************************************************************** 482*cdf0e10cSrcweir * 483*cdf0e10cSrcweir * Accessing the image 484*cdf0e10cSrcweir * 485*cdf0e10cSrcweir **************************************************************************/ 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir // Note: IDs start with 1 488*cdf0e10cSrcweir String SbiImage::GetString( short nId ) const 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir if( nId && nId <= nStrings ) 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir sal_uInt32 nOff = pStringOff[ nId - 1 ]; 493*cdf0e10cSrcweir sal_Unicode* pStr = pStrings + nOff; 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir // #i42467: Special treatment for vbNullChar 496*cdf0e10cSrcweir if( *pStr == 0 ) 497*cdf0e10cSrcweir { 498*cdf0e10cSrcweir sal_uInt32 nNextOff = (nId < nStrings) ? pStringOff[ nId ] : nStringOff; 499*cdf0e10cSrcweir sal_uInt32 nLen = nNextOff - nOff - 1; 500*cdf0e10cSrcweir if( nLen == 1 ) 501*cdf0e10cSrcweir { 502*cdf0e10cSrcweir // Force length 1 and make char 0 afterwards 503*cdf0e10cSrcweir String aNullCharStr( String::CreateFromAscii( " " ) ); 504*cdf0e10cSrcweir aNullCharStr.SetChar( 0, 0 ); 505*cdf0e10cSrcweir return aNullCharStr; 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir else 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir String aStr( pStr ); 511*cdf0e10cSrcweir return aStr; 512*cdf0e10cSrcweir } 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir return String(); 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir const SbxObject* SbiImage::FindType (String aTypeName) const 518*cdf0e10cSrcweir { 519*cdf0e10cSrcweir return rTypes.Is() ? (SbxObject*)rTypes->Find(aTypeName,SbxCLASS_OBJECT) : NULL; 520*cdf0e10cSrcweir } 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir sal_uInt16 SbiImage::CalcLegacyOffset( sal_Int32 nOffset ) 523*cdf0e10cSrcweir { 524*cdf0e10cSrcweir return SbiCodeGen::calcLegacyOffSet( (sal_uInt8*)pCode, nOffset ) ; 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir sal_uInt32 SbiImage::CalcNewOffset( sal_Int16 nOffset ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir return SbiCodeGen::calcNewOffSet( (sal_uInt8*)pLegacyPCode, nOffset ) ; 530*cdf0e10cSrcweir } 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir void SbiImage::ReleaseLegacyBuffer() 533*cdf0e10cSrcweir { 534*cdf0e10cSrcweir delete[] pLegacyPCode; 535*cdf0e10cSrcweir pLegacyPCode = NULL; 536*cdf0e10cSrcweir nLegacyCodeSize = 0; 537*cdf0e10cSrcweir } 538*cdf0e10cSrcweir 539*cdf0e10cSrcweir sal_Bool SbiImage::ExceedsLegacyLimits() 540*cdf0e10cSrcweir { 541*cdf0e10cSrcweir if ( ( nStringSize > 0xFF00L ) || ( CalcLegacyOffset( nCodeSize ) > 0xFF00L ) ) 542*cdf0e10cSrcweir return sal_True; 543*cdf0e10cSrcweir return sal_False; 544*cdf0e10cSrcweir } 545