DFStorage.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.Linq;
  5. namespace InABox.Core
  6. {
  7. /// <summary>
  8. /// Class to manage the storing of form data, including the separation of blob and form data.
  9. /// </summary>
  10. public class DFSaveStorage
  11. {
  12. public Dictionary<string, object?> FormData { get; private set; }
  13. public Dictionary<string, object?> BlobData { get; private set; }
  14. public DFSaveStorage()
  15. {
  16. FormData = new Dictionary<string, object?>();
  17. BlobData = new Dictionary<string, object?>();
  18. }
  19. public int Count() => FormData.Count();
  20. public void AddValue(string key, object? value)
  21. {
  22. FormData.Add(key, value);
  23. }
  24. public void AddBlobValue(string key, object? value)
  25. {
  26. if(value != null)
  27. {
  28. var id = Guid.NewGuid().ToString();
  29. BlobData.Add(id, value);
  30. FormData.Add(key, id);
  31. }
  32. }
  33. public object? GetValue(string key) => FormData.GetValueOrDefault(key);
  34. public DFSaveStorageEntry GetEntry(string key)
  35. {
  36. return new DFSaveStorageEntry(this, key);
  37. }
  38. public DFLoadStorage ToLoadStorage()
  39. {
  40. return new DFLoadStorage(FormData, BlobData);
  41. }
  42. }
  43. public class DFSaveStorageEntry
  44. {
  45. private readonly DFSaveStorage storage;
  46. private readonly string key;
  47. public DFSaveStorageEntry(DFSaveStorage storage, string key)
  48. {
  49. this.storage = storage;
  50. this.key = key;
  51. }
  52. public object? GetValue() => storage.GetValue(key);
  53. public object? GetValue(string subKey) => storage.GetValue($"{key}.{subKey}");
  54. public void SetValue(object? value)
  55. {
  56. storage.AddValue(key, value);
  57. }
  58. public void AddValue(string subKey, object? value)
  59. {
  60. storage.AddValue($"{key}.{subKey}", value);
  61. }
  62. public void SetBlobValue(object? value)
  63. {
  64. storage.AddBlobValue(key, value);
  65. }
  66. public void AddBlobValue(string subKey, object? value)
  67. {
  68. storage.AddBlobValue($"{key}.{subKey}", value);
  69. }
  70. }
  71. public class DFLoadStorage
  72. {
  73. public Dictionary<string, object?> FormData { get; private set; } = new Dictionary<string, object?>();
  74. public DFLoadStorage() : this(new Dictionary<string, object?>(), null)
  75. {
  76. }
  77. public DFLoadStorage(Dictionary<string, object?> formData, Dictionary<string, object?>? blobData)
  78. {
  79. Load(formData, blobData);
  80. }
  81. public void Load(Dictionary<string, object?> formData, Dictionary<string, object?>? blobData)
  82. {
  83. FormData = formData;
  84. if (blobData != null)
  85. {
  86. var updates = new List<Tuple<string, object?>>();
  87. foreach (var (key, value) in FormData)
  88. {
  89. if ((value is string str && blobData.TryGetValue(str, out var blob))
  90. || (value is Guid guid && blobData.TryGetValue(guid.ToString(), out blob)))
  91. {
  92. updates.Add(new Tuple<string, object?>(key, blob));
  93. }
  94. }
  95. foreach (var (key, value) in updates)
  96. {
  97. FormData[key] = value;
  98. }
  99. }
  100. }
  101. public void Clear() => FormData.Clear();
  102. public int Count() => FormData.Count();
  103. /// <summary>
  104. /// Get a value from the storage, returning <see langword="null"/> if the key does not exist.
  105. /// </summary>
  106. /// <param name="key"></param>
  107. /// <returns></returns>
  108. public object? GetValue(string key)
  109. {
  110. return FormData.GetValueOrDefault(key);
  111. }
  112. [return: MaybeNull]
  113. public T GetValue<T>(string key)
  114. {
  115. if(FormData.TryGetValue(key, out var value))
  116. {
  117. if(value is T t)
  118. {
  119. return t;
  120. }
  121. else if(value is string str)
  122. {
  123. if(Guid.TryParse(str, out var id))
  124. {
  125. if(id is T)
  126. {
  127. return (T)(object)id;
  128. }
  129. else
  130. {
  131. return default;
  132. }
  133. }
  134. try
  135. {
  136. return Serialization.Deserialize<T>(str, strict: true);
  137. }
  138. catch
  139. {
  140. return CoreUtils.ChangeType<T>(value);
  141. }
  142. }
  143. //else if(value is JToken jToken)
  144. //{
  145. // return Serialization.Deserialize<T>(jToken);
  146. //}
  147. else
  148. {
  149. return CoreUtils.ChangeType<T>(value);
  150. }
  151. }
  152. return default;
  153. }
  154. public bool HasValue(string key)
  155. {
  156. return FormData.ContainsKey(key);
  157. }
  158. public DFLoadStorageEntry GetEntry(string key)
  159. {
  160. return new DFLoadStorageEntry(this, key);
  161. }
  162. public IEnumerable<KeyValuePair<string, object?>> Items()
  163. {
  164. return FormData;
  165. }
  166. }
  167. public class DFLoadStorageEntry
  168. {
  169. private readonly DFLoadStorage storage;
  170. private readonly string key;
  171. public DFLoadStorageEntry(DFLoadStorage storage, string key)
  172. {
  173. this.storage = storage;
  174. this.key = key;
  175. }
  176. /// <summary>
  177. /// Gets the value from the storage entry, returning <see langword="null"/> if it does not exist.
  178. /// </summary>
  179. /// <param name="key"></param>
  180. /// <returns></returns>
  181. public object? GetValue()
  182. {
  183. return storage.GetValue(key);
  184. }
  185. [return: MaybeNull]
  186. public T GetValue<T>()
  187. {
  188. return storage.GetValue<T>(key);
  189. }
  190. /// <summary>
  191. /// Gets a sub-value from the storage entry, returning <see langword="null"/> if it does not exist.
  192. /// </summary>
  193. /// <param name="subKey"></param>
  194. /// <returns></returns>
  195. public object? GetValue(string subKey)
  196. {
  197. return storage.GetValue($"{key}.{subKey}");
  198. }
  199. [return: MaybeNull]
  200. public T GetValue<T>(string subKey)
  201. {
  202. return storage.GetValue<T>($"{key}.{subKey}");
  203. }
  204. public bool HasValue() => storage.HasValue(key);
  205. public bool HasValue(string subKey) => storage.HasValue($"{key}.{subKey}");
  206. public IEnumerable<KeyValuePair<string, object?>> SubItems()
  207. {
  208. var prefix = $"{key}.";
  209. foreach(var (key, value) in storage.Items())
  210. {
  211. if (key.StartsWith(prefix))
  212. {
  213. yield return new KeyValuePair<string, object?>(key[prefix.Length..], value);
  214. }
  215. }
  216. }
  217. }
  218. }