CoreTableJsonConverter.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using System;
  2. using System.Reflection;
  3. using System.Text.Json;
  4. namespace InABox.Core
  5. {
  6. public class CoreTableJsonConverter : CustomJsonConverter<CoreTable>
  7. {
  8. public override void Write(Utf8JsonWriter writer, CoreTable value, JsonSerializerOptions options)
  9. {
  10. writer.WriteStartObject();
  11. // Columns
  12. writer.WritePropertyName("Columns");
  13. writer.WriteStartObject();
  14. foreach (var column in value.Columns)
  15. writer.WriteString(column.ColumnName, column.DataType.EntityName());
  16. writer.WriteEndObject();
  17. // Rows
  18. writer.WritePropertyName("Rows");
  19. writer.WriteStartArray();
  20. foreach (var row in value.Rows)
  21. {
  22. writer.WriteStartArray();
  23. foreach (var column in value.Columns)
  24. {
  25. WriteJson(writer, row[column.ColumnName]);
  26. }
  27. writer.WriteEndArray();
  28. }
  29. writer.WriteEndArray();
  30. writer.WriteEndObject();
  31. }
  32. public override CoreTable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  33. {
  34. if (reader.TokenType == JsonTokenType.Null)
  35. return null;
  36. var result = new CoreTable();
  37. try
  38. {
  39. reader.Read();
  40. while(reader.TokenType != JsonTokenType.EndObject)
  41. {
  42. if (reader.TokenType == JsonTokenType.PropertyName)
  43. {
  44. var propertyName = reader.GetString();
  45. reader.Read(); // Move to property value
  46. if (propertyName == "Columns")
  47. {
  48. if(reader.TokenType != JsonTokenType.StartObject)
  49. {
  50. throw new SerialisationException($"Unexpected token type after \"Columns\": {reader.TokenType}");
  51. }
  52. reader.Read(); // Skip over StartObject
  53. while (reader.TokenType != JsonTokenType.EndObject)
  54. {
  55. string name = reader.GetString()!;
  56. reader.Read(); // Advance to the property value
  57. var type = reader.GetString();
  58. result.Columns.Add(new CoreColumn { ColumnName = name, DataType = CoreUtils.GetEntity(type ?? "") });
  59. reader.Read(); // Move to next token
  60. }
  61. reader.Read(); // Skip EndObject
  62. }
  63. else if (propertyName == "Rows")
  64. {
  65. if(reader.TokenType != JsonTokenType.StartArray)
  66. {
  67. throw new SerialisationException($"Unexpected token type after \"Rows\": {reader.TokenType}");
  68. }
  69. reader.Read(); // Skip StartArray
  70. while (reader.TokenType != JsonTokenType.EndArray)
  71. {
  72. if(reader.TokenType != JsonTokenType.StartArray)
  73. {
  74. throw new SerialisationException($"Unexpected token type: {reader.TokenType}");
  75. }
  76. reader.Read(); // Skip StartArray
  77. var iCol = 0;
  78. var newrow = result.NewRow();
  79. while (reader.TokenType != JsonTokenType.EndArray)
  80. {
  81. var col = result.Columns[iCol];
  82. newrow[col.ColumnName] = CoreUtils.ChangeType(ReadJson(ref reader), col.DataType);
  83. reader.Read();
  84. iCol++;
  85. }
  86. result.Rows.Add(newrow);
  87. reader.Read(); // Skip EndArray
  88. }
  89. reader.Read(); // Skip EndArray
  90. }
  91. }
  92. }
  93. }
  94. catch(SerialisationException e)
  95. {
  96. Logger.Send(LogType.Error, "", $"SerialisationException: {e.Message}");
  97. return null;
  98. }
  99. catch (Exception e)
  100. {
  101. Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
  102. }
  103. return result;
  104. }
  105. public override bool CanConvert(Type objectType)
  106. {
  107. return typeof(CoreTable).IsAssignableFrom(objectType);
  108. }
  109. }
  110. }