LibreOffice Module sc (master)  1
dpitemdata.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 <dpitemdata.hxx>
21 #include <global.hxx>
22 
25 #include <rtl/math.hxx>
26 
27 const sal_Int32 ScDPItemData::DateFirst = -1;
28 const sal_Int32 ScDPItemData::DateLast = 10000;
29 
30 sal_Int32 ScDPItemData::Compare(const ScDPItemData& rA, const ScDPItemData& rB)
31 {
32  if (rA.meType != rB.meType)
33  {
34  // group value, value and string in this order. Ensure that the empty
35  // type comes last.
36  return rA.meType < rB.meType ? -1 : 1;
37  }
38 
39  switch (rA.meType)
40  {
41  case GroupValue:
42  {
44  {
46  return 0;
47 
48  return rA.maGroupValue.mnValue < rB.maGroupValue.mnValue ? -1 : 1;
49  }
50 
51  return rA.maGroupValue.mnGroupType < rB.maGroupValue.mnGroupType ? -1 : 1;
52  }
53  case Value:
54  case RangeStart:
55  {
56  if (rA.mfValue == rB.mfValue)
57  return 0;
58 
59  return rA.mfValue < rB.mfValue ? -1 : 1;
60  }
61  case String:
62  case Error:
63  if (rA.mpString == rB.mpString)
64  // strings may be interned.
65  return 0;
66 
68  default:
69  ;
70  }
71  return 0;
72 }
73 
75  mfValue(0.0), meType(Empty), mbStringInterned(false) {}
76 
78  meType(r.meType), mbStringInterned(r.mbStringInterned)
79 {
80  switch (r.meType)
81  {
82  case String:
83  case Error:
84  mpString = r.mpString;
85  if (!mbStringInterned)
86  rtl_uString_acquire(mpString);
87  break;
88  case Value:
89  case RangeStart:
90  mfValue = r.mfValue;
91  break;
92  case GroupValue:
95  break;
96  case Empty:
97  default:
98  mfValue = 0.0;
99  }
100 }
101 
103 {
104  if (!mbStringInterned)
105  {
106  if (meType == String || meType == Error)
107  rtl_uString_release(mpString);
108  }
109 
110  mbStringInterned = false;
111 }
112 
113 ScDPItemData::ScDPItemData(const OUString& rStr) :
114  mpString(rStr.pData), meType(String), mbStringInterned(false)
115 {
116  rtl_uString_acquire(mpString);
117 }
118 
119 ScDPItemData::ScDPItemData(sal_Int32 nGroupType, sal_Int32 nValue) :
120  meType(GroupValue), mbStringInterned(false)
121 {
122  maGroupValue.mnGroupType = nGroupType;
123  maGroupValue.mnValue = nValue;
124 }
125 
127 {
128  DisposeString();
129 }
130 
132 {
133  DisposeString();
134  meType = Empty;
135 }
136 
137 void ScDPItemData::SetString(const OUString& rS)
138 {
139  DisposeString();
140  mpString = rS.pData;
141  rtl_uString_acquire(mpString);
142  meType = String;
143 }
144 
145 void ScDPItemData::SetStringInterned( rtl_uString* pS )
146 {
147  DisposeString();
148  mpString = pS;
149  meType = String;
150  mbStringInterned = true;
151 }
152 
153 void ScDPItemData::SetValue(double fVal)
154 {
155  DisposeString();
156  mfValue = fVal;
157  meType = Value;
158 }
159 
161 {
162  DisposeString();
163  mfValue = fVal;
164  meType = RangeStart;
165 }
166 
168 {
169  DisposeString();
170  rtl::math::setInf(&mfValue, true);
171  meType = RangeStart;
172 }
173 
175 {
176  DisposeString();
177  rtl::math::setInf(&mfValue, false);
178  meType = RangeStart;
179 }
180 
182 {
183  SetStringInterned(pS);
184  meType = Error;
185 }
186 
188 {
189  if (meType != r.meType)
190  return false;
191 
192  switch (meType)
193  {
194  case Value:
195  case RangeStart:
196  return rtl::math::approxEqual(mfValue, r.mfValue);
197  case GroupValue:
200  default:
201  ;
202  }
203 
204  if (mpString == r.mpString)
205  // Fast equality check for interned strings.
206  return true;
207 
208  return ScGlobal::GetpTransliteration()->isEqual(GetString(), r.GetString());
209 }
210 
212 {
213  if (meType != r.meType)
214  return false;
215 
216  switch (meType)
217  {
218  case Value:
219  case RangeStart:
220  return rtl::math::approxEqual(mfValue, r.mfValue);
221  case GroupValue:
224  default:
225  ;
226  }
227 
228  // need exact equality until we have a safe case insensitive string hash
229  return GetString() == r.GetString();
230 }
231 
233 {
234  return Compare(*this, r) == -1;
235 }
236 
238 {
239  DisposeString();
240  meType = r.meType;
241  switch (r.meType)
242  {
243  case String:
244  case Error:
246  mpString = r.mpString;
247  if (!mbStringInterned)
248  rtl_uString_acquire(mpString);
249  break;
250  case Value:
251  case RangeStart:
252  mfValue = r.mfValue;
253  break;
254  case GroupValue:
257  break;
258  case Empty:
259  default:
260  mfValue = 0.0;
261  }
262  return *this;
263 }
264 
266 {
267  switch (meType)
268  {
269  case Error:
270  return ScDPValue::Error;
271  case Empty:
272  return ScDPValue::Empty;
273  case Value:
274  return ScDPValue::Value;
275  default:
276  ;
277  }
278 
279  return ScDPValue::String;
280 }
281 
282 #if DEBUG_PIVOT_TABLE
283 
284 void ScDPItemData::Dump(const char* msg) const
285 {
286  printf("--- (%s)\n", msg);
287  switch (meType)
288  {
289  case Empty:
290  printf("empty\n");
291  break;
292  case Error:
293  printf("error: %s\n",
294  OUStringToOString(OUString(mpString), RTL_TEXTENCODING_UTF8).getStr());
295  break;
296  case GroupValue:
297  printf("group value: group type = %d value = %d\n",
299  break;
300  case String:
301  printf("string: %s\n",
302  OUStringToOString(OUString(mpString), RTL_TEXTENCODING_UTF8).getStr());
303  break;
304  case Value:
305  printf("value: %g\n", mfValue);
306  break;
307  case RangeStart:
308  printf("range start: %g\n", mfValue);
309  break;
310  default:
311  printf("unknown type\n");
312  }
313  printf("---\n");
314 }
315 #endif
316 
318 {
319  return meType == Empty;
320 }
321 
323 {
324  return meType == Value;
325 }
326 
327 OUString ScDPItemData::GetString() const
328 {
329  switch (meType)
330  {
331  case String:
332  case Error:
333  return OUString(mpString);
334  case Value:
335  case RangeStart:
336  return OUString::number(mfValue);
337  case GroupValue:
338  return OUString::number(maGroupValue.mnValue);
339  case Empty:
340  default:
341  ;
342  }
343 
344  return OUString();
345 }
346 
348 {
349  if (meType == Value || meType == RangeStart)
350  return mfValue;
351 
352  return 0.0;
353 }
354 
356 {
357  if (meType == GroupValue)
358  return maGroupValue;
359 
360  GroupValueAttr aGV;
361  aGV.mnGroupType = -1;
362  aGV.mnValue = -1;
363  return aGV;
364 }
365 
367 {
368  return meType == String || meType == Error;
369 }
370 
371 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetValue(double fVal)
Definition: dpitemdata.cxx:153
void SetRangeLast()
Definition: dpitemdata.cxx:174
sal_Int32 compareString(const OUString &s1, const OUString &s2) const
static SC_DLLPUBLIC::utl::TransliterationWrapper * GetpTransliteration()
Definition: global.cxx:979
std::unique_ptr< ContentProperties > pData
sal_uInt8 meType
Definition: dpitemdata.hxx:53
void SetString(const OUString &rS)
Definition: dpitemdata.cxx:137
static SC_DLLPUBLIC CollatorWrapper * GetCollator()
Definition: global.cxx:1032
ScDPItemData & operator=(const ScDPItemData &r)
Definition: dpitemdata.cxx:237
double mfValue
Definition: dpitemdata.hxx:50
bool IsEmpty() const
Definition: dpitemdata.cxx:317
rtl_uString * mpString
Definition: dpitemdata.hxx:48
static sal_Int32 Compare(const ScDPItemData &rA, const ScDPItemData &rB)
Definition: dpitemdata.cxx:30
void SetStringInterned(rtl_uString *pS)
Definition: dpitemdata.cxx:145
When assigning a string value, you can also assign an interned string whose life-cycle is managed by ...
Definition: dpitemdata.hxx:29
void SetErrorStringInterned(rtl_uString *pS)
Definition: dpitemdata.cxx:181
GroupValueAttr GetGroupValue() const
Definition: dpitemdata.cxx:355
GroupValueAttr maGroupValue
Definition: dpitemdata.hxx:49
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
void DisposeString()
Definition: dpitemdata.cxx:102
static const sal_Int32 DateLast
Definition: dpitemdata.hxx:37
void SetRangeFirst()
Definition: dpitemdata.cxx:167
static const sal_Int32 DateFirst
Definition: dpitemdata.hxx:36
bool HasStringData() const
Definition: dpitemdata.cxx:366
double GetValue() const
Definition: dpitemdata.cxx:347
bool IsValue() const
Definition: dpitemdata.cxx:322
bool mbStringInterned
Definition: dpitemdata.hxx:54
OUString GetString() const
Definition: dpitemdata.cxx:327
ScDPValue::Type GetCellType() const
Definition: dpitemdata.cxx:265
bool IsCaseInsEqual(const ScDPItemData &r) const
Definition: dpitemdata.cxx:187
Empty
RedlineType meType
void SetEmpty()
Definition: dpitemdata.cxx:131
bool operator==(const ScDPItemData &r) const
Definition: dpitemdata.cxx:211
bool operator<(const ScDPItemData &r) const
Definition: dpitemdata.cxx:232
void SetRangeStart(double fVal)
Definition: dpitemdata.cxx:160