Example #1
0
        /// <summary>
        /// Decodes the specified buffer as string.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <returns></returns>
        protected string DecodeString(ReadOnlySpan <byte> buffer)
        {
            string result = null;

            if (buffer.Length > 0)
            {
                result = ByteConverter.ToString(buffer);
            }
            return(result);
        }
Example #2
0
        /// <summary>
        /// Decodes the specified buffer as char.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <returns></returns>
        protected char DecodeChar(ReadOnlySpan <byte> buffer)
        {
            char result = default(char);

            if (buffer.Length > 0)
            {
                var str = ByteConverter.ToString(buffer);
                if (str.Length == 1)
                {
                    result = str[0];
                }
                else if (str.Length > 1)
                {
                    var msg = string.Format("Can not convert string \"{0}\" to char", str);
                    throw new InvalidCastException(msg);
                }
            }
            return(result);
        }
        public virtual T?Decode <T>(ReadOnlyMemory <byte> buffer, OpCode opcode)
        {
            object?value = default(T);

            var typeCode = Type.GetTypeCode(typeof(T));

            switch (typeCode)
            {
            case TypeCode.Empty:
            case TypeCode.String:
                value = DecodeString(buffer.Span);
                break;

            case TypeCode.Char:
                value = DecodeChar(buffer.Span);
                break;

            case TypeCode.Int16:
                if (buffer.Length > 0)
                {
                    value = ByteConverter.ToInt16(buffer.Span, false);
                }
                break;

            case TypeCode.UInt16:
                if (buffer.Length > 0)
                {
                    value = ByteConverter.ToUInt16(buffer.Span, false);
                }
                break;

            case TypeCode.Int32:
                if (buffer.Length > 0)
                {
                    value = ByteConverter.ToInt32(buffer.Span, false);
                }
                break;

            case TypeCode.UInt32:
                if (buffer.Length > 0)
                {
                    value = ByteConverter.ToUInt32(buffer.Span, false);
                }
                break;

            case TypeCode.Int64:
                if (buffer.Length > 0)
                {
                    value = ByteConverter.ToInt64(buffer.Span, false);
                }
                break;

            case TypeCode.UInt64:
                if (buffer.Length > 0)
                {
                    if (opcode == OpCode.Increment || opcode == OpCode.Decrement)
                    {
                        value = ByteConverter.ToUInt64(buffer.Span, true);
                    }
                    else
                    {
                        value = ByteConverter.ToUInt64(buffer.Span, false);
                    }
                }
                break;

            case TypeCode.Single:
                break;

            case TypeCode.Double:
                break;

            case TypeCode.Decimal:
                break;

            case TypeCode.DateTime:
                break;

            case TypeCode.Boolean:
                break;

            case TypeCode.SByte:
                break;

            case TypeCode.Byte:
                break;

            case TypeCode.Object:
                value = DeserializeAsJson <T>(buffer);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            return((T?)value);
        }
        public virtual void Encode <T>(Stream stream, T value, TypeCode typeCode, OpCode opcode)
        {
            switch (typeCode)
            {
            case TypeCode.Empty:
            case TypeCode.String:
            case TypeCode.Char:
                var str = Convert.ToString(value);
                using (var bufferOwner = MemoryPool <byte> .Shared.Rent(ByteConverter.GetStringByteCount(str)))
                {
                    var length = ByteConverter.FromString(str, bufferOwner.Memory.Span);
                    stream.Write(bufferOwner.Memory.Slice(0, length));
                }
                break;

            case TypeCode.Int16:
            {
                Span <byte> bytes = stackalloc byte[sizeof(short)];
                ByteConverter.FromInt16(Convert.ToInt16(value), bytes, false);
                WriteHelper(stream, bytes);
                break;
            }

            case TypeCode.UInt16:
            {
                Span <byte> bytes = stackalloc byte[sizeof(ushort)];
                ByteConverter.FromUInt16(Convert.ToUInt16(value), bytes, false);
                WriteHelper(stream, bytes);
                break;
            }

            case TypeCode.Int32:
            {
                Span <byte> bytes = stackalloc byte[sizeof(int)];
                ByteConverter.FromInt32(Convert.ToInt32(value), bytes, false);
                WriteHelper(stream, bytes);
                break;
            }

            case TypeCode.UInt32:
            {
                Span <byte> bytes = stackalloc byte[sizeof(uint)];
                ByteConverter.FromUInt32(Convert.ToUInt32(value), bytes, false);
                WriteHelper(stream, bytes);
                break;
            }

            case TypeCode.Int64:
            {
                Span <byte> bytes = stackalloc byte[sizeof(long)];
                ByteConverter.FromInt64(Convert.ToInt64(value), bytes, false);
                WriteHelper(stream, bytes);
                break;
            }

            case TypeCode.UInt64:
            {
                Span <byte> bytes = stackalloc byte[sizeof(ulong)];
                if (opcode == OpCode.Increment || opcode == OpCode.Decrement)
                {
                    ByteConverter.FromUInt64(Convert.ToUInt64(value), bytes, true);
                }
                else
                {
                    ByteConverter.FromUInt64(Convert.ToUInt64(value), bytes, false);
                }
                WriteHelper(stream, bytes);
                break;
            }

            case TypeCode.Single:
            case TypeCode.Double:
            case TypeCode.Decimal:
            case TypeCode.DateTime:
            case TypeCode.Boolean:
            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Object:
                SerializeAsJson(stream, value);
                break;

            default:
                throw new InvalidEnumArgumentException(nameof(typeCode), (int)typeCode, typeof(TypeCode));
            }
        }