diff --git a/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/CziDocumentInfo.cs b/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/CziDocumentInfo.cs index ba8b15d..ff8c42c 100644 --- a/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/CziDocumentInfo.cs +++ b/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/CziDocumentInfo.cs @@ -7,7 +7,8 @@ namespace Zeiss.Micro.LibCzi.Net.Implementation using System; using System.Collections.Generic; using System.Runtime.InteropServices; - using System.Text.Json; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; using Zeiss.Micro.LibCzi.Net.Interface; using Zeiss.Micro.LibCzi.Net.Interop; @@ -62,25 +63,18 @@ public IReadOnlyDictionary GetGeneralDocumentInfo() // Parse the JSON string, and store the key-value pairs in the dictionary. // We assume here that the root element must be an object. - using (JsonDocument document = JsonDocument.Parse(json)) - { - JsonElement root = document.RootElement; + JObject root = JObject.Parse(json); - if (root.ValueKind == JsonValueKind.Object) + foreach (var property in root.Properties()) + { + if (property.Name == CziDocumentPropertyKeys.GeneralDocumentInfoCreationDateTime) { - foreach (JsonProperty property in root.EnumerateObject()) - { - // Perform additional parsing for specific nodes if needed - if (property.Name == CziDocumentPropertyKeys.GeneralDocumentInfoCreationDateTime) - { - // Parse the "creation_data_time" node as a DateTime - dictionary[property.Name] = CziDocumentInfo.ParseCreationDateTime(property.Value); - } - else - { - dictionary[property.Name] = CziDocumentInfo.GetValue(property.Value); - } - } + // Parse the "creation_data_time" node as a DateTime + dictionary[property.Name] = CziDocumentInfo.ParseCreationDateTime(property.Value); + } + else + { + dictionary[property.Name] = CziDocumentInfo.GetValue(property.Value); } } @@ -94,10 +88,10 @@ public DimensionIndex[] GetAvailableDimensions() } /// - public JsonDocument GetDimensionInfo(DimensionIndex dimensionIndex) + public JObject GetDimensionInfo(DimensionIndex dimensionIndex) { string jsonText = LibCziApiInterop.Instance.CziDocumentInfoGetDimensionInfo(this.handle, dimensionIndex); - return JsonDocument.Parse(jsonText); + return JObject.Parse(jsonText); } /// @@ -107,53 +101,63 @@ public IDisplaySettings GetDisplaySettings() return new DisplaySettings(displaySettingsHandle); } - private static DateTime ParseCreationDateTime(JsonElement element) + private static DateTime ParseCreationDateTime(JToken token) { - if (element.ValueKind == JsonValueKind.String) + if (token.Type == JTokenType.String) { - string dateTimeString = element.GetString(); - if (DateTime.TryParse(dateTimeString, null, System.Globalization.DateTimeStyles.RoundtripKind, out DateTime dateTime)) + string dateTimeString = token.Value(); + if (DateTime.TryParseExact(dateTimeString, "O", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.RoundtripKind, out DateTime dt)) + { + return dt; + } + + if (DateTime.TryParse(dateTimeString, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.RoundtripKind, out dt)) + { + return dt; + } + + if (DateTime.TryParse(dateTimeString, System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.RoundtripKind, out dt)) { - return dateTime; + return dt; } + + throw new FormatException($"Invalid date time format for 'creation_data_time': '{dateTimeString}'."); + } + + if (token.Type == JTokenType.Date) + { + // Use the already-parsed DateTime value + return token.Value(); } throw new FormatException("Invalid date time format for 'creation_data_time'."); } - private static object GetValue(JsonElement element) + private static object GetValue(JToken token) { - switch (element.ValueKind) + switch (token.Type) { - case JsonValueKind.String: - return element.GetString(); - case JsonValueKind.Number: - if (element.TryGetInt32(out int intValue)) + case JTokenType.String: + return token.Value(); + case JTokenType.Integer: + // Try to fit into int, long, or just return as Int64 + long longValue = token.Value(); + if (longValue >= int.MinValue && longValue <= int.MaxValue) { - return intValue; + return (int)longValue; } - if (element.TryGetInt64(out long longValue)) - { - return longValue; - } - - if (element.TryGetDouble(out double doubleValue)) - { - return doubleValue; - } - - break; - case JsonValueKind.True: - return true; - case JsonValueKind.False: - return false; - case JsonValueKind.Null: + return longValue; + case JTokenType.Float: + return token.Value(); + case JTokenType.Boolean: + return token.Value(); + case JTokenType.Null: return null; + default: + // Default case: return the token as a string + return token.ToString(); } - - // Default case: return the element as a string - return element.ToString(); } } } diff --git a/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/InternalUtilities.cs b/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/InternalUtilities.cs index 841f4fc..eaf1cd4 100644 --- a/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/InternalUtilities.cs +++ b/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/InternalUtilities.cs @@ -5,7 +5,7 @@ namespace Zeiss.Micro.LibCzi.Net.Implementation { using System.Collections.Generic; - using System.Text.Json; + using Newtonsoft.Json; /// /// Here we collect some internal utilities that are used internally in the implementation of the library. @@ -24,7 +24,7 @@ public static string FormatPropertyBagAsJson(IReadOnlyDictionary return string.Empty; } - var jsonString = JsonSerializer.Serialize(parametersPropertyBag); + var jsonString = JsonConvert.SerializeObject(parametersPropertyBag); return jsonString; } } diff --git a/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/PyramidStatistics.cs b/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/PyramidStatistics.cs index 0b82859..aebe6c8 100644 --- a/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/PyramidStatistics.cs +++ b/dotnet/Zeiss.Micro.LibCzi.Net/Implementation/PyramidStatistics.cs @@ -6,7 +6,8 @@ namespace Zeiss.Micro.LibCzi.Net.Implementation { using System; using System.Collections.Generic; - using System.Text.Json; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; using Zeiss.Micro.LibCzi.Net.Interface; @@ -29,43 +30,53 @@ public PyramidStatistics(string json) this.pyramidLayerStatisticsPerScene = new Dictionary>(); // Parse the JSON string - using (JsonDocument document = JsonDocument.Parse(json)) + JObject root = JObject.Parse(json); + + // Navigate to the "scenePyramidStatistics" object + JToken scenePyramidStatistics = root["scenePyramidStatistics"]; + if (scenePyramidStatistics == null || scenePyramidStatistics.Type != JTokenType.Object) { - // Navigate to the "scenePyramidStatistics" object - JsonElement root = document.RootElement; - JsonElement scenePyramidStatistics = root.GetProperty("scenePyramidStatistics"); + throw new FormatException("Missing or invalid 'scenePyramidStatistics' object."); + } - // Iterate through the keys (e.g., "0", "1") and arrays - foreach (JsonProperty property in scenePyramidStatistics.EnumerateObject()) - { - List pyramidLayerStatistics = new List(); + // Iterate through the keys (e.g., "0", "1") and arrays + foreach (var property in ((JObject)scenePyramidStatistics).Properties()) + { + List pyramidLayerStatistics = new List(); - string key = property.Name; - if (string.IsNullOrWhiteSpace(key)) - { - throw new FormatException("'key' cannot be null or whitespace."); - } + string key = property.Name; + if (string.IsNullOrWhiteSpace(key)) + { + throw new FormatException("'key' cannot be null or whitespace."); + } - int sceneIndex = int.Parse(key); + int sceneIndex = int.Parse(key); - JsonElement array = property.Value; + JArray array = property.Value as JArray; + if (array == null) + { + throw new FormatException("Expected an array for scene '" + key + "'."); + } - // Iterate through each array element - foreach (JsonElement element in array.EnumerateArray()) + // Iterate through each array element + foreach (JToken element in array) + { + JToken layerInfo = element["layerInfo"]; + if (layerInfo == null) { - JsonElement layerInfo = element.GetProperty("layerInfo"); - byte minificationFactor = layerInfo.GetProperty("minificationFactor").GetByte(); - byte pyramidLayerNo = layerInfo.GetProperty("pyramidLayerNo").GetByte(); - int count = element.GetProperty("count").GetInt32(); - - PyramidLayerStatistics pyramidLayerStatistic = new PyramidLayerStatistics( - count, - new PyramidLayerInfo(minificationFactor, pyramidLayerNo)); - pyramidLayerStatistics.Add(pyramidLayerStatistic); + throw new FormatException("Missing 'layerInfo' in pyramid layer statistics."); } - - this.pyramidLayerStatisticsPerScene.Add(sceneIndex, pyramidLayerStatistics); + byte minificationFactor = layerInfo["minificationFactor"].Value(); + byte pyramidLayerNo = layerInfo["pyramidLayerNo"].Value(); + int count = element["count"].Value(); + + PyramidLayerStatistics pyramidLayerStatistic = new PyramidLayerStatistics( + count, + new PyramidLayerInfo(minificationFactor, pyramidLayerNo)); + pyramidLayerStatistics.Add(pyramidLayerStatistic); } + + this.pyramidLayerStatisticsPerScene.Add(sceneIndex, pyramidLayerStatistics); } } diff --git a/dotnet/Zeiss.Micro.LibCzi.Net/Interface/ICziDocumentInfo.cs b/dotnet/Zeiss.Micro.LibCzi.Net/Interface/ICziDocumentInfo.cs index bf99633..3bc07b9 100644 --- a/dotnet/Zeiss.Micro.LibCzi.Net/Interface/ICziDocumentInfo.cs +++ b/dotnet/Zeiss.Micro.LibCzi.Net/Interface/ICziDocumentInfo.cs @@ -6,7 +6,8 @@ namespace Zeiss.Micro.LibCzi.Net.Interface { using System; using System.Collections.Generic; - using System.Text.Json; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; /// /// This interface is used for retrieving parsed and consolidated metadata information from a CZI document. @@ -31,7 +32,7 @@ public interface ICziDocumentInfo : IDisposable /// Gets "dimension-info" for the specified dimension. /// The dimension to request "dimension info" for. /// The dimension information, formatted as JSON. - JsonDocument GetDimensionInfo(DimensionIndex dimensionIndex); + JObject GetDimensionInfo(DimensionIndex dimensionIndex); /// Gets the display settings. /// The display settings. diff --git a/dotnet/Zeiss.Micro.LibCzi.Net/Interop/LibCziApiInterop.cs b/dotnet/Zeiss.Micro.LibCzi.Net/Interop/LibCziApiInterop.cs index 7cf97c7..1b7aa80 100644 --- a/dotnet/Zeiss.Micro.LibCzi.Net/Interop/LibCziApiInterop.cs +++ b/dotnet/Zeiss.Micro.LibCzi.Net/Interop/LibCziApiInterop.cs @@ -12,7 +12,7 @@ namespace Zeiss.Micro.LibCzi.Net.Interop using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; - using System.Text.Json; + using Newtonsoft.Json; using Zeiss.Micro.LibCzi.Net.Implementation; using Zeiss.Micro.LibCzi.Net.Interface; @@ -2760,7 +2760,8 @@ private static Span AccessorAdditionalOptionsJsonFromPropertyBag(in Access } // Serialize directly to a UTF-8 byte array. - byte[] jsonBytes = JsonSerializer.SerializeToUtf8Bytes(jsonObject); + string jsonString = JsonConvert.SerializeObject(jsonObject); + byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString); // Create a new array with space for the null terminator. byte[] zeroTerminatedBytes = new byte[jsonBytes.Length + 1]; diff --git a/dotnet/Zeiss.Micro.LibCzi.Net/Zeiss.Micro.LibCzi.Net.csproj b/dotnet/Zeiss.Micro.LibCzi.Net/Zeiss.Micro.LibCzi.Net.csproj index 35788b7..b6805f6 100644 --- a/dotnet/Zeiss.Micro.LibCzi.Net/Zeiss.Micro.LibCzi.Net.csproj +++ b/dotnet/Zeiss.Micro.LibCzi.Net/Zeiss.Micro.LibCzi.Net.csproj @@ -13,8 +13,8 @@ + - diff --git a/version.txt b/version.txt index 6c6aa7c..6da28dd 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.1.0 \ No newline at end of file +0.1.1 \ No newline at end of file