Line data Source code
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 :
25 : // Byte/Unicode strings =======================================================
26 :
27 : /** All allowed flags for import. */
28 : const XclStrFlags nAllowedFlags = EXC_STR_8BITLENGTH | EXC_STR_SMARTFLAGS | EXC_STR_SEPARATEFORMATS;
29 :
30 2998 : XclImpString::XclImpString()
31 : {
32 2998 : }
33 :
34 20 : XclImpString::XclImpString( const OUString& rString ) :
35 20 : maString( rString )
36 : {
37 20 : }
38 :
39 5203 : XclImpString::~XclImpString()
40 : {
41 5203 : }
42 :
43 2975 : void XclImpString::Read( XclImpStream& rStrm, XclStrFlags nFlags )
44 : {
45 2975 : if( !::get_flag( nFlags, EXC_STR_SEPARATEFORMATS ) )
46 2935 : maFormats.clear();
47 :
48 : SAL_WARN_IF(
49 : (nFlags & ~nAllowedFlags) != 0, "sc.filter",
50 : "XclImpString::Read - unknown flag");
51 2975 : bool b16BitLen = !::get_flag( nFlags, EXC_STR_8BITLENGTH );
52 :
53 2975 : switch( rStrm.GetRoot().GetBiff() )
54 : {
55 : case EXC_BIFF2:
56 : case EXC_BIFF3:
57 : case EXC_BIFF4:
58 : case EXC_BIFF5:
59 : // no integrated formatting in BIFF2-BIFF7
60 746 : maString = rStrm.ReadByteString( b16BitLen );
61 746 : break;
62 :
63 : case EXC_BIFF8:
64 : {
65 : // --- string header ---
66 2229 : sal_uInt16 nChars = b16BitLen ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
67 2229 : sal_uInt8 nFlagField = 0;
68 2229 : if( nChars || !::get_flag( nFlags, EXC_STR_SMARTFLAGS ) )
69 2229 : nFlagField = rStrm.ReaduInt8();
70 :
71 : bool b16Bit, bRich, bFarEast;
72 : sal_uInt16 nRunCount;
73 : sal_uInt32 nExtInf;
74 2229 : rStrm.ReadUniStringExtHeader( b16Bit, bRich, bFarEast, nRunCount, nExtInf, nFlagField );
75 : // ignore the flags, they may be wrong
76 :
77 : // --- character array ---
78 2229 : maString = rStrm.ReadRawUniString( nChars, b16Bit );
79 :
80 : // --- formatting ---
81 2229 : if( nRunCount > 0 )
82 39 : ReadFormats( rStrm, nRunCount );
83 :
84 : // --- extended (FarEast) information ---
85 2229 : rStrm.Ignore( nExtInf );
86 : }
87 2229 : break;
88 :
89 : default:
90 : DBG_ERROR_BIFF();
91 : }
92 2975 : }
93 :
94 130 : void XclImpString::AppendFormat( XclFormatRunVec& rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx )
95 : {
96 : // #i33341# real life -- same character index may occur several times
97 : OSL_ENSURE( rFormats.empty() || (rFormats.back().mnChar <= nChar), "XclImpString::AppendFormat - wrong char order" );
98 130 : if( rFormats.empty() || (rFormats.back().mnChar < nChar) )
99 130 : rFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
100 : else
101 0 : rFormats.back().mnFontIdx = nFontIdx;
102 130 : }
103 :
104 0 : void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats )
105 : {
106 0 : bool bBiff8 = rStrm.GetRoot().GetBiff() == EXC_BIFF8;
107 0 : sal_uInt16 nRunCount = bBiff8 ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
108 0 : ReadFormats( rStrm, rFormats, nRunCount );
109 0 : }
110 :
111 39 : void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nRunCount )
112 : {
113 39 : rFormats.clear();
114 39 : rFormats.reserve( nRunCount );
115 : /* #i33341# real life -- same character index may occur several times
116 : -> use AppendFormat() to validate formats */
117 39 : if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
118 : {
119 129 : for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
120 : {
121 90 : sal_uInt16 nChar = rStrm.ReaduInt16();
122 90 : sal_uInt16 nFontIdx = rStrm.ReaduInt16();
123 90 : AppendFormat( rFormats, nChar, nFontIdx );
124 : }
125 : }
126 : else
127 : {
128 0 : for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
129 : {
130 0 : sal_uInt8 nChar = rStrm.ReaduInt8();
131 0 : sal_uInt8 nFontIdx = rStrm.ReaduInt8();
132 0 : AppendFormat( rFormats, nChar, nFontIdx );
133 : }
134 : }
135 39 : }
136 :
137 20 : void XclImpString::ReadObjFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nFormatSize )
138 : {
139 : // number of formatting runs, each takes 8 bytes
140 20 : sal_uInt16 nRunCount = nFormatSize / 8;
141 20 : rFormats.clear();
142 20 : rFormats.reserve( nRunCount );
143 60 : for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
144 : {
145 40 : sal_uInt16 nChar = rStrm.ReaduInt16();
146 40 : sal_uInt16 nFontIdx = rStrm.ReaduInt16();
147 40 : rStrm.Ignore( 4 );
148 40 : AppendFormat( rFormats, nChar, nFontIdx );
149 : }
150 20 : }
151 :
152 : // String iterator ============================================================
153 :
154 21 : XclImpStringIterator::XclImpStringIterator( const XclImpString& rString ) :
155 21 : mrText( rString.GetText() ),
156 21 : mrFormats( rString.GetFormats() ),
157 : mnPortion( 0 ),
158 : mnTextBeg( 0 ),
159 : mnTextEnd( 0 ),
160 : mnFormatsBeg( 0 ),
161 42 : mnFormatsEnd( 0 )
162 : {
163 : // first portion is formatted, adjust vector index to next portion
164 21 : if( !mrFormats.empty() && (mrFormats.front().mnChar == 0) )
165 0 : ++mnFormatsEnd;
166 : // find end position of the first portion
167 21 : mnTextEnd = (mnFormatsEnd < mrFormats.size() ?
168 21 : mrFormats[ mnFormatsEnd ].mnChar : mrText.getLength() );
169 21 : }
170 :
171 21 : OUString XclImpStringIterator::GetPortionText() const
172 : {
173 21 : return mrText.copy( mnTextBeg, mnTextEnd - mnTextBeg );
174 : }
175 :
176 21 : sal_uInt16 XclImpStringIterator::GetPortionFont() const
177 : {
178 21 : return (mnFormatsBeg < mnFormatsEnd) ? mrFormats[ mnFormatsBeg ].mnFontIdx : EXC_FONT_NOTFOUND;
179 : }
180 :
181 21 : XclImpStringIterator& XclImpStringIterator::operator++()
182 : {
183 21 : if( Is() )
184 : {
185 21 : ++mnPortion;
186 21 : do
187 : {
188 : // indexes into vector of formatting runs
189 21 : if( mnFormatsBeg < mnFormatsEnd )
190 0 : ++mnFormatsBeg;
191 21 : if( mnFormatsEnd < mrFormats.size() )
192 0 : ++mnFormatsEnd;
193 : // character positions of next portion
194 21 : mnTextBeg = mnTextEnd;
195 21 : mnTextEnd = (mnFormatsEnd < mrFormats.size()) ?
196 21 : mrFormats[ mnFormatsEnd ].mnChar : mrText.getLength();
197 : }
198 21 : while( Is() && (mnTextBeg == mnTextEnd) );
199 : }
200 21 : return *this;
201 : }
202 :
203 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|