-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathApplicationDataKeyValueStorage.cs
136 lines (110 loc) · 3.18 KB
/
ApplicationDataKeyValueStorage.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
namespace Uno.Extensions.Storage.KeyValueStorage;
internal record ApplicationDataKeyValueStorage
(ILogger<ApplicationDataKeyValueStorage> Logger,
InMemoryKeyValueStorage InMemoryStorage,
KeyValueStorageSettings Settings,
ISerializer Serializer) : BaseKeyValueStorageWithCaching(InMemoryStorage, Settings)
{
public const string Name = "ApplicationData";
// Do not change this value.
private const string KeyNameSuffix = "_ADCSSS";
private readonly ApplicationDataContainer _dataContainer = ApplicationData.Current.LocalSettings;
/// <inheritdoc />
public override bool IsEncrypted => false;
/// <inheritdoc />
protected override async ValueTask InternalClearAsync(string? name, CancellationToken ct)
{
if (Logger.IsEnabled(LogLevel.Debug))
{
Logger.LogDebugMessage($"Clearing value for key '{name}'.");
}
if (name is not null &&
!string.IsNullOrEmpty(name))
{
_ = _dataContainer.Values.Remove(GetKey(name));
}
else
{
_dataContainer.Values.Clear();
}
if (Logger.IsEnabled(LogLevel.Information))
{
Logger.LogInformationMessage($"Cleared value for key '{name}'.");
}
}
/// <inheritdoc />
protected override async ValueTask<string[]> InternalGetKeysAsync(CancellationToken ct)
{
return _dataContainer
.Values
.Keys
.Where(key=>key.EndsWith(KeyNameSuffix))
.Select(key => GetName(key)) // filter-out non-encrypted storage
.Trim()
.ToArray();
}
/// <inheritdoc />
#nullable disable
protected override async ValueTask<T> InternalGetAsync<T>(string name, CancellationToken ct)
{
if (Logger.IsEnabled(LogLevel.Debug))
{
Logger.LogDebugMessage($"Getting value for key '{name}'.");
}
if (!_dataContainer.Values.TryGetValue(GetKey(name), out var data))
{
throw new KeyNotFoundException(name);
}
var value = await GetTypedValue<T>(data,ct);
if (Logger.IsEnabled(LogLevel.Information))
{
Logger.LogInformationMessage($"Retrieved value for key '{name}'.");
}
return value;
}
#nullable restore
protected virtual async Task<T?> GetTypedValue<T>(object? data, CancellationToken ct)
{
return this.Deserialize<T>(data as string);
}
protected virtual async Task<object> GetObjectValue<T>(T data, CancellationToken ct) where T :notnull
{
return this.Serialize(data);
}
/// <inheritdoc />
protected override async ValueTask InternalSetAsync<T>(string name, T value, CancellationToken ct)
{
if (Logger.IsEnabled(LogLevel.Debug))
{
Logger.LogDebugMessage($"Setting value for key '{name}'.");
}
var data= await GetObjectValue(value, ct);
_dataContainer.Values[GetKey(name)] = data;
if (Logger.IsEnabled(LogLevel.Information))
{
Logger.LogInformationMessage($"Value for key '{name}' set.");
}
}
private static string GetKey(string name)
{
return name + KeyNameSuffix;
}
private static string GetName(string key)
{
return key.EndsWith(KeyNameSuffix, StringComparison.Ordinal)
? key.Substring(0, key.Length - KeyNameSuffix.Length)
: key;
}
protected T? Deserialize<T>(string? data)
{
if (data is null || string.IsNullOrEmpty(data))
{
return default;
}
return Serializer.FromString<T>(data);
}
protected string Serialize<T>(T value)
{
return Serializer.ToString(value);
}
}