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