update dev300-m58
[ooovba.git] / sc / source / filter / excel / xistring.cxx
blobd6e0b3182d417824098221d179cfc6ca762010ba
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xistring.cxx,v $
10 * $Revision: 1.5.90.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "precompiled_sc.hxx"
32 #include "xistring.hxx"
33 #include "xlstyle.hxx"
34 #include "xistream.hxx"
35 #include "xiroot.hxx"
37 // Byte/Unicode strings =======================================================
39 /** All allowed flags for import. */
40 const XclStrFlags nAllowedFlags = EXC_STR_8BITLENGTH | EXC_STR_SMARTFLAGS | EXC_STR_SEPARATEFORMATS;
42 // ----------------------------------------------------------------------------
44 XclImpString::XclImpString()
48 XclImpString::XclImpString( const String& rString ) :
49 maString( rString )
53 XclImpString::~XclImpString()
57 void XclImpString::Read( XclImpStream& rStrm, XclStrFlags nFlags )
59 if( !::get_flag( nFlags, EXC_STR_SEPARATEFORMATS ) )
60 maFormats.clear();
62 DBG_ASSERT( (nFlags & ~nAllowedFlags) == 0, "XclImpString::Read - unknown flag" );
63 bool b16BitLen = !::get_flag( nFlags, EXC_STR_8BITLENGTH );
65 switch( rStrm.GetRoot().GetBiff() )
67 case EXC_BIFF2:
68 case EXC_BIFF3:
69 case EXC_BIFF4:
70 case EXC_BIFF5:
71 // no integrated formatting in BIFF2-BIFF7
72 maString = rStrm.ReadByteString( b16BitLen );
73 break;
75 case EXC_BIFF8:
77 // --- string header ---
78 sal_uInt16 nChars = b16BitLen ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
79 sal_uInt8 nFlagField = 0;
80 if( nChars || !::get_flag( nFlags, EXC_STR_SMARTFLAGS ) )
81 rStrm >> nFlagField;
83 bool b16Bit, bRich, bFarEast;
84 sal_uInt16 nRunCount;
85 sal_uInt32 nExtInf;
86 rStrm.ReadUniStringExtHeader( b16Bit, bRich, bFarEast, nRunCount, nExtInf, nFlagField );
87 // #122185# ignore the flags, they may be wrong
89 // --- character array ---
90 maString = rStrm.ReadRawUniString( nChars, b16Bit );
92 // --- formatting ---
93 if( nRunCount > 0 )
94 ReadFormats( rStrm, nRunCount );
96 // --- extended (FarEast) information ---
97 rStrm.Ignore( nExtInf );
99 break;
101 default:
102 DBG_ERROR_BIFF();
106 void XclImpString::AppendFormat( XclFormatRunVec& rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx )
108 // #i33341# real life -- same character index may occur several times
109 DBG_ASSERT( rFormats.empty() || (rFormats.back().mnChar <= nChar), "XclImpString::AppendFormat - wrong char order" );
110 if( rFormats.empty() || (rFormats.back().mnChar < nChar) )
111 rFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
112 else
113 rFormats.back().mnFontIdx = nFontIdx;
116 void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats )
118 bool bBiff8 = rStrm.GetRoot().GetBiff() == EXC_BIFF8;
119 sal_uInt16 nRunCount = bBiff8 ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
120 ReadFormats( rStrm, rFormats, nRunCount );
123 void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nRunCount )
125 rFormats.clear();
126 rFormats.reserve( nRunCount );
127 /* #i33341# real life -- same character index may occur several times
128 -> use AppendFormat() to validate formats */
129 if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
131 for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
133 sal_uInt16 nChar, nFontIdx;
134 rStrm >> nChar >> nFontIdx;
135 AppendFormat( rFormats, nChar, nFontIdx );
138 else
140 for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
142 sal_uInt8 nChar, nFontIdx;
143 rStrm >> nChar >> nFontIdx;
144 AppendFormat( rFormats, nChar, nFontIdx );
149 void XclImpString::ReadObjFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nFormatSize )
151 // number of formatting runs, each takes 8 bytes
152 sal_uInt16 nRunCount = nFormatSize / 8;
153 rFormats.clear();
154 rFormats.reserve( nRunCount );
155 for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
157 sal_uInt16 nChar, nFontIdx;
158 rStrm >> nChar >> nFontIdx;
159 rStrm.Ignore( 4 );
160 AppendFormat( rFormats, nChar, nFontIdx );
164 // String iterator ============================================================
166 XclImpStringIterator::XclImpStringIterator( const XclImpString& rString ) :
167 mrText( rString.GetText() ),
168 mrFormats( rString.GetFormats() ),
169 mnPortion( 0 ),
170 mnTextBeg( 0 ),
171 mnTextEnd( 0 ),
172 mnFormatsBeg( 0 ),
173 mnFormatsEnd( 0 )
175 // first portion is formatted, adjust vector index to next portion
176 if( !mrFormats.empty() && (mrFormats.front().mnChar == 0) )
177 ++mnFormatsEnd;
178 // find end position of the first portion
179 mnTextEnd = static_cast< xub_StrLen >( (mnFormatsEnd < mrFormats.size()) ?
180 mrFormats[ mnFormatsEnd ].mnChar : mrText.Len() );
183 String XclImpStringIterator::GetPortionText() const
185 return String( mrText, mnTextBeg, mnTextEnd - mnTextBeg );
188 sal_uInt16 XclImpStringIterator::GetPortionFont() const
190 return (mnFormatsBeg < mnFormatsEnd) ? mrFormats[ mnFormatsBeg ].mnFontIdx : EXC_FONT_NOTFOUND;
193 XclImpStringIterator& XclImpStringIterator::operator++()
195 if( Is() )
197 ++mnPortion;
200 // indexes into vector of formatting runs
201 if( mnFormatsBeg < mnFormatsEnd )
202 ++mnFormatsBeg;
203 if( mnFormatsEnd < mrFormats.size() )
204 ++mnFormatsEnd;
205 // character positions of next portion
206 mnTextBeg = mnTextEnd;
207 mnTextEnd = static_cast< xub_StrLen >( (mnFormatsEnd < mrFormats.size()) ?
208 mrFormats[ mnFormatsEnd ].mnChar : mrText.Len() );
210 while( Is() && (mnTextBeg == mnTextEnd) );
212 return *this;
215 // ============================================================================