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