using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace InABox.Core { public class CoreTableJsonConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { if(!(value is CoreTable table)) { writer.WriteNull(); return; } writer.WriteStartObject(); writer.WritePropertyName("Columns"); var cols = new Dictionary(); foreach (var column in table.Columns) cols[column.ColumnName] = column.DataType.EntityName(); serializer.Serialize(writer, cols); //writer.WriteEndObject(); //writer.WriteStartObject(); writer.WritePropertyName("Rows"); writer.WriteStartArray(); var size = 0; foreach (var row in table.Rows) //Console.WriteLine("- Serializing Row #"+row.Index.ToString()); try { writer.WriteStartArray(); foreach (var col in table.Columns) { var val = row[col.ColumnName]; if (val != null) size += val.ToString().Length; //Console.WriteLine(String.Format("Serializing Row #{0} Column [{1}] Length={2}", row.Index.ToString(), col.ColumnName, val.ToString().Length)); if (col.DataType.IsArray && val != null) { writer.WriteStartArray(); foreach (var val1 in (Array)val) writer.WriteValue(val1); writer.WriteEndArray(); } else if (col.DataType.GetInterfaces().Contains(typeof(IPackableList))) { writer.WriteStartArray(); foreach (var val1 in (IList)val) writer.WriteValue(val1); writer.WriteEndArray(); } else { writer.WriteValue(val ?? CoreUtils.GetDefault(col.DataType)); } } writer.WriteEndArray(); //Console.WriteLine(String.Format("[{0:D8}] Serializing Row #{1}", size, row.Index.ToString())); } catch (Exception e) { Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace)); } writer.WriteEndArray(); writer.WriteEndObject(); } public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; var result = new CoreTable(); try { var json = JObject.Load(reader); if (json.TryGetValue("Columns", out var columns)) { foreach (JProperty column in columns.Children()) { var name = column.Name; var type = column.Value.ToObject(); result.Columns.Add(new CoreColumn { ColumnName = name, DataType = CoreUtils.GetEntity(type ?? "") }); } } if (json.TryGetValue("Rows", out var rows)) { foreach (JArray row in rows.Children()) if (row.Children().ToArray().Length == result.Columns.Count) { var newrow = result.NewRow(); var iCol = 0; foreach (var cell in row.Children()) { var column = result.Columns[iCol]; try { if (column.DataType.IsArray) { newrow[column.ColumnName] = cell.ToObject(column.DataType); } else if (column.DataType.GetInterfaces().Contains(typeof(IPackableList))) { } else { newrow[column.ColumnName] = cell.ToObject(column.DataType); } } catch (Exception e) { Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace)); } iCol++; } result.Rows.Add(newrow); } } } catch (Exception e) { Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace)); } return result; } public override bool CanConvert(Type objectType) { return typeof(CoreTable).GetTypeInfo().IsAssignableFrom(objectType); } } }