xref: /aoo4110/main/oox/source/xls/biffhelper.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 #include "oox/xls/biffhelper.hxx"
25*b1cdbd2cSJim Jagielski 
26*b1cdbd2cSJim Jagielski #include <rtl/math.hxx>
27*b1cdbd2cSJim Jagielski #include <rtl/tencinfo.h>
28*b1cdbd2cSJim Jagielski #include "oox/xls/biffinputstream.hxx"
29*b1cdbd2cSJim Jagielski #include "oox/xls/biffoutputstream.hxx"
30*b1cdbd2cSJim Jagielski #include "oox/xls/worksheethelper.hxx"
31*b1cdbd2cSJim Jagielski 
32*b1cdbd2cSJim Jagielski namespace oox {
33*b1cdbd2cSJim Jagielski namespace xls {
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski // ============================================================================
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski using ::rtl::OUString;
38*b1cdbd2cSJim Jagielski using ::rtl::OUStringBuffer;
39*b1cdbd2cSJim Jagielski 
40*b1cdbd2cSJim Jagielski // ============================================================================
41*b1cdbd2cSJim Jagielski 
42*b1cdbd2cSJim Jagielski namespace {
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski const sal_Int32 BIFF_RK_100FLAG             = 0x00000001;
45*b1cdbd2cSJim Jagielski const sal_Int32 BIFF_RK_INTFLAG             = 0x00000002;
46*b1cdbd2cSJim Jagielski const sal_Int32 BIFF_RK_VALUEMASK           = 0xFFFFFFFC;
47*b1cdbd2cSJim Jagielski 
48*b1cdbd2cSJim Jagielski const sal_Int32 BITMAPFILEHEADER_SIZE       = 14;
49*b1cdbd2cSJim Jagielski const sal_Int32 BITMAPCOREHEADER_SIZE       = 12;
50*b1cdbd2cSJim Jagielski const sal_Int32 BITMAPINFOHEADER_SIZE       = 40;
51*b1cdbd2cSJim Jagielski 
52*b1cdbd2cSJim Jagielski const sal_uInt16 BIFF_IMGDATA_WMF           = 2;
53*b1cdbd2cSJim Jagielski const sal_uInt16 BIFF_IMGDATA_DIB           = 9;
54*b1cdbd2cSJim Jagielski const sal_uInt16 BIFF_IMGDATA_NATIVE        = 14;
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
57*b1cdbd2cSJim Jagielski 
58*b1cdbd2cSJim Jagielski union DecodedDouble
59*b1cdbd2cSJim Jagielski {
60*b1cdbd2cSJim Jagielski     double              mfValue;
61*b1cdbd2cSJim Jagielski     sal_math_Double     maStruct;
62*b1cdbd2cSJim Jagielski 
DecodedDouble()63*b1cdbd2cSJim Jagielski     inline explicit     DecodedDouble() {}
DecodedDouble(double fValue)64*b1cdbd2cSJim Jagielski     inline explicit     DecodedDouble( double fValue ) : mfValue( fValue ) {}
65*b1cdbd2cSJim Jagielski };
66*b1cdbd2cSJim Jagielski 
lclCalcRkFromDouble(sal_Int32 & ornRkValue,const DecodedDouble & rDecDbl)67*b1cdbd2cSJim Jagielski bool lclCalcRkFromDouble( sal_Int32& ornRkValue, const DecodedDouble& rDecDbl )
68*b1cdbd2cSJim Jagielski {
69*b1cdbd2cSJim Jagielski     // double
70*b1cdbd2cSJim Jagielski     if( (rDecDbl.maStruct.w32_parts.lsw == 0) && ((rDecDbl.maStruct.w32_parts.msw & 0x3) == 0) )
71*b1cdbd2cSJim Jagielski     {
72*b1cdbd2cSJim Jagielski         ornRkValue = static_cast< sal_Int32 >( rDecDbl.maStruct.w32_parts.msw );
73*b1cdbd2cSJim Jagielski         return true;
74*b1cdbd2cSJim Jagielski     }
75*b1cdbd2cSJim Jagielski 
76*b1cdbd2cSJim Jagielski     // integer
77*b1cdbd2cSJim Jagielski     double fInt = 0.0;
78*b1cdbd2cSJim Jagielski     double fFrac = modf( rDecDbl.mfValue, &fInt );
79*b1cdbd2cSJim Jagielski     if( (fFrac == 0.0) && (-536870912.0 <= fInt) && (fInt <= 536870911.0) ) // 2^29
80*b1cdbd2cSJim Jagielski     {
81*b1cdbd2cSJim Jagielski         ornRkValue = static_cast< sal_Int32 >( fInt );
82*b1cdbd2cSJim Jagielski         ornRkValue <<= 2;
83*b1cdbd2cSJim Jagielski         ornRkValue |= BIFF_RK_INTFLAG;
84*b1cdbd2cSJim Jagielski         return true;
85*b1cdbd2cSJim Jagielski     }
86*b1cdbd2cSJim Jagielski 
87*b1cdbd2cSJim Jagielski     return false;
88*b1cdbd2cSJim Jagielski }
89*b1cdbd2cSJim Jagielski 
lclCalcRkFromDouble(sal_Int32 & ornRkValue,double fValue)90*b1cdbd2cSJim Jagielski bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue )
91*b1cdbd2cSJim Jagielski {
92*b1cdbd2cSJim Jagielski     DecodedDouble aDecDbl( fValue );
93*b1cdbd2cSJim Jagielski     if( lclCalcRkFromDouble( ornRkValue, aDecDbl ) )
94*b1cdbd2cSJim Jagielski         return true;
95*b1cdbd2cSJim Jagielski 
96*b1cdbd2cSJim Jagielski     aDecDbl.mfValue *= 100.0;
97*b1cdbd2cSJim Jagielski     if( lclCalcRkFromDouble( ornRkValue, aDecDbl ) )
98*b1cdbd2cSJim Jagielski     {
99*b1cdbd2cSJim Jagielski         ornRkValue |= BIFF_RK_100FLAG;
100*b1cdbd2cSJim Jagielski         return true;
101*b1cdbd2cSJim Jagielski     }
102*b1cdbd2cSJim Jagielski 
103*b1cdbd2cSJim Jagielski     return false;
104*b1cdbd2cSJim Jagielski }
105*b1cdbd2cSJim Jagielski 
106*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
107*b1cdbd2cSJim Jagielski 
lclImportImgDataDib(StreamDataSequence & orDataSeq,BiffInputStream & rStrm,sal_Int32 nBytes,BiffType eBiff)108*b1cdbd2cSJim Jagielski void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, sal_Int32 nBytes, BiffType eBiff )
109*b1cdbd2cSJim Jagielski {
110*b1cdbd2cSJim Jagielski     /*  The IMGDATA record for bitmap format contains a Windows DIB (a bitmap
111*b1cdbd2cSJim Jagielski         file without the 'BITMAPFILEHEADER' header structure). Usually, the DIB
112*b1cdbd2cSJim Jagielski         header consists of 12 bytes (called 'OS/2 V1 header' or
113*b1cdbd2cSJim Jagielski         'BITMAPCOREHEADER', see http://en.wikipedia.org/wiki/BMP_file_format)
114*b1cdbd2cSJim Jagielski         followed by the remaining pixel data, but the 'Windows V3' or
115*b1cdbd2cSJim Jagielski         'BITMAPINFOHEADER' is also supported here. This function creates a
116*b1cdbd2cSJim Jagielski         complete 'BMP file' that can be read by the OOo graphic provider used
117*b1cdbd2cSJim Jagielski         to import graphic objects. For that, the BITMAPFILEHEADER has to be
118*b1cdbd2cSJim Jagielski         inserted before the DIB data, and it has to contain the correct offset
119*b1cdbd2cSJim Jagielski         to the pixel data. Currently, in real life there are only 24-bit and
120*b1cdbd2cSJim Jagielski         32-bit DIBs (without color palette) in use. This code relies on this
121*b1cdbd2cSJim Jagielski         fact and calculates the offset to the pixel data according to the size
122*b1cdbd2cSJim Jagielski         of the DIB header.
123*b1cdbd2cSJim Jagielski         Remaining tasks are (if really used somewhere):
124*b1cdbd2cSJim Jagielski         - Support of DIBs with color palette,
125*b1cdbd2cSJim Jagielski         - Support of 'Windows V4' and 'Windows V5' DIB header. */
126*b1cdbd2cSJim Jagielski 
127*b1cdbd2cSJim Jagielski     // read and check validity of DIB header
128*b1cdbd2cSJim Jagielski     sal_Int64 nInStrmPos = rStrm.tell();
129*b1cdbd2cSJim Jagielski     sal_Int32 nDibHdrSize = rStrm.readInt32();
130*b1cdbd2cSJim Jagielski     sal_uInt16 nPlanes = 0, nDepth = 0;
131*b1cdbd2cSJim Jagielski     switch( nDibHdrSize )
132*b1cdbd2cSJim Jagielski     {
133*b1cdbd2cSJim Jagielski         case BITMAPCOREHEADER_SIZE:
134*b1cdbd2cSJim Jagielski             rStrm.skip( 4 );    // width/height as 16-bit integer
135*b1cdbd2cSJim Jagielski             rStrm >> nPlanes >> nDepth;
136*b1cdbd2cSJim Jagielski         break;
137*b1cdbd2cSJim Jagielski         case BITMAPINFOHEADER_SIZE:
138*b1cdbd2cSJim Jagielski             rStrm.skip( 8 );    // width/height as 32-bit integer
139*b1cdbd2cSJim Jagielski             rStrm >> nPlanes >> nDepth;
140*b1cdbd2cSJim Jagielski         break;
141*b1cdbd2cSJim Jagielski     }
142*b1cdbd2cSJim Jagielski     rStrm.seek( nInStrmPos );
143*b1cdbd2cSJim Jagielski 
144*b1cdbd2cSJim Jagielski     if( (nPlanes == 1) && ((nDepth == 24) || (nDepth == 32)) )
145*b1cdbd2cSJim Jagielski     {
146*b1cdbd2cSJim Jagielski         // allocate enough space for the BITMAPFILEHEADER and the DIB data
147*b1cdbd2cSJim Jagielski         orDataSeq.realloc( BITMAPFILEHEADER_SIZE + nBytes );
148*b1cdbd2cSJim Jagielski         SequenceOutputStream aOutStrm( orDataSeq );
149*b1cdbd2cSJim Jagielski 
150*b1cdbd2cSJim Jagielski         // write the BITMAPFILEHEADER of a regular BMP file
151*b1cdbd2cSJim Jagielski         sal_Int32 nBmpSize = BITMAPFILEHEADER_SIZE + nBytes;
152*b1cdbd2cSJim Jagielski         sal_Int32 nOffset = BITMAPFILEHEADER_SIZE + nDibHdrSize;
153*b1cdbd2cSJim Jagielski         aOutStrm << sal_uInt16( 0x4D42 ) << nBmpSize << sal_Int32( 0 ) << nOffset;
154*b1cdbd2cSJim Jagielski 
155*b1cdbd2cSJim Jagielski         // copy the DIB header
156*b1cdbd2cSJim Jagielski         rStrm.copyToStream( aOutStrm, nDibHdrSize );
157*b1cdbd2cSJim Jagielski         nBytes -= nDibHdrSize;
158*b1cdbd2cSJim Jagielski 
159*b1cdbd2cSJim Jagielski         /*  Excel 3.x and Excel 4.x seem to write broken or out-dated DIB data.
160*b1cdbd2cSJim Jagielski             Usually they write a BITMAPCOREHEADER containing width, height,
161*b1cdbd2cSJim Jagielski             planes as usual. The pixel depth field is set to 32 bit (though
162*b1cdbd2cSJim Jagielski             this is not allowed according to documentation). Between that
163*b1cdbd2cSJim Jagielski             header and the actual pixel data, 3 unused bytes are inserted. This
164*b1cdbd2cSJim Jagielski             does even confuse Excel 5.x and later, which cannot read the image
165*b1cdbd2cSJim Jagielski             data correctly. */
166*b1cdbd2cSJim Jagielski         if( (eBiff <= BIFF4) && (nDibHdrSize == BITMAPCOREHEADER_SIZE) && (nDepth == 32) )
167*b1cdbd2cSJim Jagielski         {
168*b1cdbd2cSJim Jagielski             // skip the dummy bytes in input stream
169*b1cdbd2cSJim Jagielski             rStrm.skip( 3 );
170*b1cdbd2cSJim Jagielski             nBytes -= 3;
171*b1cdbd2cSJim Jagielski             // correct the total BMP file size in output stream
172*b1cdbd2cSJim Jagielski             sal_Int64 nOutStrmPos = aOutStrm.tell();
173*b1cdbd2cSJim Jagielski             aOutStrm.seek( 2 );
174*b1cdbd2cSJim Jagielski             aOutStrm << sal_Int32( nBmpSize - 3 );
175*b1cdbd2cSJim Jagielski             aOutStrm.seek( nOutStrmPos );
176*b1cdbd2cSJim Jagielski         }
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski         // copy remaining pixel data to output stream
179*b1cdbd2cSJim Jagielski         rStrm.copyToStream( aOutStrm, nBytes );
180*b1cdbd2cSJim Jagielski     }
181*b1cdbd2cSJim Jagielski     rStrm.seek( nInStrmPos + nBytes );
182*b1cdbd2cSJim Jagielski }
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski } // namespace
185*b1cdbd2cSJim Jagielski 
186*b1cdbd2cSJim Jagielski // ============================================================================
187*b1cdbd2cSJim Jagielski 
188*b1cdbd2cSJim Jagielski // conversion -----------------------------------------------------------------
189*b1cdbd2cSJim Jagielski 
calcDoubleFromRk(sal_Int32 nRkValue)190*b1cdbd2cSJim Jagielski /*static*/ double BiffHelper::calcDoubleFromRk( sal_Int32 nRkValue )
191*b1cdbd2cSJim Jagielski {
192*b1cdbd2cSJim Jagielski     DecodedDouble aDecDbl( 0.0 );
193*b1cdbd2cSJim Jagielski     if( getFlag( nRkValue, BIFF_RK_INTFLAG ) )
194*b1cdbd2cSJim Jagielski     {
195*b1cdbd2cSJim Jagielski         sal_Int32 nTemp = nRkValue >> 2;
196*b1cdbd2cSJim Jagielski         setFlag< sal_Int32 >( nTemp, 0xE0000000, nRkValue < 0 );
197*b1cdbd2cSJim Jagielski         aDecDbl.mfValue = nTemp;
198*b1cdbd2cSJim Jagielski     }
199*b1cdbd2cSJim Jagielski     else
200*b1cdbd2cSJim Jagielski     {
201*b1cdbd2cSJim Jagielski         aDecDbl.maStruct.w32_parts.msw = static_cast< sal_uInt32 >( nRkValue & BIFF_RK_VALUEMASK );
202*b1cdbd2cSJim Jagielski     }
203*b1cdbd2cSJim Jagielski 
204*b1cdbd2cSJim Jagielski     if( getFlag( nRkValue, BIFF_RK_100FLAG ) )
205*b1cdbd2cSJim Jagielski         aDecDbl.mfValue /= 100.0;
206*b1cdbd2cSJim Jagielski 
207*b1cdbd2cSJim Jagielski     return aDecDbl.mfValue;
208*b1cdbd2cSJim Jagielski }
209*b1cdbd2cSJim Jagielski 
calcRkFromDouble(sal_Int32 & ornRkValue,double fValue)210*b1cdbd2cSJim Jagielski /*static*/ bool BiffHelper::calcRkFromDouble( sal_Int32& ornRkValue, double fValue )
211*b1cdbd2cSJim Jagielski {
212*b1cdbd2cSJim Jagielski     if( lclCalcRkFromDouble( ornRkValue, fValue ) )
213*b1cdbd2cSJim Jagielski         return true;
214*b1cdbd2cSJim Jagielski 
215*b1cdbd2cSJim Jagielski     if( lclCalcRkFromDouble( ornRkValue, fValue * 100 ) )
216*b1cdbd2cSJim Jagielski     {
217*b1cdbd2cSJim Jagielski         ornRkValue |= BIFF_RK_100FLAG;
218*b1cdbd2cSJim Jagielski         return true;
219*b1cdbd2cSJim Jagielski     }
220*b1cdbd2cSJim Jagielski 
221*b1cdbd2cSJim Jagielski     return false;
222*b1cdbd2cSJim Jagielski }
223*b1cdbd2cSJim Jagielski 
calcDoubleFromError(sal_uInt8 nErrorCode)224*b1cdbd2cSJim Jagielski /*static*/ double BiffHelper::calcDoubleFromError( sal_uInt8 nErrorCode )
225*b1cdbd2cSJim Jagielski {
226*b1cdbd2cSJim Jagielski     sal_uInt16 nApiError = 0x7FFF;
227*b1cdbd2cSJim Jagielski     switch( nErrorCode )
228*b1cdbd2cSJim Jagielski     {
229*b1cdbd2cSJim Jagielski         case BIFF_ERR_NULL:     nApiError = 521;    break;
230*b1cdbd2cSJim Jagielski         case BIFF_ERR_DIV0:     nApiError = 532;    break;
231*b1cdbd2cSJim Jagielski         case BIFF_ERR_VALUE:    nApiError = 519;    break;
232*b1cdbd2cSJim Jagielski         case BIFF_ERR_REF:      nApiError = 524;    break;
233*b1cdbd2cSJim Jagielski         case BIFF_ERR_NAME:     nApiError = 525;    break;
234*b1cdbd2cSJim Jagielski         case BIFF_ERR_NUM:      nApiError = 503;    break;
235*b1cdbd2cSJim Jagielski         case BIFF_ERR_NA:       nApiError = 0x7FFF; break;
236*b1cdbd2cSJim Jagielski         default:    OSL_ENSURE( false, "BiffHelper::calcDoubleFromError - unknown error code" );
237*b1cdbd2cSJim Jagielski     }
238*b1cdbd2cSJim Jagielski     DecodedDouble aDecDbl;
239*b1cdbd2cSJim Jagielski     ::rtl::math::setNan( &aDecDbl.mfValue );
240*b1cdbd2cSJim Jagielski     aDecDbl.maStruct.nan_parts.fraction_lo = nApiError;
241*b1cdbd2cSJim Jagielski     return aDecDbl.mfValue;
242*b1cdbd2cSJim Jagielski }
243*b1cdbd2cSJim Jagielski 
calcTextEncodingFromCodePage(sal_uInt16 nCodePage)244*b1cdbd2cSJim Jagielski /*static*/ rtl_TextEncoding BiffHelper::calcTextEncodingFromCodePage( sal_uInt16 nCodePage )
245*b1cdbd2cSJim Jagielski {
246*b1cdbd2cSJim Jagielski     // some specials for BIFF
247*b1cdbd2cSJim Jagielski     switch( nCodePage )
248*b1cdbd2cSJim Jagielski     {
249*b1cdbd2cSJim Jagielski         case 1200:  return RTL_TEXTENCODING_DONTKNOW;       // BIFF8 Unicode
250*b1cdbd2cSJim Jagielski         case 32768: return RTL_TEXTENCODING_APPLE_ROMAN;
251*b1cdbd2cSJim Jagielski         case 32769: return RTL_TEXTENCODING_MS_1252;        // BIFF2-BIFF3
252*b1cdbd2cSJim Jagielski     }
253*b1cdbd2cSJim Jagielski 
254*b1cdbd2cSJim Jagielski     rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
255*b1cdbd2cSJim Jagielski     OSL_ENSURE( eTextEnc != RTL_TEXTENCODING_DONTKNOW, "BiffHelper::calcTextEncodingFromCodePage - unknown code page" );
256*b1cdbd2cSJim Jagielski     return eTextEnc;
257*b1cdbd2cSJim Jagielski }
258*b1cdbd2cSJim Jagielski 
calcCodePageFromTextEncoding(rtl_TextEncoding eTextEnc)259*b1cdbd2cSJim Jagielski /*static*/ sal_uInt16 BiffHelper::calcCodePageFromTextEncoding( rtl_TextEncoding eTextEnc )
260*b1cdbd2cSJim Jagielski {
261*b1cdbd2cSJim Jagielski     sal_uInt32 nCodePage = rtl_getWindowsCodePageFromTextEncoding( eTextEnc );
262*b1cdbd2cSJim Jagielski     OSL_ENSURE( (0 < nCodePage) && (nCodePage <= SAL_MAX_UINT16), "BiffHelper::calcCodePageFromTextEncoding - unknown text encoding" );
263*b1cdbd2cSJim Jagielski     return static_cast< sal_uInt16 >( (nCodePage == 0) ? 1252 : nCodePage );
264*b1cdbd2cSJim Jagielski }
265*b1cdbd2cSJim Jagielski 
266*b1cdbd2cSJim Jagielski // BIFF12 import --------------------------------------------------------------
267*b1cdbd2cSJim Jagielski 
readString(SequenceInputStream & rStrm,bool b32BitLen,bool bAllowNulChars)268*b1cdbd2cSJim Jagielski /*static*/ OUString BiffHelper::readString( SequenceInputStream& rStrm, bool b32BitLen, bool bAllowNulChars )
269*b1cdbd2cSJim Jagielski {
270*b1cdbd2cSJim Jagielski     OUString aString;
271*b1cdbd2cSJim Jagielski     if( !rStrm.isEof() )
272*b1cdbd2cSJim Jagielski     {
273*b1cdbd2cSJim Jagielski         sal_Int32 nCharCount = b32BitLen ? rStrm.readValue< sal_Int32 >() : rStrm.readValue< sal_Int16 >();
274*b1cdbd2cSJim Jagielski         // string length -1 is often used to indicate a missing string
275*b1cdbd2cSJim Jagielski         OSL_ENSURE( !rStrm.isEof() && (nCharCount >= -1), "BiffHelper::readString - invalid string length" );
276*b1cdbd2cSJim Jagielski         if( !rStrm.isEof() && (nCharCount > 0) )
277*b1cdbd2cSJim Jagielski         {
278*b1cdbd2cSJim Jagielski             // SequenceInputStream always supports getRemaining()
279*b1cdbd2cSJim Jagielski             nCharCount = ::std::min( nCharCount, static_cast< sal_Int32 >( rStrm.getRemaining() / 2 ) );
280*b1cdbd2cSJim Jagielski             aString = rStrm.readUnicodeArray( nCharCount, bAllowNulChars );
281*b1cdbd2cSJim Jagielski         }
282*b1cdbd2cSJim Jagielski     }
283*b1cdbd2cSJim Jagielski     return aString;
284*b1cdbd2cSJim Jagielski }
285*b1cdbd2cSJim Jagielski 
286*b1cdbd2cSJim Jagielski // BIFF2-BIFF8 import ---------------------------------------------------------
287*b1cdbd2cSJim Jagielski 
isBofRecord(BiffInputStream & rStrm)288*b1cdbd2cSJim Jagielski /*static*/ bool BiffHelper::isBofRecord( BiffInputStream& rStrm )
289*b1cdbd2cSJim Jagielski {
290*b1cdbd2cSJim Jagielski     return
291*b1cdbd2cSJim Jagielski         (rStrm.getRecId() == BIFF2_ID_BOF) ||
292*b1cdbd2cSJim Jagielski         (rStrm.getRecId() == BIFF3_ID_BOF) ||
293*b1cdbd2cSJim Jagielski         (rStrm.getRecId() == BIFF4_ID_BOF) ||
294*b1cdbd2cSJim Jagielski         (rStrm.getRecId() == BIFF5_ID_BOF);
295*b1cdbd2cSJim Jagielski }
296*b1cdbd2cSJim Jagielski 
skipRecordBlock(BiffInputStream & rStrm,sal_uInt16 nEndRecId)297*b1cdbd2cSJim Jagielski /*static*/ bool BiffHelper::skipRecordBlock( BiffInputStream& rStrm, sal_uInt16 nEndRecId )
298*b1cdbd2cSJim Jagielski {
299*b1cdbd2cSJim Jagielski     sal_uInt16 nStartRecId = rStrm.getRecId();
300*b1cdbd2cSJim Jagielski     while( rStrm.startNextRecord() && (rStrm.getRecId() != nEndRecId) )
301*b1cdbd2cSJim Jagielski         if( rStrm.getRecId() == nStartRecId )
302*b1cdbd2cSJim Jagielski             skipRecordBlock( rStrm, nEndRecId );
303*b1cdbd2cSJim Jagielski     return !rStrm.isEof() && (rStrm.getRecId() == nEndRecId);
304*b1cdbd2cSJim Jagielski }
305*b1cdbd2cSJim Jagielski 
importImgData(StreamDataSequence & orDataSeq,BiffInputStream & rStrm,BiffType eBiff)306*b1cdbd2cSJim Jagielski /*static*/ void BiffHelper::importImgData( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, BiffType eBiff )
307*b1cdbd2cSJim Jagielski {
308*b1cdbd2cSJim Jagielski     sal_uInt16 nFormat, nEnv;
309*b1cdbd2cSJim Jagielski     sal_Int32 nBytes;
310*b1cdbd2cSJim Jagielski     rStrm >> nFormat >> nEnv >> nBytes;
311*b1cdbd2cSJim Jagielski     OSL_ENSURE( nBytes > 0, "BiffHelper::importImgData - invalid data size" );
312*b1cdbd2cSJim Jagielski     if( (0 < nBytes) && (nBytes <= rStrm.getRemaining()) )
313*b1cdbd2cSJim Jagielski     {
314*b1cdbd2cSJim Jagielski         switch( nFormat )
315*b1cdbd2cSJim Jagielski         {
316*b1cdbd2cSJim Jagielski //            case BIFF_IMGDATA_WMF:      /* TODO */                                              break;
317*b1cdbd2cSJim Jagielski             case BIFF_IMGDATA_DIB:      lclImportImgDataDib( orDataSeq, rStrm, nBytes, eBiff ); break;
318*b1cdbd2cSJim Jagielski //            case BIFF_IMGDATA_NATIVE:   /* TODO */                                              break;
319*b1cdbd2cSJim Jagielski             default:                    OSL_ENSURE( false, "BiffHelper::importImgData - unknown image format" );
320*b1cdbd2cSJim Jagielski         }
321*b1cdbd2cSJim Jagielski     }
322*b1cdbd2cSJim Jagielski }
323*b1cdbd2cSJim Jagielski 
324*b1cdbd2cSJim Jagielski // ============================================================================
325*b1cdbd2cSJim Jagielski 
326*b1cdbd2cSJim Jagielski } // namespace xls
327*b1cdbd2cSJim Jagielski } // namespace oox
328