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 <xistring.hxx>
21 #include <xlstyle.hxx>
22 #include <xistream.hxx>
23 #include <xiroot.hxx>
24 #include <xltools.hxx>
25 #include <sal/log.hxx>
26 
27 // Byte/Unicode strings =======================================================
28 
31 
33 {
34 }
35 
36 XclImpString::XclImpString( const OUString& rString ) :
37  maString( rString )
38 {
39 }
40 
42 {
43  if( !( nFlags & XclStrFlags::SeparateFormats ) )
44  maFormats.clear();
45 
47  nFlags & ~nAllowedFlags, "sc.filter",
48  "XclImpString::Read - unknown flag");
49  bool b16BitLen = !( nFlags & XclStrFlags::EightBitLength );
50 
51  switch( rStrm.GetRoot().GetBiff() )
52  {
53  case EXC_BIFF2:
54  case EXC_BIFF3:
55  case EXC_BIFF4:
56  case EXC_BIFF5:
57  // no integrated formatting in BIFF2-BIFF7
58  maString = rStrm.ReadByteString( b16BitLen );
59  break;
60 
61  case EXC_BIFF8:
62  {
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();
68 
69  bool b16Bit, bRich, bFarEast;
70  sal_uInt16 nRunCount;
71  sal_uInt32 nExtInf;
72  rStrm.ReadUniStringExtHeader( b16Bit, bRich, bFarEast, nRunCount, nExtInf, nFlagField );
73  // ignore the flags, they may be wrong
74 
75  // --- character array ---
76  maString = rStrm.ReadRawUniString( nChars, b16Bit );
77 
78  // --- formatting ---
79  if (nRunCount)
80  ReadFormats( rStrm, maFormats, nRunCount );
81 
82  // --- extended (FarEast) information ---
83  rStrm.Ignore( nExtInf );
84  }
85  break;
86 
87  default:
89  }
90 }
91 
92 void XclImpString::AppendFormat( XclFormatRunVec& rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx )
93 {
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 );
98  else
99  rFormats.back().mnFontIdx = nFontIdx;
100 }
101 
103 {
104  bool bBiff8 = rStrm.GetRoot().GetBiff() == EXC_BIFF8;
105  sal_uInt16 nRunCount = bBiff8 ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
106  ReadFormats( rStrm, rFormats, nRunCount );
107 }
108 
109 void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nRunCount )
110 {
111  rFormats.clear();
112 
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)
117  {
118  SAL_WARN("sc.filter", "XclImpString::ReadFormats - more formats claimed than stream could contain");
120  return;
121  }
122 
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 )
127  {
128  for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
129  {
130  sal_uInt16 nChar = rStrm.ReaduInt16();
131  sal_uInt16 nFontIdx = rStrm.ReaduInt16();
132  AppendFormat( rFormats, nChar, nFontIdx );
133  }
134  }
135  else
136  {
137  for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
138  {
139  sal_uInt8 nChar = rStrm.ReaduInt8();
140  sal_uInt8 nFontIdx = rStrm.ReaduInt8();
141  AppendFormat( rFormats, nChar, nFontIdx );
142  }
143  }
144 }
145 
146 void XclImpString::ReadObjFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nFormatSize )
147 {
148  // number of formatting runs, each takes 8 bytes
149  sal_uInt16 nRunCount = nFormatSize / 8;
150  rFormats.clear();
151  rFormats.reserve( nRunCount );
152  for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
153  {
154  sal_uInt16 nChar = rStrm.ReaduInt16();
155  sal_uInt16 nFontIdx = rStrm.ReaduInt16();
156  rStrm.Ignore( 4 );
157  AppendFormat( rFormats, nChar, nFontIdx );
158  }
159 }
160 
161 // String iterator ============================================================
162 
164  mrText( rString.GetText() ),
165  mrFormats( rString.GetFormats() ),
166  mnPortion( 0 ),
167  mnTextBeg( 0 ),
168  mnTextEnd( 0 ),
169  mnFormatsBeg( 0 ),
170  mnFormatsEnd( 0 )
171 {
172  // first portion is formatted, adjust vector index to next portion
173  if( !mrFormats.empty() && (mrFormats.front().mnChar == 0) )
174  ++mnFormatsEnd;
175  // find end position of the first portion
176  mnTextEnd = (mnFormatsEnd < mrFormats.size() ?
177  mrFormats[ mnFormatsEnd ].mnChar : mrText.getLength() );
178 }
179 
181 {
182  return mrText.copy( mnTextBeg, mnTextEnd - mnTextBeg );
183 }
184 
186 {
188 }
189 
191 {
192  if( Is() )
193  {
194  ++mnPortion;
195  do
196  {
197  // indexes into vector of formatting runs
198  if( mnFormatsBeg < mnFormatsEnd )
199  ++mnFormatsBeg;
200  if( mnFormatsEnd < mrFormats.size() )
201  ++mnFormatsEnd;
202  // character positions of next portion
204  mnTextEnd = (mnFormatsEnd < mrFormats.size()) ?
205  mrFormats[ mnFormatsEnd ].mnChar : mrText.getLength();
206  }
207  while( Is() && (mnTextBeg == mnTextEnd) );
208  }
209  return *this;
210 }
211 
212 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define DBG_ERROR_BIFF()
Definition: xltools.hxx:31
void ReadFormats(XclImpStream &rStrm)
Reads and appends the formatting information (run count and runs) from stream.
Definition: xistring.hxx:47
sal_Int32 mnTextEnd
First character of current portion.
Definition: xistring.hxx:100
XclStrFlags
Flags used to specify import/export mode of strings.
Definition: xlstring.hxx:29
svl::SharedString maString
Definition: scmatrix.cxx:3338
sal_uInt16 GetPortionFont() const
Returns the font index of the current text portion.
Definition: xistring.cxx:185
void Read(XclImpStream &rStrm, XclStrFlags nFlags=XclStrFlags::NONE)
Reads a complete string from the passed stream.
Definition: xistring.cxx:41
OUString GetPortionText() const
Returns the string of the current text portion.
Definition: xistring.cxx:180
const sal_uInt16 EXC_FONT_NOTFOUND
Application font index.
Definition: xlstyle.hxx:78
MS Excel 4.0.
Definition: xlconst.hxx:35
Omit flags on empty string (default: read/write always). BIFF8 only.
::std::vector< XclFormatRun > XclFormatRunVec
A vector with all formatting runs for a rich-string.
Definition: xlstring.hxx:85
MS Excel 5.0, MS Excel 7.0 (95)
Definition: xlconst.hxx:36
OUString ReadRawUniString(sal_uInt16 nChars, bool b16Bit)
Reads nChars characters and returns the string.
Definition: xistream.cxx:832
OUString maString
Definition: xistring.hxx:71
8-bit string length field (default: 16-bit).
void ReadObjFormats(XclImpStream &rStrm, sal_uInt16 nFormatSize)
Reads and appends formatting runs from an OBJ or TXO record.
Definition: xistring.hxx:49
bool Is() const
Returns true, if the iterator references a valid text portion.
Definition: xistring.hxx:84
size_t mnFormatsBeg
First character of next portion.
Definition: xistring.hxx:101
MS Excel 3.0.
Definition: xlconst.hxx:34
Iterates over formatted string portions.
Definition: xistring.hxx:78
sal_uInt16 ReaduInt16()
Definition: xistream.cxx:648
const XclFormatRunVec & mrFormats
The processed string.
Definition: xistring.hxx:97
XclFormatRunVec maFormats
The text data of the string.
Definition: xistring.hxx:72
static void AppendFormat(XclFormatRunVec &rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx)
Insert a formatting run to the passed format buffer.
Definition: xistring.cxx:92
const XclImpRoot & GetRoot() const
Returns the filter root data.
Definition: xistream.hxx:294
std::size_t GetRecLeft()
Returns remaining data size of the whole record without record headers.
Definition: xistream.cxx:581
XclImpString()
Constructs an empty string.
Definition: xistring.cxx:32
XclImpStringIterator(const XclImpString &rString)
Definition: xistring.cxx:163
OUString ReadByteString(bool b16BitLen)
Reads 8/16 bit string length, character array and returns the string.
Definition: xistream.cxx:954
std::size_t ReadUniStringExtHeader(bool &rb16Bit, bool &rbRich, bool &rbFareast, sal_uInt16 &rnFormatRuns, sal_uInt32 &rnExtInf, sal_uInt8 nFlags)
Reads ext.
Definition: xistream.cxx:811
void SetSvStreamError(const ErrCode &rErrCode)
Set an SVSTREAM_..._ERROR.
Definition: xistream.hxx:470
#define SAL_WARN_IF(condition, area, stream)
void Ignore(std::size_t nBytes)
Seeks forward inside the current record.
Definition: xistream.cxx:795
XclImpStringIterator & operator++()
Moves iterator to next text portion.
Definition: xistring.cxx:190
unsigned char sal_uInt8
const OUString & mrText
Definition: xistring.hxx:96
sal_uInt8 ReaduInt8()
Definition: xistream.cxx:616
sal_Int32 mnTextBeg
Current text portion.
Definition: xistring.hxx:99
Always use UCS-2 characters (default: try to compress). BIFF8 only.
#define SVSTREAM_FILEFORMAT_ERROR
const XclStrFlags nAllowedFlags
All allowed flags for import.
Definition: xistring.cxx:30
XclBiff GetBiff() const
Returns the current BIFF version of the importer/exporter.
Definition: xlroot.hxx:140
#define SAL_WARN(area, stream)
size_t mnFormatsEnd
Formatting run index for current portion.
Definition: xistring.hxx:102
MS Excel 2.1.
Definition: xlconst.hxx:33
This class is used to import record oriented streams.
Definition: xistream.hxx:278
This class represents an unformatted or formatted string and provides importing from stream...
Definition: xistring.hxx:31
size_t mnPortion
The vector of formatting runs.
Definition: xistring.hxx:98