Beispiel #1
0
        /// <summary>已重载。</summary>
        /// <param name="stream">数据流</param>
        /// <param name="rwkind">序列化类型</param>
        protected override bool OnRead(Stream stream, RWKinds rwkind)
        {
            if (stream.Position == stream.Length)
            {
                return(true);
            }

            // 读取对象引用
            var r = stream.ReadByte();

            if (r <= 0)
            {
                return(true);
            }

            var ms = new MemoryStream();

            // 读取消息。对剩下的数据流,进行解压缩后,读取成为另一个消息
            using (var ds = new DeflateStream(stream, CompressionMode.Decompress, true))
            {
                //Message = Read(stream);
                // 必须全部复制到内存流,然后再读取,否则可能因为加密流不能读取位置和长度而导致消息读取失败
                ds.CopyTo(ms);
            }
            Message = Read(ms, rwkind);

            return(true);
        }
Beispiel #2
0
        /// <summary>序列化为数据流</summary>
        /// <param name="rwkind"></param>
        /// <returns></returns>
        public MemoryStream GetStream(RWKinds rwkind = RWKinds.Binary)
        {
            var ms = new MemoryStream();

            Write(ms, rwkind);
            ms.Position = 0;
            return(ms);
        }
Beispiel #3
0
        /// <summary>已重载。</summary>
        /// <param name="stream">数据流</param>
        /// <param name="rwkind">序列化类型</param>
        protected override void OnWrite(Stream stream, RWKinds rwkind)
        {
            // 因为不写对象引用,所以不能为null
            if (Data == null)
            {
                Data = new Byte[0];
            }

            base.OnWrite(stream, rwkind);
        }
Beispiel #4
0
 public static IWriter CreateWriter(RWKinds kind)
 {
     switch (kind)
     {
         case RWKinds.Binary:
             return new BinaryWriterX();
         case RWKinds.Xml:
             return new XmlWriterX();
         case RWKinds.Json:
             return new JsonWriter();
         default:
             break;
     }
     return null;
 }
Beispiel #5
0
 public static IReader CreateReader(RWKinds kind)
 {
     switch (kind)
     {
         case RWKinds.Binary:
             return new BinaryReaderX();
         case RWKinds.Xml:
             return new XmlReaderX();
         case RWKinds.Json:
             return new JsonReader();
         default:
             break;
     }
     return null;
 }
Beispiel #6
0
        /// <summary>把消息写入流中,默认调用序列化框架</summary>
        /// <param name="stream">数据流</param>
        /// <param name="rwkind">序列化类型</param>
        protected virtual void OnWrite(Stream stream, RWKinds rwkind)
        {
            var writer = RWService.CreateWriter(rwkind);

            writer.Stream = stream;
            OnReadWriteSet(writer);
            writer.Settings.Encoding = new UTF8Encoding(false);

            if (Debug)
            {
                writer.Debug = true;
                writer.EnableTraceStream();
            }

            writer.WriteObject(this);
            writer.Flush();
        }
Beispiel #7
0
        /// <summary>序列化当前消息到流中</summary>
        /// <param name="stream">数据流</param>
        /// <param name="rwkind">序列化类型</param>
        public void Write(Stream stream, RWKinds rwkind = RWKinds.Binary)
        {
            // 二进制增加头部
            if (rwkind == RWKinds.Binary)
            {
                // 基类写入编号,保证编号在最前面
                stream.WriteByte((Byte)Kind);
            }
            else
            {
                var n   = (Byte)Kind;
                var bts = Encoding.ASCII.GetBytes(n.ToString());
                stream.Write(bts, 0, bts.Length);
            }

            OnWrite(stream, rwkind);
        }
Beispiel #8
0
        public static IReader CreateReader(RWKinds kind)
        {
            switch (kind)
            {
            case RWKinds.Binary:
                return(new BinaryReaderX());

            case RWKinds.Xml:
                return(new XmlReaderX());

            case RWKinds.Json:
                return(new JsonReader());

            default:
                break;
            }
            return(null);
        }
Beispiel #9
0
        public static IWriter CreateWriter(RWKinds kind)
        {
            switch (kind)
            {
            case RWKinds.Binary:
                return(new BinaryWriterX());

            case RWKinds.Xml:
                return(new XmlWriterX());

            case RWKinds.Json:
                return(new JsonWriter());

            default:
                break;
            }
            return(null);
        }
Beispiel #10
0
        /// <summary>从流中读取消息内容,默认调用序列化框架</summary>
        /// <param name="stream"></param>
        /// <param name="rwkind"></param>
        /// <returns></returns>
        protected virtual Boolean OnRead(Stream stream, RWKinds rwkind)
        {
            var reader = RWService.CreateReader(rwkind);

            reader.Stream = stream;
            OnReadWriteSet(reader);

            if (Debug)
            {
                reader.Debug = true;
                reader.EnableTraceStream();
            }

            // 传msg进去,因为是引用类型,所以问题不大
            Object msg = this;

            return(reader.ReadObject(msg.GetType(), ref msg, null));
        }
Beispiel #11
0
        /// <summary>已重载。</summary>
        /// <param name="stream">数据流</param>
        /// <param name="rwkind">序列化类型</param>
        protected override void OnWrite(Stream stream, RWKinds rwkind)
        {
            if (Message == null)
            {
                // 对象引用
                stream.WriteByte(0);
                return;
            }

            // 对象引用。this为1,所以这里为2
            stream.WriteByte(2);

            // 写入消息。把消息写入压缩流,压缩后写入到输出流
            using (var ds = new DeflateStream(stream, CompressionMode.Compress, true))
            {
                Message.Write(ds, rwkind);
            }
        }
Beispiel #12
0
        ///// <summary>序列化当前消息到流中</summary>
        ///// <param name="stream"></param>
        //public void Write(Stream stream) { Write(stream, SerializationKinds.Binary); }

        /// <summary>序列化当前消息到流中</summary>
        /// <param name="stream"></param>
        /// <param name="rwkind"></param>
        public void Write(Stream stream, RWKinds rwkind = RWKinds.Binary)
        {
            //var writer = new BinaryWriterX(stream);
            var writer = RWService.CreateWriter(rwkind);

            writer.Stream = stream;
            Set(writer.Settings);
            writer.Settings.Encoding = new UTF8Encoding(false);

            if (Debug)
            {
                writer.Debug = true;
                writer.EnableTraceStream();
            }

            // 二进制增加头部
            if (rwkind == RWKinds.Binary)
            {
                // 判断并写入消息头
                if (_Header != null && _Header.UseHeader)
                {
                    Header.Write(writer.Stream);
                }

                // 基类写入编号,保证编号在最前面
                writer.Write((Byte)Kind);
            }
            else
            {
                var n   = (Byte)Kind;
                var bts = Encoding.ASCII.GetBytes(n.ToString());
                stream.Write(bts, 0, bts.Length);
            }

            writer.WriteObject(this);
            writer.Flush();
        }
Beispiel #13
0
        /// <summary>从流中读取消息</summary>
        /// <param name="stream">数据流</param>
        /// <param name="rwkind"></param>
        /// <param name="ignoreException">忽略异常。如果忽略异常,读取失败时将返回空,并还原数据流位置</param>
        /// <returns></returns>
        public static Message Read(Stream stream, RWKinds rwkind = RWKinds.Binary, Boolean ignoreException = false)
        {
            if (stream == null || stream.Length - stream.Position < 1)
            {
                return(null);
            }

            #region 根据第一个字节判断消息类型
            var start = stream.Position;
            // 消息类型,不同序列化方法的识别方式不同
            var  kind = (MessageKind)0;
            Type type = null;

            if (rwkind == RWKinds.Binary)
            {
                // 检查第一个字节
                var ch = stream.ReadByte();
                if (ch < 0)
                {
                    return(null);
                }

                kind = (MessageKind)ch;
            }
            else
            {
                // 前面的数字表示消息种类
                var  sb = new StringBuilder(32);
                Char c;
                while (true)
                {
                    c = (Char)stream.ReadByte();
                    if (c < '0' || c > '9')
                    {
                        break;
                    }
                    sb.Append(c);
                }
                // 多读了一个,退回去
                stream.Seek(-1, SeekOrigin.Current);
                kind = (MessageKind)Convert.ToByte(sb.ToString());
            }
            #endregion

            #region 识别消息类型
            if (type == null)
            {
                type = ObjectContainer.Current.ResolveType <Message>(kind);
            }
            if (type == null)
            {
                if (!ignoreException)
                {
                    throw new XException("无法识别的消息类型(Kind={0})!", kind);
                }

                stream.Position = start;
                return(null);
            }
            #endregion

            #region 读取消息
            var msg = type.CreateInstance(null) as Message;
            if (stream.Position == stream.Length)
            {
                return(msg);
            }

            try
            {
                var rs = msg.OnRead(stream, rwkind);
                if (!rs)
                {
                    throw new XException("数据格式不正确!");
                }

                return(msg);
            }
            catch (Exception ex)
            {
                if (ignoreException)
                {
                    stream.Position = start;
                    return(null);
                }

                var em = ex.Message;
                if (DumpStreamWhenError)
                {
                    stream.Position = start;
                    var bin = String.Format("{0:yyyy_MM_dd_HHmmss_fff}.msg", DateTime.Now);
                    //bin = Path.Combine(XTrace.LogPath, bin);
                    //if (!Path.IsPathRooted(bin)) bin = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, bin);
                    //bin = Path.GetFullPath(bin);
                    //var dir = Path.GetDirectoryName(bin);
                    //if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
                    bin = XTrace.LogPath.CombinePath(bin).EnsureDirectory(true);
                    File.WriteAllBytes(bin, stream.ReadBytes());
                    em = String.Format("已Dump数据流到{0}。{1}", bin, em);
                }
                throw new XException(ex, "无法从数据流中读取{0}(Kind={1})消息!{2}", type.Name, kind, em);
            }
            #endregion
        }
Beispiel #14
0
 /// <summary>已重载。</summary>
 /// <param name="stream">数据流</param>
 /// <param name="rwkind">序列化类型</param>
 protected override bool OnRead(Stream stream, RWKinds rwkind)
 {
     return(true);
 }
Beispiel #15
0
 /// <summary>已重载。</summary>
 /// <param name="stream">数据流</param>
 /// <param name="rwkind">序列化类型</param>
 protected override void OnWrite(Stream stream, RWKinds rwkind)
 {
 }
Beispiel #16
0
        ///// <summary>从流中读取消息</summary>
        ///// <param name="stream">数据流</param>
        ///// <returns></returns>
        //public static Message Read(Stream stream) { return Read(stream, false); }

        /// <summary>从流中读取消息</summary>
        /// <param name="stream">数据流</param>
        /// <param name="rwkind"></param>
        /// <param name="ignoreException">忽略异常。如果忽略异常,读取失败时将返回空,并还原数据流位置</param>
        /// <returns></returns>
        public static Message Read(Stream stream, RWKinds rwkind = RWKinds.Binary, Boolean ignoreException = false)
        {
            if (stream == null || stream.Length - stream.Position < 1)
            {
                return(null);
            }

            //var reader = new BinaryReaderX(stream);
            var reader = RWService.CreateReader(rwkind);

            reader.Stream = stream;
            Set(reader.Settings);

            if (Debug)
            {
                reader.Debug = true;
                reader.EnableTraceStream();
            }

            var start = stream.Position;
            // 消息类型,不同序列化方法的识别方式不同
            MessageKind   kind   = (MessageKind)0;
            Type          type   = null;
            MessageHeader header = null;

            if (rwkind == RWKinds.Binary)
            {
                // 检查第一个字节
                //var ch = reader.Reader.PeekChar();
                var ch = stream.ReadByte();
                if (ch < 0)
                {
                    return(null);
                }
                stream.Seek(-1, SeekOrigin.Current);

                var first = (Byte)ch;

                #region 消息头部扩展
                // 第一个字节的最高位决定是否扩展
                if (MessageHeader.IsValid(first))
                {
                    try
                    {
                        header = new MessageHeader();
                        header.Read(reader.Stream);
                    }
                    catch
                    {
                        stream.Position = start;
                        return(null);
                    }

                    // 如果使用了消息头,判断一下数据流长度是否满足
                    if (header.HasFlag(MessageHeader.Flags.Length) && header.Length > stream.Length - stream.Position)
                    {
                        stream.Position = start;
                        return(null);
                    }
                }
                #endregion

                // 读取了响应类型和消息类型后,动态创建消息对象
                kind = (MessageKind)(reader.ReadByte() & 0x7F);
            }
            else
            {
                // 前面的数字表示消息种类
                var  sb = new StringBuilder();
                Char c;
                while (true)
                {
                    c = (Char)stream.ReadByte();
                    if (c < '0' || c > '9')
                    {
                        break;
                    }
                    sb.Append(c);
                }
                // 多读了一个,退回去
                stream.Seek(-1, SeekOrigin.Current);
                kind = (MessageKind)Convert.ToByte(sb.ToString());

                //var s = stream.IndexOf(new Byte[] { (Byte)'<' });
                //if (s >= 0)
                //{
                //    var e = stream.IndexOf(new Byte[] { (Byte)'>' }, s + 1);
                //    if (e >= 0)
                //    {
                //        stream.Position = s;
                //        var msgName = Encoding.UTF8.GetString(stream.ReadBytes(e - s - 1));
                //        if (!String.IsNullOrEmpty(msgName) && !msgName.Contains(" ")) type = TypeX.GetType(msgName);
                //    }
                //}
                //var settings = new XmlReaderSettings();
                //settings.IgnoreWhitespace = true;
                //settings.IgnoreComments = true;
                //var xr = XmlReader.Create(stream, settings);
                //while (xr.NodeType != XmlNodeType.Element) { if (!xr.Read())break; }

                //stream.Position = start;
            }

            #region 识别消息类型
            if (type == null)
            {
                type = ObjectContainer.Current.ResolveType <Message>(kind);
            }
            if (type == null)
            {
                if (ignoreException)
                {
                    stream.Position = start;
                    return(null);
                }
                else
                {
                    throw new XException("无法识别的消息类型(Kind={0})!", kind);
                }
            }
            #endregion

            #region 读取消息
            Message msg;
            if (stream.Position == stream.Length)
            {
                msg = TypeX.CreateInstance(type, null) as Message;
            }
            else
            {
                try
                {
                    msg = reader.ReadObject(type) as Message;
                    if (msg == null)
                    {
                        throw new XException("数据格式不正确!");
                    }
                }
                catch (Exception ex)
                {
                    if (ignoreException)
                    {
                        stream.Position = start;
                        return(null);
                    }

                    var em = ex.Message;
                    if (DumpStreamWhenError)
                    {
                        stream.Position = start;
                        var bin = String.Format("{0:yyyy_MM_dd_HHmmss_fff}.msg", DateTime.Now);
                        bin = Path.Combine(XTrace.LogPath, bin);
                        if (!Path.IsPathRooted(bin))
                        {
                            bin = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, bin);
                        }
                        bin = Path.GetFullPath(bin);
                        var dir = Path.GetDirectoryName(bin);
                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }
                        File.WriteAllBytes(bin, stream.ReadBytes());
                        em = String.Format("已Dump数据流到{0}。{1}", bin, em);
                    }
                    var ex2 = new XException("无法从数据流中读取{0}(Kind={1})消息!{2}", type.Name, kind, em);
                    throw ex2;
                }
            }
            msg.Header = header;
            return(msg);

            #endregion
        }