public int IndexOf(ICharSequence subString, int start) { int thisLen = this.length; uint uThisLen = (uint)thisLen; if (0u >= uThisLen) { return(IndexNotFound); } uint uStart = (uint)start; if (uStart > SharedConstants.TooBigOrNegative) { start = 0; uStart = 0u; } int subCount = subString.Count; uint uSubCount = (uint)subCount; if (0u >= uSubCount) { return(uStart < uThisLen ? start : thisLen); } var searchLen = thisLen - start; if (uSubCount > (uint)searchLen) { return(IndexNotFound); } char firstChar = subString[0]; if ((uint)firstChar > uMaxCharValue) { return(IndexNotFound); } if (0u >= uStart) { if (subString is IHasAsciiSpan hasAscii) { return(SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(this.AsciiSpan), thisLen, ref MemoryMarshal.GetReference(hasAscii.AsciiSpan), subCount)); } if (subString is IHasUtf16Span hasUtf16) { return(SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(this.Utf16Span), thisLen, ref MemoryMarshal.GetReference(hasUtf16.Utf16Span), subCount)); } } else { if (subString is IHasAsciiSpan hasAscii) { var result = SpanHelpers.IndexOf( ref Unsafe.Add(ref MemoryMarshal.GetReference(this.AsciiSpan), start), searchLen, ref MemoryMarshal.GetReference(hasAscii.AsciiSpan), subCount); return(SharedConstants.TooBigOrNegative >= (uint)result ? start + result : IndexNotFound); } if (subString is IHasUtf16Span hasUtf16) { var result = SpanHelpers.IndexOf( ref Unsafe.Add(ref MemoryMarshal.GetReference(this.Utf16Span), start), searchLen, ref MemoryMarshal.GetReference(hasUtf16.Utf16Span), subCount); return(SharedConstants.TooBigOrNegative >= (uint)result ? start + result : IndexNotFound); } } return(IndexOf0(subString, start)); }
public static void CastSpanShortToLong() { short[] a = { 0x1234, 0x2345, 0x3456, 0x4567, 0x5678 }; Span <short> span = new Span <short>(a); Span <long> asLong = MemoryMarshal.Cast <short, long>(span); Assert.True(Unsafe.AreSame <long>(ref Unsafe.As <short, long>(ref MemoryMarshal.GetReference(span)), ref MemoryMarshal.GetReference(asLong))); asLong.Validate <long>(0x4567345623451234); }
internal static int GetHashCodeOrdinalIgnoreCase(ReadOnlySpan <char> value) { ulong seed = Marvin.DefaultSeed; return(Marvin.ComputeHash32OrdinalIgnoreCase(ref MemoryMarshal.GetReference(value), value.Length /* in chars, not bytes */, (uint)seed, (uint)(seed >> 32))); }
/// <summary> /// Returns <c>true</c> if and only if the two specified buffers are /// identical to each other for {@code length} bytes starting at {@code aStartIndex} /// index for the {@code a} buffer and {@code bStartIndex} index for the {@code b} buffer. /// A more compact way to express this is: /// <p /> /// {@code a[aStartIndex : aStartIndex + length] == b[bStartIndex : bStartIndex + length]} /// </summary> public static bool Equals(IByteBuffer a, int aStartIndex, IByteBuffer b, int bStartIndex, int length) { if (aStartIndex < 0 || bStartIndex < 0 || length < 0) { ThrowHelper.ThrowArgumentException_NonNegative(); } if (a.WriterIndex - length < aStartIndex || b.WriterIndex - length < bStartIndex) { return(false); } if (a.IsSingleIoBuffer && b.IsSingleIoBuffer) { var spanA = a.GetReadableSpan(aStartIndex, length); var spanB = b.GetReadableSpan(bStartIndex, length); #if NET return(spanA.SequenceEqual(spanB)); #else return(SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(spanA), ref MemoryMarshal.GetReference(spanB), length)); #endif } return(EqualsSlow(a, aStartIndex, b, bStartIndex, length)); }
/// <inheritdoc/> protected override void OnFrameApply( ImageFrame <TPixel> source, ImageFrame <TPixel> destination, Rectangle sourceRectangle, Configuration configuration) { int height = this.TargetDimensions.Height; int width = this.TargetDimensions.Width; Rectangle sourceBounds = source.Bounds(); var targetBounds = new Rectangle(0, 0, width, height); // Since could potentially be resizing the canvas we might need to re-calculate the matrix Matrix3x2 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds); // Convert from screen to world space. Matrix3x2.Invert(matrix, out matrix); if (this.Sampler is NearestNeighborResampler) { ParallelFor.WithConfiguration( 0, height, configuration, y => { Span <TPixel> destRow = destination.GetPixelRowSpan(y); for (int x = 0; x < width; x++) { var point = Point.Transform(new Point(x, y), matrix); if (sourceBounds.Contains(point.X, point.Y)) { destRow[x] = source[point.X, point.Y]; } } }); return; } int maxSourceX = source.Width - 1; int maxSourceY = source.Height - 1; (float radius, float scale, float ratio)xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width); (float radius, float scale, float ratio)yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height); float xScale = xRadiusScale.scale; float yScale = yRadiusScale.scale; var radius = new Vector2(xRadiusScale.radius, yRadiusScale.radius); IResampler sampler = this.Sampler; var maxSource = new Vector4(maxSourceX, maxSourceY, maxSourceX, maxSourceY); int xLength = (int)MathF.Ceiling((radius.X * 2) + 2); int yLength = (int)MathF.Ceiling((radius.Y * 2) + 2); MemoryAllocator memoryAllocator = configuration.MemoryAllocator; using (Buffer2D <float> yBuffer = memoryAllocator.Allocate2D <float>(yLength, height)) using (Buffer2D <float> xBuffer = memoryAllocator.Allocate2D <float>(xLength, height)) { ParallelFor.WithConfiguration( 0, height, configuration, y => { ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y)); ref float ySpanRef = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y)); ref float xSpanRef = ref MemoryMarshal.GetReference(xBuffer.GetRowSpan(y));
internal static bool EcDsaSign(ReadOnlySpan <byte> dgst, int dlen, Span <byte> sig, [In, Out] ref int siglen, SafeEcKeyHandle ecKey) => EcDsaSign(ref MemoryMarshal.GetReference(dgst), dlen, ref MemoryMarshal.GetReference(sig), ref siglen, ecKey);
/// <inheritdoc /> protected override void OnFrameApply(ImageFrame <TPixel> source) { DenseMatrix <float>[] kernels = this.Kernels.Flatten(); int startY = this.SourceRectangle.Y; int endY = this.SourceRectangle.Bottom; int startX = this.SourceRectangle.X; int endX = this.SourceRectangle.Right; // Align start/end positions. int minX = Math.Max(0, startX); int maxX = Math.Min(source.Width, endX); int minY = Math.Max(0, startY); int maxY = Math.Min(source.Height, endY); // we need a clean copy for each pass to start from using (ImageFrame <TPixel> cleanCopy = source.Clone()) { using (var processor = new ConvolutionProcessor <TPixel>(kernels[0], true, this.Source, this.SourceRectangle)) { processor.Apply(source); } if (kernels.Length == 1) { return; } int shiftY = startY; int shiftX = startX; // Reset offset if necessary. if (minX > 0) { shiftX = 0; } if (minY > 0) { shiftY = 0; } var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); // Additional runs. // ReSharper disable once ForCanBeConvertedToForeach for (int i = 1; i < kernels.Length; i++) { using (ImageFrame <TPixel> pass = cleanCopy.Clone()) { using (var processor = new ConvolutionProcessor <TPixel>(kernels[i], true, this.Source, this.SourceRectangle)) { processor.Apply(pass); } Buffer2D <TPixel> passPixels = pass.PixelBuffer; Buffer2D <TPixel> targetPixels = source.PixelBuffer; ParallelHelper.IterateRows( workingRect, this.Configuration, rows => { for (int y = rows.Min; y < rows.Max; y++) { int offsetY = y - shiftY; ref TPixel passPixelsBase = ref MemoryMarshal.GetReference(passPixels.GetRowSpan(offsetY)); ref TPixel targetPixelsBase = ref MemoryMarshal.GetReference(targetPixels.GetRowSpan(offsetY)); for (int x = minX; x < maxX; x++) { int offsetX = x - shiftX; // Grab the max components of the two pixels ref TPixel currentPassPixel = ref Unsafe.Add(ref passPixelsBase, offsetX); ref TPixel currentTargetPixel = ref Unsafe.Add(ref targetPixelsBase, offsetX); var pixelValue = Vector4.Max( currentPassPixel.ToVector4(), currentTargetPixel.ToVector4()); currentTargetPixel.FromVector4(pixelValue); } } });
private unsafe bool StartsWithOrdinalHelper(ReadOnlySpan <char> source, ReadOnlySpan <char> prefix, CompareOptions options) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(!source.IsEmpty); Debug.Assert(!prefix.IsEmpty); Debug.Assert(_isAsciiEqualityOrdinal); int length = Math.Min(source.Length, prefix.Length); fixed(char *ap = &MemoryMarshal.GetReference(source)) fixed(char *bp = &MemoryMarshal.GetReference(prefix)) { char *a = ap; char *b = bp; while (length != 0) { int charA = *a; int charB = *b; if (charA >= 0x80 || charB >= 0x80 || HighCharTable[charA] || HighCharTable[charB]) { goto InteropCall; } if (charA == charB) { a++; b++; length--; continue; } // The match may be affected by special character. Verify that the following character is regular ASCII. if (a < ap + source.Length - 1 && *(a + 1) >= 0x80) { goto InteropCall; } if (b < bp + prefix.Length - 1 && *(b + 1) >= 0x80) { goto InteropCall; } return(false); } // The match may be affected by special character. Verify that the following character is regular ASCII. if (source.Length < prefix.Length) { if (*b >= 0x80) { goto InteropCall; } return(false); } if (source.Length > prefix.Length) { if (*a >= 0x80) { goto InteropCall; } } return(true); InteropCall: return(Interop.Globalization.StartsWith(_sortHandle, bp, prefix.Length, ap, source.Length, options)); } }
internal static int EvpDigestUpdate(SafeEvpMdCtxHandle ctx, ReadOnlySpan <byte> d, int cnt) => EvpDigestUpdate(ctx, ref MemoryMarshal.GetReference(d), cnt);
private static int GetExtraBlBits(int i) => Unsafe.Add(ref MemoryMarshal.GetReference(ExtraBlbits), i);
private unsafe int IndexOfOrdinalHelper(ReadOnlySpan <char> source, ReadOnlySpan <char> target, CompareOptions options, int *matchLengthPtr, bool fromBeginning) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(!target.IsEmpty); Debug.Assert(_isAsciiEqualityOrdinal); fixed(char *ap = &MemoryMarshal.GetReference(source)) fixed(char *bp = &MemoryMarshal.GetReference(target)) { char *a = ap; char *b = bp; for (int j = 0; j < target.Length; j++) { char targetChar = *(b + j); if (targetChar >= 0x80 || HighCharTable[targetChar]) { goto InteropCall; } } if (target.Length > source.Length) { for (int k = 0; k < source.Length; k++) { char targetChar = *(a + k); if (targetChar >= 0x80 || HighCharTable[targetChar]) { goto InteropCall; } } return(-1); } int startIndex, endIndex, jump; if (fromBeginning) { // Left to right, from zero to last possible index in the source string. // Incrementing by one after each iteration. Stop condition is last possible index plus 1. startIndex = 0; endIndex = source.Length - target.Length + 1; jump = 1; } else { // Right to left, from first possible index in the source string to zero. // Decrementing by one after each iteration. Stop condition is last possible index minus 1. startIndex = source.Length - target.Length; endIndex = -1; jump = -1; } for (int i = startIndex; i != endIndex; i += jump) { int targetIndex = 0; int sourceIndex = i; for (; targetIndex < target.Length; targetIndex++, sourceIndex++) { char valueChar = *(a + sourceIndex); char targetChar = *(b + targetIndex); if (valueChar >= 0x80 || HighCharTable[valueChar]) { goto InteropCall; } else if (valueChar != targetChar) { break; } } if (targetIndex == target.Length) { if (matchLengthPtr != null) { *matchLengthPtr = target.Length; } return(i); } } return(-1); InteropCall: if (fromBeginning) { return(Interop.Globalization.IndexOf(_sortHandle, b, target.Length, a, source.Length, options, matchLengthPtr)); } else { return(Interop.Globalization.LastIndexOf(_sortHandle, b, target.Length, a, source.Length, options)); } } }
private static byte GetBitLength(int i) => Unsafe.Add(ref MemoryMarshal.GetReference(BlOrder), i);
public static int GetLengthCode(int match) => Unsafe.Add(ref MemoryMarshal.GetReference(LengthCode), match);
public static int GetBaseLength(int match) => Unsafe.Add(ref MemoryMarshal.GetReference(BaseLength), match);
private void WriteControlUtf8(byte value) { MemoryMarshal.GetReference(EnsureBuffer(1)) = value; _bufferWriter.Advance(1); }
/// <summary> /// Returns the list of FT4222 connected /// </summary> /// <returns>A list of devices connected</returns> public static List <DeviceInformation> GetDevices() { List <DeviceInformation> devInfos = new List <DeviceInformation>(); FtStatus ftStatus = 0; // Check device uint numOfDevices; ftStatus = FtFunction.FT_CreateDeviceInfoList(out numOfDevices); Debug.WriteLine($"Number of devices: {numOfDevices}"); if (numOfDevices == 0) { throw new IOException($"No device found"); } Span <byte> sernum = stackalloc byte[16]; Span <byte> desc = stackalloc byte[64]; for (uint i = 0; i < numOfDevices; i++) { uint flags = 0; FtDevice ftDevice; uint id; uint locId; IntPtr handle; ftStatus = FtFunction.FT_GetDeviceInfoDetail(i, out flags, out ftDevice, out id, out locId, in MemoryMarshal.GetReference(sernum), in MemoryMarshal.GetReference(desc), out handle); if (ftStatus != FtStatus.Ok) { throw new IOException($"Can't read device information on device index {i}, error {ftStatus}"); } var devInfo = new DeviceInformation( (FtFlag)flags, ftDevice, id, locId, Encoding.ASCII.GetString(sernum.ToArray(), 0, FindFirstZero(sernum)), Encoding.ASCII.GetString(desc.ToArray(), 0, FindFirstZero(desc))); devInfos.Add(devInfo); } return(devInfos); }
/// <summary> /// The activation function; span implementation. /// </summary> /// <param name="v">A span of pre-activation levels to pass through the function. /// The resulting post-activation levels are written back to this same span.</param> public void Fn(Span <double> v) { Fn(ref MemoryMarshal.GetReference(v), v.Length); }
internal unsafe void WriteCore(ReadOnlySpan <byte> source) { EnsureNotClosed(); EnsureWriteable(); long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition long len = Interlocked.Read(ref _length); long n = pos + source.Length; // Check for overflow if (n < 0) { throw new IOException(SR.IO_StreamTooLong); } if (n > _capacity) { throw new NotSupportedException(SR.IO_FixedCapacity); } if (_buffer == null) { // Check to see whether we are now expanding the stream and must // zero any memory in the middle. if (pos > len) { Buffer.ZeroMemory(_mem + len, pos - len); } // set length after zeroing memory to avoid race condition of accessing unzeroed memory if (n > len) { Interlocked.Exchange(ref _length, n); } } fixed(byte *pBuffer = &MemoryMarshal.GetReference(source)) { if (_buffer != null) { long bytesLeft = _capacity - pos; if (bytesLeft < source.Length) { throw new ArgumentException(SR.Arg_BufferTooSmall); } byte *pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); Buffer.Memcpy(pointer + pos + _offset, pBuffer, source.Length); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } else { Buffer.Memcpy(_mem + pos, pBuffer, source.Length); } } Interlocked.Exchange(ref _position, n); return; }
internal static unsafe int EcDsaVerify(ReadOnlySpan <byte> dgst, int dgst_len, ReadOnlySpan <byte> sigbuf, int sig_len, SafeEcKeyHandle ecKey) => EcDsaVerify(ref MemoryMarshal.GetReference(dgst), dgst_len, ref MemoryMarshal.GetReference(sigbuf), sig_len, ecKey);
/// <inheritdoc/> protected override void OnFrameApply(ImageFrame <TPixel> source, ImageFrame <TPixel> destination, Rectangle sourceRectangle, Configuration configuration) { int height = this.TargetDimensions.Height; int width = this.TargetDimensions.Width; Rectangle sourceBounds = source.Bounds(); var targetBounds = new Rectangle(0, 0, width, height); // Since could potentially be resizing the canvas we might need to re-calculate the matrix Matrix4x4 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds); // Convert from screen to world space. Matrix4x4.Invert(matrix, out matrix); const float Epsilon = 0.0000001F; if (this.Sampler is NearestNeighborResampler) { Parallel.For( 0, height, configuration.ParallelOptions, y => { Span <TPixel> destRow = destination.GetPixelRowSpan(y); for (int x = 0; x < width; x++) { var v3 = Vector3.Transform(new Vector3(x, y, 1), matrix); float z = MathF.Max(v3.Z, Epsilon); int px = (int)MathF.Round(v3.X / z); int py = (int)MathF.Round(v3.Y / z); if (sourceBounds.Contains(px, py)) { destRow[x] = source[px, py]; } } }); return; } int maxSourceX = source.Width - 1; int maxSourceY = source.Height - 1; (float radius, float scale, float ratio)xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width); (float radius, float scale, float ratio)yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height); float xScale = xRadiusScale.scale; float yScale = yRadiusScale.scale; // Using Vector4 with dummy 0-s, because Vector2 SIMD implementation is not reliable: var radius = new Vector4(xRadiusScale.radius, yRadiusScale.radius, 0, 0); IResampler sampler = this.Sampler; var maxSource = new Vector4(maxSourceX, maxSourceY, maxSourceX, maxSourceY); int xLength = (int)MathF.Ceiling((radius.X * 2) + 2); int yLength = (int)MathF.Ceiling((radius.Y * 2) + 2); MemoryManager memoryManager = configuration.MemoryManager; using (Buffer2D <float> yBuffer = memoryManager.Allocate2D <float>(yLength, height)) using (Buffer2D <float> xBuffer = memoryManager.Allocate2D <float>(xLength, height)) { Parallel.For( 0, height, configuration.ParallelOptions, y => { ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y)); ref float ySpanRef = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y)); ref float xSpanRef = ref MemoryMarshal.GetReference(xBuffer.GetRowSpan(y));
/// <summary> /// Submit a log entry to the journal. /// </summary> public static unsafe LogResult Log(LogFlags flags, JournalMessage message) { Socket socket = GetJournalSocket(); if (socket == null) { if (s_isSupported.Value) { return(LogResult.NotAvailable); } else { return(LogResult.NotSupported); } } if (message.IsEmpty) { return(LogResult.Success); } int priority = (int)flags & 0xf; if (priority != 0) { message.Append(JournalFieldName.Priority, priority - 1); } if (((flags & LogFlags.DontAppendSyslogIdentifier) == LogFlags.None) && SyslogIdentifier != null) { message.Append(JournalFieldName.SyslogIdentifier, SyslogIdentifier); } List <ArraySegment <byte> > data = message.GetData(); int dataLength = data.Count; if (dataLength > MaxIovs) { // We should handle this the same way as EMSGSIZE, which we don't handle atm. ErrorWhileLogging("size exceeded"); return(LogResult.Size); } Span <IOVector> iovs = stackalloc IOVector[dataLength]; Span <GCHandle> handles = stackalloc GCHandle[dataLength]; for (int i = 0; i < data.Count; i++) { handles[i] = GCHandle.Alloc(data[i].Array, GCHandleType.Pinned); iovs[i].Base = handles[i].AddrOfPinnedObject(); iovs[i].Length = new IntPtr(data[i].Count); } int sendmsgFlags = 0; if ((flags & LogFlags.DropWhenBusy) != 0) { sendmsgFlags |= MSG_DONTWAIT; } LogResult result = LogResult.Success; fixed(IOVector *pIovs = &MemoryMarshal.GetReference(iovs)) { bool loop; do { loop = false; msghdr msg; msg.msg_iov = pIovs; msg.msg_iovlen = (SizeT)dataLength; int rv = sendmsg(socket.Handle.ToInt32(), &msg, sendmsgFlags).ToInt32(); if (rv < 0) { int errno = Marshal.GetLastWin32Error(); if (errno == EINTR) { loop = true; } else if (errno == EAGAIN) { result = LogResult.Busy; } else { result = LogResult.UnknownError; ErrorWhileLogging($"errno={errno}"); } } } while (loop); } for (int i = 0; i < handles.Length; i++) { handles[i].Free(); } return(result); }
/// <summary> /// Encode the span of binary data into UTF-8 encoded text represented as base64. /// </summary> /// <param name="bytes">The input span which contains binary data that needs to be encoded.</param> /// <param name="utf8">The output span which contains the result of the operation, i.e. the UTF-8 encoded text in base64.</param> /// <param name="bytesConsumed">The number of input bytes consumed during the operation. This can be used to slice the input for subsequent calls, if necessary.</param> /// <param name="bytesWritten">The number of bytes written into the output span. This can be used to slice the output for subsequent calls, if necessary.</param> /// <param name="isFinalBlock"><see langword="true"/> (default) when the input span contains the entire data to encode. /// Set to <see langword="true"/> when the source buffer contains the entirety of the data to encode. /// Set to <see langword="false"/> if this method is being called in a loop and if more input data may follow. /// At the end of the loop, call this (potentially with an empty source buffer) passing <see langword="true"/>.</param> /// <returns>It returns the OperationStatus enum values: /// - Done - on successful processing of the entire input span /// - DestinationTooSmall - if there is not enough space in the output span to fit the encoded input /// - NeedMoreData - only if <paramref name="isFinalBlock"/> is <see langword="false"/>, otherwise the output is padded if the input is not a multiple of 3 /// It does not return InvalidData since that is not possible for base64 encoding. /// </returns> public static unsafe OperationStatus EncodeToUtf8(ReadOnlySpan <byte> bytes, Span <byte> utf8, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true) { if (bytes.IsEmpty) { bytesConsumed = 0; bytesWritten = 0; return(OperationStatus.Done); } fixed(byte *srcBytes = &MemoryMarshal.GetReference(bytes)) fixed(byte *destBytes = &MemoryMarshal.GetReference(utf8)) { int srcLength = bytes.Length; int destLength = utf8.Length; int maxSrcLength; if (srcLength <= MaximumEncodeLength && destLength >= GetMaxEncodedToUtf8Length(srcLength)) { maxSrcLength = srcLength; } else { maxSrcLength = (destLength >> 2) * 3; } byte *src = srcBytes; byte *dest = destBytes; byte *srcEnd = srcBytes + (uint)srcLength; byte *srcMax = srcBytes + (uint)maxSrcLength; if (maxSrcLength >= 16) { byte *end = srcMax - 32; if (Avx2.IsSupported && (end >= src)) { Avx2Encode(ref src, ref dest, end, maxSrcLength, destLength, srcBytes, destBytes); if (src == srcEnd) { goto DoneExit; } } end = srcMax - 16; if (Ssse3.IsSupported && (end >= src)) { Ssse3Encode(ref src, ref dest, end, maxSrcLength, destLength, srcBytes, destBytes); if (src == srcEnd) { goto DoneExit; } } } ref byte encodingMap = ref MemoryMarshal.GetReference(EncodingMap); uint result = 0; srcMax -= 2; while (src < srcMax) { result = Encode(src, ref encodingMap); Unsafe.WriteUnaligned(dest, result); src += 3; dest += 4; } if (srcMax + 2 != srcEnd) { goto DestinationTooSmallExit; } if (!isFinalBlock) { if (src == srcEnd) { goto DoneExit; } goto NeedMoreData; } if (src + 1 == srcEnd) { result = EncodeAndPadTwo(src, ref encodingMap); Unsafe.WriteUnaligned(dest, result); src += 1; dest += 4; } else if (src + 2 == srcEnd) { result = EncodeAndPadOne(src, ref encodingMap); Unsafe.WriteUnaligned(dest, result); src += 2; dest += 4; } DoneExit: bytesConsumed = (int)(src - srcBytes); bytesWritten = (int)(dest - destBytes); return(OperationStatus.Done); DestinationTooSmallExit: bytesConsumed = (int)(src - srcBytes); bytesWritten = (int)(dest - destBytes); return(OperationStatus.DestinationTooSmall); NeedMoreData: bytesConsumed = (int)(src - srcBytes); bytesWritten = (int)(dest - destBytes); return(OperationStatus.NeedMoreData); }
public static int ComputeHash32(ReadOnlySpan <byte> data, ulong seed) => ComputeHash32(ref MemoryMarshal.GetReference(data), data.Length, (uint)seed, (uint)(seed >> 32));
internal static bool DsaSign(SafeDsaHandle dsa, ReadOnlySpan <byte> hash, Span <byte> refSignature, out int outSignatureLength) => DsaSign(dsa, ref MemoryMarshal.GetReference(hash), hash.Length, ref MemoryMarshal.GetReference(refSignature), out outSignatureLength);
public static void CastSpanUIntToUShort() { uint[] a = { 0x44332211, 0x88776655 }; Span <uint> span = new Span <uint>(a); Span <ushort> asUShort = MemoryMarshal.Cast <uint, ushort>(span); Assert.True(Unsafe.AreSame <ushort>(ref Unsafe.As <uint, ushort>(ref MemoryMarshal.GetReference(span)), ref MemoryMarshal.GetReference(asUShort))); asUShort.Validate <ushort>(0x2211, 0x4433, 0x6655, 0x8877); }
/// <summary> /// Transcodes the UTF-8 <paramref name="source"/> buffer to <paramref name="destination"/> as UTF-16. /// </summary> /// <remarks> /// If <paramref name="replaceInvalidSequences"/> is <see langword="true"/>, invalid UTF-8 sequences /// in <paramref name="source"/> will be replaced with U+FFFD in <paramref name="destination"/>, and /// this method will not return <see cref="OperationStatus.InvalidData"/>. /// </remarks> public static unsafe OperationStatus ToUtf16(ReadOnlySpan <byte> source, Span <char> destination, out int numBytesRead, out int numCharsWritten, bool replaceInvalidSequences = true, bool isFinalBlock = true) { // Throwaway span accesses - workaround for https://github.com/dotnet/coreclr/issues/23437 _ = source.Length; _ = destination.Length; // We'll be mutating these values throughout our loop. fixed(byte *pOriginalSource = &MemoryMarshal.GetReference(source)) fixed(char *pOriginalDestination = &MemoryMarshal.GetReference(destination)) { // We're going to bulk transcode as much as we can in a loop, iterating // every time we see bad data that requires replacement. OperationStatus operationStatus = OperationStatus.Done; byte * pInputBufferRemaining = pOriginalSource; char * pOutputBufferRemaining = pOriginalDestination; while (!source.IsEmpty) { // We've pinned the spans at the entry point to this method. // It's safe for us to use Unsafe.AsPointer on them during this loop. operationStatus = Utf8Utility.TranscodeToUtf16( pInputBuffer: (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(source)), inputLength: source.Length, pOutputBuffer: (char *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(destination)), outputCharsRemaining: destination.Length, pInputBufferRemaining: out pInputBufferRemaining, pOutputBufferRemaining: out pOutputBufferRemaining); // If we finished the operation entirely or we ran out of space in the destination buffer, // or if we need more input data and the caller told us that there's possibly more data // coming, return immediately. if (operationStatus <= OperationStatus.DestinationTooSmall || (operationStatus == OperationStatus.NeedMoreData && !isFinalBlock)) { break; } // We encountered invalid data, or we need more data but the caller told us we're // at the end of the stream. In either case treat this as truly invalid. // If the caller didn't tell us to replace invalid sequences, return immediately. if (!replaceInvalidSequences) { operationStatus = OperationStatus.InvalidData; // status code may have been NeedMoreData - force to be error break; } // We're going to attempt to write U+FFFD to the destination buffer. // Do we even have enough space to do so? destination = destination.Slice((int)(pOutputBufferRemaining - (char *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(destination)))); if (destination.IsEmpty) { operationStatus = OperationStatus.DestinationTooSmall; break; } destination[0] = (char)UnicodeUtility.ReplacementChar; destination = destination.Slice(1); // Now figure out how many bytes of the source we must skip over before we should retry // the operation. This might be more than 1 byte. source = source.Slice((int)(pInputBufferRemaining - (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(source)))); Debug.Assert(!source.IsEmpty, "Expected 'Done' if source is fully consumed."); Rune.DecodeFromUtf8(source, out _, out int bytesConsumedJustNow); source = source.Slice(bytesConsumedJustNow); operationStatus = OperationStatus.Done; // we patched the error - if we're about to break out of the loop this is a success case pInputBufferRemaining = (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(source)); pOutputBufferRemaining = (char *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(destination)); } // Not possible to make any further progress - report to our caller how far we got. numBytesRead = (int)(pInputBufferRemaining - pOriginalSource); numCharsWritten = (int)(pOutputBufferRemaining - pOriginalDestination); return(operationStatus); } }
internal static int CompareOrdinal(ReadOnlySpan <char> strA, ReadOnlySpan <char> strB) => SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(strA), strA.Length, ref MemoryMarshal.GetReference(strB), strB.Length);
/* * OperationStatus-based APIs for transcoding of chunked data. * This method is similar to Encoding.UTF8.GetBytes / GetChars but has a * different calling convention, different error handling mechanisms, and * different performance characteristics. * * If 'replaceInvalidSequences' is true, the method will replace any ill-formed * subsequence in the source with U+FFFD when transcoding to the destination, * then it will continue processing the remainder of the buffers. Otherwise * the method will return OperationStatus.InvalidData. * * If the method does return an error code, the out parameters will represent * how much of the data was successfully transcoded, and the location of the * ill-formed subsequence can be deduced from these values. * * If 'replaceInvalidSequences' is true, the method is guaranteed never to return * OperationStatus.InvalidData. If 'isFinalBlock' is true, the method is * guaranteed never to return OperationStatus.NeedMoreData. */ /// <summary> /// Transcodes the UTF-16 <paramref name="source"/> buffer to <paramref name="destination"/> as UTF-8. /// </summary> /// <remarks> /// If <paramref name="replaceInvalidSequences"/> is <see langword="true"/>, invalid UTF-16 sequences /// in <paramref name="source"/> will be replaced with U+FFFD in <paramref name="destination"/>, and /// this method will not return <see cref="OperationStatus.InvalidData"/>. /// </remarks> public static unsafe OperationStatus FromUtf16(ReadOnlySpan <char> source, Span <byte> destination, out int charsRead, out int bytesWritten, bool replaceInvalidSequences = true, bool isFinalBlock = true) { // Throwaway span accesses - workaround for https://github.com/dotnet/coreclr/issues/23437 _ = source.Length; _ = destination.Length; fixed(char *pOriginalSource = &MemoryMarshal.GetReference(source)) fixed(byte *pOriginalDestination = &MemoryMarshal.GetReference(destination)) { // We're going to bulk transcode as much as we can in a loop, iterating // every time we see bad data that requires replacement. OperationStatus operationStatus = OperationStatus.Done; char * pInputBufferRemaining = pOriginalSource; byte * pOutputBufferRemaining = pOriginalDestination; while (!source.IsEmpty) { // We've pinned the spans at the entry point to this method. // It's safe for us to use Unsafe.AsPointer on them during this loop. operationStatus = Utf8Utility.TranscodeToUtf8( pInputBuffer: (char *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(source)), inputLength: source.Length, pOutputBuffer: (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(destination)), outputBytesRemaining: destination.Length, pInputBufferRemaining: out pInputBufferRemaining, pOutputBufferRemaining: out pOutputBufferRemaining); // If we finished the operation entirely or we ran out of space in the destination buffer, // or if we need more input data and the caller told us that there's possibly more data // coming, return immediately. if (operationStatus <= OperationStatus.DestinationTooSmall || (operationStatus == OperationStatus.NeedMoreData && !isFinalBlock)) { break; } // We encountered invalid data, or we need more data but the caller told us we're // at the end of the stream. In either case treat this as truly invalid. // If the caller didn't tell us to replace invalid sequences, return immediately. if (!replaceInvalidSequences) { operationStatus = OperationStatus.InvalidData; // status code may have been NeedMoreData - force to be error break; } // We're going to attempt to write U+FFFD to the destination buffer. // Do we even have enough space to do so? destination = destination.Slice((int)(pOutputBufferRemaining - (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(destination)))); if (2 >= (uint)destination.Length) { operationStatus = OperationStatus.DestinationTooSmall; break; } destination[0] = 0xEF; // U+FFFD = [ EF BF BD ] in UTF-8 destination[1] = 0xBF; destination[2] = 0xBD; destination = destination.Slice(3); // Invalid UTF-16 sequences are always of length 1. Just skip the next character. source = source.Slice((int)(pInputBufferRemaining - (char *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(source))) + 1); operationStatus = OperationStatus.Done; // we patched the error - if we're about to break out of the loop this is a success case pInputBufferRemaining = (char *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(source)); pOutputBufferRemaining = (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(destination)); } // Not possible to make any further progress - report to our caller how far we got. charsRead = (int)(pInputBufferRemaining - pOriginalSource); bytesWritten = (int)(pOutputBufferRemaining - pOriginalDestination); return(operationStatus); } }
internal static bool EcdhDeriveKey(SafeEcKeyHandle ourKey, SafeEcKeyHandle peerKey, Span <byte> buffer, out int usedBuffer) => EcdhDeriveKey(ourKey, peerKey, ref MemoryMarshal.GetReference(buffer), buffer.Length, out usedBuffer);
public bool ContentEquals(ICharSequence other) { if (ReferenceEquals(this, other)) { return(true); } var thisLength = this.length; if (other is null || thisLength != other.Count) { return(false); } switch (other) { case AsciiString asciiStr: return(this.GetHashCode() == asciiStr.GetHashCode() && SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(this.AsciiSpan), ref MemoryMarshal.GetReference(asciiStr.AsciiSpan), thisLength)); case IHasAsciiSpan hasAscii: return(SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(this.AsciiSpan), ref MemoryMarshal.GetReference(hasAscii.AsciiSpan), thisLength)); case IHasUtf16Span hasUtf16: return(SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(this.Utf16Span), ref MemoryMarshal.GetReference(hasUtf16.Utf16Span), thisLength)); default: return(ContentEquals0(other)); } }