diff --git a/File_Engine/Compute/ReadFromCsvFile.cs b/File_Engine/Compute/ReadFromCsvFile.cs new file mode 100644 index 0000000..6c6012a --- /dev/null +++ b/File_Engine/Compute/ReadFromCsvFile.cs @@ -0,0 +1,337 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2025, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Adapters.File; +using BH.oM.Base.Attributes; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; + +namespace BH.Engine.Adapters.File +{ + public static partial class Compute + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("Read a CSV file into a 2D object array, parsing each column using CsvConfig.ColumnDataFormats when provided.")] + [Input("filePath", "Path to the CSV file.")] + [Input("settings", "CSV settings including delimiter, decimal separator, and per-column formats. If null, defaults are used.")] + [Input("active", "Boolean used to trigger the function.")] + public static IEnumerable> ReadFromCsvFile(string filePath, CsvConfig settings = null, bool active = false) + { + if (!active) + return Array.Empty>(); + + if (string.IsNullOrWhiteSpace(filePath)) + { + BH.Engine.Base.Compute.RecordError("The file path must not be empty."); + return Array.Empty>(); + } + + if (!System.IO.File.Exists(filePath)) + { + BH.Engine.Base.Compute.RecordError($"The file `{filePath}` does not exist."); + return Array.Empty>(); + } + + if (settings == null) + settings = new CsvConfig(); + + var delim = settings.Delimiter ?? "\t"; + string[] lines; + try + { + lines = System.IO.File.ReadAllLines(filePath); + } + catch (Exception e) + { + BH.Engine.Base.Compute.RecordError($"Error reading file:\n\t{e}"); + return Array.Empty>(); + } + + if (lines.Length == 0) + return Array.Empty>(); + + // 1) Parse lines into raw string rows (CSV rules: quotes + escaped quotes) + var rawRows = new List(); + for (int i = 0; i < lines.Length; i++) + { + var line = lines[i]; + if (string.IsNullOrEmpty(line)) + continue; + + rawRows.Add(SplitCsvLine(line, delim)); + } + + if (rawRows.Count == 0) + return Array.Empty>(); + + // 2) Normalize columns (pad ragged rows to max width) + int rAll = rawRows.Count; + int c = 0; + for (int i = 0; i < rAll; i++) + if (rawRows[i].Length > c) c = rawRows[i].Length; + + if (c == 0) + return Array.Empty>(); + + // 3) Decide data start index based on IncludeHeader + var result = new List>(rAll); + + for (int i = 0; i < rAll; i++) + { + bool isHeader = settings.IncludeHeader && i == 0; + + var src = rawRows[i]; + var row = new List(c); + + for (int j = 0; j < c; j++) + { + string cell = j < src.Length ? src[j] : null; + row.Add(ParseCell(cell, j, settings, isHeader)); + } + + result.Add(row); + } + + return result; + } + + /***************************************************/ + /**** Private Helpers ****/ + /***************************************************/ + + private static string[] SplitCsvLine(string line, string delimiter) + { + if (string.IsNullOrEmpty(line)) + return Array.Empty(); + + var cells = new List(); + var current = new System.Text.StringBuilder(); + bool inQuotes = false; + int i = 0; + int n = line.Length; + int dlen = string.IsNullOrEmpty(delimiter) ? 0 : delimiter.Length; + + while (i < n) + { + char ch = line[i]; + + if (ch == '"') + { + if (inQuotes && i + 1 < n && line[i + 1] == '"') + { + current.Append('"'); // Escaped quote + i += 2; + continue; + } + inQuotes = !inQuotes; + i++; + continue; + } + + if (!inQuotes && dlen > 0 && i + dlen <= n && + string.CompareOrdinal(line, i, delimiter, 0, dlen) == 0) + { + cells.Add(current.ToString()); + current.Length = 0; + i += dlen; + continue; + } + + current.Append(ch); + i++; + } + + cells.Add(current.ToString()); + return cells.ToArray(); + } + + /***************************************************/ + + private static object ParseCell(string raw, int columnIndex, CsvConfig settings, bool isHeader = false) + { + if (string.IsNullOrEmpty(raw)) + return null; + + if (isHeader) + return raw; + + bool hasColumnFormat = + settings.ColumnDataFormats != null && + columnIndex >= 0 && + columnIndex < settings.ColumnDataFormats.Count; + + if (hasColumnFormat) + { + switch (settings.ColumnDataFormats[columnIndex]) + { + case StringType.Boolean: + { + var b = ParseBool(raw, settings); + return b.HasValue ? (object)b.Value : null; + } + + case StringType.Numeric: + { + var num = ParseNumeric(raw, settings.DecimalSeparator); + return num.HasValue ? (object)num.Value : null; + } + + case StringType.Date: + { + var dt = ParseDate(raw, settings.DateTimeFormat); + if (dt.HasValue) return dt.Value; + + // OA serial fallback (Excel serial date) + var serial = ParseNumeric(raw, settings.DecimalSeparator); + if (serial.HasValue) + { + try { return DateTime.FromOADate(serial.Value); } + catch { /* ignore */ } + } + return null; + } + + case StringType.Text: + return raw; + } + } + + // Try Bool + var bParsed = ParseBool(raw, settings); + if (bParsed.HasValue) return bParsed.Value; + + // Try Number + var d = ParseNumeric(raw, settings.DecimalSeparator); + if (d.HasValue) return d.Value; + + // Try Date + var when = ParseDate(raw, settings.DateTimeFormat); + if (when.HasValue) return when.Value; + + // OA serial fallback + var serial2 = ParseNumeric(raw, settings.DecimalSeparator); + if (serial2.HasValue) + { + try { return DateTime.FromOADate(serial2.Value); } + catch { /* ignore */ } + } + + // Text as-is + return raw; + } + + /***************************************************/ + + private static bool? ParseBool(string raw, CsvConfig settings) + { + if (string.Equals(raw, "true", StringComparison.OrdinalIgnoreCase)) return true; + if (string.Equals(raw, "false", StringComparison.OrdinalIgnoreCase)) return false; + + if (settings.BooleanAsNumber) + { + if (raw == "1") return true; + if (raw == "0") return false; + } + return null; + } + + /***************************************************/ + + private static double? ParseNumeric(string raw, string decimalSeparator) + { + if (string.IsNullOrEmpty(raw)) + return null; + + var norm = string.IsNullOrEmpty(decimalSeparator) || decimalSeparator == "." + ? raw + : raw.Replace(decimalSeparator, "."); + + if (double.TryParse(norm, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) + return value; + + return null; + } + + /***************************************************/ + + private static DateTime? ParseDate(string raw, DateFormatOptions option) + { + if (string.IsNullOrEmpty(raw)) + return null; + + string[] patterns; + + switch (option) + { + case DateFormatOptions.ISO8601: + patterns = new[] + { + "o", + "yyyy-MM-ddTHH:mm:ss", + "yyyy-MM-ddTHH:mm:ss.FFFFFFFK", + "yyyy-MM-dd" + }; + break; + + case DateFormatOptions.US: + patterns = new[] + { + "MM/dd/yyyy", + "M/d/yyyy", + "MM/dd/yy" + }; + break; + + case DateFormatOptions.EU: + default: + patterns = new[] + { + "dd/MM/yyyy", + "d/M/yyyy", + "dd/MM/yy" + }; + break; + } + + for (int i = 0; i < patterns.Length; i++) + { + DateTime tmp; + if (DateTime.TryParseExact(raw, patterns[i], CultureInfo.InvariantCulture, + DateTimeStyles.None, out tmp)) + return tmp; + } + + DateTime any; + if (DateTime.TryParse(raw, CultureInfo.InvariantCulture, DateTimeStyles.None, out any)) + return any; + + return null; + } + + /***************************************************/ + } +} \ No newline at end of file diff --git a/File_Engine/Compute/WriteToCsvFile.cs b/File_Engine/Compute/WriteToCsvFile.cs new file mode 100644 index 0000000..16c5fbe --- /dev/null +++ b/File_Engine/Compute/WriteToCsvFile.cs @@ -0,0 +1,440 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2025, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.Engine.Base; +using BH.oM.Adapters.File; +using BH.oM.Base.Attributes; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + + +namespace BH.Engine.Adapters.File +{ + public static partial class Compute + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("Write a CSV file with the input data or objects.")] + [Input("data", "Data to write to the file.")] + [Input("filePath", "Path to the file.")] + [Input("settings", "Settings to use when writing the CSV file. If null, default settings will be used.")] + [Input("replace", "If the file exists, you need to set this to true in order to allow overwriting it.")] + [Input("active", "Boolean used to trigger the function.")] + public static bool WriteToCsvFile(object data, string filePath, CsvConfig settings = null, bool replace = false, bool active = false) + { + if (!active || data == null) + return false; + + if (string.IsNullOrWhiteSpace(filePath)) + { + BH.Engine.Base.Compute.RecordError($"The filePath `{filePath}` must not be empty."); + return false; + } + + // Make sure no invalid chars are present. + filePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileName(filePath)); + + // If the file exists already, stop execution if `replace` is not true. + bool fileExisted = System.IO.File.Exists(filePath); + if (!replace && fileExisted) + { + BH.Engine.Base.Compute.RecordWarning($"The file `{filePath}` exists already. To replace its content, set `{nameof(replace)}` to true."); + return false; + } + + // Serialise to csv and create the file and directory. + string table = FromObject(data,settings); + System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath); + fileInfo.Directory.Create(); // If the directory already exists, this method does nothing. + + try + { + System.IO.File.WriteAllText(filePath, table, Query.FromEnum(settings.Encoding)); + } + catch (Exception e) + { + BH.Engine.Base.Compute.RecordError($"Error writing to file:\n\t{e.ToString()}"); + return false; + } + + return true; + } + + /***************************************************/ + + public static string FromObject(this object obj, CsvConfig settings = null) + { + if (settings == null) + settings = new CsvConfig(); + + object[,] flatten; + + if (obj is string || obj.GetType().IsPrimitive || obj is Enum || obj is IFormattable) + { + return FormatCell(obj, settings, null); + } + // Shape normalisation (priority to arrays) + else if (obj is object[,] rect) + { + flatten = rect; + } + else if (obj is object[][] jagged) + { + flatten = ToRect(jagged); + } + else if (obj is IEnumerable> nested) + { + flatten = ToRect(nested); + } + else if (obj is IEnumerable list && !(obj is string)) + { + flatten = ToRect(list); + } + else + { + BH.Engine.Base.Compute.RecordError( + $"The input data of type `{obj?.GetType().Name ?? "null"}` is not supported. "); + return string.Empty; + } + + // Convert cells to string array with formatting rules + string[,] table = ToStringTable(flatten, settings); + + // Serialize to CSV + var delim = settings.Delimiter ?? "\t"; + int r = table.GetLength(0); + int c = table.GetLength(1); + var sb = new StringBuilder(r * Math.Max(1, c) * 4); + + for (int i = 0; i < r; i++) + { + var encoded = Enumerable.Range(0, c).Select(j => EscapeCsv(table[i, j] ?? string.Empty, delim)); + sb.Append(string.Join(delim, encoded)); + if (i < r - 1) sb.Append('\n'); + } + + return sb.ToString(); + } + /*******************************************/ + /**** Private Methods *****/ + /*******************************************/ + + private static object[,] ToRect(object[][] obj) + { + if (obj == null || obj.Length == 0) + return new object[0, 0]; + int r = obj.Length; + int c = obj.Max(a => a?.Length ?? 0); + var result = new object[r, c]; + for (int i = 0; i < r; i++) + { + var row = obj[i] ?? new object[0]; + for (int j = 0; j < c; j++) + { + result[i, j] = j < row.Length ? row[j] : null; + } + } + return result; + } + + /***************************************************/ + + private static object[,] ToRect(IEnumerable> obj) + { + if (obj == null) + return new object[0, 0]; + var list = obj.ToList(); + if (list.Count == 0) + return new object[0, 0]; + int r = list.Count; + int c = list.Max(a => a?.Count() ?? 0); + var result = new object[r, c]; + for (int i = 0; i < r; i++) + { + var row = list[i]?.ToList() ?? new List(); + for (int j = 0; j < c; j++) + { + result[i, j] = j < row.Count ? row[j] : null; + } + } + return result; + } + + /***************************************************/ + + private static object[,] ToRect(IEnumerable obj) + { + if (obj == null) + return new object[0, 0]; + + var list = obj.ToList(); + if (list.Count == 0) + return new object[0, 0]; + + int r = list.Count; + int c = 0; + var result = new object[r, c]; + for (int i = 0; i < r; i++) + { + result[i, 0] = list[i]; + } + return result; + } + + /***************************************************/ + + private static string[,] ToStringTable(object[,] obj, CsvConfig settings) + { + if (obj == null) + return new string[0, 0]; + + int r = obj.GetLength(0); + int c = obj.GetLength(1); + var result = new string[r, c]; + + for (int i = 0; i < r; i++) + { + bool isHeader = (i == 0); + for (int j = 0; j < c; j++) + result[i, j] = FormatCell(obj[i, j], settings, j, isHeader); + } + + return result; + } + + /***************************************************/ + + private static string FormatCell(object value, CsvConfig settings, int? column, bool isHeader = false) + { + if (settings.ColumnDataFormats != null + && column.HasValue + && column.Value < settings.ColumnDataFormats.Count + && ((settings.IncludeHeader && !isHeader) || !settings.IncludeHeader)) + { + StringType? format = settings.ColumnDataFormats[column.Value]; + + if (format.HasValue) + { + switch (format) + { + case StringType.Boolean: + if(value is bool boolean) + return boolean.FormatBool(settings.BooleanAsNumber); + else + return string.Empty; + + case StringType.Date: + if (value is IFormattable date) + return date.FormatDate(settings.DateTimeFormat); + else + return string.Empty; + + case StringType.Numeric: + // Accept only IFormattable numerics here; else fall through to generic branch below + var fnum = value as IFormattable; + return fnum != null + ? fnum.FormatNumeric((int?)settings.Digit, settings.DecimalSeparator) + : string.Empty; + + case StringType.Text: + // Re-run without ColumnDataFormats influence + var noColumnFormats = new CsvConfig + { + IncludeHeader = settings.IncludeHeader, + Digit = settings.Digit, + DecimalSeparator = settings.DecimalSeparator, + DateTimeFormat = settings.DateTimeFormat, + Delimiter = settings.Delimiter, + IncludeObjects = settings.IncludeObjects, + ColumnDataFormats = null + }; + return FormatCell(value, noColumnFormats, null, isHeader); + } + } + } + + // numeric (round if Digit set) + if (value.GetType().IsNumeric(false)) + { + double d = System.Convert.ToDouble(value, CultureInfo.InvariantCulture); + return d.FormatNumeric((int?)settings.Digit, settings.DecimalSeparator); + } + // Date/Time + if (value is DateTime dt) + return dt.FormatDate(settings.DateTimeFormat); + + // Bool + if (value is bool b) + return b.FormatBool(settings.BooleanAsNumber); + + // IFormattable (decimal, Guid, etc.) + var formattable = value as IFormattable; + if (formattable != null) + return formattable.FormatIFormattable(); + + // Enum + if (value.GetType().IsEnum) + return (value as Enum).FormatEnum(); + + // Other unformattable types + if (settings.IncludeObjects) + return value.FormatObject(); + + //String + if (value is string s) + return s; + + return string.Empty; + } + + /***************************************************/ + + private static string FormatDate(this IFormattable date, DateFormatOptions option) + { + if (date == null) + return string.Empty; + + // Handle Excel-style serial number (double) + if (date is double serial) + { + try + { + var dt = DateTime.FromOADate(serial); + return dt.FormatDate(option); + } + catch + { + return serial.ToString(CultureInfo.InvariantCulture); + } + } + + // Handle DateTimeOffset + if (date is DateTime dt2) + { + switch (option) + { + case DateFormatOptions.ISO8601: + return dt2.ToString("o", CultureInfo.InvariantCulture); + case DateFormatOptions.US: + return dt2.ToString("MM/dd/yyyy", CultureInfo.InvariantCulture); + case DateFormatOptions.EU: + default: + return dt2.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture); + } + } + + return date.ToString(null, CultureInfo.InvariantCulture); + } + + /***************************************************/ + + private static string FormatNumeric(this IFormattable number, int? digits, string decimalSeparator) + { + if (number == null) + return string.Empty; + string raw; + if (digits.HasValue) + { + int d = Math.Max(0, digits.Value); + var format = d > 0 ? "0." + new string('#', d) : "0"; + raw = number.ToString(format, CultureInfo.InvariantCulture); + } + else + { + raw = number.ToString("G", CultureInfo.InvariantCulture); + } + // Apply custom decimal separator if needed + if (decimalSeparator != "." && raw.Contains(".")) + { + raw = raw.Replace(".", decimalSeparator); + } + return raw; + } + + /***************************************************/ + + private static string FormatBool(this bool b, bool asNumber) + { + return asNumber ? (b ? "1" : "0") : (b ? "true" : "false"); + } + + /***************************************************/ + + private static string FormatEnum(this Enum e) + { + return System.Convert.ToString(e, CultureInfo.InvariantCulture); + } + + /***************************************************/ + + private static string FormatIFormattable(this IFormattable f) + { + return f.ToString(null, CultureInfo.InvariantCulture); + } + + /***************************************************/ + + private static string FormatObject(this object obj, string propName = null) + { + if (obj == null) + return string.Empty; + + if (propName != null) + return obj.GetType().GetProperty(propName)?.GetValue(obj).ToString(); + + var toString = obj.ToString(); + if (toString != null && toString != obj.GetType().FullName) + return toString; + + return $"<{obj.GetType().Name}>"; + } + + /***************************************************/ + + private static string EscapeCsv(string input, string delimiter) + { + if (input == null) return string.Empty; + + bool mustQuote = + input.IndexOf('"') >= 0 || + input.IndexOf('\n') >= 0 || + input.IndexOf('\r') >= 0 || + (!string.IsNullOrEmpty(delimiter) && input.IndexOf(delimiter, StringComparison.Ordinal) >= 0); + + if (!mustQuote) + return input; + + var doubled = input.Replace("\"", "\"\""); + return "\"" + doubled + "\""; + } + + /***************************************************/ + + } +} diff --git a/File_Engine/Query/Encoding.cs b/File_Engine/Query/Encoding.cs index 22bbdd9..27cc3c5 100644 --- a/File_Engine/Query/Encoding.cs +++ b/File_Engine/Query/Encoding.cs @@ -62,7 +62,7 @@ public static Encoding Encoding(this FSFile file) /***************************************************/ - private static Encoding FromEnum(Encodings encodingEnumValue) + public static Encoding FromEnum(Encodings encodingEnumValue) { switch (encodingEnumValue) { diff --git a/File_oM/Config/CsvConfig.cs b/File_oM/Config/CsvConfig.cs new file mode 100644 index 0000000..c1c1407 --- /dev/null +++ b/File_oM/Config/CsvConfig.cs @@ -0,0 +1,68 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2025, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + + +using BH.oM.Adapter; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace BH.oM.Adapters.File +{ + public class CsvConfig : ActionConfig + { + [Description(" The delimiter to use in the CSV file. Common options are ',' for comma, ';' for semicolon, and '\\t' for tab by default.")] + public string Delimiter { get; set; } = "\t"; + + [Description(" Whether to include objects that do not have a string representation. If true, these objects will be included using their ToString() method or a placeholder if not available. If false, such objects will be skipped.")] + public bool IncludeObjects { get; set; } = false; + + [Description(" If specified, the value of the property representing object will be serialized in the CSV file. If null, object type name will shown.")] + public string PropertyName { get; set; } = null; + + [Description(" Whether to include a header row with column names in the CSV file. Default is true, meaning the first row will contain the property names.")] + public bool IncludeHeader { get; set; } = true; + + [Description("Configuration for formatting datatype for each column. If null, default formatting will be applied based on the data type.")] + public List ColumnDataFormats { get; set; } = null; + + [Description(" Whether to represent boolean values as numbers (1 for true, 0 for false) instead of text (true/false). Default is false, meaning booleans will be represented as text.")] + public bool BooleanAsNumber { get; set; } = false; + + [Description(" The character to use as the decimal separator in numerical values. Common options are '.' for dot and ',' for comma. Default is '.'")] + public string DecimalSeparator { get; set; } = "."; + + [Description(" If specified, numerical values will be rounded to this number of decimal places. If null, no rounding is applied.")] + public double? Digit { get; set; } = null; + + [Description(" The format to use for date values. Options include ISO8601 (e.g., 2023-10-05T14:48:00Z), US (e.g., 10/05/2023), and EU (e.g., 05/10/2023). Default is ISO8601.")] + public DateFormatOptions DateTimeFormat { get; set; } = DateFormatOptions.EU; + + [Description(" The text encoding to use when reading or writing the CSV file. Default is UTF-8.")] + public Encodings Encoding { get; set; } = Encodings.UTF8; + } +} + + + + + diff --git a/File_oM/enums/DateTime.cs b/File_oM/enums/DateTime.cs new file mode 100644 index 0000000..ef404b5 --- /dev/null +++ b/File_oM/enums/DateTime.cs @@ -0,0 +1,42 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2025, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BH.oM.Adapters.File +{ + public enum DateFormatOptions + { + ISO8601, // e.g., 2023-10-05T14:48:00Z + US, // e.g., 10/05/2023 + EU // e.g., 05/10/2023 + } +} + + + + + diff --git a/File_oM/enums/FileFormat.cs b/File_oM/enums/FileFormat.cs index 1615b66..afc7136 100644 --- a/File_oM/enums/FileFormat.cs +++ b/File_oM/enums/FileFormat.cs @@ -33,6 +33,8 @@ public enum FileFormat JSON, BSON, XML, + TXT, + CSV, byteArray } } diff --git a/File_oM/enums/StringType.cs b/File_oM/enums/StringType.cs new file mode 100644 index 0000000..41832d7 --- /dev/null +++ b/File_oM/enums/StringType.cs @@ -0,0 +1,43 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2025, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BH.oM.Adapters.File +{ + public enum StringType + { + Text, + Numeric, + Date, + Boolean, + } +} + + + + +