1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <xistring.hxx>
21 #include <xlstyle.hxx>
22 #include <xistream.hxx>
24 #include <xltools.hxx>
25 #include <sal/log.hxx>
27 // Byte/Unicode strings =======================================================
29 /** All allowed flags for import. */
30 const XclStrFlags nAllowedFlags
= XclStrFlags::EightBitLength
| XclStrFlags::SmartFlags
| XclStrFlags::SeparateFormats
;
32 XclImpString::XclImpString()
36 XclImpString::XclImpString( const OUString
& rString
) :
41 void XclImpString::Read( XclImpStream
& rStrm
, XclStrFlags nFlags
)
43 if( !( nFlags
& XclStrFlags::SeparateFormats
) )
47 nFlags
& ~nAllowedFlags
, "sc.filter",
48 "XclImpString::Read - unknown flag");
49 bool b16BitLen
= !( nFlags
& XclStrFlags::EightBitLength
);
51 switch( rStrm
.GetRoot().GetBiff() )
57 // no integrated formatting in BIFF2-BIFF7
58 maString
= rStrm
.ReadByteString( b16BitLen
);
63 // --- string header ---
64 sal_uInt16 nChars
= b16BitLen
? rStrm
.ReaduInt16() : rStrm
.ReaduInt8();
65 sal_uInt8 nFlagField
= 0;
66 if( nChars
|| !( nFlags
& XclStrFlags::SmartFlags
) )
67 nFlagField
= rStrm
.ReaduInt8();
69 bool b16Bit
, bRich
, bFarEast
;
72 rStrm
.ReadUniStringExtHeader( b16Bit
, bRich
, bFarEast
, nRunCount
, nExtInf
, nFlagField
);
73 // ignore the flags, they may be wrong
75 // --- character array ---
76 maString
= rStrm
.ReadRawUniString( nChars
, b16Bit
);
80 ReadFormats( rStrm
, maFormats
, nRunCount
);
82 // --- extended (FarEast) information ---
83 rStrm
.Ignore( nExtInf
);
92 void XclImpString::AppendFormat( XclFormatRunVec
& rFormats
, sal_uInt16 nChar
, sal_uInt16 nFontIdx
)
94 // #i33341# real life -- same character index may occur several times
95 OSL_ENSURE( rFormats
.empty() || (rFormats
.back().mnChar
<= nChar
), "XclImpString::AppendFormat - wrong char order" );
96 if( rFormats
.empty() || (rFormats
.back().mnChar
< nChar
) )
97 rFormats
.emplace_back( nChar
, nFontIdx
);
99 rFormats
.back().mnFontIdx
= nFontIdx
;
102 void XclImpString::ReadFormats( XclImpStream
& rStrm
, XclFormatRunVec
& rFormats
)
104 bool bBiff8
= rStrm
.GetRoot().GetBiff() == EXC_BIFF8
;
105 sal_uInt16 nRunCount
= bBiff8
? rStrm
.ReaduInt16() : rStrm
.ReaduInt8();
106 ReadFormats( rStrm
, rFormats
, nRunCount
);
109 void XclImpString::ReadFormats( XclImpStream
& rStrm
, XclFormatRunVec
& rFormats
, sal_uInt16 nRunCount
)
113 size_t nElementSize
= rStrm
.GetRoot().GetBiff() == EXC_BIFF8
? 4 : 2;
114 size_t nAvailableBytes
= rStrm
.GetRecLeft();
115 size_t nMaxElements
= nAvailableBytes
/ nElementSize
;
116 if (nRunCount
> nMaxElements
)
118 SAL_WARN("sc.filter", "XclImpString::ReadFormats - more formats claimed than stream could contain");
119 rStrm
.SetSvStreamError(SVSTREAM_FILEFORMAT_ERROR
);
123 rFormats
.reserve( nRunCount
);
124 /* #i33341# real life -- same character index may occur several times
125 -> use AppendFormat() to validate formats */
126 if( rStrm
.GetRoot().GetBiff() == EXC_BIFF8
)
128 for( sal_uInt16 nIdx
= 0; nIdx
< nRunCount
; ++nIdx
)
130 sal_uInt16 nChar
= rStrm
.ReaduInt16();
131 sal_uInt16 nFontIdx
= rStrm
.ReaduInt16();
132 AppendFormat( rFormats
, nChar
, nFontIdx
);
137 for( sal_uInt16 nIdx
= 0; nIdx
< nRunCount
; ++nIdx
)
139 sal_uInt8 nChar
= rStrm
.ReaduInt8();
140 sal_uInt8 nFontIdx
= rStrm
.ReaduInt8();
141 AppendFormat( rFormats
, nChar
, nFontIdx
);
146 void XclImpString::ReadObjFormats( XclImpStream
& rStrm
, XclFormatRunVec
& rFormats
, sal_uInt16 nFormatSize
)
148 // number of formatting runs, each takes 8 bytes
149 sal_uInt16 nRunCount
= nFormatSize
/ 8;
151 rFormats
.reserve( nRunCount
);
152 for( sal_uInt16 nIdx
= 0; nIdx
< nRunCount
; ++nIdx
)
154 sal_uInt16 nChar
= rStrm
.ReaduInt16();
155 sal_uInt16 nFontIdx
= rStrm
.ReaduInt16();
157 AppendFormat( rFormats
, nChar
, nFontIdx
);
161 // String iterator ============================================================
163 XclImpStringIterator::XclImpStringIterator( const XclImpString
& rString
) :
164 mrText( rString
.GetText() ),
165 mrFormats( rString
.GetFormats() ),
172 // first portion is formatted, adjust vector index to next portion
173 if( !mrFormats
.empty() && (mrFormats
.front().mnChar
== 0) )
175 // find end position of the first portion
176 mnTextEnd
= (mnFormatsEnd
< mrFormats
.size() ?
177 mrFormats
[ mnFormatsEnd
].mnChar
: mrText
.getLength() );
180 OUString
XclImpStringIterator::GetPortionText() const
182 return mrText
.copy( mnTextBeg
, mnTextEnd
- mnTextBeg
);
185 sal_uInt16
XclImpStringIterator::GetPortionFont() const
187 return (mnFormatsBeg
< mnFormatsEnd
) ? mrFormats
[ mnFormatsBeg
].mnFontIdx
: EXC_FONT_NOTFOUND
;
190 XclImpStringIterator
& XclImpStringIterator::operator++()
197 // indexes into vector of formatting runs
198 if( mnFormatsBeg
< mnFormatsEnd
)
200 if( mnFormatsEnd
< mrFormats
.size() )
202 // character positions of next portion
203 mnTextBeg
= mnTextEnd
;
204 mnTextEnd
= (mnFormatsEnd
< mrFormats
.size()) ?
205 mrFormats
[ mnFormatsEnd
].mnChar
: mrText
.getLength();
207 while( Is() && (mnTextBeg
== mnTextEnd
) );
212 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */