static BEncodedString DecodeString(Stream reader, int length) { int read; while ((read = reader.ReadByte()) != -1) { if (read == ':') { var bytes = new byte[length]; if (reader.Read(bytes, 0, length) != length) { throw new BEncodingException("Couldn't decode string"); } return(BEncodedString.FromMemory(new ReadOnlyMemory <byte> (bytes))); } if (read < '0' || read > '9') { throw new BEncodingException($"Invalid BEncodedString. Length was '{length}' instead of a number"); } length = length * 10 + (read - '0'); } throw new BEncodingException("Invalid data found. Aborting"); }
static BEncodedString DecodeString(ref ReadOnlySpan <byte> buffer) { int length = 0; for (int i = 0; i < buffer.Length; i++) { if (buffer[i] == (byte)':') { // Consume the ':' character i++; // Ensure we have enough bytes left if (buffer.Length < (i + length)) { throw new BEncodingException($"Invalid BEncodedString. The buffer does not contain at least {length} bytes."); } // Copy the data out! var bytes = new byte[length]; buffer.Slice(i, length).CopyTo(bytes); buffer = buffer.Slice(i + length); return(BEncodedString.FromMemory(bytes)); } if (buffer[i] < (byte)'0' || buffer[i] > (byte)'9') { throw new BEncodingException($"Invalid BEncodedString. Length was '{length}' instead of a number"); } length = length * 10 + (buffer[i] - '0'); } throw new BEncodingException($"Invalid BEncodedString. The ':' separater was not found."); }
public void EmptyStringTests() { var variants = new[] { new BEncodedString(Array.Empty <byte> ()), new BEncodedString(Array.Empty <char> ()), new BEncodedString(""), BEncodedString.FromMemory(null), BEncodedString.FromMemory(Memory <byte> .Empty), }; foreach (var variant in variants) { Assert.IsTrue(BEncodedString.IsNullOrEmpty(variant)); Assert.AreEqual(2, variant.LengthInBytes()); Assert.AreEqual("", variant.Text); Assert.AreEqual(0, variant.Span.Length); } }