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