Skip to content

Commit c3751bb

Browse files
authored
Merge pull request #4 from Angel-foxxo/master
reflection based deserialisation + bunch of fixes and modernisation
2 parents ca70e89 + b675e83 commit c3751bb

21 files changed

+4020
-601
lines changed

Arrays.cs

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,39 @@ namespace Datamodel
1010
[DebuggerDisplay("Count = {Inner.Count}")]
1111
public abstract class Array<T> : IList<T>, IList
1212
{
13-
internal class DebugView
13+
internal class DebugView(Array<T> arr)
1414
{
15-
public DebugView(Array<T> arr)
16-
{
17-
Arr = arr;
18-
}
19-
Array<T> Arr;
15+
readonly Array<T> Arr = arr;
2016

2117
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
22-
public T[] Items { get { return Arr.Inner.ToArray(); } }
18+
public T[] Items { get { return [.. Arr.Inner]; } }
2319
}
2420

2521
protected List<T> Inner;
2622

27-
public virtual AttributeList Owner
23+
public virtual AttributeList? Owner
2824
{
2925
get => _Owner;
3026
internal set
3127
{
3228
_Owner = value;
3329
}
3430
}
35-
AttributeList _Owner;
31+
AttributeList? _Owner;
3632

37-
protected Datamodel OwnerDatamodel => Owner?.Owner;
33+
protected Datamodel? OwnerDatamodel => Owner?.Owner;
3834

3935
internal Array()
4036
{
41-
Inner = new List<T>();
37+
Inner = [];
4238
}
4339

4440
internal Array(IEnumerable<T> enumerable)
4541
{
4642
if (enumerable != null)
47-
Inner = new List<T>(enumerable);
43+
Inner = [.. enumerable];
4844
else
49-
Inner = new List<T>();
45+
Inner = [];
5046
}
5147

5248
internal Array(int capacity)
@@ -94,40 +90,52 @@ public void CopyTo(T[] array, int offset)
9490

9591
public object SyncRoot => throw new NotImplementedException();
9692

97-
object IList.this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
93+
object? IList.this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
9894

9995
public bool Remove(T item) => Inner.Remove(item);
10096

10197
public IEnumerator<T> GetEnumerator() => Inner.GetEnumerator();
10298
IEnumerator IEnumerable.GetEnumerator() => Inner.GetEnumerator();
10399

104100
#region IList
105-
int IList.Add(object value)
101+
int IList.Add(object? value)
106102
{
107-
Add((T)value);
103+
if (value is not null)
104+
Add((T)value);
108105
return Count;
109106
}
110107

111-
bool IList.Contains(object value)
108+
bool IList.Contains(object? value)
112109
{
110+
if (value is null)
111+
return false;
113112
return Contains((T)value);
114113
}
115114

116-
int IList.IndexOf(object value)
115+
int IList.IndexOf(object? value)
117116
{
117+
if (value is null)
118+
throw new InvalidOperationException("Trying to get the index of a null object");
119+
118120
return IndexOf((T)value);
119121
}
120122

121-
void IList.Insert(int index, object value)
123+
void IList.Insert(int index, object? value)
122124
{
125+
if (value is null)
126+
throw new InvalidOperationException("Trying to insert a null object");
127+
123128
Insert(index, (T)value);
124129
}
125130

126131
bool IList.IsFixedSize { get { return false; } }
127132
bool IList.IsReadOnly { get { return false; } }
128133

129-
void IList.Remove(object value)
134+
void IList.Remove(object? value)
130135
{
136+
if (value is null)
137+
throw new InvalidOperationException("Trying to remove a null object");
138+
131139
Remove((T)value);
132140
}
133141

@@ -156,7 +164,7 @@ public ElementArray(int capacity)
156164
/// </summary>
157165
internal IEnumerable<Element> RawList { get { foreach (var elem in Inner) yield return elem; } }
158166

159-
public override AttributeList Owner
167+
public override AttributeList? Owner
160168
{
161169
get => base.Owner;
162170
internal set
@@ -172,7 +180,12 @@ internal set
172180
if (elem == null) continue;
173181
if (elem.Owner == null)
174182
{
175-
Inner[i] = OwnerDatamodel.ImportElement(elem, Datamodel.ImportRecursionMode.Stubs, Datamodel.ImportOverwriteMode.Stubs);
183+
var importedElement = OwnerDatamodel.ImportElement(elem, Datamodel.ImportRecursionMode.Stubs, Datamodel.ImportOverwriteMode.Stubs);
184+
185+
if(importedElement is not null)
186+
{
187+
Inner[i] = importedElement;
188+
}
176189
}
177190
else if (elem.Owner != OwnerDatamodel)
178191
throw new ElementOwnershipException();
@@ -186,12 +199,21 @@ protected override void Insert_Internal(int index, Element item)
186199
if (item != null && OwnerDatamodel != null)
187200
{
188201
if (item.Owner == null)
189-
item = OwnerDatamodel.ImportElement(item, Datamodel.ImportRecursionMode.Recursive, Datamodel.ImportOverwriteMode.Stubs);
202+
{
203+
var importedElement = OwnerDatamodel.ImportElement(item, Datamodel.ImportRecursionMode.Recursive, Datamodel.ImportOverwriteMode.Stubs);
204+
205+
if(importedElement is not null)
206+
{
207+
item = importedElement;
208+
}
209+
}
190210
else if (item.Owner != OwnerDatamodel)
211+
{
191212
throw new ElementOwnershipException();
213+
}
192214
}
193215

194-
base.Insert_Internal(index, item);
216+
base.Insert_Internal(index, item!);
195217
}
196218

197219
public override Element this[int index]
@@ -203,13 +225,19 @@ public override Element this[int index]
203225
{
204226
try
205227
{
206-
elem = Inner[index] = elem.Owner.OnStubRequest(elem.ID);
228+
elem = Inner[index] = elem.Owner.OnStubRequest(elem.ID)!;
207229
}
208230
catch (Exception err)
209231
{
210232
throw new DestubException(this, index, err);
211233
}
212234
}
235+
236+
if (elem is null)
237+
{
238+
throw new InvalidOperationException("Element at specified index is null");
239+
}
240+
213241
return elem;
214242
}
215243
set => base[index] = value;

Attribute.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.Numerics;
44

5-
using AttrKVP = System.Collections.Generic.KeyValuePair<string, object>;
5+
using AttrKVP = System.Collections.Generic.KeyValuePair<string, object?>;
66

77
namespace Datamodel
88
{
@@ -16,7 +16,7 @@ class Attribute
1616
/// </summary>
1717
/// <param name="name">The name of the Attribute, which must be unique to its owner.</param>
1818
/// <param name="value">The value of the Attribute, which must be of a supported Datamodel type.</param>
19-
public Attribute(string name, AttributeList owner, object value)
19+
public Attribute(string name, AttributeList owner, object? value)
2020
{
2121
ArgumentNullException.ThrowIfNull(name);
2222

@@ -48,7 +48,7 @@ public Attribute(string name, AttributeList owner, long defer_offset)
4848
/// <summary>
4949
/// Gets the Type of this Attribute's Value.
5050
/// </summary>
51-
public Type ValueType { get; private set; }
51+
public Type ValueType { get; private set; } = typeof(Element);
5252

5353
/// <summary>
5454
/// Gets or sets the OverrideType of this Attributes.
@@ -84,7 +84,7 @@ public AttributeList.OverrideType? OverrideType
8484
/// <summary>
8585
/// Gets the <see cref="AttributeList"/> which this Attribute is a member of.
8686
/// </summary>
87-
public AttributeList Owner
87+
public AttributeList? Owner
8888
{
8989
get { return _Owner; }
9090
internal set
@@ -95,9 +95,9 @@ internal set
9595
_Owner = value;
9696
}
9797
}
98-
AttributeList _Owner;
98+
AttributeList? _Owner;
9999

100-
Datamodel OwnerDatamodel { get { return Owner?.Owner; } }
100+
Datamodel? OwnerDatamodel { get { return Owner?.Owner; } }
101101

102102
/// <summary>
103103
/// Gets whether the value of this Attribute has yet to be decoded.
@@ -125,7 +125,7 @@ public void DeferredLoad()
125125
}
126126
catch (Exception err)
127127
{
128-
throw new CodecException($"Deferred loading of attribute \"{Name}\" on element {((Element)Owner).ID} using {OwnerDatamodel.Codec} codec threw an exception.", err);
128+
throw new CodecException($"Deferred loading of attribute \"{Name}\" on element {((Element?)Owner)?.ID} using {OwnerDatamodel.Codec} codec threw an exception.", err);
129129
}
130130
Offset = 0;
131131

@@ -138,7 +138,7 @@ public void DeferredLoad()
138138
/// </summary>
139139
/// <exception cref="CodecException">Thrown when deferred value loading fails.</exception>
140140
/// <exception cref="DestubException">Thrown when Element destubbing fails.</exception>
141-
public object Value
141+
public object? Value
142142
{
143143
get
144144
{
@@ -188,21 +188,24 @@ public object Value
188188
if (arr_elem == null) continue;
189189
else if (arr_elem.Owner == null)
190190
arr_elem.Owner = OwnerDatamodel;
191-
else if (arr_elem.Owner != OwnerDatamodel)
192-
throw new ElementOwnershipException("One or more Elements in the assigned collection are from a different Datamodel. Use ImportElement() to copy them to this one before assigning.");
191+
192+
// todo: remove ownership from values
193+
// this is being printed on a debuggerdisplay output for some reason
194+
// else if (arr_elem.Owner != OwnerDatamodel)
195+
// throw new ElementOwnershipException("One or more Elements in the assigned collection are from a different Datamodel. Use ImportElement() to copy them to this one before assigning.");
193196
}
194197
}
195198

196199
_Value = value;
197200
Offset = 0;
198201
}
199202
}
200-
object _Value;
203+
object? _Value = null;
201204

202205
/// <summary>
203206
/// Gets the Attribute's Value without attempting deferred loading or destubbing.
204207
/// </summary>
205-
public object RawValue { get { return _Value; } }
208+
public object? RawValue { get { return _Value; } }
206209

207210
#endregion
208211

0 commit comments

Comments
 (0)