LibreOffice Module sc (master)  1
address.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */
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 #pragma once
21 
22 #include <rtl/ustrbuf.hxx>
23 #include <rtl/strbuf.hxx>
24 
25 #include <array>
26 #include <limits>
27 #include <ostream>
28 
29 #include "scdllapi.h"
30 #include "types.hxx"
31 #include <formula/grammar.hxx>
32 
33 #include <o3tl/typed_flags_set.hxx>
35 
36 namespace com::sun::star {
37  namespace sheet {
38  struct ExternalLinkInfo;
39  }
40 }
41 
42 namespace com::sun::star::uno { template <typename > class Sequence; }
43 
44 class ScDocument;
45 
48 typedef size_t SCSIZE;
49 
50 // Maximum possible value of data type, NOT maximum row value.
51 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
52 // included, we should not be using those stupid macros anyway.
53 #undef min
54 #undef max
55 const SCROW SCROW_MAX = ::std::numeric_limits<SCROW>::max();
56 const SCCOL SCCOL_MAX = ::std::numeric_limits<SCCOL>::max();
57 const SCTAB SCTAB_MAX = ::std::numeric_limits<SCTAB>::max();
58 const SCCOLROW SCCOLROW_MAX = ::std::numeric_limits<SCCOLROW>::max();
59 const SCSIZE SCSIZE_MAX = ::std::numeric_limits<SCSIZE>::max();
60 
61 // Count values
62 const SCROW MAXROWCOUNT = 1048576;
63 const SCCOL MAXCOLCOUNT = 16384;
64 const SCCOL INITIALCOLCOUNT = 1; // initial number of columns we allocate memory for
66 const SCTAB MAXTABCOUNT = 10000;
67 // Maximum values
68 const SCROW MAXROW = MAXROWCOUNT - 1;
69 const SCCOL MAXCOL = MAXCOLCOUNT - 1;
70 const SCTAB MAXTAB = MAXTABCOUNT - 1;
72 const SCROW MAXROWCOUNT_JUMBO = 16 * 1024 * 1024;
73 const SCCOL MAXCOLCOUNT_JUMBO = 16384;
76 // Maximum tiled rendering values
78 // Limit the initial tab count to prevent users to set the count too high,
79 // which could cause the memory usage of blank documents to exceed the
80 // available system memory.
81 const SCTAB MAXINITTAB = 1024;
82 const SCTAB MININITTAB = 1;
83 
84 inline constexpr OUStringLiteral MAXROW_STRING(u"1048575");
85 inline constexpr OUStringLiteral MAXCOL_STRING(u"XFD");
86 inline constexpr OUStringLiteral MAXROW_JUMBO_STRING(u"16777215");
87 inline constexpr OUStringLiteral MAXCOL_JUMBO_STRING(u"XFD");
88 
89 // Special values
91 const SCTAB TABLEID_DOC = SCTAB_MAX; // entire document, e.g. protect
92 const SCROW SCROWS32K = 32000; // for fuzzing
96 
97 const SCROW MAXROW_30 = 8191;
98 
99 [[nodiscard]] inline bool ValidCol( SCCOL nCol, SCCOL nMaxCol )
100 {
101  assert(nMaxCol == MAXCOL || nMaxCol == MAXCOL_JUMBO); // temporary to debug jumbo sheets work
102  return nCol >= 0 && nCol <= nMaxCol;
103 }
104 
105 [[nodiscard]] inline bool ValidRow( SCROW nRow, SCROW nMaxRow)
106 {
107  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
108  return nRow >= 0 && nRow <= nMaxRow;
109 }
110 
111 [[nodiscard]] inline bool ValidTab( SCTAB nTab )
112 {
113  return nTab >= 0 && nTab <= MAXTAB;
114 }
115 
116 [[nodiscard]] inline bool ValidTab( SCTAB nTab, SCTAB nMaxTab )
117 {
118  return nTab >= 0 && nTab <= nMaxTab;
119 }
120 
121 [[nodiscard]] inline bool ValidColRow( SCCOL nCol, SCROW nRow, SCCOL nMaxCol, SCROW nMaxRow )
122 {
123  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
124  return ValidCol(nCol,nMaxCol) && ValidRow(nRow,nMaxRow);
125 }
126 
127 [[nodiscard]] inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL nMaxCol, SCROW nMaxRow )
128 {
129  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
130  return ValidCol(nCol,nMaxCol) && ValidRow(nRow,nMaxRow) && ValidTab( nTab);
131 }
132 
133 [[nodiscard]] inline SCCOL SanitizeCol( SCCOL nCol, SCCOL nMaxCol )
134 {
135  assert(nMaxCol == MAXCOL || nMaxCol == MAXCOL_JUMBO); // temporary to debug jumbo sheets work
136  return nCol < 0 ? 0 : (nCol > nMaxCol ? nMaxCol : nCol);
137 }
138 
139 [[nodiscard]] inline SCROW SanitizeRow( SCROW nRow, SCROW nMaxRow )
140 {
141  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
142  return nRow < 0 ? 0 : (nRow > nMaxRow ? nMaxRow : nRow);
143 }
144 
145 [[nodiscard]] inline SCTAB SanitizeTab( SCTAB nTab )
146 {
147  return nTab < 0 ? 0 : (nTab > MAXTAB ? MAXTAB : nTab);
148 }
149 
150 template <typename T> inline void PutInOrder(T& nStart, T& nEnd)
151 {
152  if (nEnd < nStart)
153  std::swap(nStart, nEnd);
154 }
155 
156 // The result of ConvertRef() is a bit group of the following:
157 enum class ScRefFlags : sal_uInt16
158 {
159  ZERO = 0x0000,
160  COL_ABS = 0x0001,
161  ROW_ABS = 0x0002,
162  TAB_ABS = 0x0004,
163  TAB_3D = 0x0008,
164  COL2_ABS = 0x0010,
165  ROW2_ABS = 0x0020,
166  TAB2_ABS = 0x0040,
167  TAB2_3D = 0x0080,
168  ROW_VALID = 0x0100,
169  COL_VALID = 0x0200,
170  TAB_VALID = 0x0400,
171  // BITS for convenience
174  // somewhat cheesy kludge to force the display of the document name even for
175  // local references. Requires TAB_3D to be valid
176  FORCE_DOC = 0x0800,
177  ROW2_VALID = 0x1000,
178  COL2_VALID = 0x2000,
179  TAB2_VALID = 0x4000,
180  VALID = 0x8000,
181 
183 
185 
186  RANGE_ABS = ADDR_ABS | COL2_ABS | ROW2_ABS | TAB2_ABS,
187 
188  ADDR_ABS_3D = ADDR_ABS | TAB_3D,
189  RANGE_ABS_3D = RANGE_ABS | TAB_3D
190 };
191 
192 namespace o3tl
193 {
194  template<> struct typed_flags<ScRefFlags> : is_typed_flags<ScRefFlags, 0xffff> {};
195 }
196 inline void applyStartToEndFlags(ScRefFlags &target,const ScRefFlags source)
197 {
198  target |= ScRefFlags(o3tl::to_underlying(source) << 4);
199 }
200 inline void applyStartToEndFlags(ScRefFlags &target)
201 {
202  target |= ScRefFlags(o3tl::to_underlying(target) << 4);
203 }
204 
205 // ScAddress
207 {
208 private:
209  // Even if the fields are in the order "row, column, tab", in all (?) the ScAddress and
210  // ScDocument APIs that take separate row, column, and tab parameters, the parameters are in the
211  // order "column, row, tab", which matches the most common (A1) address syntax, if you ignore
212  // the sheet (tab). Don't let this confuse you, like it confused me for a while.
213 
217 
218 public:
219 
220  enum Uninitialized { UNINITIALIZED };
221  enum InitializeInvalid { INITIALIZE_INVALID };
222 
223  struct Details
224  {
228 
230  eConv(eConvP), nRow(nRowP), nCol(nColP)
231  {}
233  eConv(eConvP), nRow(rAddr.Row()), nCol(rAddr.Col())
234  {}
236  eConv(eConvP), nRow(0), nCol(0)
237  {}
238  /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
239  Details( const ScDocument& rDoc, const ScAddress& rAddr );
240  };
242 
244  {
245  OUString maTabName;
246  sal_uInt16 mnFileId;
248 
250  mnFileId(0), mbExternal(false)
251  {}
252  };
253 
255  nRow(0), nCol(0), nTab(0)
256  {}
257  ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP ) :
258  nRow(nRowP), nCol(nColP), nTab(nTabP)
259  {}
263  {}
265  nRow(-1), nCol(-1), nTab(-1)
266  {}
267  ScAddress( const ScAddress& rAddress ) :
268  nRow(rAddress.nRow), nCol(rAddress.nCol), nTab(rAddress.nTab)
269  {}
270  inline ScAddress& operator=( const ScAddress& rAddress );
271 
272  inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
273 
274  SCROW Row() const
275  {
276  return nRow;
277  }
278 
279  SCCOL Col() const
280  {
281  return nCol;
282  }
283  SCTAB Tab() const
284  {
285  return nTab;
286  }
287  void SetRow( SCROW nRowP )
288  {
289  nRow = nRowP;
290  }
291  void SetCol( SCCOL nColP )
292  {
293  nCol = nColP;
294  }
295  void SetTab( SCTAB nTabP )
296  {
297  nTab = nTabP;
298  }
299  void SetInvalid()
300  {
301  nRow = -1;
302  nCol = -1;
303  nTab = -1;
304  }
305  bool IsValid() const
306  {
307  return (nRow >= 0) && (nCol >= 0) && (nTab >= 0);
308  }
309 
310  inline void PutInOrder( ScAddress& rAddress );
311 
312  void IncRow( SCROW nDelta = 1 )
313  {
314  nRow = sal::static_int_cast<SCROW>(nRow + nDelta);
315  }
316  void IncCol( SCCOL nDelta = 1 )
317  {
318  nCol = sal::static_int_cast<SCCOL>(nCol + nDelta);
319  }
320  void IncTab( SCTAB nDelta = 1 )
321  {
322  nTab = sal::static_int_cast<SCTAB>(nTab + nDelta);
323  }
324  void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
325  {
326  nColP = nCol;
327  nRowP = nRow;
328  nTabP = nTab;
329  }
330 
338  SC_DLLPUBLIC ScRefFlags Parse(
339  const OUString&, const ScDocument&,
340  const Details& rDetails = detailsOOOa1,
341  ExternalInfo* pExtInfo = nullptr,
342  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
343  sal_Int32* pSheetEndPos = nullptr,
344  const OUString* pErrRef = nullptr );
345 
346  SC_DLLPUBLIC void Format( OStringBuffer& r, ScRefFlags nFlags,
347  const ScDocument* pDocument = nullptr,
348  const Details& rDetails = detailsOOOa1) const;
349 
350  SC_DLLPUBLIC OUString Format( ScRefFlags nFlags,
351  const ScDocument* pDocument = nullptr,
352  const Details& rDetails = detailsOOOa1) const;
353 
361  [[nodiscard]] SC_DLLPUBLIC bool Move( SCCOL nDeltaX, SCROW nDeltaY, SCTAB nDeltaZ,
362  ScAddress& rErrorPos, const ScDocument& rDoc );
363 
364  inline bool operator==( const ScAddress& rAddress ) const;
365  inline bool operator!=( const ScAddress& rAddress ) const;
366  inline bool operator<( const ScAddress& rAddress ) const;
367  inline bool operator<=( const ScAddress& rAddress ) const;
368  inline bool lessThanByRow( const ScAddress& rAddress ) const;
369 
370  inline size_t hash() const;
371 
381  OUString GetColRowString() const;
382 };
383 
384 // For use in SAL_DEBUG etc. Output format not guaranteed to be stable.
385 template<typename charT, typename traits>
386 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ScAddress& rAddress)
387 {
388  stream <<
389  rAddress.Tab()+1 << "!"
390  "R" << rAddress.Row()+1 <<
391  "C" << rAddress.Col()+1;
392 
393  return stream;
394 }
395 
396 inline void ScAddress::PutInOrder( ScAddress& rAddress )
397 {
398  ::PutInOrder(nCol, rAddress.nCol);
399  ::PutInOrder(nRow, rAddress.nRow);
400  ::PutInOrder(nTab, rAddress.nTab);
401 }
402 
403 inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
404 {
405  nCol = nColP;
406  nRow = nRowP;
407  nTab = nTabP;
408 }
409 
410 inline ScAddress& ScAddress::operator=( const ScAddress& rAddress )
411 {
412  nCol = rAddress.nCol;
413  nRow = rAddress.nRow;
414  nTab = rAddress.nTab;
415  return *this;
416 }
417 
418 inline bool ScAddress::operator==( const ScAddress& rAddress ) const
419 {
420  return nRow == rAddress.nRow && nCol == rAddress.nCol && nTab == rAddress.nTab;
421 }
422 
423 inline bool ScAddress::operator!=( const ScAddress& rAddress ) const
424 {
425  return !operator==( rAddress );
426 }
427 
429 inline bool ScAddress::operator<( const ScAddress& rAddress ) const
430 {
431  if (nTab == rAddress.nTab)
432  {
433  if (nCol == rAddress.nCol)
434  return nRow < rAddress.nRow;
435  else
436  return nCol < rAddress.nCol;
437  }
438  else
439  return nTab < rAddress.nTab;
440 }
441 
442 inline bool ScAddress::operator<=( const ScAddress& rAddress ) const
443 {
444  return operator<( rAddress ) || operator==( rAddress );
445 }
446 
448 inline bool ScAddress::lessThanByRow( const ScAddress& rAddress ) const
449 {
450  if (nTab == rAddress.nTab)
451  {
452  if (nRow == rAddress.nRow)
453  return nCol < rAddress.nCol;
454  else
455  return nRow < rAddress.nRow;
456  }
457  else
458  return nTab < rAddress.nTab;
459 }
460 
461 inline size_t ScAddress::hash() const
462 {
463 #if SAL_TYPES_SIZEOFPOINTER == 8
464  // 16 bits for the columns, and 20 bits for the rows
465  return (static_cast<size_t>(nTab) << 36) ^
466  (static_cast<size_t>(nCol) << 20) ^
467  static_cast<size_t>(nRow);
468 #else
469  // Assume that there are not that many addresses with row > 2^16 AND column
470  // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
471  if (nRow <= 0xffff)
472  return (static_cast<size_t>(nTab) << 24) ^
473  (static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
474  else
475  return (static_cast<size_t>(nTab) << 28) ^
476  (static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
477 #endif
478 }
479 
481 {
482  size_t operator()( const ScAddress & rAddress ) const
483  {
484  return rAddress.hash();
485  }
486 };
487 
488 [[nodiscard]] inline bool ValidAddress( const ScAddress& rAddress, SCCOL nMaxCol, SCROW nMaxRow )
489 {
490  return ValidCol(rAddress.Col(), nMaxCol) && ValidRow(rAddress.Row(), nMaxRow) && ValidTab(rAddress.Tab());
491 }
492 
493 // ScRange
495 {
496 public:
499 
501  aStart(), aEnd()
502  {}
503 
504  ScRange( ScAddress::Uninitialized eUninitialized ) :
505  aStart( eUninitialized ), aEnd( eUninitialized )
506  {}
508  aStart( eInvalid ), aEnd( eInvalid )
509  {}
510  ScRange( const ScAddress& aInputStart, const ScAddress& aInputEnd ) :
511  aStart( aInputStart ), aEnd( aInputEnd )
512  {
513  PutInOrder();
514  }
515  ScRange( const ScRange& rRange ) :
516  aStart( rRange.aStart ), aEnd( rRange.aEnd )
517  {}
518  ScRange( const ScAddress& rRange ) :
519  aStart( rRange ), aEnd( rRange )
520  {}
521  ScRange( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
522  aStart( nCol, nRow, nTab ), aEnd( aStart )
523  {}
524  ScRange( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2 ) :
525  aStart( nCol1, nRow1, nTab1 ), aEnd( nCol2, nRow2, nTab2 )
526  {}
527 
528  ScRange& operator=( const ScRange& rRange )
529  {
530  aStart = rRange.aStart;
531  aEnd = rRange.aEnd;
532  return *this;
533  }
534  ScRange& operator=( const ScAddress& rPos )
535  {
536  aStart = aEnd = rPos;
537  return *this;
538  }
539  void SetInvalid()
540  {
541  aStart.SetInvalid();
542  aEnd.SetInvalid();
543  }
544  bool IsValid() const
545  {
546  return aStart.IsValid() && aEnd.IsValid();
547  }
548  inline bool Contains( const ScAddress& ) const;
549  inline bool Contains( const ScRange& ) const;
550  inline bool Intersects( const ScRange& rRange ) const; // do two ranges intersect?
551 
552  ScRefFlags Parse( const OUString&, const ScDocument&,
554  ScAddress::ExternalInfo* pExtInfo = nullptr,
555  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
556  const OUString* pErrRef = nullptr );
557 
558  ScRefFlags ParseAny( const OUString&, const ScDocument&,
559  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
560  ScRefFlags ParseCols( const ScDocument& rDoc,
561  const OUString&,
562  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
563  void ParseRows( const ScDocument& rDoc,
564  const OUString&,
565  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
566 
588  const sal_Unicode* Parse_XL_Header( const sal_Unicode* pString, const ScDocument& rDocument,
589  OUString& rExternDocName, OUString& rStartTabName,
590  OUString& rEndTabName, ScRefFlags& nFlags,
591  bool bOnlyAcceptSingle,
592  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
593  const OUString* pErrRef = nullptr );
594 
615  OUString Format( const ScDocument& rDocument,
616  ScRefFlags nFlags = ScRefFlags::ZERO,
618  bool bFullAddressNotation = false ) const;
619 
620  inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
621  SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
622  void PutInOrder() { aStart.PutInOrder(aEnd); }
623 
631  [[nodiscard]] bool Move( SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ,
632  ScRange& rErrorRange, const ScDocument& rDoc );
633 
635  [[nodiscard]] bool MoveSticky( const ScDocument& rDoc, SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ,
636  ScRange& rErrorRange );
637 
638  void IncColIfNotLessThan(const ScDocument& rDoc, SCCOL nStartCol, SCCOL nOffset);
639  void IncRowIfNotLessThan(const ScDocument& rDoc, SCROW nStartRow, SCROW nOffset);
640 
641  void ExtendTo( const ScRange& rRange );
642 
643  ScRange Intersection( const ScRange& rOther ) const;
644 
646  bool IsEndColSticky( const ScDocument& rDoc ) const;
648  bool IsEndRowSticky( const ScDocument& rDoc ) const;
649 
653  void IncEndColSticky( const ScDocument& rDoc, SCCOL nDelta );
654 
658  void IncEndRowSticky( const ScDocument& rDoc, SCROW nDelta );
659 
660  inline bool operator==( const ScRange& rRange ) const;
661  inline bool operator!=( const ScRange& rRange ) const;
662  inline bool operator<( const ScRange& rRange ) const;
663  inline bool operator<=( const ScRange& rRange ) const;
664 
666  inline size_t hashArea() const;
668  inline size_t hashStartColumn() const;
669 };
670 
671 // For use in SAL_DEBUG etc. Output format not guaranteed to be stable.
672 template<typename charT, typename traits>
673 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ScRange& rRange)
674 {
675  stream << rRange.aStart;
676  if (rRange.aEnd != rRange.aStart)
677  {
678  stream << ":";
679  if (rRange.aEnd.Tab() != rRange.aStart.Tab())
680  stream << rRange.aEnd;
681  else
682  stream <<
683  "R" << rRange.aEnd.Row()+1 <<
684  "C" << rRange.aEnd.Col()+1;
685  }
686 
687  return stream;
688 }
689 
690 inline void ScRange::GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
691  SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const
692 {
693  aStart.GetVars( nCol1, nRow1, nTab1 );
694  aEnd.GetVars( nCol2, nRow2, nTab2 );
695 }
696 
697 inline bool ScRange::operator==( const ScRange& rRange ) const
698 {
699  return ( (aStart == rRange.aStart) && (aEnd == rRange.aEnd) );
700 }
701 
702 inline bool ScRange::operator!=( const ScRange& rRange ) const
703 {
704  return !operator==( rRange );
705 }
706 
708 inline bool ScRange::operator<( const ScRange& r ) const
709 {
710  return aStart < r.aStart || (aStart == r.aStart && aEnd < r.aEnd) ;
711 }
712 
713 inline bool ScRange::operator<=( const ScRange& rRange ) const
714 {
715  return operator<( rRange ) || operator==( rRange );
716 }
717 
718 inline bool ScRange::Contains( const ScAddress& rAddress ) const
719 {
720  return
721  aStart.Col() <= rAddress.Col() && rAddress.Col() <= aEnd.Col() &&
722  aStart.Row() <= rAddress.Row() && rAddress.Row() <= aEnd.Row() &&
723  aStart.Tab() <= rAddress.Tab() && rAddress.Tab() <= aEnd.Tab();
724 }
725 
726 inline bool ScRange::Contains( const ScRange& rRange ) const
727 {
728  return
729  aStart.Col() <= rRange.aStart.Col() && rRange.aEnd.Col() <= aEnd.Col() &&
730  aStart.Row() <= rRange.aStart.Row() && rRange.aEnd.Row() <= aEnd.Row() &&
731  aStart.Tab() <= rRange.aStart.Tab() && rRange.aEnd.Tab() <= aEnd.Tab();
732 }
733 
734 inline bool ScRange::Intersects( const ScRange& rRange ) const
735 {
736  return
737  aStart.Col() <= rRange.aEnd.Col() && rRange.aStart.Col() <= aEnd.Col() &&
738  aStart.Row() <= rRange.aEnd.Row() && rRange.aStart.Row() <= aEnd.Row() &&
739  aStart.Tab() <= rRange.aEnd.Tab() && rRange.aStart.Tab() <= aEnd.Tab();
740 }
741 
742 inline size_t ScRange::hashArea() const
743 {
744 #if SAL_TYPES_SIZEOFPOINTER == 8
745  // 12 bits for the columns and 20 bits for the rows
746  return
747  (static_cast<size_t>(aStart.Row()) << 44) ^
748  (static_cast<size_t>(aStart.Col()) << 32) ^
749  (static_cast<size_t>(aEnd.Col()) << 20) ^
750  static_cast<size_t>(aEnd.Row());
751 #else
752  // Assume that there are not that many ranges with identical corners so we
753  // won't have too many collisions. Also assume that more lower row and
754  // column numbers are used so that there are not too many conflicts with
755  // the columns hashed into the values, and that start row and column
756  // usually don't exceed certain values. High bits are not masked off and
757  // may overlap with lower bits of other values, e.g. if start column is
758  // greater than assumed.
759  return
760  (static_cast<size_t>(aStart.Row()) << 26) ^ // start row <= 2^6
761  (static_cast<size_t>(aStart.Col()) << 21) ^ // start column <= 2^5
762  (static_cast<size_t>(aEnd.Col()) << 15) ^ // end column <= 2^6
763  static_cast<size_t>(aEnd.Row()); // end row <= 2^15
764 #endif
765 }
766 
767 inline size_t ScRange::hashStartColumn() const
768 {
769 #if SAL_TYPES_SIZEOFPOINTER == 8
770  // 20 bits for the rows
771  return
772  (static_cast<size_t>(aStart.Col()) << 40) ^
773  (static_cast<size_t>(aStart.Row()) << 20) ^
774  static_cast<size_t>(aEnd.Row());
775 #else
776  // Assume that for the start row more lower row numbers are used so that
777  // there are not too many conflicts with the column hashed into the higher
778  // values.
779  return
780  (static_cast<size_t>(aStart.Col()) << 24) ^ // start column <= 2^8
781  (static_cast<size_t>(aStart.Row()) << 16) ^ // start row <= 2^8
782  static_cast<size_t>(aEnd.Row());
783 #endif
784 }
785 
786 [[nodiscard]] inline bool ValidRange( const ScRange& rRange, SCCOL nMaxCol, SCROW nMaxRow )
787 {
788  return ValidAddress(rRange.aStart, nMaxCol, nMaxRow) && ValidAddress(rRange.aEnd, nMaxCol, nMaxRow);
789 }
790 
791 // ScRangePair
793 {
794 private:
795  std::array<ScRange,2> aRange;
796 
797 public:
799  {
800  aRange[0] = r.aRange[0];
801  aRange[1] = r.aRange[1];
802  }
803  ScRangePair( const ScRange& rRange1, const ScRange& rRange2 )
804  {
805  aRange[0] = rRange1;
806  aRange[1] = rRange2;
807  }
808 
809  inline ScRangePair& operator= ( const ScRangePair& rRange );
810  const ScRange& GetRange( sal_uInt16 n ) const
811  {
812  return aRange[n];
813  }
814  ScRange& GetRange( sal_uInt16 n )
815  {
816  return aRange[n];
817  }
818 };
819 
821 {
822  aRange[0] = rRange.aRange[0];
823  aRange[1] = rRange.aRange[1];
824  return *this;
825 }
826 
827 // ScRefAddress
829 {
830 private:
832  bool bRelCol;
833  bool bRelRow;
834  bool bRelTab;
835 public:
837  bRelCol(false), bRelRow(false), bRelTab(false)
838  {}
839  ScRefAddress( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
840  aAdr(nCol, nRow, nTab),
841  bRelCol(false), bRelRow(false), bRelTab(false)
842  {}
843  ScRefAddress( const ScRefAddress& rRef ) :
844  aAdr(rRef.aAdr), bRelCol(rRef.bRelCol), bRelRow(rRef.bRelRow),
845  bRelTab(rRef.bRelTab)
846  {}
847 
848  inline ScRefAddress& operator=( const ScRefAddress& );
849 
850  bool IsRelCol() const
851  {
852  return bRelCol;
853  }
854  bool IsRelRow() const
855  {
856  return bRelRow;
857  }
858  bool IsRelTab() const
859  {
860  return bRelTab;
861  }
862 
863  void SetRelCol(bool bNewRelCol)
864  {
865  bRelCol = bNewRelCol;
866  }
867  void SetRelRow(bool bNewRelRow)
868  {
869  bRelRow = bNewRelRow;
870  }
871  void SetRelTab(bool bNewRelTab)
872  {
873  bRelTab = bNewRelTab;
874  }
875 
876  inline void Set( const ScAddress& rAdr,
877  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
878  inline void Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
879  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
880 
881  const ScAddress& GetAddress() const
882  {
883  return aAdr;
884  }
885 
886  SCCOL Col() const
887  {
888  return aAdr.Col();
889  }
890  SCROW Row() const
891  {
892  return aAdr.Row();
893  }
894  SCTAB Tab() const
895  {
896  return aAdr.Tab();
897  }
898 
899  inline bool operator == ( const ScRefAddress& r ) const;
900 
901  OUString GetRefString( const ScDocument& rDocument, SCTAB nActTab,
902  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
903 };
904 
906 {
907  aAdr = rRef.aAdr;
908  bRelCol = rRef.bRelCol;
909  bRelRow = rRef.bRelRow;
910  bRelTab = rRef.bRelTab;
911  return *this;
912 }
913 
914 inline void ScRefAddress::Set( const ScAddress& rAdr,
915  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
916 {
917  aAdr = rAdr;
918  bRelCol = bNewRelCol;
919  bRelRow = bNewRelRow;
920  bRelTab = bNewRelTab;
921 }
922 
923 inline void ScRefAddress::Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
924  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
925 {
926  aAdr.Set( nNewCol, nNewRow, nNewTab);
927  bRelCol = bNewRelCol;
928  bRelRow = bNewRelRow;
929  bRelTab = bNewRelTab;
930 }
931 
932 inline bool ScRefAddress::operator==( const ScRefAddress& rRefAddress ) const
933 {
934  return aAdr == rRefAddress.aAdr &&
935  bRelCol == rRefAddress.bRelCol &&
936  bRelRow == rRefAddress.bRelRow &&
937  bRelTab == rRefAddress.bRelTab;
938 }
939 
940 // Global functions
941 
942 // Special values for cells always broadcasting or listening (ScRecalcMode::ALWAYS
943 // and the like).
944 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
945 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
946 
947 bool ConvertSingleRef( const ScDocument& pDocument, const OUString& rRefString,
948  SCTAB nDefTab, ScRefAddress& rRefAddress,
949  const ScAddress::Details& rDetails,
950  ScAddress::ExternalInfo* pExtInfo = nullptr );
951 
952 bool ConvertDoubleRef( const ScDocument& rDocument, const OUString& rRefString,
953  SCTAB nDefTab, ScRefAddress& rStartRefAddress,
954  ScRefAddress& rEndRefAddress,
955  const ScAddress::Details& rDetails,
956  ScAddress::ExternalInfo* pExtInfo = nullptr );
957 
959 SC_DLLPUBLIC void ScColToAlpha( OUStringBuffer& rBuffer, SCCOL nCol);
960 
961 inline void ScColToAlpha( OUString& rStr, SCCOL nCol)
962 {
963  OUStringBuffer aBuf(4);
964  ScColToAlpha( aBuf, nCol);
965  rStr += aBuf;
966 }
967 
968 inline OUString ScColToAlpha( SCCOL nCol )
969 {
970  OUStringBuffer aBuf(4);
971  ScColToAlpha( aBuf, nCol);
972  return aBuf.makeStringAndClear();
973 }
974 
976 bool AlphaToCol(const ScDocument& rDoc, SCCOL& rCol, const OUString& rStr);
977 
978 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)
Definition: xlstyle.cxx:519
Details(formula::FormulaGrammar::AddressConvention eConvP)
Definition: address.hxx:235
ScAddress(const ScAddress &rAddress)
Definition: address.hxx:267
void Set(const ScAddress &rAdr, bool bNewRelCol, bool bNewRelRow, bool bNewRelTab)
Definition: address.hxx:914
bool bRelTab
Definition: address.hxx:834
const SCROW SCROWS32K
Definition: address.hxx:92
void GetVars(SCCOL &nColP, SCROW &nRowP, SCTAB &nTabP) const
Definition: address.hxx:324
bool operator!=(const ScAddress &rAddress) const
Definition: address.hxx:423
size_t hashArea() const
Hash 2D area ignoring table number.
Definition: address.hxx:742
ScAddress aStart
Definition: address.hxx:497
SC_DLLPUBLIC void ScColToAlpha(OUStringBuffer &rBuffer, SCCOL nCol)
append alpha representation of column to buffer
Definition: address.cxx:1884
constexpr OUStringLiteral MAXROW_STRING(u"1048575")
constexpr OUStringLiteral MAXROW_JUMBO_STRING(u"16777215")
ScRange(const ScRange &rRange)
Definition: address.hxx:515
const SCROW MAXROW_30
Definition: address.hxx:97
bool operator!=(const XclExpString &rLeft, const XclExpString &rRight)
Definition: xestring.hxx:248
void IncTab(SCTAB nDelta=1)
Definition: address.hxx:320
SCROW Row() const
Definition: address.hxx:274
const SCCOLROW SCCOLROW_MAX
Definition: address.hxx:58
size_t hash() const
Definition: address.hxx:461
bool ConvertDoubleRef(const ScDocument &rDocument, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rStartRefAddress, ScRefAddress &rEndRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo=nullptr)
Definition: address.cxx:1511
ScRangePair & operator=(const ScRangePair &rRange)
Definition: address.hxx:820
constexpr std::underlying_type_t< T > to_underlying(T e)
bool Intersects(const ScRange &rRange) const
Definition: address.hxx:734
size_t hashStartColumn() const
Hash start column and start and end rows.
Definition: address.hxx:767
void SetRelTab(bool bNewRelTab)
Definition: address.hxx:871
const SCCOL SCCOL_MAX
Definition: address.hxx:56
const SCROW MAXROWCOUNT_JUMBO
Definition: address.hxx:72
bool ValidRange(const ScRange &rRange, SCCOL nMaxCol, SCROW nMaxRow)
Definition: address.hxx:786
aBuf
void PutInOrder(ScAddress &rAddress)
Definition: address.hxx:396
ScRange(const ScAddress &rRange)
Definition: address.hxx:518
ScAddress aEnd
Definition: address.hxx:498
bool operator<=(const BigInt &rVal1, const BigInt &rVal2)
ScRange(ScAddress::Uninitialized eUninitialized)
Definition: address.hxx:504
const SCCOL MAXCOLCOUNT
Definition: address.hxx:63
bool operator<(const ScRange &rRange) const
Sort on upper left corner tab,col,row, if equal then use lower right too.
Definition: address.hxx:708
bool operator==(const ScRefAddress &r) const
Definition: address.hxx:932
const SCROW SCROW_MAX
Definition: address.hxx:55
ScRefAddress & operator=(const ScRefAddress &)
Definition: address.hxx:905
exports com.sun.star. sheet
ScAddress(InitializeInvalid)
Definition: address.hxx:264
bool ConvertSingleRef(const ScDocument &pDocument, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo=nullptr)
Definition: address.cxx:1489
constexpr OUStringLiteral MAXCOL_JUMBO_STRING(u"XFD")
sal_uInt16 sal_Unicode
const SCROW MAXROW_JUMBO
Definition: address.hxx:74
ScRange()
Definition: address.hxx:500
bool ValidColRowTab(SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL nMaxCol, SCROW nMaxRow)
Definition: address.hxx:127
formula::FormulaGrammar::AddressConvention eConv
Definition: address.hxx:225
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
const SCROW MAXROW
Definition: address.hxx:68
static SC_DLLPUBLIC const Details detailsOOOa1
Definition: address.hxx:241
SCTAB Tab() const
Definition: address.hxx:283
ScAddress & operator=(const ScAddress &rAddress)
Definition: address.hxx:410
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCROW SanitizeRow(SCROW nRow, SCROW nMaxRow)
Definition: address.hxx:139
SCCOL nCol
Definition: address.hxx:215
const SCCOLROW MAXCOLROW
Definition: address.hxx:71
void SetCol(SCCOL nColP)
Definition: address.hxx:291
ScRange(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
Definition: address.hxx:524
const SCROW MAXROWCOUNT
Definition: address.hxx:62
ScRange & operator=(const ScRange &rRange)
Definition: address.hxx:528
bool ValidAddress(const ScAddress &rAddress, SCCOL nMaxCol, SCROW nMaxRow)
Definition: address.hxx:488
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:150
ScRefAddress(const ScRefAddress &rRef)
Definition: address.hxx:843
bool IsRelTab() const
Definition: address.hxx:858
SCCOL SanitizeCol(SCCOL nCol, SCCOL nMaxCol)
Definition: address.hxx:133
bool IsValid() const
Definition: address.hxx:305
SCROW nRow
Definition: address.hxx:214
ScRange & GetRange(sal_uInt16 n)
Definition: address.hxx:814
bool ValidCol(SCCOL nCol, SCCOL nMaxCol)
Definition: address.hxx:99
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
ScRange & operator=(const ScAddress &rPos)
Definition: address.hxx:534
const SCTAB SC_TAB_APPEND
Definition: address.hxx:90
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:316
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:403
sal_Int16 SCCOL
Definition: types.hxx:21
Details(formula::FormulaGrammar::AddressConvention eConvP, SCROW nRowP, SCCOL nColP)
Definition: address.hxx:229
bool operator!=(const ScRange &rRange) const
Definition: address.hxx:702
void applyStartToEndFlags(ScRefFlags &target, const ScRefFlags source)
Definition: address.hxx:196
const SCTAB MININITTAB
Definition: address.hxx:82
const SCCOL MAXCOL
Definition: address.hxx:69
const SCSIZE SCSIZE_MAX
Definition: address.hxx:59
std::array< ScRange, 2 > aRange
Definition: address.hxx:795
void IncRow(SCROW nDelta=1)
Definition: address.hxx:312
const ScRange & GetRange(sal_uInt16 n) const
Definition: address.hxx:810
ScRange(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:521
InitializeInvalid
Definition: address.hxx:221
constexpr OUStringLiteral MAXCOL_STRING(u"XFD")
bool operator<=(const ScRange &rRange) const
Definition: address.hxx:713
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
Definition: address.hxx:690
bool AlphaToCol(const ScDocument &rDoc, SCCOL &rCol, const OUString &rStr)
get column number of A..IV... string
Definition: address.cxx:2511
ScRangePair(const ScRangePair &r)
Definition: address.hxx:798
const SCTAB MAXTAB
Definition: address.hxx:70
bool operator<(const ScAddress &rAddress) const
Less than ordered by tab,col,row.
Definition: address.hxx:429
void SetInvalid()
Definition: address.hxx:539
bool IsValid() const
Definition: address.hxx:544
const SCROW SCROW_REPEAT_NONE
Definition: address.hxx:94
const SCTAB TABLEID_DOC
Definition: address.hxx:91
const SCTAB MAXINITTAB
Definition: address.hxx:81
ScAddress aAdr
Definition: address.hxx:831
ScRange(const ScAddress &aInputStart, const ScAddress &aInputEnd)
Definition: address.hxx:510
ScRange(ScAddress::InitializeInvalid eInvalid)
Definition: address.hxx:507
SCCOL Col() const
Definition: address.hxx:279
Details(formula::FormulaGrammar::AddressConvention eConvP, ScAddress const &rAddr)
Definition: address.hxx:232
Reference< XOutputStream > stream
#define SAL_WARN_UNUSED
const SCCOL MAXCOLCOUNT_JUMBO
Definition: address.hxx:73
SCTAB SanitizeTab(SCTAB nTab)
Definition: address.hxx:145
sal_Int32 SCROW
Definition: types.hxx:17
bool operator<(const ScDPCollection::DBType &left, const ScDPCollection::DBType &right)
Definition: dpobject.cxx:3931
void PutInOrder()
Definition: address.hxx:622
const ScAddress & GetAddress() const
Definition: address.hxx:881
size_t operator()(const ScAddress &rAddress) const
Definition: address.hxx:482
const SCCOL INITIALCOLCOUNT
Definition: address.hxx:64
const SCCOL MAXCOL_JUMBO
Definition: address.hxx:75
bool IsRelCol() const
Definition: address.hxx:850
bool IsRelRow() const
Definition: address.hxx:854
SCROW Row() const
Definition: address.hxx:890
SCCOL Col() const
Definition: address.hxx:886
bool Contains(const ScAddress &) const
is Address& fully in Range?
Definition: address.hxx:718
void SetInvalid()
Definition: address.hxx:299
const SCROW MAXTILEDROW
Definition: address.hxx:77
void SetRelCol(bool bNewRelCol)
Definition: address.hxx:863
ScRefAddress(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:839
bool ValidColRow(SCCOL nCol, SCROW nRow, SCCOL nMaxCol, SCROW nMaxRow)
Definition: address.hxx:121
bool ValidRow(SCROW nRow, SCROW nMaxRow)
Definition: address.hxx:105
bool bRelCol
Definition: address.hxx:832
SCTAB nTab
Definition: address.hxx:216
const SCCOL SC_TABSTART_NONE
Definition: address.hxx:95
ScAddress(Uninitialized)
coverity[uninit_member] - Yes, it is what it seems to be: Uninitialized.
Definition: address.hxx:262
SCTAB Tab() const
Definition: address.hxx:894
ScAddress(SCCOL nColP, SCROW nRowP, SCTAB nTabP)
Definition: address.hxx:257
bool lessThanByRow(const ScAddress &rAddress) const
Less than ordered by tab,row,col as needed by row-wise import/export.
Definition: address.hxx:448
ScRefFlags
Definition: address.hxx:157
const SCTAB MAXTABCOUNT
limiting to 10000 for now, problem with 32 bit builds for now
Definition: address.hxx:66
const SCTAB SCTAB_MAX
Definition: address.hxx:57
ScRangePair(const ScRange &rRange1, const ScRange &rRange2)
Definition: address.hxx:803
#define SC_DLLPUBLIC
Definition: scdllapi.h:27
bool ValidTab(SCTAB nTab)
Definition: address.hxx:111
const SCCOL SCCOL_REPEAT_NONE
Definition: address.hxx:93
bool operator==(const ScAddress &rAddress) const
Definition: address.hxx:418
bool operator<=(const ScAddress &rAddress) const
Definition: address.hxx:442
sal_Int16 SCTAB
Definition: types.hxx:22
bool bRelRow
Definition: address.hxx:833
void SetRelRow(bool bNewRelRow)
Definition: address.hxx:867
bool m_bDetectedRangeSegmentation false
bool operator==(const ScRange &rRange) const
Definition: address.hxx:697