Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for DateOnly and TimeOnly #1498

Open
wants to merge 1 commit into
base: develop7
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
#1496 - Added support for DateOnly and TimeOnly (supported from .NET …
…6 and later). Changed thread locking object in the cellstore and updated a few functions.
  • Loading branch information
JanKallman committed Jun 19, 2024
commit cc5e1b04083ef198e505e64efb87c505650dc5b5
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