-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[feature request] add support for System.Collections.Immutable
#4 - ImmutableArray - ImmutableList - ImmutableSortedSet - ImmutableHashSet - ImmutableDictionary - ImmutableSortedDictionary
- Loading branch information
Michael Catanzariti
committed
Aug 18, 2019
1 parent
77fbe4f
commit 87c4da7
Showing
9 changed files
with
384 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
|
||
namespace Dahomey.Cbor.Tests | ||
{ | ||
[TestClass] | ||
public class ImmutableCollectionsTests | ||
{ | ||
[TestMethod] | ||
public void WriteImmutableArrayOfInt32() | ||
{ | ||
ImmutableArray<int> value = ImmutableArray.CreateRange(new[] { 1, 2, 3 }); | ||
const string expectedHexBuffer = "83010203"; | ||
Helper.TestWrite(value, expectedHexBuffer); | ||
} | ||
|
||
[TestMethod] | ||
public void ReadImmutableArrayOfInt32() | ||
{ | ||
ImmutableArray<int> expectedValue = ImmutableArray.CreateRange(new[] { 1, 2, 3 }); | ||
const string hexBuffer = "83010203"; | ||
Helper.TestRead(hexBuffer, expectedValue); | ||
} | ||
|
||
[TestMethod] | ||
public void WriteImmutableListOfInt32() | ||
{ | ||
ImmutableList<int> value = ImmutableList.CreateRange(new[] { 1, 2, 3 }); | ||
const string expectedHexBuffer = "83010203"; | ||
Helper.TestWrite(value, expectedHexBuffer); | ||
} | ||
|
||
[TestMethod] | ||
public void ReadImmutableListOfInt32() | ||
{ | ||
ImmutableList<int> expectedValue = ImmutableList.CreateRange(new[] { 1, 2, 3 }); | ||
const string hexBuffer = "83010203"; | ||
Helper.TestRead(hexBuffer, expectedValue); | ||
} | ||
|
||
[TestMethod] | ||
public void WriteImmutableHashSetOfInt32() | ||
{ | ||
ImmutableHashSet<int> value = ImmutableHashSet.CreateRange(new[] { 1, 2, 3 }); | ||
const string expectedHexBuffer = "83010203"; | ||
Helper.TestWrite(value, expectedHexBuffer); | ||
} | ||
|
||
[TestMethod] | ||
public void ReadImmutableHashSetOfInt32() | ||
{ | ||
ImmutableHashSet<int> expectedValue = ImmutableHashSet.CreateRange(new[] { 1, 2, 3 }); | ||
const string hexBuffer = "83010203"; | ||
Helper.TestRead(hexBuffer, expectedValue); | ||
} | ||
|
||
[TestMethod] | ||
public void WriteImmutableSortedSetOfInt32() | ||
{ | ||
ImmutableSortedSet<int> value = ImmutableSortedSet.CreateRange(new[] { 1, 2, 3 }); | ||
const string expectedHexBuffer = "83010203"; | ||
Helper.TestWrite(value, expectedHexBuffer); | ||
} | ||
|
||
[TestMethod] | ||
public void ReadImmutableSortedSetOfInt32() | ||
{ | ||
ImmutableSortedSet<int> expectedValue = ImmutableSortedSet.CreateRange(new[] { 1, 2, 3 }); | ||
const string hexBuffer = "83010203"; | ||
Helper.TestRead(hexBuffer, expectedValue); | ||
} | ||
|
||
[TestMethod] | ||
public void WriteImmutableDictionaryOfInt32() | ||
{ | ||
ImmutableDictionary<int, int> value = ImmutableDictionary.CreateRange(new Dictionary<int, int> | ||
{ | ||
{ 1, 1 }, | ||
{ 2, 2 }, | ||
{ 3, 3 } | ||
}); | ||
const string expectedHexBuffer = "A3010102020303"; | ||
Helper.TestWrite(value, expectedHexBuffer); | ||
} | ||
|
||
[TestMethod] | ||
public void ReadImmutableDictionaryOfInt32() | ||
{ | ||
ImmutableDictionary<int, int> expectedValue = ImmutableDictionary.CreateRange(new Dictionary<int, int> | ||
{ | ||
{ 1, 1 }, | ||
{ 2, 2 }, | ||
{ 3, 3 } | ||
}); | ||
const string hexBuffer = "A3010102020303"; | ||
Helper.TestRead(hexBuffer, expectedValue); | ||
} | ||
|
||
[TestMethod] | ||
public void WriteImmutableSortedDictionaryOfInt32() | ||
{ | ||
ImmutableSortedDictionary<int, int> value = ImmutableSortedDictionary.CreateRange(new SortedDictionary<int, int> | ||
{ | ||
{ 1, 1 }, | ||
{ 2, 2 }, | ||
{ 3, 3 } | ||
}); | ||
const string expectedHexBuffer = "A3010102020303"; | ||
Helper.TestWrite(value, expectedHexBuffer); | ||
} | ||
|
||
[TestMethod] | ||
public void ReadImmutableSortedDictionaryOfInt32() | ||
{ | ||
ImmutableSortedDictionary<int, int> expectedValue = ImmutableSortedDictionary.CreateRange(new SortedDictionary<int, int> | ||
{ | ||
{ 1, 1 }, | ||
{ 2, 2 }, | ||
{ 3, 3 } | ||
}); | ||
const string hexBuffer = "A3010102020303"; | ||
Helper.TestRead(hexBuffer, expectedValue); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
src/Dahomey.Cbor/Serialization/Converters/AbstractCollectionConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Dahomey.Cbor.Serialization.Converters | ||
{ | ||
public abstract class AbstractCollectionConverter<TC, TI> : | ||
CborConverterBase<TC>, | ||
ICborArrayReader<AbstractCollectionConverter<TC, TI>.ReaderContext>, | ||
ICborArrayWriter<AbstractCollectionConverter<TC, TI>.WriterContext> | ||
where TC : ICollection<TI> | ||
{ | ||
public struct ReaderContext | ||
{ | ||
public ICollection<TI> collection; | ||
} | ||
|
||
public struct WriterContext | ||
{ | ||
public int count; | ||
public IEnumerator<TI> enumerator; | ||
} | ||
|
||
private static readonly ICborConverter<TI> _itemConverter = CborConverter.Lookup<TI>(); | ||
|
||
protected abstract ICollection<TI> InstantiateTempCollection(); | ||
protected abstract TC InstantiateCollection(ICollection<TI> tempCollection); | ||
|
||
public override TC Read(ref CborReader reader) | ||
{ | ||
if (reader.ReadNull()) | ||
{ | ||
return default; | ||
} | ||
|
||
ReaderContext context = new ReaderContext(); | ||
reader.ReadArray(this, ref context); | ||
|
||
return InstantiateCollection(context.collection); | ||
} | ||
|
||
public override void Write(ref CborWriter writer, TC value) | ||
{ | ||
WriterContext context = new WriterContext | ||
{ | ||
count = value.Count, | ||
enumerator = value.GetEnumerator() | ||
}; | ||
writer.WriteArray(this, ref context); | ||
} | ||
|
||
public void ReadBeginArray(int size, ref ReaderContext context) | ||
{ | ||
context.collection = InstantiateTempCollection(); | ||
|
||
if (size != -1 && context.collection is List<TI> list) | ||
{ | ||
list.Capacity = size; | ||
} | ||
} | ||
|
||
public void ReadArrayItem(ref CborReader reader, ref ReaderContext context) | ||
{ | ||
TI item = _itemConverter.Read(ref reader); | ||
context.collection.Add(item); | ||
} | ||
|
||
public int GetArraySize(ref WriterContext context) | ||
{ | ||
return context.count; | ||
} | ||
|
||
public void WriteArrayItem(ref CborWriter writer, ref WriterContext context) | ||
{ | ||
if (context.enumerator.MoveNext()) | ||
{ | ||
_itemConverter.Write(ref writer, context.enumerator.Current); | ||
} | ||
} | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
src/Dahomey.Cbor/Serialization/Converters/AbstractDictionaryConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Dahomey.Cbor.Serialization.Converters | ||
{ | ||
public abstract class AbstractDictionaryConverter<TC, TK, TV> : | ||
CborConverterBase<TC>, | ||
ICborMapReader<AbstractDictionaryConverter<TC, TK, TV>.ReaderContext>, | ||
ICborMapWriter<AbstractDictionaryConverter<TC, TK, TV>.WriterContext> | ||
where TC : IDictionary<TK, TV> | ||
{ | ||
public struct ReaderContext | ||
{ | ||
public IDictionary<TK, TV> dict; | ||
} | ||
|
||
public struct WriterContext | ||
{ | ||
public int count; | ||
public IEnumerator<KeyValuePair<TK, TV>> enumerator; | ||
} | ||
|
||
private static readonly ICborConverter<TK> _keyConverter = CborConverter.Lookup<TK>(); | ||
private static readonly ICborConverter<TV> _valueConverter = CborConverter.Lookup<TV>(); | ||
|
||
protected abstract IDictionary<TK, TV> InstantiateTempCollection(); | ||
protected abstract TC InstantiateCollection(IDictionary<TK, TV> tempCollection); | ||
|
||
public override TC Read(ref CborReader reader) | ||
{ | ||
if (reader.ReadNull()) | ||
{ | ||
return default; | ||
} | ||
|
||
ReaderContext context = new ReaderContext(); | ||
reader.ReadMap(this, ref context); | ||
return InstantiateCollection(context.dict); | ||
} | ||
|
||
public override void Write(ref CborWriter writer, TC value) | ||
{ | ||
WriterContext context = new WriterContext | ||
{ | ||
count = value.Count, | ||
enumerator = value.GetEnumerator() | ||
}; | ||
writer.WriteMap(this, ref context); | ||
} | ||
|
||
public void ReadBeginMap(int size, ref ReaderContext context) | ||
{ | ||
context.dict = InstantiateTempCollection(); | ||
} | ||
|
||
public void ReadMapItem(ref CborReader reader, ref ReaderContext context) | ||
{ | ||
TK key = _keyConverter.Read(ref reader); | ||
TV value = _valueConverter.Read(ref reader); | ||
|
||
context.dict.Add(key, value); | ||
} | ||
|
||
public int GetMapSize(ref WriterContext context) | ||
{ | ||
return context.count; | ||
} | ||
|
||
public void WriteMapItem(ref CborWriter writer, ref WriterContext context) | ||
{ | ||
if (context.enumerator.MoveNext()) | ||
{ | ||
_keyConverter.Write(ref writer, context.enumerator.Current.Key); | ||
_valueConverter.Write(ref writer, context.enumerator.Current.Value); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.