< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.MessageEncoder
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/MessageEncoder.cs
Line coverage
29%
Covered lines: 22
Uncovered lines: 53
Coverable lines: 75
Total lines: 225
Line coverage: 29.3%
Branch coverage
32%
Covered branches: 18
Total branches: 56
Branch coverage: 32.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
GetProperty()0%220%
ReadMessageAsync(...)100%11100%
ReadMessage(...)100%11100%
BufferMessageStreamAsync()0%880%
ReadMessageAsync()100%110%
ToString()100%110%
WriteMessage(...)100%11100%
IsContentTypeSupported(...)50%2266.66%
IsContentTypeSupported(...)38.09%424240%
IsCharSetSupported(...)100%110%
ThrowIfMismatchedMessageVersion(...)50%2240%
GetTraceSourceString()100%110%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/MessageEncoder.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.IO;
 6using System.Net.Http.Headers;
 7using System.Threading.Tasks;
 8using CoreWCF.Diagnostics;
 9
 10namespace CoreWCF.Channels
 11{
 12    public abstract class MessageEncoder
 13    {
 14        public abstract string ContentType { get; }
 15
 16        public abstract string MediaType { get; }
 17
 18        public abstract MessageVersion MessageVersion { get; }
 19
 20        public virtual T GetProperty<T>() where T : class
 21        {
 022            if (typeof(T) == typeof(FaultConverter))
 23            {
 024                return (T)(object)FaultConverter.GetDefaultFaultConverter(MessageVersion);
 25            }
 26
 027            return null;
 28        }
 29
 30        public Task<Message> ReadMessageAsync(Stream stream, int maxSizeOfHeaders)
 31        {
 253632            return ReadMessageAsync(stream, maxSizeOfHeaders, null);
 33        }
 34
 35        public abstract Task<Message> ReadMessageAsync(Stream stream, int maxSizeOfHeaders, string contentType);
 36
 37        public Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager)
 38        {
 19539            return ReadMessage(buffer, bufferManager, null);
 40        }
 41
 42        public abstract Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType);
 43
 44        // used for buffered streaming
 45        internal async Task<ArraySegment<byte>> BufferMessageStreamAsync(Stream stream, BufferManager bufferManager, int
 46        {
 047            byte[] buffer = bufferManager.TakeBuffer(ConnectionOrientedTransportDefaults.ConnectionBufferSize);
 048            int offset = 0;
 049            int currentBufferSize = Math.Min(buffer.Length, maxBufferSize);
 50
 051            while (offset < currentBufferSize)
 52            {
 053                int count = await stream.ReadAsync(buffer, offset, currentBufferSize - offset);
 054                if (count == 0)
 55                {
 056                    stream.Dispose();
 057                    break;
 58                }
 59
 060                offset += count;
 061                if (offset == currentBufferSize)
 62                {
 063                    if (currentBufferSize >= maxBufferSize)
 64                    {
 065                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 066                            MaxMessageSizeStream.CreateMaxReceivedMessageSizeExceededException(maxBufferSize));
 67                    }
 68
 069                    currentBufferSize = Math.Min(currentBufferSize * 2, maxBufferSize);
 070                    byte[] temp = bufferManager.TakeBuffer(currentBufferSize);
 071                    Buffer.BlockCopy(buffer, 0, temp, 0, offset);
 072                    bufferManager.ReturnBuffer(buffer);
 073                    buffer = temp;
 74                }
 75            }
 76
 077            return new ArraySegment<byte>(buffer, 0, offset);
 078        }
 79
 80        // used for buffered streaming
 81        internal virtual async Task<Message> ReadMessageAsync(Stream stream, BufferManager bufferManager, int maxBufferS
 82            string contentType)
 83        {
 084            return ReadMessage(await BufferMessageStreamAsync(stream, bufferManager, maxBufferSize), bufferManager, cont
 085        }
 86
 87        public override string ToString()
 88        {
 089            return ContentType;
 90        }
 91
 92        public abstract Task WriteMessageAsync(Message message, Stream stream);
 93
 94        public ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager)
 95        {
 53396            ArraySegment<byte> arraySegment = WriteMessage(message, maxMessageSize, bufferManager, 0);
 53397            return arraySegment;
 98        }
 99
 100        public abstract ArraySegment<byte> WriteMessage(Message message, int maxMessageSize,
 101            BufferManager bufferManager, int messageOffset);
 102
 103        public virtual bool IsContentTypeSupported(string contentType)
 104        {
 672105            if (contentType == null)
 106            {
 0107                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(contentType))
 108            }
 109
 672110            return IsContentTypeSupported(contentType, ContentType, MediaType);
 111        }
 112
 113        protected bool IsContentTypeSupported(string contentType, string supportedContentType, string supportedMediaType
 114        {
 713115            if (supportedContentType == contentType)
 116            {
 670117                return true;
 118            }
 119
 43120            if (contentType.Length > supportedContentType.Length &&
 43121                contentType.StartsWith(supportedContentType, StringComparison.Ordinal) &&
 43122                contentType[supportedContentType.Length] == ';')
 123            {
 8124                return true;
 125            }
 126
 127            // now check case-insensitively
 35128            if (contentType.StartsWith(supportedContentType, StringComparison.OrdinalIgnoreCase))
 129            {
 0130                if (contentType.Length == supportedContentType.Length)
 131                {
 0132                    return true;
 133                }
 0134                else if (contentType.Length > supportedContentType.Length)
 135                {
 0136                    char ch = contentType[supportedContentType.Length];
 137
 138                    // Linear Whitespace is allowed to appear between the end of one property and the semicolon.
 139                    // LWS = [CRLF]? (SP | HT)+
 0140                    if (ch == ';')
 141                    {
 0142                        return true;
 143                    }
 144
 145                    // Consume the [CRLF]?
 0146                    int i = supportedContentType.Length;
 0147                    if (ch == '\r' && contentType.Length > supportedContentType.Length + 1 && contentType[i + 1] == '\n'
 148                    {
 0149                        i += 2;
 0150                        ch = contentType[i];
 151                    }
 152
 153                    // Look for a ';' or nothing after (SP | HT)+
 0154                    if (ch == ' ' || ch == '\t')
 155                    {
 0156                        i++;
 0157                        while (i < contentType.Length)
 158                        {
 0159                            ch = contentType[i];
 0160                            if (ch != ' ' && ch != '\t')
 161                            {
 162                                break;
 163                            }
 164
 0165                            ++i;
 166                        }
 167                    }
 0168                    if (ch == ';' || i == contentType.Length)
 169                    {
 0170                        return true;
 171                    }
 172                }
 173            }
 174
 175            // sometimes we get a contentType that has parameters, but our encoders
 176            // merely expose the base content-type, so we will check a stripped version
 177            try
 178            {
 35179                MediaTypeHeaderValue parsedContentType = MediaTypeHeaderValue.Parse(contentType);
 180
 35181                if (supportedMediaType.Length > 0 && !supportedMediaType.Equals(parsedContentType.MediaType, StringCompa
 182                {
 15183                    return false;
 184                }
 185
 20186                if (!IsCharSetSupported(parsedContentType.CharSet))
 187                {
 0188                    return false;
 189                }
 20190            }
 0191            catch (FormatException)
 192            {
 193                // bad content type, so we definitely don't support it!
 0194                return false;
 195            }
 196
 20197            return true;
 15198        }
 199
 200        protected virtual bool IsCharSetSupported(string charset)
 201        {
 0202            return false;
 203        }
 204
 205        protected void ThrowIfMismatchedMessageVersion(Message message)
 206        {
 1708207            if (message.Version != MessageVersion)
 208            {
 0209                throw TraceUtility.ThrowHelperError(
 0210                    new ProtocolException(SR.Format(SR.EncoderMessageVersionMismatch, message.Version, MessageVersion)),
 0211                    message);
 212            }
 1708213        }
 214
 215        internal string GetTraceSourceString()
 216        {
 217            // if (_traceSourceString == null)
 218            // {
 219            //     _traceSourceString = Runtime.Diagnostics.DiagnosticTraceBase.CreateDefaultSourceString(this);
 220            // }
 221
 0222            return null;
 223        }
 224    }
 225}