Пример #1
0
        public static DisposableSegment GetBytesUsingThreadStaticBuffer(this Encoding encoding, string value)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            var length = value.Length;

            if (length == 0)
            {
                return(new DisposableSegment(null, __emptySegment));
            }

            var maxSize      = encoding.GetMaxByteCount(length);
            var rentedBuffer = ThreadStaticBuffer.RentBuffer(maxSize);

            var size    = encoding.GetBytes(value, 0, length, rentedBuffer.Bytes, 0);
            var segment = new ArraySegment <byte>(rentedBuffer.Bytes, 0, size);

            return(new DisposableSegment(rentedBuffer, segment));
        }
Пример #2
0
        /// <inheritdoc/>
        public override void WriteCString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            ThrowIfDisposed();

            var maxLength = CStringUtf8Encoding.GetMaxByteCount(value.Length) + 1;

            PrepareToWrite(maxLength);

            int actualLength;
            var segment = _buffer.AccessBackingBytes(_position);

            if (segment.Count >= maxLength)
            {
                actualLength = CStringUtf8Encoding.GetBytes(value, segment.Array, segment.Offset, Utf8Encodings.Strict);
                segment.Array[segment.Offset + actualLength] = 0;
            }
            else
            {
                // Compare to 128 to preserve original behavior
                const int maxLengthToUseCStringUtf8EncodingWith = 128;

                if (maxLength <= maxLengthToUseCStringUtf8EncodingWith)
                {
                    using var rentedBuffer = ThreadStaticBuffer.RentBuffer(maxLengthToUseCStringUtf8EncodingWith);
                    actualLength           = CStringUtf8Encoding.GetBytes(value, rentedBuffer.Bytes, 0, Utf8Encodings.Strict);

                    SetBytes(rentedBuffer.Bytes, actualLength);
                }
                else
                {
                    using var rentedSegmentEncoded = Utf8Encodings.Strict.GetBytesUsingThreadStaticBuffer(value);
                    var segmentEncoded = rentedSegmentEncoded.Segment;
                    actualLength = segmentEncoded.Count;

                    if (Array.IndexOf <byte>(segmentEncoded.Array, 0, 0, actualLength) != -1)
                    {
                        throw new ArgumentException("A CString cannot contain null bytes.", "value");
                    }

                    SetBytes(segmentEncoded.Array, actualLength);
                }

                void SetBytes(byte[] bytes, int lenght)
                {
                    _buffer.SetBytes(_position, bytes, 0, actualLength);
                    _buffer.SetByte(_position + actualLength, 0);
                }
            }

            SetPositionAfterWrite(_position + actualLength + 1);
        }
Пример #3
0
        /// <inheritdoc/>
        public override string ReadString(UTF8Encoding encoding)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }
            ThrowIfDisposed();

            var length = ReadInt32();

            if (length <= 0)
            {
                var message = string.Format("Invalid string length: {0}.", length);
                throw new FormatException(message);
            }

            var segment = _buffer.AccessBackingBytes(_position);

            if (segment.Count >= length)
            {
                ThrowIfEndOfStream(length);
                if (segment.Array[segment.Offset + length - 1] != 0)
                {
                    throw new FormatException("String is missing terminating null byte.");
                }
                _position += length;
                return(Utf8Helper.DecodeUtf8String(segment.Array, segment.Offset, length - 1, encoding));
            }
            else
            {
                using var rentedBuffer = ThreadStaticBuffer.RentBuffer(length);
                var bytes = rentedBuffer.Bytes;
                this.ReadBytes(bytes, 0, length);
                if (bytes[length - 1] != 0)
                {
                    throw new FormatException("String is missing terminating null byte.");
                }

                return(Utf8Helper.DecodeUtf8String(bytes, 0, length - 1, encoding));
            }
        }
        /// <inheritdoc/>
        public override string ReadString(UTF8Encoding encoding)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }
            ThrowIfDisposed();

            var length = ReadInt32();

            using var rentedBuffer = ThreadStaticBuffer.RentBuffer(length);
            var bytes = rentedBuffer.Bytes;

            this.ReadBytes(bytes, 0, length);
            if (bytes[length - 1] != 0)
            {
                throw new FormatException("String is missing terminating null byte.");
            }

            return(encoding.GetString(bytes, 0, length - 1));
        }
        /// <inheritdoc/>
        public override void WriteCString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            ThrowIfDisposed();


            // Compare to 128 to preserve original behavior
            const int maxLengthToUseCStringUtf8EncodingWith = 128;

            if (CStringUtf8Encoding.GetMaxByteCount(value.Length) <= maxLengthToUseCStringUtf8EncodingWith)
            {
                using var rentedBuffer = ThreadStaticBuffer.RentBuffer(maxLengthToUseCStringUtf8EncodingWith);

                var length = CStringUtf8Encoding.GetBytes(value, rentedBuffer.Bytes, 0, Utf8Encodings.Strict);
                WriteBytes(rentedBuffer.Bytes, length);
            }
            else
            {
                using var rentedSegment = Utf8Encodings.Strict.GetBytesUsingThreadStaticBuffer(value);
                var segment = rentedSegment.Segment;
                if (Array.IndexOf <byte>(segment.Array, 0, 0, segment.Count) != -1)
                {
                    throw new ArgumentException("A CString cannot contain null bytes.", "value");
                }

                WriteBytes(segment.Array, segment.Count);
            }

            void WriteBytes(byte[] bytes, int length)
            {
                _stream.Write(bytes, 0, length);
                _stream.WriteByte(0);
            }
        }