diff --git a/Projects/Server/Buffers/BufferReader.cs b/Projects/Server/Buffers/BufferReader.cs deleted file mode 100644 index c9a924132..000000000 --- a/Projects/Server/Buffers/BufferReader.cs +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (c) Harry Pierson. All rights reserved. -// Licensed under the MIT license. -// See LICENSE file in the project root for full license information. - -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using System.Threading; - -namespace System.Buffers -{ - public ref struct BufferReader - { - private readonly bool usingSequence; - private readonly ReadOnlySequence sequence; - private SequencePosition currentPosition; - private SequencePosition nextPosition; - private bool moreData; - private readonly long length; - - public BufferReader(ReadOnlySpan span) - { - usingSequence = false; - CurrentSpanIndex = 0; - Consumed = 0; - sequence = default; - currentPosition = default; - length = span.Length; - - CurrentSpan = span; - nextPosition = default; - moreData = span.Length > 0; - } - - public BufferReader(in ReadOnlySequence sequence) - { - usingSequence = true; - CurrentSpanIndex = 0; - Consumed = 0; - this.sequence = sequence; - currentPosition = sequence.Start; - length = -1; - - var first = sequence.First.Span; - CurrentSpan = first; - nextPosition = sequence.GetPosition(first.Length); - moreData = first.Length > 0; - - if (!moreData && !sequence.IsSingleSegment) - { - moreData = true; - GetNextSpan(); - } - } - - public readonly bool End => !moreData; - - public ReadOnlySpan CurrentSpan { get; private set; } - - public int CurrentSpanIndex { get; private set; } - - public readonly ReadOnlySpan UnreadSpan - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => CurrentSpan.Slice(CurrentSpanIndex); - } - - public long Consumed { get; private set; } - - public readonly long Remaining => Length - Consumed; - - public readonly long Length - { - get - { - if (length < 0) - // Cast-away readonly to initialize lazy field - { - Volatile.Write(ref Unsafe.AsRef(length), sequence.Length); - } - - return length; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly bool TryPeek([MaybeNullWhen(false)] out T value) - { - if (moreData) - { - value = CurrentSpan[CurrentSpanIndex]; - return true; - } - - value = default!; - return false; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryRead([MaybeNullWhen(false)] out T value) - { - if (End) - { - value = default!; - return false; - } - - value = CurrentSpan[CurrentSpanIndex]; - CurrentSpanIndex++; - Consumed++; - - if (CurrentSpanIndex >= CurrentSpan.Length) - { - if (usingSequence) - { - GetNextSpan(); - } - else - { - moreData = false; - } - } - - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Rewind(long count) - { - if ((ulong)count > (ulong)Consumed) - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - - Consumed -= count; - - if (CurrentSpanIndex >= count) - { - CurrentSpanIndex -= (int)count; - moreData = true; - } - else if (usingSequence) - { - // Current segment doesn't have enough data, scan backward through segments - RetreatToPreviousSpan(Consumed); - } - else - { - throw new ArgumentOutOfRangeException( - nameof(count), - $"Rewind went past the start of the memory by {count}." - ); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void RetreatToPreviousSpan(long consumed) - { - ResetReader(); - Advance(consumed); - } - - private void ResetReader() - { - CurrentSpanIndex = 0; - Consumed = 0; - currentPosition = sequence.Start; - nextPosition = currentPosition; - - if (sequence.TryGet(ref nextPosition, out var memory)) - { - moreData = true; - - if (memory.Length == 0) - { - CurrentSpan = default; - // No data in the first span, move to one with data - GetNextSpan(); - } - else - { - CurrentSpan = memory.Span; - } - } - else - { - // No data in any spans and at end of sequence - moreData = false; - CurrentSpan = default; - } - } - - private void GetNextSpan() - { - if (!sequence.IsSingleSegment) - { - var previousNextPosition = nextPosition; - while (sequence.TryGet(ref nextPosition, out var memory)) - { - currentPosition = previousNextPosition; - if (memory.Length > 0) - { - CurrentSpan = memory.Span; - CurrentSpanIndex = 0; - return; - } - - CurrentSpan = default; - CurrentSpanIndex = 0; - previousNextPosition = nextPosition; - } - } - - moreData = false; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Advance(long count) - { - const long TooBigOrNegative = unchecked((long)0xFFFFFFFF80000000); - if ((count & TooBigOrNegative) == 0 && CurrentSpan.Length - CurrentSpanIndex > (int)count) - { - CurrentSpanIndex += (int)count; - Consumed += count; - } - else if (usingSequence) - { - // Can't satisfy from the current span - AdvanceToNextSpan(count); - } - else if (CurrentSpan.Length - CurrentSpanIndex == (int)count) - { - CurrentSpanIndex += (int)count; - Consumed += count; - moreData = false; - } - else - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - } - - private void AdvanceToNextSpan(long count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - - Consumed += count; - while (moreData) - { - var remaining = CurrentSpan.Length - CurrentSpanIndex; - - if (remaining > count) - { - CurrentSpanIndex += (int)count; - count = 0; - break; - } - - // As there may not be any further segments we need to - // push the current index to the end of the span. - CurrentSpanIndex += remaining; - count -= remaining; - - GetNextSpan(); - - if (count == 0) - { - break; - } - } - - if (count != 0) - { - // Not enough data left- adjust for where we actually ended and throw - Consumed -= count; - throw new ArgumentOutOfRangeException(nameof(count)); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly bool TryCopyTo(Span destination) - { - // This API doesn't advance to facilitate conditional advancement based on the data returned. - // We don't provide an advance option to allow easier utilizing of stack allocated destination spans. - // (Because we can make this method readonly we can guarantee that we won't capture the span.) - - var firstSpan = UnreadSpan; - if (firstSpan.Length >= destination.Length) - { - firstSpan.Slice(0, destination.Length).CopyTo(destination); - return true; - } - - // Not enough in the current span to satisfy the request, fall through to the slow path - return TryCopyMultisegment(destination); - } - - internal readonly bool TryCopyMultisegment(Span destination) - { - // If we don't have enough to fill the requested buffer, return false - if (Remaining < destination.Length) - { - return false; - } - - var firstSpan = UnreadSpan; - firstSpan.CopyTo(destination); - var copied = firstSpan.Length; - - var next = nextPosition; - while (sequence.TryGet(ref next, out var nextSegment)) - { - if (nextSegment.Length > 0) - { - var nextSpan = nextSegment.Span; - var toCopy = Math.Min(nextSpan.Length, destination.Length - copied); - nextSpan.Slice(0, toCopy).CopyTo(destination.Slice(copied)); - copied += toCopy; - if (copied >= destination.Length) - { - break; - } - } - } - - return true; - } - } -} diff --git a/Projects/Server/Buffers/BufferReaderExtensions.cs b/Projects/Server/Buffers/BufferReaderExtensions.cs deleted file mode 100644 index f19242b35..000000000 --- a/Projects/Server/Buffers/BufferReaderExtensions.cs +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) Harry Pierson. All rights reserved. -// Licensed under the MIT license. -// See LICENSE file in the project root for full license information. - -using System.Buffers.Binary; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System.Buffers -{ - public static class BufferReaderExtensions - { - private static unsafe bool TryRead(ref this BufferReader reader, out T value) - where T : unmanaged - { - var span = reader.UnreadSpan; - if (span.Length < sizeof(T)) - { - return TryReadMultisegment(ref reader, out value); - } - - value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(span)); - reader.Advance(sizeof(T)); - return true; - } - - private static unsafe bool TryReadMultisegment(ref BufferReader reader, out T value) - where T : unmanaged - { - // Not enough data in the current segment, try to peek for the data we need. - T buffer = default; - var tempSpan = new Span(&buffer, sizeof(T)); - - if (!reader.TryCopyTo(tempSpan)) - { - value = default; - return false; - } - - value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(tempSpan)); - reader.Advance(sizeof(T)); - return true; - } - - public static bool TryRead(ref this BufferReader reader, out sbyte value) - { - if (TryRead(ref reader, out byte byteValue)) - { - value = unchecked((sbyte)byteValue); - return true; - } - - value = default; - return false; - } - - public static bool TryReadLittleEndian(ref this BufferReader reader, out short value) => - BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value); - - public static bool TryReadBigEndian(ref this BufferReader reader, out short value) => - !BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value); - - private static bool TryReadReverseEndianness(ref BufferReader reader, out short value) - { - if (reader.TryRead(out value)) - { - value = BinaryPrimitives.ReverseEndianness(value); - return true; - } - - return false; - } - - public static bool TryReadLittleEndian(ref this BufferReader reader, out ushort value) - { - if (TryReadLittleEndian(ref reader, out short signedvalue)) - { - value = unchecked((ushort)signedvalue); - return true; - } - - value = default; - return false; - } - - public static bool TryReadBigEndian(ref this BufferReader reader, out ushort value) - { - if (TryReadBigEndian(ref reader, out short signedvalue)) - { - value = unchecked((ushort)signedvalue); - return true; - } - - value = default; - return false; - } - - public static bool TryReadLittleEndian(ref this BufferReader reader, out int value) => - BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value); - - public static bool TryReadBigEndian(ref this BufferReader reader, out int value) => - !BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value); - - private static bool TryReadReverseEndianness(ref BufferReader reader, out int value) - { - if (reader.TryRead(out value)) - { - value = BinaryPrimitives.ReverseEndianness(value); - return true; - } - - return false; - } - - public static bool TryReadLittleEndian(ref this BufferReader reader, out uint value) - { - if (TryReadLittleEndian(ref reader, out int signedvalue)) - { - value = unchecked((uint)signedvalue); - return true; - } - - value = default; - return false; - } - - public static bool TryReadBigEndian(ref this BufferReader reader, out uint value) - { - if (TryReadBigEndian(ref reader, out int signedvalue)) - { - value = unchecked((uint)signedvalue); - return true; - } - - value = default; - return false; - } - - public static bool TryReadLittleEndian(ref this BufferReader reader, out long value) => - BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value); - - public static bool TryReadBigEndian(ref this BufferReader reader, out long value) => - !BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value); - - private static bool TryReadReverseEndianness(ref BufferReader reader, out long value) - { - if (reader.TryRead(out value)) - { - value = BinaryPrimitives.ReverseEndianness(value); - return true; - } - - return false; - } - - public static bool TryReadLittleEndian(ref this BufferReader reader, out ulong value) - { - if (TryReadLittleEndian(ref reader, out long signedvalue)) - { - value = unchecked((ulong)signedvalue); - return true; - } - - value = default; - return false; - } - - public static bool TryReadBigEndian(ref this BufferReader reader, out ulong value) - { - if (TryReadBigEndian(ref reader, out long signedvalue)) - { - value = unchecked((ulong)signedvalue); - return true; - } - - value = default; - return false; - } - } -} diff --git a/Projects/Server/Buffers/BufferWriter.cs b/Projects/Server/Buffers/BufferWriter.cs deleted file mode 100644 index 1999b1612..000000000 --- a/Projects/Server/Buffers/BufferWriter.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Runtime.CompilerServices; - -namespace System.Buffers -{ - /// - /// A fast access struct that wraps . - /// - /// The type of element to be written. - internal ref struct BufferWriter where T : IBufferWriter - { - /// - /// The underlying . - /// - private T _output; - - /// - /// The result of the last call to , less any bytes already "consumed" with - /// . - /// Backing field for the property. - /// - private Span _span; - - /// - /// The number of uncommitted bytes (all the calls to since the last call to - /// ). - /// - private int _buffered; - - /// - /// The total number of bytes written with this writer. - /// Backing field for the property. - /// - private long _bytesCommitted; - - /// - /// Initializes a new instance of the struct. - /// - /// The to be wrapped. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public BufferWriter(T output) - { - _buffered = 0; - _bytesCommitted = 0; - _output = output; - _span = output.GetSpan(); - } - - /// - /// Gets the result of the last call to . - /// - public Span Span => _span; - - /// - /// Gets the total number of bytes written with this writer. - /// - public long BytesCommitted => _bytesCommitted; - - /// - /// Calls on the underlying writer - /// with the number of uncommitted bytes. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Commit() - { - var buffered = _buffered; - if (buffered > 0) - { - _bytesCommitted += buffered; - _buffered = 0; - _output.Advance(buffered); - } - } - - /// - /// Used to indicate that part of the buffer has been written to. - /// - /// The number of bytes written to. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Advance(int count) - { - _buffered += count; - _span = _span.Slice(count); - } - - /// - /// Copies the caller's buffer into this writer and calls with the length of the source buffer. - /// - /// The buffer to copy in. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ReadOnlySpan source) - { - if (_span.Length >= source.Length) - { - source.CopyTo(_span); - Advance(source.Length); - } - else - { - WriteMultiBuffer(source); - } - } - - /// - /// Acquires a new buffer if necessary to ensure that some given number of bytes can be written to a single buffer. - /// - /// The number of bytes that must be allocated in a single buffer. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Ensure(int count = 1) - { - if (_span.Length < count) - { - EnsureMore(count); - } - } - - /// - /// Gets a fresh span to write to, with an optional minimum size. - /// - /// The minimum size for the next requested buffer. - [MethodImpl(MethodImplOptions.NoInlining)] - private void EnsureMore(int count = 0) - { - if (_buffered > 0) - { - Commit(); - } - - _span = _output.GetSpan(count); - } - - /// - /// Copies the caller's buffer into this writer, potentially across multiple buffers from the underlying writer. - /// - /// The buffer to copy into this writer. - private void WriteMultiBuffer(ReadOnlySpan source) - { - while (source.Length > 0) - { - if (_span.Length == 0) - { - EnsureMore(); - } - - var writable = Math.Min(source.Length, _span.Length); - source.Slice(0, writable).CopyTo(_span); - source = source.Slice(writable); - Advance(writable); - } - } - } -} diff --git a/Projects/Server/Buffers/SpanReadExtensions.cs b/Projects/Server/Buffers/SpanReadExtensions.cs new file mode 100644 index 000000000..015ab37aa --- /dev/null +++ b/Projects/Server/Buffers/SpanReadExtensions.cs @@ -0,0 +1,90 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: SpanReadExtensions.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System.Buffers.Binary; +using System.Runtime.CompilerServices; + +namespace System.Buffers +{ + public static class SpanReadExtensions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte ReadInt8(this Span span, ref int pos) => span[pos++]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short ReadInt16(this Span span, ref int pos) + { + var v = BinaryPrimitives.ReadInt16BigEndian(span.Slice(pos, 2)); + pos += 2; + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort ReadUInt16(this Span span, ref int pos) + { + var v = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(pos, 2)); + pos += 2; + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ReadInt32(this Span span, ref int pos) + { + var v = BinaryPrimitives.ReadInt32BigEndian(span.Slice(pos, 4)); + pos += 4; + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint ReadUInt32(this Span span, ref int pos) + { + var v = BinaryPrimitives.ReadUInt32BigEndian(span.Slice(pos, 4)); + pos += 4; + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short ReadInt16LE(this Span span, ref int pos) + { + var v = BinaryPrimitives.ReadInt16LittleEndian(span.Slice(pos, 2)); + pos += 2; + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort ReadUInt16LE(this Span span, ref int pos) + { + var v = BinaryPrimitives.ReadUInt16LittleEndian(span.Slice(pos, 2)); + pos += 2; + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ReadInt32LE(this Span span, ref int pos) + { + var v = BinaryPrimitives.ReadInt32LittleEndian(span.Slice(pos, 4)); + pos += 4; + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint ReadUInt32LE(this Span span, ref int pos) + { + var v = BinaryPrimitives.ReadUInt32LittleEndian(span.Slice(pos, 4)); + pos += 4; + return v; + } + } +} diff --git a/Projects/Server/Buffers/SpanExtensions.cs b/Projects/Server/Buffers/SpanWriteExtensions.cs similarity index 82% rename from Projects/Server/Buffers/SpanExtensions.cs rename to Projects/Server/Buffers/SpanWriteExtensions.cs index 0bc613d80..3746d8e10 100644 --- a/Projects/Server/Buffers/SpanExtensions.cs +++ b/Projects/Server/Buffers/SpanWriteExtensions.cs @@ -1,3 +1,18 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: SpanWriteExtensions.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + using System.Buffers.Binary; using System.Runtime.CompilerServices; using System.Text; @@ -5,7 +20,7 @@ using Server; namespace System.Buffers { - public static class SpanExtensions + public static class SpanWriteExtensions { // Extensions [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -137,7 +152,7 @@ namespace System.Buffers var length = value.Length; pos += Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length)); #if NO_LOCAL_INIT - span[pos] = 0; // Null terminator + span[pos] = 0; // Null terminator #endif pos++; } @@ -149,7 +164,7 @@ namespace System.Buffers pos += Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length)); #if NO_LOCAL_INIT - span[pos] = 0; // Null terminator + span[pos] = 0; // Null terminator #endif pos++; } @@ -159,10 +174,10 @@ namespace System.Buffers { var length = value.Length <= amount ? value.Length : amount; #if NO_LOCAL_INIT - int bytesWritten = Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length)); + int bytesWritten = Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length)); - if (bytesWritten < amount) - span.Slice(pos + bytesWritten, amount - bytesWritten).Clear(); + if (bytesWritten < amount) + span.Slice(pos + bytesWritten, amount - bytesWritten).Clear(); #else Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length)); #endif @@ -187,7 +202,7 @@ namespace System.Buffers { pos += Encoding.BigEndianUnicode.GetBytes(value, span.Slice(pos)); #if NO_LOCAL_INIT - BinaryPrimitives.WriteUInt16BigEndian(span.Slice(pos, 2), 0); // Null terminator + BinaryPrimitives.WriteUInt16BigEndian(span.Slice(pos, 2), 0); // Null terminator #endif pos += 2; } @@ -197,7 +212,7 @@ namespace System.Buffers { pos += Encoding.Unicode.GetBytes(value, span.Slice(pos)); #if NO_LOCAL_INIT - BinaryPrimitives.WriteUInt16BigEndian(span.Slice(pos, 2), 0); // Null terminator + BinaryPrimitives.WriteUInt16BigEndian(span.Slice(pos, 2), 0); // Null terminator #endif pos += 2; } diff --git a/Projects/Server/MultiData.cs b/Projects/Server/MultiData.cs index e6bd8edfb..66ebfda12 100644 --- a/Projects/Server/MultiData.cs +++ b/Projects/Server/MultiData.cs @@ -174,18 +174,16 @@ namespace Server var tileList = new List(); // Skip the first 4 bytes - var reader = new BufferReader(data); - - reader.Advance(4); // ??? - reader.TryReadLittleEndian(out uint count); + var pos = 4; + var count = data.ReadUInt32LE(ref pos); for (uint i = 0; i < count; i++) { - reader.TryReadLittleEndian(out ushort itemid); - reader.TryReadLittleEndian(out short x); - reader.TryReadLittleEndian(out short y); - reader.TryReadLittleEndian(out short z); - reader.TryReadLittleEndian(out ushort flagValue); + var itemId = data.ReadUInt16LE(ref pos); + var x = data.ReadInt16LE(ref pos); + var y = data.ReadInt16LE(ref pos); + var z = data.ReadInt16LE(ref pos); + var flagValue = data.ReadUInt16LE(ref pos); var tileFlag = flagValue switch { @@ -194,10 +192,10 @@ namespace Server _ => TileFlag.Background // 0 }; - reader.TryReadLittleEndian(out uint clilocsCount); - reader.Advance(clilocsCount * 4); // bypass binary block + var clilocsCount = data.ReadUInt32LE(ref pos); + pos += (int)Math.Min(clilocsCount, int.MaxValue) * 4; // bypass binary block - tileList.Add(new MultiTileEntry(itemid, x, y, z, tileFlag)); + tileList.Add(new MultiTileEntry(itemId, x, y, z, tileFlag)); } Components[chunkID] = new MultiComponentList(tileList); diff --git a/THIRD-PARTY-NOTICES b/THIRD-PARTY-NOTICES index ca3b77e94..acca725b4 100644 --- a/THIRD-PARTY-NOTICES +++ b/THIRD-PARTY-NOTICES @@ -580,30 +580,6 @@ consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. -License notice for BufferReader/BufferWrite ---------------------------- -The MIT License (MIT) - -Copyright (c) Harry Pierson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - License notice for csharp-argon-2 --------------------------- The MIT License (MIT)