From c7ca66897a71ee7998b01b6c459004ea1d7c3985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 10 Dec 2021 20:16:26 +0100 Subject: [PATCH 01/45] Ignore libxlsxreader.a --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5920849..2f9da7f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ xlsxreader-test-* *.o *.obj *.lst +libxlsxreader.a From 6dff694e76f9cfd310069d2e56b23241d2920c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 10 Dec 2021 20:23:23 +0100 Subject: [PATCH 02/45] Qualify all Cell members starting with convertTo as const --- source/xlsxreader.d | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index b5fe8bb..6a8a3ea 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -132,31 +132,31 @@ struct Cell { (); } - bool convertToBool() { + bool convertToBool() const { return convertTo!bool(this.value); } - long convertToLong() { + long convertToLong() const { return convertTo!long(this.value); } - double convertToDouble() { + double convertToDouble() const { return convertTo!double(this.value); } - string convertToString() { + string convertToString() const { return convertTo!string(this.value); } - Date convertToDate() { + Date convertToDate() const { return convertTo!Date(this.value); } - TimeOfDay convertToTimeOfDay() { + TimeOfDay convertToTimeOfDay() const { return convertTo!TimeOfDay(this.value); } - DateTime convertToDateTime() { + DateTime convertToDateTime() const { return convertTo!DateTime(this.value); } } @@ -783,7 +783,7 @@ struct SheetNameId { string rid; } -string convertToString(ubyte[] d) { +string convertToString(const ubyte[] d) { import std.encoding; auto b = getBOM(d); switch(b.schema) { From 6169aee7392de67aadd7fc266ed8803100d3e9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 10 Dec 2021 20:25:21 +0100 Subject: [PATCH 03/45] Ignore dub.selections.json --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2f9da7f..69016c7 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ xlsxreader-test-* *.obj *.lst libxlsxreader.a +dub.selections.json From 2b37c80a75bcf8244252a020d8350983c61f5839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 10 Dec 2021 20:43:53 +0100 Subject: [PATCH 04/45] Qualify all Cell members starting with convertTo as @trusted --- source/xlsxreader.d | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 6a8a3ea..6cf2af9 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -132,31 +132,31 @@ struct Cell { (); } - bool convertToBool() const { + bool convertToBool() @trusted const { return convertTo!bool(this.value); } - long convertToLong() const { + long convertToLong() @trusted const { return convertTo!long(this.value); } - double convertToDouble() const { + double convertToDouble() @trusted const { return convertTo!double(this.value); } - string convertToString() const { + string convertToString() @trusted const { return convertTo!string(this.value); } - Date convertToDate() const { + Date convertToDate() @trusted const { return convertTo!Date(this.value); } - TimeOfDay convertToTimeOfDay() const { + TimeOfDay convertToTimeOfDay() @trusted const { return convertTo!TimeOfDay(this.value); } - DateTime convertToDateTime() const { + DateTime convertToDateTime() @trusted const { return convertTo!DateTime(this.value); } } From 2d85223deb9c92445d781b3c7f1158b86a1362aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 9 Feb 2022 11:14:40 +0100 Subject: [PATCH 05/45] Add overload of getRow that defaults `end` to `start + 1` --- source/xlsxreader.d | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 6cf2af9..6298aa0 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -281,6 +281,11 @@ struct Sheet { // Row + Iterator!T getRow(T)(size_t row, size_t start) { + auto c = this.iterateRow!T(row, start, start + 1); + return Iterator!T(c.array); + } + Iterator!T getRow(T)(size_t row, size_t start, size_t end) { auto c = this.iterateRow!T(row, start, end); return Iterator!T(c.array); From 01bab67428ab882b1ebf1b87bad76cf583637145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Thu, 10 Feb 2022 22:38:58 +0100 Subject: [PATCH 06/45] Rename start and end to more descriptive names and default init them to 0 and size_t.max when releveant --- source/xlsxreader.d | 129 +++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 69 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 6298aa0..ea8218e 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -227,14 +227,14 @@ struct Sheet { // Column - Iterator!T getColumn(T)(size_t col, size_t start, size_t end) { - auto c = this.iterateColumn!T(col, start, end); + Iterator!T getColumn(T)(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { + auto c = this.iterateColumn!T(col, startColumn, endColumn); return Iterator!T(c.array); } private enum t = q{ - Iterator!(%1$s) getColumn%2$s(size_t col, size_t start, size_t end) { - return getColumn!(%1$s)(col, start, end); + Iterator!(%1$s) getColumn%2$s(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { + return getColumn!(%1$s)(col, startColumn, endColumn); } }; static foreach(T; ["long", "double", "string", "Date", "TimeOfDay", @@ -243,57 +243,50 @@ struct Sheet { mixin(format(t, T, T[0].toUpper ~ T[1 .. $])); } - ColumnUntyped iterateColumnUntyped(size_t col, size_t start, size_t end) { - return ColumnUntyped(&this, col, start, end); + ColumnUntyped iterateColumnUntyped(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { + return ColumnUntyped(&this, col, startColumn, endColumn); } - Column!(T) iterateColumn(T)(size_t col, size_t start, size_t end) { - return Column!(T)(&this, col, start, end); + Column!(T) iterateColumn(T)(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Column!(T)(&this, col, startColumn, endColumn); } - Column!(long) iterateColumnLong(size_t col, size_t start, size_t end) { - return Column!(long)(&this, col, start, end); + Column!(long) iterateColumnLong(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Column!(long)(&this, col, startColumn, endColumn); } - Column!(double) iterateColumnDouble(size_t col, size_t start, size_t end) { - return Column!(double)(&this, col, start, end); + Column!(double) iterateColumnDouble(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Column!(double)(&this, col, startColumn, endColumn); } - Column!(string) iterateColumnString(size_t col, size_t start, size_t end) { - return Column!(string)(&this, col, start, end); + Column!(string) iterateColumnString(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Column!(string)(&this, col, startColumn, endColumn); } - Column!(DateTime) iterateColumnDateTime(size_t col, size_t start, - size_t end) + Column!(DateTime) iterateColumnDateTime(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(DateTime)(&this, col, start, end); + return Column!(DateTime)(&this, col, startColumn, endColumn); } - Column!(Date) iterateColumnDate(size_t col, size_t start, size_t end) { - return Column!(Date)(&this, col, start, end); + Column!(Date) iterateColumnDate(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Column!(Date)(&this, col, startColumn, endColumn); } - Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t start, - size_t end) + Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(TimeOfDay)(&this, col, start, end); + return Column!(TimeOfDay)(&this, col, startColumn, endColumn); } // Row - Iterator!T getRow(T)(size_t row, size_t start) { - auto c = this.iterateRow!T(row, start, start + 1); - return Iterator!T(c.array); - } - - Iterator!T getRow(T)(size_t row, size_t start, size_t end) { - auto c = this.iterateRow!T(row, start, end); + Iterator!T getRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + auto c = this.iterateRow!T(row, startColumn, endColumn); return Iterator!T(c.array); } private enum t2 = q{ - Iterator!(%1$s) getRow%2$s(size_t row, size_t start, size_t end) { - return getRow!(%1$s)(row, start, end); + Iterator!(%1$s) getRow%2$s(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + return getRow!(%1$s)(row, startColumn, endColumn); } }; static foreach(T; ["long", "double", "string", "Date", "TimeOfDay", @@ -302,40 +295,38 @@ struct Sheet { mixin(format(t2, T, T[0].toUpper ~ T[1 .. $])); } - RowUntyped iterateRowUntyped(size_t row, size_t start, size_t end) { - return RowUntyped(&this, row, start, end); + RowUntyped iterateRowUntyped(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + return RowUntyped(&this, row, startColumn, endColumn); } - Row!(T) iterateRow(T)(size_t row, size_t start, size_t end) { - return Row!(T)(&this, row, start, end); + Row!(T) iterateRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Row!(T)(&this, row, startColumn, endColumn); } - Row!(long) iterateRowLong(size_t row, size_t start, size_t end) { - return Row!(long)(&this, row, start, end); + Row!(long) iterateRowLong(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Row!(long)(&this, row, startColumn, endColumn); } - Row!(double) iterateRowDouble(size_t row, size_t start, size_t end) { - return Row!(double)(&this, row, start, end); + Row!(double) iterateRowDouble(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Row!(double)(&this, row, startColumn, endColumn); } - Row!(string) iterateRowString(size_t row, size_t start, size_t end) { - return Row!(string)(&this, row, start, end); + Row!(string) iterateRowString(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Row!(string)(&this, row, startColumn, endColumn); } - Row!(DateTime) iterateRowDateTime(size_t row, size_t start, - size_t end) + Row!(DateTime) iterateRowDateTime(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(DateTime)(&this, row, start, end); + return Row!(DateTime)(&this, row, startColumn, endColumn); } - Row!(Date) iterateRowDate(size_t row, size_t start, size_t end) { - return Row!(Date)(&this, row, start, end); + Row!(Date) iterateRowDate(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + return Row!(Date)(&this, row, startColumn, endColumn); } - Row!(TimeOfDay) iterateRowTimeOfDay(size_t row, size_t start, - size_t end) + Row!(TimeOfDay) iterateRowTimeOfDay(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(TimeOfDay)(&this, row, start, end); + return Row!(TimeOfDay)(&this, row, startColumn, endColumn); } } @@ -367,20 +358,20 @@ struct Iterator(T) { struct RowUntyped { Sheet* sheet; /*const*/ size_t row; - size_t start; - size_t end; + size_t startColumn; + size_t endColumn; size_t cur; - this(Sheet* sheet, size_t row, size_t start, size_t end) { + this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) { this.sheet = sheet; this.row = row; - this.start = start; - this.end = end; - this.cur = this.start; + this.startColumn = startColumn; + this.endColumn = endColumn; + this.cur = this.startColumn; } @property bool empty() const { - return this.cur >= this.end; + return this.cur >= this.endColumn; } void popFront() { @@ -402,8 +393,8 @@ struct Row(T) { T front; - this(Sheet* sheet, size_t row, size_t start, size_t end) { - this.ru = RowUntyped(sheet, row, start, end); + this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) { + this.ru = RowUntyped(sheet, row, startColumn, endColumn); this.read(); } @@ -427,7 +418,7 @@ struct Row(T) { } bool canConvertTo(CellType ct) const { - for(size_t it = this.ru.start; it < this.ru.end; ++it) { + for(size_t it = this.ru.startColumn; it < this.ru.endColumn; ++it) { if(!this.ru.sheet.table[this.ru.row][it].canConvertTo(ct)) { return false; } @@ -440,20 +431,20 @@ struct Row(T) { struct ColumnUntyped { Sheet* sheet; /*const*/ size_t col; - size_t start; - size_t end; + size_t startRow; + size_t endRow; size_t cur; - this(Sheet* sheet, size_t col, size_t start, size_t end) { + this(Sheet* sheet, size_t col, size_t startRow, size_t endRow) { this.sheet = sheet; this.col = col; - this.start = start; - this.end = end; - this.cur = this.start; + this.startRow = startRow; + this.endRow = endRow; + this.cur = this.startRow; } @property bool empty() const { - return this.cur >= this.end; + return this.cur >= this.endRow; } void popFront() { @@ -475,8 +466,8 @@ struct Column(T) { T front; - this(Sheet* sheet, size_t col, size_t start, size_t end) { - this.cu = ColumnUntyped(sheet, col, start, end); + this(Sheet* sheet, size_t col, size_t startRow, size_t endRow) { + this.cu = ColumnUntyped(sheet, col, startRow, endRow); this.read(); } @@ -500,7 +491,7 @@ struct Column(T) { } bool canConvertTo(CellType ct) const { - for(size_t it = this.cu.start; it < this.cu.end; ++it) { + for(size_t it = this.cu.startRow; it < this.cu.endRow; ++it) { if(!this.cu.sheet.table[it][this.cu.col].canConvertTo(ct)) { return false; } From e6c64fc4ed5dc8b47577a3e1f75c0d5f7c16f406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 11 Feb 2022 12:45:39 +0100 Subject: [PATCH 07/45] Remove unused import --- source/xlsxreader.d | 1 - 1 file changed, 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index ea8218e..a3ee2d4 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -6,7 +6,6 @@ import std.algorithm.searching : all, canFind, startsWith; import std.algorithm.sorting : sort; import std.array : array, empty, front, popFront; import std.ascii : isDigit; -import std.experimental.logger; import std.conv : to; import std.datetime : DateTime, Date, TimeOfDay; import std.exception : enforce; From cda0f60d0e7559b126901a9dc6a72e41d3828449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 18 Feb 2022 14:29:31 +0100 Subject: [PATCH 08/45] Qualify members of xlsxreader --- source/xlsxreader.d | 47 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index a3ee2d4..836a337 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -22,6 +22,8 @@ import std.zip; import dxml.dom; +@safe: + /// struct Pos { // zero based @@ -44,7 +46,7 @@ struct Cell { Data value; Pos position; - bool canConvertTo(CellType ct) const { + bool canConvertTo(CellType ct) const @trusted { auto b = (bool l) { switch(ct) { case CellType.datetime: return false; @@ -178,7 +180,7 @@ struct Sheet { Cell[][] table; Pos maxPos; - string toString() { + string toString() @trusted { import std.format : formattedWrite; import std.array : appender; long[] maxCol = new long[](maxPos.col + 1); @@ -655,7 +657,7 @@ Date stringToDate(string s) { } } -bool tryConvertTo(T,S)(S var) { +bool tryConvertTo(T,S)(S var) @trusted { return !(tryConvertToImpl!T(Data(var)).isNull()); } @@ -667,7 +669,7 @@ Nullable!(T) tryConvertToImpl(T)(Data var) { } } -T convertTo(T)(Data var) { + T convertTo(T)(Data var) @trusted { static if(is(T == Data)) { return var; } else static if(isSomeString!T) { @@ -764,12 +766,9 @@ T convertTo(T)(Data var) { } -private ZipArchive readFile(string filename) { - enforce(exists(filename), "File with name " ~ filename ~ " does not - exist"); - - auto file = new ZipArchive(read(filename)); - return file; +private ZipArchive readFile(string filename) @trusted { + enforce(exists(filename), "File with name " ~ filename ~ " does not exist"); + return new typeof(return)(read(filename)); } struct SheetNameId { @@ -778,7 +777,7 @@ struct SheetNameId { string rid; } -string convertToString(const ubyte[] d) { +string convertToString(const ubyte[] d) @trusted { import std.encoding; auto b = getBOM(d); switch(b.schema) { @@ -797,7 +796,7 @@ string convertToString(const ubyte[] d) { } } -SheetNameId[] sheetNames(string filename) { +SheetNameId[] sheetNames(string filename) @trusted { auto file = readFile(filename); auto ams = file.directory; immutable wbStr = "xl/workbook.xml"; @@ -839,7 +838,7 @@ struct Relationships { string file; } -Relationships[string] parseRelationships(ZipArchive za, ArchiveMember am) { +Relationships[string] parseRelationships(ZipArchive za, ArchiveMember am) @trusted { ubyte[] d = za.expand(am); string relData = convertToString(d); auto dom = parseDOM(relData); @@ -878,7 +877,7 @@ string eatXlPrefix(string fn) { return fn; } -Sheet readSheetImpl(string filename, string rid) { +Sheet readSheetImpl(string filename, string rid) @trusted { scope(failure) { writefln("Failed at file '%s' and sheet '%s'", filename, rid); } @@ -917,7 +916,7 @@ Sheet readSheetImpl(string filename, string rid) { return ret; } -Data[] readSharedEntries(ZipArchive za, ArchiveMember am) { +Data[] readSharedEntries(ZipArchive za, ArchiveMember am) @trusted { ubyte[] ss = za.expand(am); string ssData = convertToString(ss); auto dom = parseDOM(ssData); @@ -1000,7 +999,7 @@ private bool canConvertToDouble(string s) { return cap.empty || cap.front.hit != s ? false : true; } -Data convert(string s) { +Data convert(string s) @trusted { struct ToRe { string from; string to; @@ -1034,7 +1033,7 @@ Data convert(string s) { } } -Cell[] readCells(ZipArchive za, ArchiveMember am) { +Cell[] readCells(ZipArchive za, ArchiveMember am) @trusted { Cell[] ret; ubyte[] ss = za.expand(am); string ssData = convertToString(ss); @@ -1104,7 +1103,7 @@ Cell[] readCells(ZipArchive za, ArchiveMember am) { return ret; } -Cell[] insertValueIntoCell(Cell[] cells, Data[] ss) { +Cell[] insertValueIntoCell(Cell[] cells, Data[] ss) @trusted { immutable excepted = ["n", "s", "b", "e", "str", "inlineStr"]; immutable same = ["n", "e", "str", "inlineStr"]; foreach(ref Cell c; cells) { @@ -1153,7 +1152,7 @@ Pos elementMax(Pos a, Pos b) { a.col < b.col ? b.col : a.col); } -unittest { +@trusted unittest { import std.math : approxEqual; auto r = readSheet("multitable.xlsx", "wb1"); assert(approxEqual(r.table[12][5].value.get!double(), 26.74), @@ -1165,7 +1164,7 @@ unittest { ); } -unittest { +@trusted unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "wb1"); auto r = s.iterateRow!long(15, 1, 6); @@ -1188,7 +1187,7 @@ unittest { .array; } -unittest { +@trusted unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "wb2"); //writefln("%s\n%(%s\n%)", s.maxPos, s.cells); @@ -1210,7 +1209,7 @@ unittest { assert(equal(rslt, it2)); } -unittest { +@trusted unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "Sheet3"); writeln(s.table[0][0].value.type()); @@ -1219,7 +1218,7 @@ unittest { assert(s.table[0][0].canConvertTo(CellType.bool_)); } -unittest { +@trusted unittest { import std.file : dirEntries, SpanMode; import std.traits : EnumMembers; foreach(de; dirEntries("xlsx_files/", "*.xlsx", SpanMode.depth) @@ -1260,7 +1259,7 @@ unittest { assert(equal(c2, r2), format("%s", c2)); } -unittest { +@trusted unittest { import std.math : approxEqual; auto sheet = readSheet("toto.xlsx", "Trades"); writefln("%(%s\n%)", sheet.cells); From c278cb16b7992fa03b11ea317177d3b930bbef96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 18 Feb 2022 14:35:50 +0100 Subject: [PATCH 09/45] Set default values for RowUntyped parameters --- source/xlsxreader.d | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 836a337..9ca20c2 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -358,32 +358,32 @@ struct Iterator(T) { /// struct RowUntyped { Sheet* sheet; - /*const*/ size_t row; - size_t startColumn; - size_t endColumn; + const size_t row; + const size_t startColumn; + const size_t endColumn; size_t cur; - this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) { + this(Sheet* sheet, in size_t row, in size_t startColumn = 0, in size_t endColumn = size_t.max) pure nothrow @nogc { this.sheet = sheet; this.row = row; this.startColumn = startColumn; - this.endColumn = endColumn; + this.endColumn = endColumn != size_t.max ? endColumn : sheet.table[row].length; this.cur = this.startColumn; } - @property bool empty() const { + @property bool empty() const pure nothrow @nogc { return this.cur >= this.endColumn; } - void popFront() { + void popFront() pure nothrow @nogc { ++this.cur; } - typeof(this) save() { + inout(typeof(this)) save() inout pure nothrow @nogc { return this; } - @property Cell front() { + @property inout(Cell) front() inout pure nothrow @nogc { return this.sheet.table[this.row][this.cur]; } } From 615544ecb2d1071a92e25a836bff735a2142b05d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 18 Feb 2022 14:36:22 +0100 Subject: [PATCH 10/45] Qualify all empty --- source/xlsxreader.d | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 9ca20c2..9f136e0 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -338,7 +338,7 @@ struct Iterator(T) { this.data = data; } - @property bool empty() const { + @property bool empty() const pure nothrow @nogc { return this.data.empty; } @@ -391,7 +391,6 @@ struct RowUntyped { /// struct Row(T) { RowUntyped ru; - T front; this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) { @@ -399,7 +398,7 @@ struct Row(T) { this.read(); } - @property bool empty() const { + @property bool empty() const pure nothrow @nogc { return this.ru.empty; } @@ -444,7 +443,7 @@ struct ColumnUntyped { this.cur = this.startRow; } - @property bool empty() const { + @property bool empty() const pure nothrow @nogc { return this.cur >= this.endRow; } @@ -472,7 +471,7 @@ struct Column(T) { this.read(); } - @property bool empty() const { + @property bool empty() const pure nothrow @nogc { return this.cu.empty; } From 4acfec5df266aa80a58028c3e47a2b430a9cd39c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 18 Feb 2022 14:37:10 +0100 Subject: [PATCH 11/45] Set default parameters of Row.this() --- source/xlsxreader.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 9f136e0..89504fb 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -393,9 +393,9 @@ struct Row(T) { RowUntyped ru; T front; - this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) { - this.ru = RowUntyped(sheet, row, startColumn, endColumn); - this.read(); + this(Sheet* sheet, size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + ru = RowUntyped(sheet, row, startColumn, endColumn); + read(); } @property bool empty() const pure nothrow @nogc { From ecaf75a2577e834022b9f2c71a626308602ce12c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 18 Feb 2022 14:38:52 +0100 Subject: [PATCH 12/45] Qualify all save() members --- source/xlsxreader.d | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 89504fb..6f8b8e7 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -350,7 +350,7 @@ struct Iterator(T) { return this.data.front; } - typeof(this) save() { + inout(typeof(this)) save() inout pure nothrow @nogc { return this; } } @@ -409,7 +409,7 @@ struct Row(T) { } } - typeof(this) save() { + inout(typeof(this)) save() inout pure nothrow @nogc { return this; } @@ -451,7 +451,7 @@ struct ColumnUntyped { ++this.cur; } - typeof(this) save() { + inout(typeof(this)) save() inout pure nothrow @nogc { return this; } @@ -482,7 +482,7 @@ struct Column(T) { } } - typeof(this) save() { + inout(typeof(this)) save() inout pure nothrow @nogc { return this; } From b0e576b8bb64b5ef0d1efda1b031b0feb8d79a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 18 Feb 2022 14:41:09 +0100 Subject: [PATCH 13/45] Initialize ColumnUntyped and Column parameters --- source/xlsxreader.d | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 6f8b8e7..b063041 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -430,16 +430,16 @@ struct Row(T) { /// struct ColumnUntyped { Sheet* sheet; - /*const*/ size_t col; - size_t startRow; - size_t endRow; + const size_t col; + const size_t startRow; + const size_t endRow; size_t cur; - this(Sheet* sheet, size_t col, size_t startRow, size_t endRow) { + this(Sheet* sheet, size_t col, size_t startRow = 0, size_t endRow = size_t.max) { this.sheet = sheet; this.col = col; this.startRow = startRow; - this.endRow = endRow; + this.endRow = endRow != size_t.max ? endRow : sheet.table.length; this.cur = this.startRow; } @@ -466,7 +466,7 @@ struct Column(T) { T front; - this(Sheet* sheet, size_t col, size_t startRow, size_t endRow) { + this(Sheet* sheet, size_t col, size_t startRow = 0, size_t endRow = size_t.max) { this.cu = ColumnUntyped(sheet, col, startRow, endRow); this.read(); } From e04d3af2fc905e33e9257e4a4eaf2798a6799aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Mon, 21 Feb 2022 12:08:15 +0100 Subject: [PATCH 14/45] Add asserts to RowUntyped and ColumnUntyped --- source/xlsxreader.d | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index b063041..4d60a52 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -364,10 +364,11 @@ struct RowUntyped { size_t cur; this(Sheet* sheet, in size_t row, in size_t startColumn = 0, in size_t endColumn = size_t.max) pure nothrow @nogc { + assert(sheet.table.length == sheet.maxPos.row + 1); this.sheet = sheet; this.row = row; this.startColumn = startColumn; - this.endColumn = endColumn != size_t.max ? endColumn : sheet.table[row].length; + this.endColumn = endColumn != size_t.max ? endColumn : sheet.maxPos.col + 1; this.cur = this.startColumn; } @@ -436,10 +437,11 @@ struct ColumnUntyped { size_t cur; this(Sheet* sheet, size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + assert(sheet.table.length == sheet.maxPos.row + 1); this.sheet = sheet; this.col = col; this.startRow = startRow; - this.endRow = endRow != size_t.max ? endRow : sheet.table.length; + this.endRow = endRow != size_t.max ? endRow : sheet.maxPos.row + 1; this.cur = this.startRow; } @@ -912,6 +914,7 @@ Sheet readSheetImpl(string filename, string rid) @trusted { foreach(c; ret.cells) { ret.table[c.position.row][c.position.col] = c; } + // debug writeln("xlsxreader: sheet members: cells.length:", ret.cells.length, " table.length:", ret.table.length, " table[0].length:", ret.table[0].length, " ret.maxPos:", ret.maxPos); return ret; } From cc7928edc592ad065ffcb9e1a826c1a153adbccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Mon, 21 Feb 2022 13:47:57 +0100 Subject: [PATCH 15/45] Expose Iterator as a an array via alias this --- source/xlsxreader.d | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 4d60a52..b70dd6c 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -353,6 +353,8 @@ struct Iterator(T) { inout(typeof(this)) save() inout pure nothrow @nogc { return this; } + + alias data this; } /// From e2b2a85962d43843bdb82e9c38b8401f5f7a84c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Mon, 21 Feb 2022 14:21:56 +0100 Subject: [PATCH 16/45] Add Iterator.array --- source/xlsxreader.d | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index b70dd6c..147299a 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -354,7 +354,10 @@ struct Iterator(T) { return this; } - alias data this; + // Request random access. + inout(T)[] array() inout @safe pure nothrow @nogc { + return data; + } } /// From 6840578add1ddceb7a424bd6b84c617744fa684e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Mon, 21 Feb 2022 14:38:11 +0100 Subject: [PATCH 17/45] Add TODO --- source/xlsxreader.d | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 147299a..ceaf7de 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -1,3 +1,4 @@ +// TODO: add const access to getter functions, such as `getRow` module xlsxreader; import std.algorithm.iteration : filter, map, joiner; @@ -282,7 +283,7 @@ struct Sheet { Iterator!T getRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { auto c = this.iterateRow!T(row, startColumn, endColumn); - return Iterator!T(c.array); + return Iterator!T(c.array); // TODO: why .array? } private enum t2 = q{ From 64c88a288039cdf88f470bce2076c50f75b0bbe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Tue, 22 Feb 2022 10:06:17 +0100 Subject: [PATCH 18/45] Qualify some parameters and members as const or in --- source/xlsxreader.d | 159 ++++++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 80 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index ceaf7de..c0bf8cf 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -181,7 +181,7 @@ struct Sheet { Cell[][] table; Pos maxPos; - string toString() @trusted { + string toString() const @trusted { import std.format : formattedWrite; import std.array : appender; long[] maxCol = new long[](maxPos.col + 1); @@ -223,7 +223,7 @@ struct Sheet { return app.data; } - void printTable() { + void printTable() const { writeln(this.toString()); } @@ -676,104 +676,103 @@ Nullable!(T) tryConvertToImpl(T)(Data var) { } } - T convertTo(T)(Data var) @trusted { +T convertTo(T)(in Data var) @trusted { static if(is(T == Data)) { return var; } else static if(isSomeString!T) { return var.visit!( - (bool l) => to!string(l), - (long l) => to!string(l), - (double l) => format("%f", l), - (string l) => l, - (DateTime l) => l.toISOExtString(), - (Date l) => l.toISOExtString(), - (TimeOfDay l) => l.toISOExtString(), - () => "") - (); + (bool l) => to!string(l), + (long l) => to!string(l), + (double l) => format("%f", l), + (string l) => l, + (DateTime l) => l.toISOExtString(), + (Date l) => l.toISOExtString(), + (TimeOfDay l) => l.toISOExtString(), + () => "") + (); } else static if(is(T == bool)) { if(var.type != typeid(bool) && var.type != typeid(long) - && var.type == typeid(string)) + && var.type == typeid(string)) { throw new Exception("Can not convert " ~ var.type.toString() ~ - " to bool"); + " to bool"); } return var.visit!( - (bool l) => l, - (long l) => l == 0 ? false : true, - (string l) => to!bool(l), - (double l) => false, - (DateTime l) => false, - (Date l) => false, - (TimeOfDay l) => false, - () => false) - (); + (bool l) => l, + (long l) => l == 0 ? false : true, + (string l) => to!bool(l), + (double l) => false, + (DateTime l) => false, + (Date l) => false, + (TimeOfDay l) => false, + () => false) + (); } else static if(isIntegral!T) { return var.visit!( - (bool l) => to!T(l), - (long l) => to!T(l), - (double l) => to!T(l), - (string l) => to!T(l), - (DateTime l) => to!T(dateToLong(l.date)), - (Date l) => to!T(dateToLong(l)), - (TimeOfDay l) => to!T(0), - () => to!T(0)) - (); + (bool l) => to!T(l), + (long l) => to!T(l), + (double l) => to!T(l), + (string l) => to!T(l), + (DateTime l) => to!T(dateToLong(l.date)), + (Date l) => to!T(dateToLong(l)), + (TimeOfDay l) => to!T(0), + () => to!T(0)) + (); } else static if(isFloatingPoint!T) { return var.visit!( - (bool l) => to!T(l), - (long l) => to!T(l), - (double l) => to!T(l), - (string l) => to!T(l), - (DateTime l) => to!T(dateToLong(l.date)), - (Date l) => to!T(dateToLong(l)), - (TimeOfDay l) => to!T(0), - () => T.init) - (); + (bool l) => to!T(l), + (long l) => to!T(l), + (double l) => to!T(l), + (string l) => to!T(l), + (DateTime l) => to!T(dateToLong(l.date)), + (Date l) => to!T(dateToLong(l)), + (TimeOfDay l) => to!T(0), + () => T.init) + (); } else static if(is(T == DateTime)) { return var.visit!( - (bool l) => DateTime.init, - (long l) => doubleToDateTime(to!long(l)), - (double l) => doubleToDateTime(l), - (string l) => doubleToDateTime(to!double(l)), - (DateTime l) => l, - (Date l) => DateTime(l, TimeOfDay.init), - (TimeOfDay l) => DateTime(Date.init, l), - () => DateTime.init) - (); + (bool l) => DateTime.init, + (long l) => doubleToDateTime(to!long(l)), + (double l) => doubleToDateTime(l), + (string l) => doubleToDateTime(to!double(l)), + (DateTime l) => l, + (Date l) => DateTime(l, TimeOfDay.init), + (TimeOfDay l) => DateTime(Date.init, l), + () => DateTime.init) + (); } else static if(is(T == Date)) { import std.math : lround; return var.visit!( - (bool l) => Date.init, - (long l) => longToDate(l), - (double l) => longToDate(lround(l)), - (string l) => stringToDate(l), - (DateTime l) => l.date, - (Date l) => l, - (TimeOfDay l) => Date.init, - () => Date.init) - (); + (bool l) => Date.init, + (long l) => longToDate(l), + (double l) => longToDate(lround(l)), + (string l) => stringToDate(l), + (DateTime l) => l.date, + (Date l) => l, + (TimeOfDay l) => Date.init, + () => Date.init) + (); } else static if(is(T == TimeOfDay)) { import std.math : lround; return var.visit!( - (bool l) => TimeOfDay.init, - (long l) => TimeOfDay.init, - (double l) => doubleToTimeOfDay(l - cast(long)l), - (string l) => doubleToTimeOfDay( - to!double(l) - cast(long)to!double(l) - ), - (DateTime l) => l.timeOfDay, - (Date l) => TimeOfDay.init, - (TimeOfDay l) => l, - () => TimeOfDay.init) - (); + (bool l) => TimeOfDay.init, + (long l) => TimeOfDay.init, + (double l) => doubleToTimeOfDay(l - cast(long)l), + (string l) => doubleToTimeOfDay( + to!double(l) - cast(long)to!double(l) + ), + (DateTime l) => l.timeOfDay, + (Date l) => TimeOfDay.init, + (TimeOfDay l) => l, + () => TimeOfDay.init) + (); } assert(false, T.stringof); } - -private ZipArchive readFile(string filename) @trusted { +private ZipArchive readFile(in string filename) @trusted { enforce(exists(filename), "File with name " ~ filename ~ " does not exist"); return new typeof(return)(read(filename)); } @@ -784,7 +783,7 @@ struct SheetNameId { string rid; } -string convertToString(const ubyte[] d) @trusted { +string convertToString(in ubyte[] d) @trusted { import std.encoding; auto b = getBOM(d); switch(b.schema) { @@ -803,7 +802,7 @@ string convertToString(const ubyte[] d) @trusted { } } -SheetNameId[] sheetNames(string filename) @trusted { +SheetNameId[] sheetNames(in string filename) @trusted { auto file = readFile(filename); auto ams = file.directory; immutable wbStr = "xl/workbook.xml"; @@ -867,7 +866,7 @@ Relationships[string] parseRelationships(ZipArchive za, ArchiveMember am) @trust return ret; } -Sheet readSheet(string filename, string sheetName) { +Sheet readSheet(in string filename, in string sheetName) { SheetNameId[] sheets = sheetNames(filename); auto sRng = sheets.filter!(s => s.name == sheetName); enforce(!sRng.empty, "No sheet with name " ~ sheetName @@ -884,7 +883,7 @@ string eatXlPrefix(string fn) { return fn; } -Sheet readSheetImpl(string filename, string rid) @trusted { +Sheet readSheetImpl(in string filename, in string rid) @trusted { scope(failure) { writefln("Failed at file '%s' and sheet '%s'", filename, rid); } @@ -992,7 +991,7 @@ string extractData(DOMEntity!string si) { assert(false); } -private bool canConvertToLong(string s) { +private bool canConvertToLong(in string s) { if(s.empty) { return false; } @@ -1002,12 +1001,12 @@ private bool canConvertToLong(string s) { private immutable rs = r"[\+-]{0,1}[0-9][0-9]*\.[0-9]*"; private auto rgx = ctRegex!rs; -private bool canConvertToDouble(string s) { +private bool canConvertToDouble(in string s) { auto cap = matchAll(s, rgx); return cap.empty || cap.front.hit != s ? false : true; } -Data convert(string s) @trusted { +Data convert(in string s) @trusted { struct ToRe { string from; string to; @@ -1135,7 +1134,7 @@ Cell[] insertValueIntoCell(Cell[] cells, Data[] ss) @trusted { return cells; } -Pos toPos(string s) { +Pos toPos(in string s) { import std.string : indexOfAny; import std.math : pow; ptrdiff_t fn = s.indexOfAny("0123456789"); From 1955e3de27d411e36dfba3968d41c89cc1c3a5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Tue, 22 Feb 2022 10:11:55 +0100 Subject: [PATCH 19/45] Use typeof(return) in Cell members --- source/xlsxreader.d | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index c0bf8cf..b9a2c83 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -231,7 +231,7 @@ struct Sheet { Iterator!T getColumn(T)(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { auto c = this.iterateColumn!T(col, startColumn, endColumn); - return Iterator!T(c.array); + return typeof(return)(c.array); } private enum t = q{ @@ -246,44 +246,44 @@ struct Sheet { } ColumnUntyped iterateColumnUntyped(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return ColumnUntyped(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startColumn, endColumn); } Column!(T) iterateColumn(T)(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(T)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startColumn, endColumn); } Column!(long) iterateColumnLong(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(long)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startColumn, endColumn); } Column!(double) iterateColumnDouble(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(double)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startColumn, endColumn); } Column!(string) iterateColumnString(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(string)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startColumn, endColumn); } Column!(DateTime) iterateColumnDateTime(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(DateTime)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startColumn, endColumn); } Column!(Date) iterateColumnDate(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(Date)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startColumn, endColumn); } Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Column!(TimeOfDay)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startColumn, endColumn); } // Row Iterator!T getRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { auto c = this.iterateRow!T(row, startColumn, endColumn); - return Iterator!T(c.array); // TODO: why .array? + return typeof(return)(c.array); // TODO: why .array? } private enum t2 = q{ @@ -298,37 +298,37 @@ struct Sheet { } RowUntyped iterateRowUntyped(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return RowUntyped(&this, row, startColumn, endColumn); + return typeof(return)(&this, row, startColumn, endColumn); } Row!(T) iterateRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(T)(&this, row, startColumn, endColumn); + return typeof(return)(&this, row, startColumn, endColumn); } Row!(long) iterateRowLong(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(long)(&this, row, startColumn, endColumn); + return typeof(return)(&this, row, startColumn, endColumn); } Row!(double) iterateRowDouble(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(double)(&this, row, startColumn, endColumn); + return typeof(return)(&this, row, startColumn, endColumn); } Row!(string) iterateRowString(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(string)(&this, row, startColumn, endColumn); + return typeof(return)(&this, row, startColumn, endColumn); } Row!(DateTime) iterateRowDateTime(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(DateTime)(&this, row, startColumn, endColumn); + return typeof(return)(&this, row, startColumn, endColumn); } Row!(Date) iterateRowDate(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(Date)(&this, row, startColumn, endColumn); + return typeof(return)(&this, row, startColumn, endColumn); } Row!(TimeOfDay) iterateRowTimeOfDay(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { - return Row!(TimeOfDay)(&this, row, startColumn, endColumn); + return typeof(return)(&this, row, startColumn, endColumn); } } From 57d3d007766a27745ba0fc097e0d463ba949085f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Tue, 22 Feb 2022 10:26:17 +0100 Subject: [PATCH 20/45] Add dep to mir-core --- dub.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dub.json b/dub.json index 43e61b7..901919e 100644 --- a/dub.json +++ b/dub.json @@ -4,7 +4,8 @@ ], "copyright": "Copyright © 2019, Robert burner Schadek", "dependencies": { - "dxml": "~>0.4.0" + "dxml": "~>0.4.0", + "mir-core": "~>1.1.103" }, "description": "A very simple xlsx reader", "license": "LGPL3", From bb31b7842f97d627a93b9a224297448534d7d6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Tue, 22 Feb 2022 10:26:31 +0100 Subject: [PATCH 21/45] Add TODO about using mir.algebraic --- source/xlsxreader.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index b9a2c83..7d2014e 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -18,7 +18,7 @@ import std.stdio; import std.traits : isIntegral, isFloatingPoint, isSomeString; import std.typecons : tuple, Nullable, nullable; import std.utf : byChar; -import std.variant : Algebraic, visit; +import std.variant : Algebraic, visit; // TODO: replace with import mir.algebraic : Algebraic, visit; import std.zip; import dxml.dom; From 1126d6cfcd48c2a2db10002574e42d3686c7941c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Tue, 22 Feb 2022 10:41:29 +0100 Subject: [PATCH 22/45] Add TODO --- source/xlsxreader.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 7d2014e..86b169e 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -231,7 +231,7 @@ struct Sheet { Iterator!T getColumn(T)(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { auto c = this.iterateColumn!T(col, startColumn, endColumn); - return typeof(return)(c.array); + return typeof(return)(c.array); // TODO: why .array? } private enum t = q{ From 53479ba70abe9a03c2b5fc2e1cf4cda40539b417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Tue, 22 Feb 2022 10:43:47 +0100 Subject: [PATCH 23/45] Correct parameter namings --- source/xlsxreader.d | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 86b169e..6585c28 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -229,14 +229,14 @@ struct Sheet { // Column - Iterator!T getColumn(T)(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - auto c = this.iterateColumn!T(col, startColumn, endColumn); + Iterator!T getColumn(T)(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + auto c = this.iterateColumn!T(col, startRow, endRow); return typeof(return)(c.array); // TODO: why .array? } private enum t = q{ - Iterator!(%1$s) getColumn%2$s(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return getColumn!(%1$s)(col, startColumn, endColumn); + Iterator!(%1$s) getColumn%2$s(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + return getColumn!(%1$s)(col, startRow, endRow); } }; static foreach(T; ["long", "double", "string", "Date", "TimeOfDay", @@ -245,38 +245,38 @@ struct Sheet { mixin(format(t, T, T[0].toUpper ~ T[1 .. $])); } - ColumnUntyped iterateColumnUntyped(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return typeof(return)(&this, col, startColumn, endColumn); + ColumnUntyped iterateColumnUntyped(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + return typeof(return)(&this, col, startRow, endRow); } - Column!(T) iterateColumn(T)(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return typeof(return)(&this, col, startColumn, endColumn); + Column!(T) iterateColumn(T)(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + return typeof(return)(&this, col, startRow, endRow); } - Column!(long) iterateColumnLong(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return typeof(return)(&this, col, startColumn, endColumn); + Column!(long) iterateColumnLong(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + return typeof(return)(&this, col, startRow, endRow); } - Column!(double) iterateColumnDouble(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return typeof(return)(&this, col, startColumn, endColumn); + Column!(double) iterateColumnDouble(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + return typeof(return)(&this, col, startRow, endRow); } - Column!(string) iterateColumnString(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return typeof(return)(&this, col, startColumn, endColumn); + Column!(string) iterateColumnString(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + return typeof(return)(&this, col, startRow, endRow); } - Column!(DateTime) iterateColumnDateTime(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) + Column!(DateTime) iterateColumnDateTime(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { - return typeof(return)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startRow, endRow); } - Column!(Date) iterateColumnDate(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) { - return typeof(return)(&this, col, startColumn, endColumn); + Column!(Date) iterateColumnDate(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + return typeof(return)(&this, col, startRow, endRow); } - Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t startColumn = 0, size_t endColumn = size_t.max) + Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { - return typeof(return)(&this, col, startColumn, endColumn); + return typeof(return)(&this, col, startRow, endRow); } // Row From 23a23712a7383bf4721c0b5fdea910776e0224e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Tue, 22 Feb 2022 10:44:46 +0100 Subject: [PATCH 24/45] Replace in size_t with size_t --- source/xlsxreader.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 6585c28..601e287 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -369,7 +369,7 @@ struct RowUntyped { const size_t endColumn; size_t cur; - this(Sheet* sheet, in size_t row, in size_t startColumn = 0, in size_t endColumn = size_t.max) pure nothrow @nogc { + this(Sheet* sheet, size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) pure nothrow @nogc { assert(sheet.table.length == sheet.maxPos.row + 1); this.sheet = sheet; this.row = row; From 49d52e3ff5361c392c211cc0b8915a82b9993d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 15 Jul 2022 12:51:11 +0200 Subject: [PATCH 25/45] Make iterateRow @trusted for now to make build pass --- source/xlsxreader.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 601e287..b8bfb11 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -301,7 +301,7 @@ struct Sheet { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(T) iterateRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + Row!(T) iterateRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) @trusted /* TODO: remove @trusted when `&this` is stored in a @safe manner in `Row` */ { return typeof(return)(&this, row, startColumn, endColumn); } From 28ee7079107147df554dff5dd8779a49f9e2b55d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 15 Jul 2022 12:51:30 +0200 Subject: [PATCH 26/45] Bump mir-core to 1.1.109 in dub.json --- dub.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dub.json b/dub.json index 901919e..deb6c8c 100644 --- a/dub.json +++ b/dub.json @@ -5,7 +5,7 @@ "copyright": "Copyright © 2019, Robert burner Schadek", "dependencies": { "dxml": "~>0.4.0", - "mir-core": "~>1.1.103" + "mir-core": "~>1.1.109" }, "description": "A very simple xlsx reader", "license": "LGPL3", From 66ba2991f049616501a32b6c1e6dedcbb5f3afc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 11:03:14 +0200 Subject: [PATCH 27/45] Convert dub.json to dub.sdl --- dub.json | 13 ------------- dub.sdl | 7 +++++++ 2 files changed, 7 insertions(+), 13 deletions(-) delete mode 100644 dub.json create mode 100644 dub.sdl diff --git a/dub.json b/dub.json deleted file mode 100644 index deb6c8c..0000000 --- a/dub.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "authors": [ - "Robert burner Schadek" - ], - "copyright": "Copyright © 2019, Robert burner Schadek", - "dependencies": { - "dxml": "~>0.4.0", - "mir-core": "~>1.1.109" - }, - "description": "A very simple xlsx reader", - "license": "LGPL3", - "name": "xlsxreader" -} diff --git a/dub.sdl b/dub.sdl new file mode 100644 index 0000000..d477692 --- /dev/null +++ b/dub.sdl @@ -0,0 +1,7 @@ +name "xlsxreader" +description "A very simple xlsx reader" +authors "Robert burner Schadek" +copyright "Copyright © 2019, Robert burner Schadek" +license "LGPL3" +dependency "dxml" version="~>0.4.0" +dependency "mir-core" version="~>1.1.109" From 22f975f910cf1fd567bfaf424a7147618cf70a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:11:45 +0200 Subject: [PATCH 28/45] Revert "Convert dub.json to dub.sdl" This reverts commit 66ba2991f049616501a32b6c1e6dedcbb5f3afc9. --- dub.json | 13 +++++++++++++ dub.sdl | 7 ------- 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 dub.json delete mode 100644 dub.sdl diff --git a/dub.json b/dub.json new file mode 100644 index 0000000..deb6c8c --- /dev/null +++ b/dub.json @@ -0,0 +1,13 @@ +{ + "authors": [ + "Robert burner Schadek" + ], + "copyright": "Copyright © 2019, Robert burner Schadek", + "dependencies": { + "dxml": "~>0.4.0", + "mir-core": "~>1.1.109" + }, + "description": "A very simple xlsx reader", + "license": "LGPL3", + "name": "xlsxreader" +} diff --git a/dub.sdl b/dub.sdl deleted file mode 100644 index d477692..0000000 --- a/dub.sdl +++ /dev/null @@ -1,7 +0,0 @@ -name "xlsxreader" -description "A very simple xlsx reader" -authors "Robert burner Schadek" -copyright "Copyright © 2019, Robert burner Schadek" -license "LGPL3" -dependency "dxml" version="~>0.4.0" -dependency "mir-core" version="~>1.1.109" From b43fc558c5b36f71a5657e351265f49f5a6a5ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:13:06 +0200 Subject: [PATCH 29/45] Remove dependency on mir-core in dub.json --- dub.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dub.json b/dub.json index deb6c8c..5932ead 100644 --- a/dub.json +++ b/dub.json @@ -4,8 +4,7 @@ ], "copyright": "Copyright © 2019, Robert burner Schadek", "dependencies": { - "dxml": "~>0.4.0", - "mir-core": "~>1.1.109" + "dxml": "~>0.4.0" }, "description": "A very simple xlsx reader", "license": "LGPL3", From a8368543a9d963586fbd480aacd9a35f035deee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:24:38 +0200 Subject: [PATCH 30/45] Remove @trusted from unittest --- source/xlsxreader.d | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 046c9a1..c5c7486 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -1245,7 +1245,7 @@ string specialCharacterReplacementReverse(string s) { .replace("&", "&"); } -@trusted unittest { +unittest { import std.math : isClose; auto r = readSheet("multitable.xlsx", "wb1"); assert(isClose(r.table[12][5].xmlValue.to!double(), 26.74), @@ -1257,7 +1257,7 @@ string specialCharacterReplacementReverse(string s) { ); } -@trusted unittest { +unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "wb1"); auto r = s.iterateRow!long(15, 1, 6); @@ -1276,7 +1276,7 @@ string specialCharacterReplacementReverse(string s) { .array; } -@trusted unittest { +unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "wb2"); //writefln("%s\n%(%s\n%)", s.maxPos, s.cells); @@ -1298,7 +1298,7 @@ string specialCharacterReplacementReverse(string s) { assert(equal(rslt, it2)); } -@trusted unittest { +unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "Sheet3"); writeln(s.table[0][0].xmlValue); @@ -1307,7 +1307,7 @@ string specialCharacterReplacementReverse(string s) { //assert(s.table[0][0].canConvertTo(CellType.bool_)); } -@trusted unittest { +unittest { import std.file : dirEntries, SpanMode; import std.traits : EnumMembers; foreach(de; dirEntries("xlsx_files/", "*.xlsx", SpanMode.depth) @@ -1345,7 +1345,7 @@ unittest { assert(equal(c2, r2), format("%s", c2)); } -@trusted unittest { +unittest { import std.math : isClose; auto sheet = readSheet("toto.xlsx", "Trades"); writefln("%(%s\n%)", sheet.cells); From 86a3ce89d500824af96431bfc999da35305eb7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:25:04 +0200 Subject: [PATCH 31/45] Remove TODO comment about using mir.algebraic --- source/xlsxreader.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index c5c7486..cea1405 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -18,7 +18,7 @@ import std.stdio; import std.traits : isIntegral, isFloatingPoint, isSomeString; import std.typecons : tuple, Nullable, nullable; import std.utf : byChar; -import std.variant : Algebraic, visit; // TODO: replace with import mir.algebraic : Algebraic, visit; +import std.variant : Algebraic, visit; import std.zip; import dxml.dom; From c89741a075436749bed3a28213e0135c6489032e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:28:42 +0200 Subject: [PATCH 32/45] Remove commented out debug code --- source/xlsxreader.d | 1 - 1 file changed, 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index cea1405..582fc6f 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -926,7 +926,6 @@ Sheet readSheetImpl(in string filename, in string rid) @trusted { foreach(c; ret.cells) { ret.table[c.position.row][c.position.col] = c; } - // debug writeln("xlsxreader: sheet members: cells.length:", ret.cells.length, " table.length:", ret.table.length, " table[0].length:", ret.table[0].length, " ret.maxPos:", ret.maxPos); return ret; } From 0c96c4b56b6e8d6c87d22901b76572a9256f8a9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:35:42 +0200 Subject: [PATCH 33/45] Remove old conversion code --- source/xlsxreader.d | 133 -------------------------------------------- 1 file changed, 133 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 582fc6f..a32fd13 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -46,121 +46,6 @@ struct Cell { string f; // c.f the formula string xmlValue; Pos position; - - bool canConvertTo(CellType ct) const @trusted { - auto b = (bool l) { - switch(ct) { - case CellType.datetime: return false; - case CellType.timeofday: return false; - case CellType.date: return false; - default: return true; - } - }; - - auto dt = (DateTime l) { - switch(ct) { - case CellType.datetime: return true; - case CellType.timeofday: return true; - case CellType.date: return true; - case CellType.double_: return true; - default: return false; - } - }; - - auto de = (Date l) { - switch(ct) { - case CellType.datetime: return false; - case CellType.timeofday: return false; - case CellType.date: return true; - case CellType.double_: return true; - case CellType.long_: return true; - default: return false; - } - }; - - auto tod = (TimeOfDay l) { - switch(ct) { - case CellType.datetime: return false; - case CellType.timeofday: return true; - case CellType.double_: return true; - default: return false; - } - }; - - auto l = (long l) { - switch(ct) { - case CellType.date: return !tryConvertTo!Date(l); - case CellType.long_: return true; - case CellType.string_: return true; - case CellType.double_: return true; - case CellType.bool_: return l == 0 || l == 1; - default: return false; - } - }; - - auto d = (double l) { - switch(ct) { - case CellType.string_: return true; - case CellType.double_: return true; - case CellType.datetime: return !tryConvertTo!DateTime(l); - case CellType.date: return !tryConvertTo!Date(l); - case CellType.timeofday: return !tryConvertTo!TimeOfDay(l); - default: return false; - } - }; - - auto s = (string l) { - switch(ct) { - case CellType.string_: return true; - case CellType.bool_: return !tryConvertTo!bool(l); - case CellType.long_: return !tryConvertTo!long(l); - case CellType.double_: return !tryConvertTo!double(l); - case CellType.datetime: return !tryConvertTo!DateTime(l); - case CellType.date: return !tryConvertTo!Date(l); - case CellType.timeofday: return !tryConvertTo!TimeOfDay(l); - default: return false; - } - }; - - return this.value.visit!( - (bool l) => b(l), - (long lo) => l(lo), - (double l) => d(l), - (string l) => s(l), - (DateTime l) => dt(l), - (Date l) => de(l), - (TimeOfDay l) => tod(l), - () => false) - (); - } - - bool convertToBool() @trusted const { - return convertTo!bool(this.value); - } - - long convertToLong() @trusted const { - return convertTo!long(this.value); - } - - double convertToDouble() @trusted const { - return convertTo!double(this.value); - } - - string convertToString() @trusted const { - return convertTo!string(this.value); - } - - Date convertToDate() @trusted const { - return convertTo!Date(this.value); - } - - TimeOfDay convertToTimeOfDay() @trusted const { - return convertTo!TimeOfDay(this.value); - } - - DateTime convertToDateTime() @trusted const { - return convertTo!DateTime(this.value); - } } // @@ -407,15 +292,6 @@ struct Row(T) { private void read() { this.front = convertTo!T(this.ru.front.value); } - - bool canConvertTo(CellType ct) const { - for(size_t it = this.ru.startColumn; it < this.ru.endColumn; ++it) { - if(!this.ru.sheet.table[this.ru.row][it].canConvertTo(ct)) { - return false; - } - } - return true; - } } /// @@ -481,15 +357,6 @@ struct Column(T) { private void read() { this.front = convertTo!T(this.cu.front.value); } - - bool canConvertTo(CellType ct) const { - for(size_t it = this.cu.startRow; it < this.cu.endRow; ++it) { - if(!this.cu.sheet.table[it][this.cu.col].canConvertTo(ct)) { - return false; - } - } - return true; - } } unittest { From 429eab3810055ae328060e0c36ca4a57b252dad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:36:51 +0200 Subject: [PATCH 34/45] Remove TODO comment --- source/xlsxreader.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index a32fd13..252a723 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -100,7 +100,7 @@ struct Sheet { Iterator!T getColumn(T)(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { auto c = this.iterateColumn!T(col, startRow, endRow); - return typeof(return)(c.array); // TODO: why .array? + return typeof(return)(c.array); } private enum t = q{ From 537af6d6953f1b2e4748f4c763fad4b33a30fb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:38:46 +0200 Subject: [PATCH 35/45] Adjust convertTo --- source/xlsxreader.d | 112 ++++++++------------------------------------ 1 file changed, 20 insertions(+), 92 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 252a723..db22195 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -529,106 +529,34 @@ Nullable!(T) tryConvertToImpl(T)(Data var) { T convertTo(T)(string var) { import std.math : lround; - static if(isSomeString!T) { return to!T(var); } else static if(is(T == bool)) { - if(var.type != typeid(bool) && var.type != typeid(long) - && var.type == typeid(string)) - { - throw new Exception("Can not convert " ~ var.type.toString() ~ - " to bool"); - } - return var.visit!( - (bool l) => l, - (long l) => l == 0 ? false : true, - (string l) => to!bool(l), - (double l) => false, - (DateTime l) => false, - (Date l) => false, - (TimeOfDay l) => false, - () => false) - (); + return var == "1"; } else static if(isIntegral!T) { - return var.visit!( - (bool l) => to!T(l), - (long l) => to!T(l), - (double l) => to!T(l), - (string l) => to!T(l), - (DateTime l) => to!T(dateToLong(l.date)), - (Date l) => to!T(dateToLong(l)), - (TimeOfDay l) => to!T(0), - () => to!T(0)) - (); - // return to!T(var); + return to!T(var); } else static if(isFloatingPoint!T) { - return var.visit!( - (bool l) => to!T(l), - (long l) => to!T(l), - (double l) => to!T(l), - (string l) => to!T(l), - (DateTime l) => to!T(dateToLong(l.date)), - (Date l) => to!T(dateToLong(l)), - (TimeOfDay l) => to!T(0), - () => T.init) - (); - // return to!T(var); + return to!T(var); } else static if(is(T == DateTime)) { - return var.visit!( - (bool l) => DateTime.init, - (long l) => doubleToDateTime(to!long(l)), - (double l) => doubleToDateTime(l), - (string l) => doubleToDateTime(to!double(l)), - (DateTime l) => l, - (Date l) => DateTime(l, TimeOfDay.init), - (TimeOfDay l) => DateTime(Date.init, l), - () => DateTime.init) - (); - // if(var.canConvertToLong()) { - // return doubleToDateTime(to!long(var)); - // } else if(var.canConvertToDouble()) { - // return doubleToDateTime(to!double(var)); - // } - // enforce(false, "Can not convert '" ~ var ~ "' to a DateTime"); - // assert(false, "Unreachable"); + if(var.canConvertToLong()) { + return doubleToDateTime(to!long(var)); + } else if(var.canConvertToDouble()) { + return doubleToDateTime(to!double(var)); + } + enforce(false, "Can not convert '" ~ var ~ "' to a DateTime"); + assert(false, "Unreachable"); } else static if(is(T == Date)) { - import std.math : lround; - - return var.visit!( - (bool l) => Date.init, - (long l) => longToDate(l), - (double l) => longToDate(lround(l)), - (string l) => stringToDate(l), - (DateTime l) => l.date, - (Date l) => l, - (TimeOfDay l) => Date.init, - () => Date.init) - (); - // if(var.canConvertToLong()) { - // return longToDate(to!long(var)); - // } else if(var.canConvertToDouble()) { - // return longToDate(lround(to!double(var))); - // } - // return stringToDate(var); + if(var.canConvertToLong()) { + return longToDate(to!long(var)); + } else if(var.canConvertToDouble()) { + return longToDate(lround(to!double(var))); + } + return stringToDate(var); } else static if(is(T == TimeOfDay)) { - import std.math : lround; - - return var.visit!( - (bool l) => TimeOfDay.init, - (long l) => TimeOfDay.init, - (double l) => doubleToTimeOfDay(l - cast(long)l), - (string l) => doubleToTimeOfDay( - to!double(l) - cast(long)to!double(l) - ), - (DateTime l) => l.timeOfDay, - (Date l) => TimeOfDay.init, - (TimeOfDay l) => l, - () => TimeOfDay.init) - (); - // double l = to!double(var); - // return doubleToTimeOfDay(l - cast(long)l); - // } else { - // static assert(false, T.stringof ~ " not supported"); + double l = to!double(var); + return doubleToTimeOfDay(l - cast(long)l); + } else { + static assert(false, T.stringof ~ " not supported"); } } From c8ec5bcdaff17ddb62ddd9b9d6156c544619c12c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:42:05 +0200 Subject: [PATCH 36/45] Rename .value to .xmlValue --- source/xlsxreader.d | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index db22195..7dcf81c 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -290,7 +290,7 @@ struct Row(T) { } private void read() { - this.front = convertTo!T(this.ru.front.value); + this.front = convertTo!T(this.ru.front.xmlValue); } } @@ -355,7 +355,7 @@ struct Column(T) { } private void read() { - this.front = convertTo!T(this.cu.front.value); + this.front = convertTo!T(this.cu.front.xmlValue); } } @@ -977,20 +977,20 @@ Cell[] insertValueIntoCell(Cell[] cells, string[] ss) @trusted { assert(canFind(excepted, c.t) || c.t.empty, format("'%s' not in [%s]", c.t, excepted)); if(c.t.empty) { - //c.value = convert(c.v); + //c.xmlValue = convert(c.v); c.xmlValue = c.v.removeSpecialCharacter(); } else if(canFind(same, c.t)) { - //c.value = convert(c.v); + //c.xmlValue = convert(c.v); c.xmlValue = c.v.removeSpecialCharacter(); } else if(c.t == "b") { //logf("'%s' %s", c.v, c); - //c.value = c.v == "1"; + //c.xmlValue = c.v == "1"; c.xmlValue = c.v.removeSpecialCharacter(); } else { if(!c.v.empty) { size_t idx = to!size_t(c.v); //logf("'%s' %s", c.v, idx); - //c.value = ss[idx]; + //c.xmlValue = ss[idx]; c.xmlValue = ss[idx]; } } From 3dec85a1db2cb69597fc37f811f2d4014051c3fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:52:21 +0200 Subject: [PATCH 37/45] Put back @trusted qualifier for a single unittest --- source/xlsxreader.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 7dcf81c..4bcc7be 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -1101,7 +1101,7 @@ unittest { //assert(s.table[0][0].canConvertTo(CellType.bool_)); } -unittest { +@trusted unittest { import std.file : dirEntries, SpanMode; import std.traits : EnumMembers; foreach(de; dirEntries("xlsx_files/", "*.xlsx", SpanMode.depth) From 32ab1f44591b01797a7074299202f01a8dbcfc8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:52:45 +0200 Subject: [PATCH 38/45] Remove TODO --- source/xlsxreader.d | 1 - 1 file changed, 1 deletion(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 4bcc7be..28eb2b3 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -1,4 +1,3 @@ -// TODO: add const access to getter functions, such as `getRow` module xlsxreader; import std.algorithm.iteration : filter, map, joiner; From d7197f2bc881e10a0a3c766c4a4d17b5b4e13d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:54:24 +0200 Subject: [PATCH 39/45] Rename xmlValue to value in insertValueIntoCell --- source/xlsxreader.d | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 28eb2b3..7b7264c 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -976,21 +976,21 @@ Cell[] insertValueIntoCell(Cell[] cells, string[] ss) @trusted { assert(canFind(excepted, c.t) || c.t.empty, format("'%s' not in [%s]", c.t, excepted)); if(c.t.empty) { - //c.xmlValue = convert(c.v); - c.xmlValue = c.v.removeSpecialCharacter(); + //c.value = convert(c.v); + c.value = c.v.removeSpecialCharacter(); } else if(canFind(same, c.t)) { - //c.xmlValue = convert(c.v); - c.xmlValue = c.v.removeSpecialCharacter(); + //c.value = convert(c.v); + c.value = c.v.removeSpecialCharacter(); } else if(c.t == "b") { //logf("'%s' %s", c.v, c); - //c.xmlValue = c.v == "1"; - c.xmlValue = c.v.removeSpecialCharacter(); + //c.value = c.v == "1"; + c.value = c.v.removeSpecialCharacter(); } else { if(!c.v.empty) { size_t idx = to!size_t(c.v); //logf("'%s' %s", c.v, idx); - //c.xmlValue = ss[idx]; - c.xmlValue = ss[idx]; + //c.value = ss[idx]; + c.value = ss[idx]; } } } From 2d2faf0686c993a8990ca81d1acd08c170c1ca74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Wed, 20 Jul 2022 16:55:30 +0200 Subject: [PATCH 40/45] Revert "Rename xmlValue to value in insertValueIntoCell" This reverts commit d7197f2bc881e10a0a3c766c4a4d17b5b4e13d74. --- source/xlsxreader.d | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 7b7264c..28eb2b3 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -976,21 +976,21 @@ Cell[] insertValueIntoCell(Cell[] cells, string[] ss) @trusted { assert(canFind(excepted, c.t) || c.t.empty, format("'%s' not in [%s]", c.t, excepted)); if(c.t.empty) { - //c.value = convert(c.v); - c.value = c.v.removeSpecialCharacter(); + //c.xmlValue = convert(c.v); + c.xmlValue = c.v.removeSpecialCharacter(); } else if(canFind(same, c.t)) { - //c.value = convert(c.v); - c.value = c.v.removeSpecialCharacter(); + //c.xmlValue = convert(c.v); + c.xmlValue = c.v.removeSpecialCharacter(); } else if(c.t == "b") { //logf("'%s' %s", c.v, c); - //c.value = c.v == "1"; - c.value = c.v.removeSpecialCharacter(); + //c.xmlValue = c.v == "1"; + c.xmlValue = c.v.removeSpecialCharacter(); } else { if(!c.v.empty) { size_t idx = to!size_t(c.v); //logf("'%s' %s", c.v, idx); - //c.value = ss[idx]; - c.value = ss[idx]; + //c.xmlValue = ss[idx]; + c.xmlValue = ss[idx]; } } } From 14e2e077cb111881ec51e97b20dd78632d4d7bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 22 Jul 2022 08:58:34 +0200 Subject: [PATCH 41/45] Qualify most foreach elements as const --- source/xlsxreader.d | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 28eb2b3..9341b83 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -71,8 +71,8 @@ struct Sheet { import std.format : formattedWrite; import std.array : appender; long[] maxCol = new long[](maxPos.col + 1); - foreach(row; this.table) { - foreach(idx, Cell col; row) { + foreach(const row; this.table) { + foreach(const idx, Cell col; row) { string s = col.xmlValue; maxCol[idx] = maxCol[idx] < s.length ? s.length : maxCol[idx]; @@ -81,8 +81,8 @@ struct Sheet { maxCol[] += 1; auto app = appender!string(); - foreach(row; this.table) { - foreach(idx, Cell col; row) { + foreach(const row; this.table) { + foreach(const idx, Cell col; row) { string s = col.xmlValue; formattedWrite(app, "%*s, ", maxCol[idx], s); } @@ -429,7 +429,7 @@ long dateToLong(Date d) { unittest { auto ds = [ Date(1900,2,1), Date(1901, 2, 28), Date(2019, 06, 05) ]; - foreach(d; ds) { + foreach(const d; ds) { long l = dateToLong(d); Date r = longToDate(l); assert(r == d, format("%s %s", r, d)); @@ -457,7 +457,7 @@ unittest { auto tods = [ TimeOfDay(23, 12, 11), TimeOfDay(11, 0, 11), TimeOfDay(0, 0, 0), TimeOfDay(0, 1, 0), TimeOfDay(23, 59, 59), TimeOfDay(0, 0, 0)]; - foreach(tod; tods) { + foreach(const tod; tods) { double d = timeOfDayToDouble(tod); assert(d <= 1.0, format("%s", d)); TimeOfDay r = doubleToTimeOfDay(d); @@ -483,8 +483,8 @@ unittest { auto tods = [ TimeOfDay(23, 12, 11), TimeOfDay(11, 0, 11), TimeOfDay(0, 0, 0), TimeOfDay(0, 1, 0), TimeOfDay(23, 59, 59), TimeOfDay(0, 0, 0)]; - foreach(d; ds) { - foreach(tod; tods) { + foreach(const d; ds) { + foreach(const tod; tods) { DateTime dt = DateTime(d, tod); double dou = datetimeToDouble(dt); @@ -676,7 +676,7 @@ Sheet readSheet(in string filename, in string sheetName) { } string eatXlPrefix(string fn) { - foreach(p; ["xl//", "/xl/"]) { + foreach(const p; ["xl//", "/xl/"]) { if(fn.startsWith(p)) { return fn[p.length .. $]; } @@ -717,7 +717,7 @@ Sheet readSheetImpl(in string filename, in string rid) @trusted { } ret.maxPos = maxPos; ret.table = new Cell[][](ret.maxPos.row + 1, ret.maxPos.col + 1); - foreach(c; ret.cells) { + foreach(const c; ret.cells) { ret.table[c.position.row][c.position.col] = c; } return ret; @@ -862,7 +862,7 @@ unittest { , Test("-0.0", true) , Test("-1100.0", true) ]; - foreach(t; tests) { + foreach(const t; tests) { assert(canConvertToDouble(t.tt) == canConvertToDoubleOld(t.tt) && canConvertToDouble(t.tt) == t.rslt , format("%s %s %s %s", t.tt @@ -888,7 +888,7 @@ string removeSpecialCharacter(string s) { string replaceStrings(string s) { import std.algorithm.searching : canFind; import std.array : replace; - foreach(tr; toRe) { + foreach(const tr; toRe) { while(canFind(s, tr.from)) { s = s.replace(tr.from, tr.to); } @@ -1005,7 +1005,7 @@ Pos toPos(in string s) { size_t row = to!size_t(to!long(s[fn .. $]) - 1); size_t col = 0; string colS = s[0 .. fn]; - foreach(idx, char c; colS) { + foreach(const idx, char c; colS) { col = col * 26 + (c - 'A' + 1); } return Pos(row, col - 1); @@ -1103,14 +1103,14 @@ unittest { @trusted unittest { import std.file : dirEntries, SpanMode; import std.traits : EnumMembers; - foreach(de; dirEntries("xlsx_files/", "*.xlsx", SpanMode.depth) + foreach(const de; dirEntries("xlsx_files/", "*.xlsx", SpanMode.depth) .filter!(a => a.name != "xlsx_files/data03.xlsx")) { //writeln(de.name); auto sn = sheetNames(de.name); - foreach(s; sn) { + foreach(const s; sn) { auto sheet = readSheet(de.name, s.name); - foreach(cell; sheet.cells) { + foreach(const cell; sheet.cells) { } } } From 4041ad121fdfb0ab59cb16b87d76f9233797bccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Fri, 22 Jul 2022 10:11:47 +0200 Subject: [PATCH 42/45] Remove default init of start and end indexes for now --- source/xlsxreader.d | 52 ++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 9341b83..118d737 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -97,13 +97,13 @@ struct Sheet { // Column - Iterator!T getColumn(T)(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + Iterator!T getColumn(T)(size_t col, size_t startRow, size_t endRow) { auto c = this.iterateColumn!T(col, startRow, endRow); return typeof(return)(c.array); } private enum t = q{ - Iterator!(%1$s) getColumn%2$s(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + Iterator!(%1$s) getColumn%2$s(size_t col, size_t startRow, size_t endRow) { return getColumn!(%1$s)(col, startRow, endRow); } }; @@ -113,49 +113,49 @@ struct Sheet { mixin(format(t, T, T[0].toUpper ~ T[1 .. $])); } - ColumnUntyped iterateColumnUntyped(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + ColumnUntyped iterateColumnUntyped(size_t col, size_t startRow, size_t endRow) { return typeof(return)(&this, col, startRow, endRow); } - Column!(T) iterateColumn(T)(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + Column!(T) iterateColumn(T)(size_t col, size_t startRow, size_t endRow) { return typeof(return)(&this, col, startRow, endRow); } - Column!(long) iterateColumnLong(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + Column!(long) iterateColumnLong(size_t col, size_t startRow, size_t endRow) { return typeof(return)(&this, col, startRow, endRow); } - Column!(double) iterateColumnDouble(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + Column!(double) iterateColumnDouble(size_t col, size_t startRow, size_t endRow) { return typeof(return)(&this, col, startRow, endRow); } - Column!(string) iterateColumnString(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + Column!(string) iterateColumnString(size_t col, size_t startRow, size_t endRow) { return typeof(return)(&this, col, startRow, endRow); } - Column!(DateTime) iterateColumnDateTime(size_t col, size_t startRow = 0, size_t endRow = size_t.max) + Column!(DateTime) iterateColumnDateTime(size_t col, size_t startRow, size_t endRow) { return typeof(return)(&this, col, startRow, endRow); } - Column!(Date) iterateColumnDate(size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + Column!(Date) iterateColumnDate(size_t col, size_t startRow, size_t endRow) { return typeof(return)(&this, col, startRow, endRow); } - Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t startRow = 0, size_t endRow = size_t.max) + Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t startRow, size_t endRow) { return typeof(return)(&this, col, startRow, endRow); } // Row - Iterator!T getRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + Iterator!T getRow(T)(size_t row, size_t startColumn, size_t endColumn) { auto c = this.iterateRow!T(row, startColumn, endColumn); return typeof(return)(c.array); // TODO: why .array? } private enum t2 = q{ - Iterator!(%1$s) getRow%2$s(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + Iterator!(%1$s) getRow%2$s(size_t row, size_t startColumn, size_t endColumn) { return getRow!(%1$s)(row, startColumn, endColumn); } }; @@ -165,36 +165,36 @@ struct Sheet { mixin(format(t2, T, T[0].toUpper ~ T[1 .. $])); } - RowUntyped iterateRowUntyped(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + RowUntyped iterateRowUntyped(size_t row, size_t startColumn, size_t endColumn) { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(T) iterateRow(T)(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) @trusted /* TODO: remove @trusted when `&this` is stored in a @safe manner in `Row` */ { + Row!(T) iterateRow(T)(size_t row, size_t startColumn, size_t endColumn) @trusted /* TODO: remove @trusted when `&this` is stored in a @safe manner in `Row` */ { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(long) iterateRowLong(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + Row!(long) iterateRowLong(size_t row, size_t startColumn, size_t endColumn) { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(double) iterateRowDouble(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + Row!(double) iterateRowDouble(size_t row, size_t startColumn, size_t endColumn) { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(string) iterateRowString(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + Row!(string) iterateRowString(size_t row, size_t startColumn, size_t endColumn) { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(DateTime) iterateRowDateTime(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) + Row!(DateTime) iterateRowDateTime(size_t row, size_t startColumn, size_t endColumn) { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(Date) iterateRowDate(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + Row!(Date) iterateRowDate(size_t row, size_t startColumn, size_t endColumn) { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(TimeOfDay) iterateRowTimeOfDay(size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) + Row!(TimeOfDay) iterateRowTimeOfDay(size_t row, size_t startColumn, size_t endColumn) { return typeof(return)(&this, row, startColumn, endColumn); } @@ -237,12 +237,12 @@ struct RowUntyped { const size_t endColumn; size_t cur; - this(Sheet* sheet, size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) pure nothrow @nogc { + this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) pure nothrow @nogc { assert(sheet.table.length == sheet.maxPos.row + 1); this.sheet = sheet; this.row = row; this.startColumn = startColumn; - this.endColumn = endColumn != size_t.max ? endColumn : sheet.maxPos.col + 1; + this.endColumn = endColumn; this.cur = this.startColumn; } @@ -268,7 +268,7 @@ struct Row(T) { RowUntyped ru; T front; - this(Sheet* sheet, size_t row, size_t startColumn = 0, size_t endColumn = size_t.max) { + this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) { ru = RowUntyped(sheet, row, startColumn, endColumn); read(); } @@ -301,12 +301,12 @@ struct ColumnUntyped { const size_t endRow; size_t cur; - this(Sheet* sheet, size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + this(Sheet* sheet, size_t col, size_t startRow, size_t endRow) { assert(sheet.table.length == sheet.maxPos.row + 1); this.sheet = sheet; this.col = col; this.startRow = startRow; - this.endRow = endRow != size_t.max ? endRow : sheet.maxPos.row + 1; + this.endRow = endRow; this.cur = this.startRow; } @@ -333,7 +333,7 @@ struct Column(T) { T front; - this(Sheet* sheet, size_t col, size_t startRow = 0, size_t endRow = size_t.max) { + this(Sheet* sheet, size_t col, size_t startRow, size_t endRow) { this.cu = ColumnUntyped(sheet, col, startRow, endRow); this.read(); } From 7a00e549333f9e5b1f35832df3ea5f149df3266a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Mon, 25 Jul 2022 11:59:39 +0200 Subject: [PATCH 43/45] Convert @safe: to individual @safe-qualifications of (member) functions --- source/xlsxreader.d | 126 +++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 118d737..757ba62 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -22,8 +22,6 @@ import std.zip; import dxml.dom; -@safe: - /// struct Pos { // zero based @@ -67,7 +65,7 @@ struct Sheet { Cell[][] table; Pos maxPos; - string toString() const @trusted { + string toString() const @safe { import std.format : formattedWrite; import std.array : appender; long[] maxCol = new long[](maxPos.col + 1); @@ -91,7 +89,7 @@ struct Sheet { return app.data; } - void printTable() const { + void printTable() const @safe { writeln(this.toString()); } @@ -103,7 +101,7 @@ struct Sheet { } private enum t = q{ - Iterator!(%1$s) getColumn%2$s(size_t col, size_t startRow, size_t endRow) { + Iterator!(%1$s) getColumn%2$s(size_t col, size_t startRow, size_t endRow) @safe { return getColumn!(%1$s)(col, startRow, endRow); } }; @@ -113,7 +111,7 @@ struct Sheet { mixin(format(t, T, T[0].toUpper ~ T[1 .. $])); } - ColumnUntyped iterateColumnUntyped(size_t col, size_t startRow, size_t endRow) { + ColumnUntyped iterateColumnUntyped(size_t col, size_t startRow, size_t endRow) @safe { return typeof(return)(&this, col, startRow, endRow); } @@ -121,41 +119,39 @@ struct Sheet { return typeof(return)(&this, col, startRow, endRow); } - Column!(long) iterateColumnLong(size_t col, size_t startRow, size_t endRow) { + Column!(long) iterateColumnLong(size_t col, size_t startRow, size_t endRow) @safe { return typeof(return)(&this, col, startRow, endRow); } - Column!(double) iterateColumnDouble(size_t col, size_t startRow, size_t endRow) { + Column!(double) iterateColumnDouble(size_t col, size_t startRow, size_t endRow) @safe { return typeof(return)(&this, col, startRow, endRow); } - Column!(string) iterateColumnString(size_t col, size_t startRow, size_t endRow) { + Column!(string) iterateColumnString(size_t col, size_t startRow, size_t endRow) @safe { return typeof(return)(&this, col, startRow, endRow); } - Column!(DateTime) iterateColumnDateTime(size_t col, size_t startRow, size_t endRow) - { + Column!(DateTime) iterateColumnDateTime(size_t col, size_t startRow, size_t endRow) @safe { return typeof(return)(&this, col, startRow, endRow); } - Column!(Date) iterateColumnDate(size_t col, size_t startRow, size_t endRow) { + Column!(Date) iterateColumnDate(size_t col, size_t startRow, size_t endRow) @safe { return typeof(return)(&this, col, startRow, endRow); } - Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t startRow, size_t endRow) - { + Column!(TimeOfDay) iterateColumnTimeOfDay(size_t col, size_t startRow, size_t endRow) @safe { return typeof(return)(&this, col, startRow, endRow); } // Row - Iterator!T getRow(T)(size_t row, size_t startColumn, size_t endColumn) { + Iterator!T getRow(T)(size_t row, size_t startColumn, size_t endColumn) @safe { auto c = this.iterateRow!T(row, startColumn, endColumn); return typeof(return)(c.array); // TODO: why .array? } private enum t2 = q{ - Iterator!(%1$s) getRow%2$s(size_t row, size_t startColumn, size_t endColumn) { + Iterator!(%1$s) getRow%2$s(size_t row, size_t startColumn, size_t endColumn) @safe { return getRow!(%1$s)(row, startColumn, endColumn); } }; @@ -165,7 +161,7 @@ struct Sheet { mixin(format(t2, T, T[0].toUpper ~ T[1 .. $])); } - RowUntyped iterateRowUntyped(size_t row, size_t startColumn, size_t endColumn) { + RowUntyped iterateRowUntyped(size_t row, size_t startColumn, size_t endColumn) @safe { return typeof(return)(&this, row, startColumn, endColumn); } @@ -173,29 +169,27 @@ struct Sheet { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(long) iterateRowLong(size_t row, size_t startColumn, size_t endColumn) { + Row!(long) iterateRowLong(size_t row, size_t startColumn, size_t endColumn) @safe { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(double) iterateRowDouble(size_t row, size_t startColumn, size_t endColumn) { + Row!(double) iterateRowDouble(size_t row, size_t startColumn, size_t endColumn) @safe { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(string) iterateRowString(size_t row, size_t startColumn, size_t endColumn) { + Row!(string) iterateRowString(size_t row, size_t startColumn, size_t endColumn) @safe { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(DateTime) iterateRowDateTime(size_t row, size_t startColumn, size_t endColumn) - { + Row!(DateTime) iterateRowDateTime(size_t row, size_t startColumn, size_t endColumn) @safe { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(Date) iterateRowDate(size_t row, size_t startColumn, size_t endColumn) { + Row!(Date) iterateRowDate(size_t row, size_t startColumn, size_t endColumn) @safe { return typeof(return)(&this, row, startColumn, endColumn); } - Row!(TimeOfDay) iterateRowTimeOfDay(size_t row, size_t startColumn, size_t endColumn) - { + Row!(TimeOfDay) iterateRowTimeOfDay(size_t row, size_t startColumn, size_t endColumn) @safe { return typeof(return)(&this, row, startColumn, endColumn); } } @@ -237,7 +231,7 @@ struct RowUntyped { const size_t endColumn; size_t cur; - this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) pure nothrow @nogc { + this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) pure nothrow @nogc @safe { assert(sheet.table.length == sheet.maxPos.row + 1); this.sheet = sheet; this.row = row; @@ -246,19 +240,19 @@ struct RowUntyped { this.cur = this.startColumn; } - @property bool empty() const pure nothrow @nogc { + @property bool empty() const pure nothrow @nogc @safe { return this.cur >= this.endColumn; } - void popFront() pure nothrow @nogc { + void popFront() pure nothrow @nogc @safe { ++this.cur; } - inout(typeof(this)) save() inout pure nothrow @nogc { + inout(typeof(this)) save() inout pure nothrow @nogc @safe { return this; } - @property inout(Cell) front() inout pure nothrow @nogc { + @property inout(Cell) front() inout pure nothrow @nogc @safe { return this.sheet.table[this.row][this.cur]; } } @@ -301,7 +295,7 @@ struct ColumnUntyped { const size_t endRow; size_t cur; - this(Sheet* sheet, size_t col, size_t startRow, size_t endRow) { + this(Sheet* sheet, size_t col, size_t startRow, size_t endRow) @safe { assert(sheet.table.length == sheet.maxPos.row + 1); this.sheet = sheet; this.col = col; @@ -310,19 +304,19 @@ struct ColumnUntyped { this.cur = this.startRow; } - @property bool empty() const pure nothrow @nogc { + @property bool empty() const pure nothrow @nogc @safe { return this.cur >= this.endRow; } - void popFront() { + void popFront() @safe { ++this.cur; } - inout(typeof(this)) save() inout pure nothrow @nogc { + inout(typeof(this)) save() inout pure nothrow @nogc @safe { return this; } - @property Cell front() { + @property Cell front() @safe { return this.sheet.table[this.cur][this.col]; } } @@ -358,7 +352,7 @@ struct Column(T) { } } -unittest { +@safe unittest { import std.range : isForwardRange; import std.meta : AliasSeq; static foreach(T; AliasSeq!(long,double,DateTime,TimeOfDay,Date,string)) {{ @@ -371,7 +365,7 @@ unittest { }} } -Date longToDate(long d) { +Date longToDate(long d) @safe { // modifed from https://www.codeproject.com/Articles/2750/ // Excel-Serial-Date-to-Day-Month-Year-and-Vice-Versa @@ -399,7 +393,7 @@ Date longToDate(long d) { return Date(nYear, nMonth, nDay); } -long dateToLong(Date d) { +long dateToLong(Date d) @safe { // modifed from https://www.codeproject.com/Articles/2750/ // Excel-Serial-Date-to-Day-Month-Year-and-Vice-Versa @@ -427,7 +421,7 @@ long dateToLong(Date d) { return nSerialDate; } -unittest { +@safe unittest { auto ds = [ Date(1900,2,1), Date(1901, 2, 28), Date(2019, 06, 05) ]; foreach(const d; ds) { long l = dateToLong(d); @@ -436,7 +430,7 @@ unittest { } } -TimeOfDay doubleToTimeOfDay(double s) { +TimeOfDay doubleToTimeOfDay(double s) @safe { import core.stdc.math : lround; double secs = (24.0 * 60.0 * 60.0) * s; @@ -446,14 +440,14 @@ TimeOfDay doubleToTimeOfDay(double s) { return TimeOfDay(secI / 3600, (secI / 60) % 60, secI % 60); } -double timeOfDayToDouble(TimeOfDay tod) { +double timeOfDayToDouble(TimeOfDay tod) @safe { long h = tod.hour * 60 * 60; long m = tod.minute * 60; long s = tod.second; return (h + m + s) / (24.0 * 60.0 * 60.0); } -unittest { +@safe unittest { auto tods = [ TimeOfDay(23, 12, 11), TimeOfDay(11, 0, 11), TimeOfDay(0, 0, 0), TimeOfDay(0, 1, 0), TimeOfDay(23, 59, 59), TimeOfDay(0, 0, 0)]; @@ -465,20 +459,20 @@ unittest { } } -double datetimeToDouble(DateTime dt) { +double datetimeToDouble(DateTime dt) @safe { double d = dateToLong(dt.date); double t = timeOfDayToDouble(dt.timeOfDay); return d + t; } -DateTime doubleToDateTime(double d) { +DateTime doubleToDateTime(double d) @safe { long l = cast(long)d; Date dt = longToDate(l); TimeOfDay t = doubleToTimeOfDay(d - l); return DateTime(dt, t); } -unittest { +@safe unittest { auto ds = [ Date(1900,2,1), Date(1901, 2, 28), Date(2019, 06, 05) ]; auto tods = [ TimeOfDay(23, 12, 11), TimeOfDay(11, 0, 11), TimeOfDay(0, 0, 0), TimeOfDay(0, 1, 0), @@ -501,7 +495,7 @@ unittest { } } -Date stringToDate(string s) { +Date stringToDate(string s) @safe { import std.array : split; import std.string : indexOf; @@ -514,7 +508,7 @@ Date stringToDate(string s) { } } -bool tryConvertTo(T,S)(S var) @trusted { +bool tryConvertTo(T,S)(S var) { return !(tryConvertToImpl!T(Data(var)).isNull()); } @@ -526,7 +520,7 @@ Nullable!(T) tryConvertToImpl(T)(Data var) { } } -T convertTo(T)(string var) { +T convertTo(T)(string var) @safe { import std.math : lround; static if(isSomeString!T) { return to!T(var); @@ -628,13 +622,13 @@ SheetNameId[] sheetNames(in string filename) @trusted { .release; } -unittest { +@safe unittest { auto r = sheetNames("multitable.xlsx"); assert(r[0].name == "wb1"); assert(r[0].id == 1); } -unittest { +@safe unittest { auto r = sheetNames("sheetnames.xlsx"); assert(r[0].name == "A & B ;", r[0].name); assert(r[0].id == 1); @@ -667,7 +661,7 @@ Relationships[string] parseRelationships(ZipArchive za, ArchiveMember am) @trust return ret; } -Sheet readSheet(in string filename, in string sheetName) { +Sheet readSheet(in string filename, in string sheetName) @safe { SheetNameId[] sheets = sheetNames(filename); auto sRng = sheets.filter!(s => s.name == sheetName); enforce(!sRng.empty, "No sheet with name " ~ sheetName @@ -675,7 +669,7 @@ Sheet readSheet(in string filename, in string sheetName) { return readSheetImpl(filename, sRng.front.rid); } -string eatXlPrefix(string fn) { +string eatXlPrefix(string fn) @safe { foreach(const p; ["xl//", "/xl/"]) { if(fn.startsWith(p)) { return fn[p.length .. $]; @@ -794,7 +788,7 @@ string extractData(DOMEntity!string si) { assert(false); } -private bool canConvertToLong(in string s) { +private bool canConvertToLong(in string s) @safe { if(s.empty) { return false; } @@ -804,7 +798,7 @@ private bool canConvertToLong(in string s) { private immutable rs = r"[\+-]{0,1}[0-9][0-9]*\.[0-9]*"; private auto rgx = ctRegex!rs; -private bool canConvertToDoubleOld(in string s) { +private bool canConvertToDoubleOld(in string s) @safe { auto cap = matchAll(s, rgx); return cap.empty || cap.front.hit != s ? false : true; } @@ -848,7 +842,7 @@ private bool canConvertToDouble(string s) pure @safe @nogc { return s.empty; } -unittest { +@safe unittest { static struct Test { string tt; bool rslt; @@ -997,7 +991,7 @@ Cell[] insertValueIntoCell(Cell[] cells, string[] ss) @trusted { return cells; } -Pos toPos(in string s) { +Pos toPos(in string s) @safe { import std.string : indexOfAny; import std.math : pow; ptrdiff_t fn = s.indexOfAny("0123456789"); @@ -1011,7 +1005,7 @@ Pos toPos(in string s) { return Pos(row, col - 1); } -unittest { +@safe unittest { assert(toPos("A1").col == 0); assert(toPos("Z1").col == 25); assert(toPos("AA1").col == 26); @@ -1038,7 +1032,7 @@ string specialCharacterReplacementReverse(string s) { .replace("&", "&"); } -unittest { +@safe unittest { import std.math : isClose; auto r = readSheet("multitable.xlsx", "wb1"); assert(isClose(r.table[12][5].xmlValue.to!double(), 26.74), @@ -1050,7 +1044,7 @@ unittest { ); } -unittest { +@safe unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "wb1"); auto r = s.iterateRow!long(15, 1, 6); @@ -1069,7 +1063,7 @@ unittest { .array; } -unittest { +@safe unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "wb2"); //writefln("%s\n%(%s\n%)", s.maxPos, s.cells); @@ -1091,7 +1085,7 @@ unittest { assert(equal(rslt, it2)); } -unittest { +@safe unittest { import std.algorithm.comparison : equal; auto s = readSheet("multitable.xlsx", "Sheet3"); writeln(s.table[0][0].xmlValue); @@ -1100,7 +1094,7 @@ unittest { //assert(s.table[0][0].canConvertTo(CellType.bool_)); } -@trusted unittest { +unittest { import std.file : dirEntries, SpanMode; import std.traits : EnumMembers; foreach(const de; dirEntries("xlsx_files/", "*.xlsx", SpanMode.depth) @@ -1116,7 +1110,7 @@ unittest { } } -unittest { +@safe unittest { import std.algorithm.comparison : equal; auto sheet = readSheet("testworkbook.xlsx", "ws1"); //writefln("%(%s\n%)", sheet.cells); @@ -1138,7 +1132,7 @@ unittest { assert(equal(c2, r2), format("%s", c2)); } -unittest { +@safe unittest { import std.math : isClose; auto sheet = readSheet("toto.xlsx", "Trades"); writefln("%(%s\n%)", sheet.cells); @@ -1149,14 +1143,14 @@ unittest { assert(isClose(d, 38204642.510000)); } -unittest { +@safe unittest { auto sheet = readSheet("leading_zeros.xlsx", "Sheet1"); auto a2 = sheet.cells.filter!(c => c.r == "A2"); assert(!a2.empty); assert(a2.front.xmlValue == "0012", format("%s", a2.front)); } -unittest { +@safe unittest { import std.algorithm.comparison : equal; auto s = readSheet("datetimes.xlsx", "Sheet1"); //writefln("%s\n%(%s\n%)", s.maxPos, s.cells); From 7f3413265a9524d9cba85d9fa75386366ba03a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Mon, 25 Jul 2022 17:41:40 +0200 Subject: [PATCH 44/45] Avoid -dip1000 compiler error --- source/xlsxreader.d | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index 757ba62..e1fda52 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -146,8 +146,7 @@ struct Sheet { // Row Iterator!T getRow(T)(size_t row, size_t startColumn, size_t endColumn) @safe { - auto c = this.iterateRow!T(row, startColumn, endColumn); - return typeof(return)(c.array); // TODO: why .array? + return typeof(return)(this.iterateRow!T(row, startColumn, endColumn).array); // TODO: why .array? } private enum t2 = q{ From a61facbeb557efb08b8c54e482b3a880f9d907e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Nordl=C3=B6w?= Date: Mon, 25 Jul 2022 18:08:18 +0200 Subject: [PATCH 45/45] Prefix references to ru and read() with this. in Row(T).this --- source/xlsxreader.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/xlsxreader.d b/source/xlsxreader.d index e1fda52..80afc2b 100644 --- a/source/xlsxreader.d +++ b/source/xlsxreader.d @@ -262,8 +262,8 @@ struct Row(T) { T front; this(Sheet* sheet, size_t row, size_t startColumn, size_t endColumn) { - ru = RowUntyped(sheet, row, startColumn, endColumn); - read(); + this.ru = RowUntyped(sheet, row, startColumn, endColumn); + this.read(); } @property bool empty() const pure nothrow @nogc {