public static MemoryOwner <LineModificationType> ComputeDiff(ReadOnlySpan <char> oldText, ReadOnlySpan <char> newText, char separator) { // If the new text is empty, no modifications are returned if (newText.IsEmpty) { return(MemoryOwner <LineModificationType> .Empty); } int oldNumberOfLines = oldText.Count(separator) + 1; int newNumberOfLines = newText.Count(separator) + 1; // Fast path if the input text segments have the same length and are short enough if (oldText.Length == newText.Length && oldNumberOfLines == newNumberOfLines && oldNumberOfLines <= ShortPathNumberOfLinesThreshold && oldText.SequenceEqual(newText)) { return(MemoryOwner <LineModificationType> .Allocate(newNumberOfLines, AllocationMode.Clear)); } using SpanOwner <object?> oldTemporaryValues = SpanOwner <object?> .Allocate(oldNumberOfLines); using SpanOwner <object?> newTemporaryValues = SpanOwner <object?> .Allocate(newNumberOfLines); ref object?oldTemporaryValuesRef = ref oldTemporaryValues.DangerousGetReference();
public static double ChangesRequired(string s1, string s2) { if (s1.Equals(s2)) { return(0d); } if (s1.Length == 0) { return(s2.Length); } if (s2.Length == 0) { return(s1.Length); } using SpanOwner <int> v0Owner = SpanOwner <int> .Allocate(s2.Length + 1); using SpanOwner <int> v1Owner = SpanOwner <int> .Allocate(s2.Length + 1); Span <int> v0 = v0Owner.Span; Span <int> v1 = v1Owner.Span; for (int i = 0; i < v0.Length; i++) { v0[i] = i; } for (int i = 0; i < s1.Length; i++) { v1[0] = i + 1; int minv1 = v1[0]; for (int j = 0; j < s2.Length; j++) { int cost = 1; if (s1[i] == s2[j]) { cost = 0; } v1[j + 1] = Math.Min( v1[j] + 1, // Cost of insertion Math.Min( v0[j + 1] + 1, // Cost of remove v0[j] + cost)); // Cost of substitution minv1 = Math.Min(minv1, v1[j + 1]); } Span <int> vtemp = v0; v0 = v1; v1 = vtemp; } return(v0[s2.Length]); }
public static SpanOwner <T> Read <T>( this Stream stream, int elements) where T : unmanaged { var spanOwner = SpanOwner <T> .Allocate(elements); stream.Read(spanOwner.Span.Cast <T, byte>()); return(spanOwner); }
private static SpanOwner <ushort> LoadDefinitionsTable(int functionsCount) { Assert(functionsCount >= 0); return(functionsCount switch { 0 => SpanOwner <ushort> .Empty, _ => SpanOwner <ushort> .Allocate(functionsCount) });
public string ReadString(int byteCount) { using var pooledBytes = byteCount > STACK_MAX ? SpanOwner <byte> .Allocate(byteCount) : SpanOwner <byte> .Empty; Span <byte> bytes = byteCount > STACK_MAX ? pooledBytes.Span : stackalloc byte[byteCount]; bytes.Clear(); int readBytes = ReadBytes(bytes); bytes = bytes[..readBytes];
static string CreateString(int count, Encoding encoding) { if (count == 0) { return(string.Empty); } using var spanOwner = SpanOwner <byte> .Allocate(count); return(encoding.GetString(spanOwner.Span)); }
public static MemoryOwner<Brainf_ckOperation>? TryParse(ReadOnlySpan<char> source, out SyntaxValidationResult validationResult) { // Check the syntax of the input source code validationResult = ValidateSyntax(source); if (!validationResult.IsSuccess) return null; // Allocate the buffer of binary items with the input operations using SpanOwner<Brainf_ckOperation> buffer = SpanOwner<Brainf_ckOperation>.Allocate(validationResult.OperatorsCount); ref Brainf_ckOperation bufferRef = ref buffer.DangerousGetReference();
internal static unsafe string GetString(this Encoding encoding, ReadOnlySpan <byte> bytes) { using var spanOwner = SpanOwner <byte> .Allocate((int) bytes.Length); bytes.CopyTo(spanOwner.Span); fixed(byte *spanBytes = spanOwner.Span) { return(encoding.GetString(spanBytes, spanOwner.Length)); } }
public void Test_SpanOwnerOfT_AllocateAndGetMemoryAndSpan() { using var buffer = SpanOwner <int> .Allocate(127); Assert.IsTrue(buffer.Length == 127); Assert.IsTrue(buffer.Span.Length == 127); buffer.Span.Fill(42); Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42)); }
private static SpanOwner <int> LoadJumpTable <TOpcode>( Span <TOpcode> opcodes, out int functionsCount) where TOpcode : unmanaged, IOpcode { SpanOwner <int> jumpTable = SpanOwner <int> .Allocate(opcodes.Length); Brainf_ckInterpreter.LoadJumpTable(opcodes, jumpTable.Span, out functionsCount); return(jumpTable); }
public static unsafe string InterleaveWithCharacter(this ReadOnlySpan <char> text, char c) { int textLength = text.Length; if (textLength == 0) { return(string.Empty); } using SpanOwner <char> buffer = SpanOwner <char> .Allocate(textLength * 2); ref char textRef = ref text.DangerousGetReference();
public int SpanOwner() { var sum = 0; var repetitions = Repetitions; for (var i = 0; i < repetitions; i++) { using var buffer = SpanOwner <byte> .Allocate(SizeInBytes, AllocationMode.Default); sum += buffer.Length; } return(sum); }
static void Main(string[] args) { var dis = Levenshtein.Distance("aaaaa", "aaaab"); Console.WriteLine("Hello World!"); using MemoryOwner <int> own = MemoryOwner <int> .Allocate(1); _ = own.Span; _ = own.Memory; using SpanOwner <int> ownSpan = SpanOwner <int> .Allocate(1); _ = ownSpan.Span; // Create an array and run the callback float[] array = new float[10_000];
public void Test_SpanOwnerOfT_AllocateAndGetArray() { using var buffer = SpanOwner <int> .Allocate(127); var segment = buffer.DangerousGetArray(); // See comments in the MemoryOwner<T> tests about this. The main difference // here is that we don't do the disposed checks, as SpanOwner<T> is optimized // with the assumption that usages after dispose are undefined behavior. This // is all documented in the XML docs for the SpanOwner<T> type. Assert.IsNotNull(segment.Array); Assert.IsTrue(segment.Array.Length >= buffer.Length); Assert.AreEqual(segment.Offset, 0); Assert.AreEqual(segment.Count, buffer.Length); }
public void Test_SpanOwnerOfT_PooledBuffersAndClear() { using (var buffer = SpanOwner <int> .Allocate(127)) { buffer.Span.Fill(42); } using (var buffer = SpanOwner <int> .Allocate(127)) { Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42)); } using (var buffer = SpanOwner <int> .Allocate(127, AllocationMode.Clear)) { Assert.IsTrue(buffer.Span.ToArray().All(i => i == 0)); } }
public void Test_SpanOwnerOfT_AllocateFromCustomPoolAndGetMemoryAndSpan() { var pool = new TrackingArrayPool <int>(); using (var buffer = SpanOwner <int> .Allocate(127, pool)) { Assert.AreEqual(pool.RentedArrays.Count, 1); Assert.IsTrue(buffer.Length == 127); Assert.IsTrue(buffer.Span.Length == 127); buffer.Span.Fill(42); Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42)); } Assert.AreEqual(pool.RentedArrays.Count, 0); }
/// <summary> /// Prepares the input to MAC, following RFC 8439, section 2.8. /// </summary> /// <param name="aad">The associated data.</param> /// <param name="ciphertext">The ciphertext.</param> /// <returns>System.Byte[].</returns> private SpanOwner <byte> GetMacDataRfc8439(ReadOnlySpan <byte> aad, ReadOnlySpan <byte> ciphertext) { var aadPaddedLen = (aad.Length % 16 == 0) ? aad.Length : (aad.Length + 16 - aad.Length % 16); var ciphertextLen = ciphertext.Length; var ciphertextPaddedLen = (ciphertextLen % 16 == 0) ? ciphertextLen : (ciphertextLen + 16 - ciphertextLen % 16); var macData = SpanOwner <byte> .Allocate(aadPaddedLen + ciphertextPaddedLen + 16, AllocationMode.Clear); // Mac Text aad.CopyTo(macData.Span); ciphertext.CopyTo(macData.Span.Slice(aadPaddedLen, ciphertextLen)); // Mac Length //macData[aadPaddedLen + ciphertextPaddedLen] = (byte)aad.Length; //macData[aadPaddedLen + ciphertextPaddedLen + 8] = (byte)ciphertextLen; SetMacLength(macData.Span, aadPaddedLen + ciphertextPaddedLen, aad.Length); SetMacLength(macData.Span, aadPaddedLen + ciphertextPaddedLen + sizeof(ulong), ciphertextLen); return(macData); }
/// <summary> /// The MAC key is the first 32 bytes of the first key stream block. /// </summary> /// <param name="nonce">The nonce.</param> /// <returns>System.Byte[].</returns> private SpanOwner <byte> GetMacKey(ReadOnlySpan <byte> nonce) { //var firstBlock = new byte[Snuffle.BLOCK_SIZE_IN_BYTES]; //_macKeySnuffle.ProcessKeyStreamBlock(nonce, 0, firstBlock); //var result = new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES]; //Array.Copy(firstBlock, result, result.Length); //return result; using (var firstBlock = SpanOwner <byte> .Allocate(Snuffle.BLOCK_SIZE_IN_BYTES, AllocationMode.Clear)) { //Span<byte> firstBlock = new byte[Snuffle.BLOCK_SIZE_IN_BYTES]; _macKeySnuffle.ProcessKeyStreamBlock(nonce, 0, firstBlock.Span); var macKey = SpanOwner <byte> .Allocate(Poly1305.MAC_KEY_SIZE_IN_BYTES, AllocationMode.Clear); firstBlock.Span.Slice(0, Poly1305.MAC_KEY_SIZE_IN_BYTES).CopyTo(macKey.Span); firstBlock.Span.Clear(); return(macKey); } }
public static unsafe string GetFormattedPath(this IFile file) { const int separatorLength = 3; // " » " int numberOfSeparators = file.Path.Count(Path.DirectorySeparatorChar), formattedLength = file.Path.Length + numberOfSeparators * (separatorLength - 1) + separatorLength; // The temporary buffer has space for one extra separator that is // always initialized even if it's not used in the final string. // This is done to avoid having to check the current index in the // main loop, which would be needed to check whether or not // the current separator should be written or not to the buffer. using SpanOwner <char> buffer = SpanOwner <char> .Allocate(formattedLength); fixed(char *p = &buffer.DangerousGetReference()) { // Write the path parts int i = 0; foreach (ReadOnlySpan <char> part in file.Path.Tokenize(Path.DirectorySeparatorChar)) { part.CopyTo(new Span <char>(p + i, part.Length)); i += part.Length; // Write the characters manually to avoid another stackalloc p[i] = ' '; p[i + 1] = '»'; p[i + 2] = ' '; i += 3; } // Create a string from the buffer and skip the last separator return(new string(p, 0, formattedLength - 3)); } }
/* * Save a game using Quetzal format. Return 1 if OK, 0 if failed. */ internal static zword SaveQuetzal(FileStream svf, System.IO.Stream stf) { zlong stkslen = 0; zword i, j, n; int nvars, nargs, nstk, p; zbyte var; long cmempos, stkspos; int c; /* Write `IFZS' header. */ if (!WriteChunk(svf, ID_FORM, 0)) { return(0); } if (!WriteLong(svf, ID_IFZS)) { return(0); } /* Write `IFhd' chunk. */ FastMem.GetPc(out long pc); if (!WriteChunk(svf, ID_IFhd, 13)) { return(0); } if (!WriteWord(svf, Main.h_release)) { return(0); } for (i = ZMachine.H_SERIAL; i < ZMachine.H_SERIAL + 6; ++i) { if (!WriteByte(svf, FastMem.ZMData[FastMem.Zmp + i])) { return(0); } } if (!WriteWord(svf, Main.h_checksum)) { return(0); } if (!WriteLong(svf, pc << 8)) /* Includes pad. */ return { (0); } /* Write `CMem' chunk. */ if ((cmempos = svf.Position) < 0) { return(0); } if (!WriteChunk(svf, ID_CMem, 0)) { return(0); } // (void) fseek (stf, 0, SEEK_SET); stf.Position = 0; uint cmemlen; /* j holds current run length. */ for (i = 0, j = 0, cmemlen = 0; i < Main.h_dynamic_size; ++i) { if ((c = stf.ReadByte()) == -1) { return(0); } c ^= FastMem.ZMData[i]; if (c == 0) { ++j; /* It's a run of equal bytes. */ } else { /* Write out any run there may be. */ if (j > 0) { for (; j > 0x100; j -= 0x100) { if (!WriteRun(svf, 0xFF)) { return(0); } cmemlen += 2; } if (!WriteRun(svf, (byte)(j - 1))) { return(0); } cmemlen += 2; j = 0; } /* Any runs are now written. Write this (nonzero) byte. */ if (!WriteByte(svf, (zbyte)c)) { return(0); } ++cmemlen; } } /* * Reached end of dynamic memory. We ignore any unwritten run there may be * at this point. */ if ((cmemlen & 1) > 0) /* Chunk length must be even. */ { if (!WriteByte(svf, 0)) { return(0); } } /* Write `Stks' chunk. You are not expected to understand this. ;) */ if ((stkspos = svf.Position) < 0) { return(0); } if (!WriteChunk(svf, ID_Stks, 0)) { return(0); } using var buffer = SpanOwner <zword> .Allocate(General.STACK_SIZE / 4 + 1); var frames = buffer.Span; /* * We construct a list of frame indices, most recent first, in `frames'. * These indices are the offsets into the `stack' array of the word before * the first word pushed in each frame. */ frames[0] = (zword)Main.sp; /* The frame we'd get by doing a call now. */ for (i = (zword)(Main.fp + 4), n = 0; i < General.STACK_SIZE + 4; i = (zword)(Main.Stack[i - 3] + 5)) { frames[++n] = i; } /* * All versions other than V6 can use evaluation stack outside a function * context. We write a faked stack frame (most fields zero) to cater for * this. */ if (Main.h_version != ZMachine.V6) { for (i = 0; i < 6; ++i) { if (!WriteByte(svf, 0)) { return(0); } } nstk = General.STACK_SIZE - frames[n]; if (!WriteWord(svf, nstk)) { return(0); } for (j = General.STACK_SIZE - 1; j >= frames[n]; --j) { if (!WriteWord(svf, Main.Stack[j])) { return(0); } } stkslen = (zword)(8 + 2 * nstk); } /* Write out the rest of the stack frames. */ for (i = n; i > 0; --i) { p = frames[i] - 4; // p = stack + frames[i] - 4; /* Points to call frame. */ nvars = (Main.Stack[p] & 0x0F00) >> 8; nargs = Main.Stack[p] & 0x00FF; nstk = (zword)(frames[i] - frames[i - 1] - nvars - 4); pc = ((zlong)Main.Stack[p + 3] << 9) | Main.Stack[p + 2]; switch (Main.Stack[p] & 0xF000) /* Check type of call. */ { case 0x0000: /* Function. */ var = FastMem.ZMData[FastMem.Zmp + pc]; pc = ((pc + 1) << 8) | (zlong)nvars; break; case 0x1000: /* Procedure. */ var = 0; pc = (pc << 8) | 0x10 | (zlong)nvars; /* Set procedure flag. */ break; /* case 0x2000: */ default: Err.RuntimeError(ErrorCodes.ERR_SAVE_IN_INTER); return(0); } if (nargs != 0) { nargs = (zword)((1 << nargs) - 1); /* Make args into bitmap. */ } /* Write the main part of the frame... */ if (!WriteLong(svf, pc) || !WriteByte(svf, var) || !WriteByte(svf, (byte)nargs) || !WriteWord(svf, nstk)) { return(0); } /* Write the variables and eval stack. */ for (j = 0, --p; j < nvars + nstk; ++j, --p) { if (!WriteWord(svf, Main.Stack[p])) { return(0); } } /* Calculate length written thus far. */ stkslen += (zword)(8 + 2 * (nvars + nstk)); } /* Fill in variable chunk lengths. */ uint ifzslen = 3 * 8 + 4 + 14 + cmemlen + stkslen; if ((cmemlen & 1) > 0) { ++ifzslen; } svf.Position = 4; if (!WriteLong(svf, ifzslen)) { return(0); } svf.Position = cmempos + 4; if (!WriteLong(svf, cmemlen)) { return(0); } svf.Position = stkspos + 4; if (!WriteLong(svf, stkslen)) { return(0); } /* After all that, still nothing went wrong! */ return(1); }
public void Test_SpanOwnerOfT_InvalidRequestedSize() { using var buffer = SpanOwner <int> .Allocate(-1); Assert.Fail("You shouldn't be here"); }