LibreOffice Module sc (master) 1
xistring.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <utility>
21#include <xistring.hxx>
22#include <xlstyle.hxx>
23#include <xistream.hxx>
24#include <xiroot.hxx>
25#include <xltools.hxx>
26#include <sal/log.hxx>
27
28// Byte/Unicode strings =======================================================
29
32
34{
35}
36
37XclImpString::XclImpString( OUString aString ) :
38 maString(std::move( aString ))
39{
40}
41
43{
44 if( !( nFlags & XclStrFlags::SeparateFormats ) )
45 maFormats.clear();
46
48 nFlags & ~nAllowedFlags, "sc.filter",
49 "XclImpString::Read - unknown flag");
50 bool b16BitLen = !( nFlags & XclStrFlags::EightBitLength );
51
52 switch( rStrm.GetRoot().GetBiff() )
53 {
54 case EXC_BIFF2:
55 case EXC_BIFF3:
56 case EXC_BIFF4:
57 case EXC_BIFF5:
58 // no integrated formatting in BIFF2-BIFF7
59 maString = rStrm.ReadByteString( b16BitLen );
60 break;
61
62 case EXC_BIFF8:
63 {
64 // --- string header ---
65 sal_uInt16 nChars = b16BitLen ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
66 sal_uInt8 nFlagField = 0;
67 if( nChars || !( nFlags & XclStrFlags::SmartFlags ) )
68 nFlagField = rStrm.ReaduInt8();
69
70 bool b16Bit, bRich, bFarEast;
71 sal_uInt16 nRunCount;
72 sal_uInt32 nExtInf;
73 rStrm.ReadUniStringExtHeader( b16Bit, bRich, bFarEast, nRunCount, nExtInf, nFlagField );
74 // ignore the flags, they may be wrong
75
76 // --- character array ---
77 maString = rStrm.ReadRawUniString( nChars, b16Bit );
78
79 // --- formatting ---
80 if (nRunCount)
81 ReadFormats( rStrm, maFormats, nRunCount );
82
83 // --- extended (FarEast) information ---
84 rStrm.Ignore( nExtInf );
85 }
86 break;
87
88 default:
90 }
91}
92
93void XclImpString::AppendFormat( XclFormatRunVec& rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx )
94{
95 // #i33341# real life -- same character index may occur several times
96 OSL_ENSURE( rFormats.empty() || (rFormats.back().mnChar <= nChar), "XclImpString::AppendFormat - wrong char order" );
97 if( rFormats.empty() || (rFormats.back().mnChar < nChar) )
98 rFormats.emplace_back( nChar, nFontIdx );
99 else
100 rFormats.back().mnFontIdx = nFontIdx;
101}
102
104{
105 bool bBiff8 = rStrm.GetRoot().GetBiff() == EXC_BIFF8;
106 sal_uInt16 nRunCount = bBiff8 ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
107 ReadFormats( rStrm, rFormats, nRunCount );
108}
109
110void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nRunCount )
111{
112 rFormats.clear();
113
114 size_t nElementSize = rStrm.GetRoot().GetBiff() == EXC_BIFF8 ? 4 : 2;
115 size_t nAvailableBytes = rStrm.GetRecLeft();
116 size_t nMaxElements = nAvailableBytes / nElementSize;
117 if (nRunCount > nMaxElements)
118 {
119 SAL_WARN("sc.filter", "XclImpString::ReadFormats - more formats claimed than stream could contain");
120 rStrm.SetSvStreamError(SVSTREAM_FILEFORMAT_ERROR);
121 return;
122 }
123
124 rFormats.reserve( nRunCount );
125 /* #i33341# real life -- same character index may occur several times
126 -> use AppendFormat() to validate formats */
127 if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
128 {
129 for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
130 {
131 sal_uInt16 nChar = rStrm.ReaduInt16();
132 sal_uInt16 nFontIdx = rStrm.ReaduInt16();
133 AppendFormat( rFormats, nChar, nFontIdx );
134 }
135 }
136 else
137 {
138 for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
139 {
140 sal_uInt8 nChar = rStrm.ReaduInt8();
141 sal_uInt8 nFontIdx = rStrm.ReaduInt8();
142 AppendFormat( rFormats, nChar, nFontIdx );
143 }
144 }
145}
146
147void XclImpString::ReadObjFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nFormatSize )
148{
149 // number of formatting runs, each takes 8 bytes
150 sal_uInt16 nRunCount = nFormatSize / 8;
151 rFormats.clear();
152 rFormats.reserve( nRunCount );
153 for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
154 {
155 sal_uInt16 nChar = rStrm.ReaduInt16();
156 sal_uInt16 nFontIdx = rStrm.ReaduInt16();
157 rStrm.Ignore( 4 );
158 AppendFormat( rFormats, nChar, nFontIdx );
159 }
160}
161
162// String iterator ============================================================
163
165 mrText( rString.GetText() ),
166 mrFormats( rString.GetFormats() ),
167 mnPortion( 0 ),
168 mnTextBeg( 0 ),
169 mnTextEnd( 0 ),
170 mnFormatsBeg( 0 ),
171 mnFormatsEnd( 0 )
172{
173 // first portion is formatted, adjust vector index to next portion
174 if( !mrFormats.empty() && (mrFormats.front().mnChar == 0) )
175 ++mnFormatsEnd;
176 // find end position of the first portion
177 mnTextEnd = (mnFormatsEnd < mrFormats.size() ?
178 mrFormats[ mnFormatsEnd ].mnChar : mrText.getLength() );
179}
180
182{
183 return mrText.copy( mnTextBeg, mnTextEnd - mnTextBeg );
184}
185
187{
189}
190
192{
193 if( Is() )
194 {
195 ++mnPortion;
196 do
197 {
198 // indexes into vector of formatting runs
200 ++mnFormatsBeg;
201 if( mnFormatsEnd < mrFormats.size() )
202 ++mnFormatsEnd;
203 // character positions of next portion
205 mnTextEnd = (mnFormatsEnd < mrFormats.size()) ?
206 mrFormats[ mnFormatsEnd ].mnChar : mrText.getLength();
207 }
208 while( Is() && (mnTextBeg == mnTextEnd) );
209 }
210 return *this;
211}
212
213/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
This class is used to import record oriented streams.
Definition: xistream.hxx:278
Iterates over formatted string portions.
Definition: xistring.hxx:78
XclImpStringIterator & operator++()
Moves iterator to next text portion.
Definition: xistring.cxx:191
XclImpStringIterator(const XclImpString &rString)
Definition: xistring.cxx:164
size_t mnFormatsBeg
First character of next portion.
Definition: xistring.hxx:100
sal_Int32 mnTextBeg
Current text portion.
Definition: xistring.hxx:98
sal_uInt16 GetPortionFont() const
Returns the font index of the current text portion.
Definition: xistring.cxx:186
const XclFormatRunVec & mrFormats
The processed string.
Definition: xistring.hxx:96
size_t mnFormatsEnd
Formatting run index for current portion.
Definition: xistring.hxx:101
size_t mnPortion
The vector of formatting runs.
Definition: xistring.hxx:97
OUString GetPortionText() const
Returns the string of the current text portion.
Definition: xistring.cxx:181
sal_Int32 mnTextEnd
First character of current portion.
Definition: xistring.hxx:99
bool Is() const
Returns true, if the iterator references a valid text portion.
Definition: xistring.hxx:83
const OUString & mrText
Definition: xistring.hxx:95
This class represents an unformatted or formatted string and provides importing from stream.
Definition: xistring.hxx:31
void ReadObjFormats(XclImpStream &rStrm, sal_uInt16 nFormatSize)
Reads and appends formatting runs from an OBJ or TXO record.
Definition: xistring.hxx:48
XclFormatRunVec maFormats
The text data of the string.
Definition: xistring.hxx:71
XclImpString()
Constructs an empty string.
Definition: xistring.cxx:33
void Read(XclImpStream &rStrm, XclStrFlags nFlags=XclStrFlags::NONE)
Reads a complete string from the passed stream.
Definition: xistring.cxx:42
OUString maString
Definition: xistring.hxx:70
static void AppendFormat(XclFormatRunVec &rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx)
Insert a formatting run to the passed format buffer.
Definition: xistring.cxx:93
void ReadFormats(XclImpStream &rStrm)
Reads and appends the formatting information (run count and runs) from stream.
Definition: xistring.hxx:46
OUString maString
#define SVSTREAM_FILEFORMAT_ERROR
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
void SvStream & rStrm
unsigned char sal_uInt8
const XclStrFlags nAllowedFlags
All allowed flags for import.
Definition: xistring.cxx:31
@ EXC_BIFF5
MS Excel 4.0.
Definition: xlconst.hxx:34
@ EXC_BIFF4
MS Excel 3.0.
Definition: xlconst.hxx:33
@ EXC_BIFF2
Definition: xlconst.hxx:31
@ EXC_BIFF8
MS Excel 5.0, MS Excel 7.0 (95)
Definition: xlconst.hxx:35
@ EXC_BIFF3
MS Excel 2.1.
Definition: xlconst.hxx:32
::std::vector< XclFormatRun > XclFormatRunVec
A vector with all formatting runs for a rich-string.
Definition: xlstring.hxx:85
XclStrFlags
Flags used to specify import/export mode of strings.
Definition: xlstring.hxx:29
@ EightBitLength
Always use UCS-2 characters (default: try to compress). BIFF8 only.
@ SeparateFormats
Omit flags on empty string (default: read/write always). BIFF8 only.
@ SmartFlags
8-bit string length field (default: 16-bit).
const sal_uInt16 EXC_FONT_NOTFOUND
Application font index.
Definition: xlstyle.hxx:78
#define DBG_ERROR_BIFF()
Definition: xltools.hxx:33