Пример #1
0
        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));
        }
Пример #2
0
        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);
        }
Пример #3
0
        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)));
        }
Пример #4
0
        /// <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));
Пример #6
0
 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);
                                }
                            }
                        });
Пример #8
0
        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);
Пример #10
0
 private static int GetExtraBlBits(int i)
 => Unsafe.Add(ref MemoryMarshal.GetReference(ExtraBlbits), i);
Пример #11
0
        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));
                }
            }
        }
Пример #12
0
 private static byte GetBitLength(int i)
 => Unsafe.Add(ref MemoryMarshal.GetReference(BlOrder), i);
Пример #13
0
 public static int GetLengthCode(int match)
 => Unsafe.Add(ref MemoryMarshal.GetReference(LengthCode), match);
Пример #14
0
 public static int GetBaseLength(int match)
 => Unsafe.Add(ref MemoryMarshal.GetReference(BaseLength), match);
Пример #15
0
 private void WriteControlUtf8(byte value)
 {
     MemoryMarshal.GetReference(EnsureBuffer(1)) = value;
     _bufferWriter.Advance(1);
 }
Пример #16
0
        /// <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);
        }
Пример #17
0
 /// <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);
 }
Пример #18
0
        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;
        }
Пример #19
0
 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);
Пример #20
0
        /// <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));
Пример #21
0
        /// <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);
        }
Пример #22
0
        /// <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);
            }
Пример #23
0
 public static int ComputeHash32(ReadOnlySpan <byte> data, ulong seed) => ComputeHash32(ref MemoryMarshal.GetReference(data), data.Length, (uint)seed, (uint)(seed >> 32));
Пример #24
0
 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);
Пример #25
0
        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);
        }
Пример #26
0
        /// <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);
            }
        }
Пример #27
0
 internal static int CompareOrdinal(ReadOnlySpan <char> strA, ReadOnlySpan <char> strB)
 => SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(strA), strA.Length, ref MemoryMarshal.GetReference(strB), strB.Length);
Пример #28
0
        /*
         * 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);
            }
        }
Пример #29
0
 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);
Пример #30
0
        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));
            }
        }