< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.DefaultMessageBuffer
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/MessageBuffer.cs
Line coverage
60%
Covered lines: 24
Uncovered lines: 16
Coverable lines: 40
Total lines: 344
Line coverage: 60%
Branch coverage
50%
Covered branches: 11
Total branches: 22
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)75%4484.61%
Close()0%660%
CreateMessage()66.66%121275%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/MessageBuffer.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.IO;
 7using System.Xml;
 8
 9namespace CoreWCF.Channels
 10{
 11    public abstract class MessageBuffer : System.IDisposable
 12    {
 13        public abstract int BufferSize { get; }
 14
 15        void IDisposable.Dispose()
 16        {
 17            Close();
 18        }
 19
 20        public abstract void Close();
 21
 22        public virtual void WriteMessage(Stream stream)
 23        {
 24            if (stream == null)
 25            {
 26                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(stream));
 27            }
 28
 29            Message message = CreateMessage();
 30            using (message)
 31            {
 32                XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream, XD.Dictionary, null, false);
 33                using (writer)
 34                {
 35                    message.WriteMessage(writer);
 36                }
 37            }
 38        }
 39
 40        public virtual string MessageContentType
 41        {
 42            get { return FramingEncodingString.Binary; }
 43        }
 44
 45        public abstract Message CreateMessage();
 46
 47        internal Exception CreateBufferDisposedException()
 48        {
 49            return new ObjectDisposedException("", SR.MessageBufferIsClosed);
 50        }
 51
 52        //public XPathNavigator CreateNavigator()
 53        //{
 54        //    return CreateNavigator(int.MaxValue, XmlSpace.None);
 55        //}
 56
 57        //public XPathNavigator CreateNavigator(int nodeQuota)
 58        //{
 59        //    return CreateNavigator(nodeQuota, XmlSpace.None);
 60        //}
 61
 62        //public XPathNavigator CreateNavigator(XmlSpace space)
 63        //{
 64        //    return CreateNavigator(int.MaxValue, space);
 65        //}
 66
 67        //public XPathNavigator CreateNavigator(int nodeQuota, XmlSpace space)
 68        //{
 69        //    if (nodeQuota <= 0)
 70        //        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("nodeQuota",
 71
 72        //    return new SeekableMessageNavigator(this.CreateMessage(), nodeQuota, space, true, true);
 73        //}
 74    }
 75
 76
 77    internal class DefaultMessageBuffer : MessageBuffer
 78    {
 79        private readonly XmlBuffer _msgBuffer;
 80        private readonly KeyValuePair<string, object>[] _properties;
 81        private readonly bool[] _understoodHeaders;
 82        private bool _closed;
 83        private readonly MessageVersion _version;
 84        private readonly Uri _to;
 85        private readonly string _action;
 86        private readonly bool _isNullMessage;
 87
 17888        public DefaultMessageBuffer(Message message, XmlBuffer msgBuffer)
 89        {
 17890            _msgBuffer = msgBuffer;
 17891            _version = message.Version;
 17892            _isNullMessage = message is NullMessage;
 93
 17894            _properties = new KeyValuePair<string, object>[message.Properties.Count];
 17895            ((ICollection<KeyValuePair<string, object>>)message.Properties).CopyTo(_properties, 0);
 17896            _understoodHeaders = new bool[message.Headers.Count];
 71297            for (int i = 0; i < _understoodHeaders.Length; ++i)
 98            {
 17899                _understoodHeaders[i] = message.Headers.IsUnderstood(i);
 100            }
 101
 102            //CSDMain 17837: CreateBufferedCopy should have code to copy over the To and Action headers
 178103            if (_version == MessageVersion.None)
 104            {
 0105                _to = message.Headers.To;
 0106                _action = message.Headers.Action;
 107            }
 178108        }
 109
 110        private object ThisLock
 111        {
 178112            get { return _msgBuffer; }
 113        }
 114
 115        public override int BufferSize
 116        {
 0117            get { return _msgBuffer.BufferSize; }
 118        }
 119
 120        public override void Close()
 121        {
 0122            lock (ThisLock)
 123            {
 0124                if (_closed)
 125                {
 0126                    return;
 127                }
 128
 0129                _closed = true;
 0130                for (int i = 0; i < _properties.Length; i++)
 131                {
 0132                    if (_properties[i].Value is IDisposable disposable)
 133                    {
 0134                        disposable.Dispose();
 135                    }
 136                }
 0137            }
 0138        }
 139
 140        public override Message CreateMessage()
 141        {
 178142            if (_closed)
 143            {
 0144                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
 145            }
 146
 147            Message msg;
 178148            if (_isNullMessage)
 149            {
 0150                msg = new NullMessage();
 151            }
 152            else
 153            {
 178154                msg = Message.CreateMessage(_msgBuffer.GetReader(0), int.MaxValue, _version);
 155            }
 156
 178157            lock (ThisLock)
 158            {
 178159                msg.Properties.CopyProperties(_properties);
 178160            }
 161
 712162            for (int i = 0; i < _understoodHeaders.Length; ++i)
 163            {
 178164                if (_understoodHeaders[i])
 165                {
 178166                    msg.Headers.AddUnderstood(i);
 167                }
 168            }
 169
 178170            if (_to != null)
 171            {
 0172                msg.Headers.To = _to;
 173            }
 174
 178175            if (_action != null)
 176            {
 0177                msg.Headers.Action = _action;
 178            }
 179
 178180            return msg;
 181        }
 182    }
 183
 184    internal class BufferedMessageBuffer : MessageBuffer
 185    {
 186        private IBufferedMessageData _messageData;
 187        private readonly KeyValuePair<string, object>[] _properties;
 188        private bool _closed;
 189        private readonly bool[] _understoodHeaders;
 190        private readonly bool _understoodHeadersModified;
 191
 192        public BufferedMessageBuffer(IBufferedMessageData messageData,
 193            KeyValuePair<string, object>[] properties, bool[] understoodHeaders, bool understoodHeadersModified)
 194        {
 195            _messageData = messageData;
 196            _properties = properties;
 197            _understoodHeaders = understoodHeaders;
 198            _understoodHeadersModified = understoodHeadersModified;
 199            messageData.Open();
 200        }
 201
 202        public override int BufferSize
 203        {
 204            get
 205            {
 206                lock (ThisLock)
 207                {
 208                    if (_closed)
 209                    {
 210                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
 211                    }
 212
 213                    return _messageData.Buffer.Count;
 214                }
 215            }
 216        }
 217
 218        public override void WriteMessage(Stream stream)
 219        {
 220            if (stream == null)
 221            {
 222                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(stream));
 223            }
 224
 225            lock (ThisLock)
 226            {
 227                if (_closed)
 228                {
 229                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
 230                }
 231
 232                ArraySegment<byte> buffer = _messageData.Buffer;
 233                stream.Write(buffer.Array, buffer.Offset, buffer.Count);
 234            }
 235        }
 236
 237        public override string MessageContentType
 238        {
 239            get
 240            {
 241                lock (ThisLock)
 242                {
 243                    if (_closed)
 244                    {
 245                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
 246                    }
 247
 248                    return _messageData.MessageEncoder.ContentType;
 249                }
 250            }
 251        }
 252
 253        private object ThisLock { get; } = new object();
 254
 255        public override void Close()
 256        {
 257            lock (ThisLock)
 258            {
 259                if (!_closed)
 260                {
 261                    _closed = true;
 262                    _messageData.Close();
 263                    _messageData = null;
 264                }
 265            }
 266        }
 267
 268        public override Message CreateMessage()
 269        {
 270            lock (ThisLock)
 271            {
 272                if (_closed)
 273                {
 274                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
 275                }
 276
 277                RecycledMessageState recycledMessageState = _messageData.TakeMessageState();
 278                if (recycledMessageState == null)
 279                {
 280                    recycledMessageState = new RecycledMessageState();
 281                }
 282
 283                BufferedMessage bufferedMessage = new BufferedMessage(_messageData, recycledMessageState, _understoodHea
 284                bufferedMessage.Properties.CopyProperties(_properties);
 285                _messageData.Open();
 286                return bufferedMessage;
 287            }
 288        }
 289    }
 290
 291    internal class BodyWriterMessageBuffer : MessageBuffer
 292    {
 293        public BodyWriterMessageBuffer(MessageHeaders headers,
 294            KeyValuePair<string, object>[] properties, BodyWriter bodyWriter)
 295        {
 296            BodyWriter = bodyWriter;
 297            Headers = new MessageHeaders(headers);
 298            Properties = properties;
 299        }
 300
 301        protected object ThisLock { get; } = new object();
 302
 303        public override int BufferSize
 304        {
 305            get { return 0; }
 306        }
 307
 308        public override void Close()
 309        {
 310            lock (ThisLock)
 311            {
 312                if (!Closed)
 313                {
 314                    Closed = true;
 315                    BodyWriter = null;
 316                    Headers = null;
 317                    Properties = null;
 318                }
 319            }
 320        }
 321
 322        public override Message CreateMessage()
 323        {
 324            lock (ThisLock)
 325            {
 326                if (Closed)
 327                {
 328                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
 329                }
 330
 331                return new BodyWriterMessage(Headers, Properties, BodyWriter);
 332            }
 333        }
 334
 335        protected BodyWriter BodyWriter { get; private set; }
 336
 337        protected MessageHeaders Headers { get; private set; }
 338
 339        protected KeyValuePair<string, object>[] Properties { get; private set; }
 340
 341        protected bool Closed { get; private set; }
 342    }
 343}
 344