public void RemoveBufferWorks_SpanAndMemory(bool readOnlySpan, bool memory, bool readOnlyMemory, bool readBeforeUpdate, bool setBeforeUpdate) { SpanAndMemory duplicate = LazinatorSpanTests.GetSpanAndMemory(false); SpanAndMemory main = LazinatorSpanTests.GetSpanAndMemory(false); main = main.CloneLazinatorTyped(); if (readBeforeUpdate) { if (readOnlySpan) { var read = main.MyReadOnlySpanChar; } else if (memory) { var read = main.MyMemoryByte; } else if (readOnlyMemory) { var read = main.MyReadOnlyMemoryChar; } } if (setBeforeUpdate) { if (readOnlySpan) { main.MyReadOnlySpanChar = duplicate.MyReadOnlySpanChar; } else if (memory) { main.MyMemoryByte = duplicate.MyMemoryByte; } else if (readOnlyMemory) { main.MyReadOnlyMemoryChar = duplicate.MyReadOnlyMemoryChar; } } var original = main.LazinatorMemoryStorage; main.RemoveBufferInHierarchy(); original.Dispose(); // make sure that attempting to access original will cause problems if (readOnlySpan) { main.MyReadOnlySpanChar.ToArray().SequenceEqual(duplicate.MyReadOnlySpanChar.ToArray()).Should().BeTrue(); } else if (memory) { main.MyMemoryByte.ToArray().SequenceEqual(duplicate.MyMemoryByte.ToArray()).Should().BeTrue(); } else if (readOnlyMemory) { main.MyReadOnlyMemoryChar.ToArray().SequenceEqual(duplicate.MyReadOnlyMemoryChar.ToArray()).Should().BeTrue(); } }
public void LazinatorNullableMemoryAsNull() { var l = new SpanAndMemory { MyNullableMemoryInt = null, MyNullableMemoryByte = null, MyNullableReadOnlyMemoryInt = null }; var c = l.CloneLazinatorTyped(); c.MyNullableReadOnlyMemoryInt.Should().Be(null); c.MyNullableMemoryByte.Should().Be(null); c.MyNullableReadOnlyMemoryInt.Should().Be(null); }
public void SpanAndMemory_EnsureUpToDate() { byte[] originalBytes = new byte[] { 1, 2, 3 }; SpanAndMemory spanAndMemory = new SpanAndMemory(); spanAndMemory.MyMemoryByte = new Memory <byte>(originalBytes); SpanAndMemory clone = spanAndMemory.CloneLazinatorTyped(); spanAndMemory.MyMemoryByte.Span[0] = 5; var byteSpan = clone.MyMemoryByte; clone.IsDirty = true; // trigger replacement of buffer clone.SerializeLazinator(); var x = byteSpan.Span[0]; x.Should().Be(1); }
public void DisposalOfBufferInvalidatesReadOnlySpan() { SpanAndMemory s = new SpanAndMemory() { MyReadOnlySpanByte = new Memory <byte>(new byte[] { 3, 4, 5 }).Span }; s = s.CloneLazinatorTyped(); var memory = s.MyReadOnlySpanByte; s.LazinatorMemoryStorage.Dispose(); s.LazinatorMemoryStorage.Disposed.Should().BeTrue(); Action a = () => { var m2 = s.MyReadOnlySpanByte; }; a.Should().Throw <ObjectDisposedException>(); }
public void LazinatorNullableMemoryInt() { SpanAndMemory GetObject() { return(new SpanAndMemory { MyNullableMemoryInt = new int[] { 3, 4, 5 } }); } SpanAndMemory GetObject2() { return(new SpanAndMemory { MyNullableMemoryInt = new int[] { 0, 0, 0 } }); } SpanAndMemory GetEmptyMemoryObject() { return(new SpanAndMemory { MyNullableMemoryInt = new int[] { } }); } void SetIndex(Memory <int> source, int index, int value) { // note: this seems to be a way to write into Memory<T>. I think that since Span lives only on the stack, the memory is guaranteed not to move. So, this works. I'm not clear why there isn't a direct way to index into Memory<T>, without getting a span. Maybe the reason is that they want to encourage you to get a Span if you are going to do a large number of writes. It's awkward that you can't say source.Span[index] = value; var sourceSpan = source.Span; sourceSpan[index] = value; } bool SequenceEqual(Memory <int> a, Memory <int> b) { if (a.Length != b.Length) { return(false); } Span <int> aSpan = a.Span; Span <int> bSpan = b.Span; for (int i = 0; i < a.Length; i++) { if (aSpan[i] != bSpan[i]) { return(false); } } return(true); } // first, we'll do the same thing we did for the non-nullable field var original = GetObject(); var copy = GetObject(); SetIndex(copy.MyNullableMemoryInt.Value, 2, 6); var span = copy.MyNullableMemoryInt.Value.Span; span[2].Should().Be(6); var result = copy.CloneLazinatorTyped(); SequenceEqual(copy.MyNullableMemoryInt.Value, result.MyNullableMemoryInt.Value).Should().BeTrue(); result.MyMemoryInt.Length.Should().Be(0); // now, see if the second object works original = GetObject2(); result = original.CloneLazinatorTyped(); SequenceEqual(result.MyNullableMemoryInt.Value, original.MyNullableMemoryInt.Value).Should().BeTrue(); // now, let's make sure that null serializes correctly original = new SpanAndMemory(); result = original.CloneLazinatorTyped(); result.MyNullableMemoryInt.Should().Be(null); result.MyMemoryInt.Length.Should().Be(0); // and empty list must serialize correctly too original = GetEmptyMemoryObject(); result = original.CloneLazinatorTyped(); result.MyNullableMemoryInt.Should().NotBeNull(); result.MyNullableMemoryInt.Value.Length.Should().Be(0); result.MyMemoryInt.Length.Should().Be(0); }