Skip to content

Commit

Permalink
#1496 - Added support for DateOnly and TimeOnly (supported from .NET …
Browse files Browse the repository at this point in the history
…6 and later). Changed thread locking object in the cellstore and updated a few functions.
  • Loading branch information
JanKallman committed Jun 19, 2024
1 parent 982fd4f commit cc5e1b0
Show file tree
Hide file tree
Showing 9 changed files with 753 additions and 491 deletions.
752 changes: 398 additions & 354 deletions src/EPPlus/Core/CellStore/CellStore.cs

Large diffs are not rendered by default.

260 changes: 138 additions & 122 deletions src/EPPlus/Core/CellStore/ColumnIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ namespace OfficeOpenXml.Core.CellStore
{
internal class ColumnIndex<T> : IndexBase, IDisposable
{
private readonly static object _syncRoot = new object();
internal List<T> _values = new List<T>();
internal PageIndex[] _pages;
internal int PageCount;

public ColumnIndex()
{
Expand All @@ -32,215 +35,228 @@ internal int GetPagePosition(int Row)
{
var page = (Row >> CellStoreSettings._pageBits);
int pagePos;
if (page >= 0 && page < PageCount && _pages[page].Index == page)
{
pagePos = page;
}
else
{
pagePos = ArrayUtil.OptimizedBinarySearch(_pages, page, PageCount);
}

if (pagePos >= 0)
lock (_syncRoot)
{
GetPage(Row, ref pagePos);
return pagePos;
}
else
{
var p = ~pagePos;

if (GetPage(Row, ref p))
if (page >= 0 && page < PageCount && _pages[page].Index == page)
{
return p;
pagePos = page;
}
else
{
return pagePos;
pagePos = ArrayUtil.OptimizedBinarySearch(_pages, page, PageCount);
}
}
}

private bool GetPage(int Row, ref int pagePos)
{
if (pagePos < PageCount && _pages[pagePos].MinIndex <= Row && (pagePos + 1 == PageCount || _pages[pagePos + 1].MinIndex > Row))
{
return true;
}
else
{
if (pagePos + 1 < PageCount && (_pages[pagePos + 1].MinIndex <= Row))
if (pagePos >= 0)
{
do
{
pagePos++;
}
while (pagePos + 1 < PageCount && _pages[pagePos + 1].MinIndex <= Row);
return true;
GetPage(Row, ref pagePos);
return pagePos;
}
else if (pagePos - 1 >= 0 && _pages[pagePos - 1].MaxIndex >= Row)
else
{
do
var p = ~pagePos;

if (GetPage(Row, ref p))
{
pagePos--;
return p;
}
else
{
return pagePos;
}
while (pagePos - 1 > 0 && _pages[pagePos - 1].MaxIndex >= Row);
return true;
}
return false;
}
}
internal int GetNextRow(int row)

private bool GetPage(int Row, ref int pagePos)
{
var p = GetPagePosition(row);
if (p < 0)
lock (_syncRoot)
{
p = ~p;
if (p >= PageCount)
if (pagePos < PageCount && _pages[pagePos].MinIndex <= Row && (pagePos + 1 == PageCount || _pages[pagePos + 1].MinIndex > Row))
{
return -1;
return true;
}
else
{

if (_pages[p].IndexOffset + _pages[p].Rows[0].Index < row)
if (pagePos + 1 < PageCount && (_pages[pagePos + 1].MinIndex <= Row))
{
if (p + 1 >= PageCount)
do
{
return -1;
}
else
{
return _pages[p + 1].IndexOffset + _pages[p].Rows[0].Index;
pagePos++;
}
while (pagePos + 1 < PageCount && _pages[pagePos + 1].MinIndex <= Row);
return true;
}
else
else if (pagePos - 1 >= 0 && _pages[pagePos - 1].MaxIndex >= Row)
{
return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
do
{
pagePos--;
}
while (pagePos - 1 > 0 && _pages[pagePos - 1].MaxIndex >= Row);
return true;
}
return false;
}
}
else
}
internal int GetNextRow(int row)
{
lock (_syncRoot)
{
if (p < PageCount)
var p = GetPagePosition(row);
if (p < 0)
{
var r = _pages[p].GetNextRow(row);
if (r >= 0)
p = ~p;
if (p >= PageCount)
{
return _pages[p].IndexOffset + _pages[p].Rows[r].Index;
return -1;
}
else
{
if (++p < PageCount)

if (_pages[p].IndexOffset + _pages[p].Rows[0].Index < row)
{
return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
if (p + 1 >= PageCount)
{
return -1;
}
else
{
return _pages[p + 1].IndexOffset + _pages[p].Rows[0].Index;
}
}
else
{
return -1;
return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
}
}
}
else
{
return -1;
}
}
}
internal int GetPrevRow(int row)
{
var p = GetPagePosition(row);
if (p < 0)
{
p = (~p)-1;
if (p < 0)
{
return -1;
}
else
{

if (_pages[p].IndexOffset + _pages[p].Rows[0].Index < row)
if (p < PageCount)
{
if (p + 1 >= PageCount)
var r = _pages[p].GetNextRow(row);
if (r >= 0)
{
return -1;
return _pages[p].IndexOffset + _pages[p].Rows[r].Index;
}
else
{
return _pages[p + 1].IndexOffset + _pages[p].Rows[0].Index;
if (++p < PageCount)
{
return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
}
else
{
return -1;
}
}
}
else
{
return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
return -1;
}
}
}
else
}
internal int GetPrevRow(int row)
{
lock (_syncRoot)
{
if (p < PageCount)
var p = GetPagePosition(row);
if (p < 0)
{
var r = _pages[p].GetNextRow(row);
if (r >= 0)
p = (~p) - 1;
if (p < 0)
{
return _pages[p].IndexOffset + _pages[p].Rows[r].Index;
return -1;
}
else
{
if (++p < PageCount)

if (_pages[p].IndexOffset + _pages[p].Rows[0].Index < row)
{
return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
if (p + 1 >= PageCount)
{
return -1;
}
else
{
return _pages[p + 1].IndexOffset + _pages[p].Rows[0].Index;
}
}
else
{
return -1;
return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
}
}
}
else
{
return -1;
if (p < PageCount)
{
var r = _pages[p].GetNextRow(row);
if (r >= 0)
{
return _pages[p].IndexOffset + _pages[p].Rows[r].Index;
}
else
{
if (++p < PageCount)
{
return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
}
else
{
return -1;
}
}
}
else
{
return -1;
}
}
}
}

internal int GetPointer(int Row)
{
var pos = GetPagePosition(Row);
if (pos >= 0 && pos < PageCount)
{
var pageItem = _pages[pos];
if (pageItem.MinIndex > Row)
//lock (_syncRoot)
//{
var pos = GetPagePosition(Row);
if (pos >= 0 && pos < PageCount)
{
pos--;
if (pos < 0)
var pageItem = _pages[pos];
if (pageItem.MinIndex > Row)
{
return -1;
pos--;
if (pos < 0)
{
return -1;
}
else
{
pageItem = _pages[pos];
}
}
else
int ix = Row - pageItem.IndexOffset;
var cellPos = ArrayUtil.OptimizedBinarySearch(pageItem.Rows, ix, pageItem.RowCount);
if (cellPos >= 0)
{
pageItem = _pages[pos];
return pageItem.Rows[cellPos].IndexPointer;
}
else //Cell does not exist
{
return -1;
}
}
int ix = Row - pageItem.IndexOffset;
var cellPos = ArrayUtil.OptimizedBinarySearch(pageItem.Rows, ix, pageItem.RowCount);
if (cellPos >= 0)
{
return pageItem.Rows[cellPos].IndexPointer;
}
else //Cell does not exist
else //Page does not exist
{
return -1;
}
}
else //Page does not exist
{
return -1;
}
// }
}
internal PageIndex[] _pages;
internal int PageCount;
public void Dispose()
{
if (_pages == null) return;
Expand Down
2 changes: 1 addition & 1 deletion src/EPPlus/Core/Worksheet/XmlWriter/WorksheetXmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ private void UpdateRowCellData(StreamWriter sw, string prefix)
else
v = string.Empty;
}
if ((TypeCompat.IsPrimitive(v) || v is double || v is decimal || v is DateTime || v is TimeSpan) && !(v is char))
if (ConvertUtil.IsNumericOrDateDatatype(v))
{
cache.Append($"<{cTag} r=\"{cse.CellAddress}\" s=\"{styleID}\"{ConvertUtil.GetCellType(v)}{mdAttr}>");
cache.Append($"{GetFormulaValue(v, prefix)}</{cTag}>");
Expand Down
Loading

0 comments on commit cc5e1b0

Please sign in to comment.