Skip to content

Commit

Permalink
update code
Browse files Browse the repository at this point in the history
  • Loading branch information
afifi-ins committed Nov 2, 2023
1 parent 7fd2c7a commit 213e27b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,69 +12,54 @@ namespace Microsoft.Samples.GZipEncoder
//This class is used to create the custom encoder (GZipMessageEncoder)
internal class GZipMessageEncoderFactory : MessageEncoderFactory
{
MessageEncoder encoder;
private readonly MessageEncoder _encoder;

//The GZip encoder wraps an inner encoder
//We require a factory to be passed in that will create this inner encoder
public GZipMessageEncoderFactory(MessageEncoderFactory messageEncoderFactory)
{
if (messageEncoderFactory == null)
throw new ArgumentNullException("messageEncoderFactory", "A valid message encoder factory must be passed to the GZipEncoder");
encoder = new GZipMessageEncoder(messageEncoderFactory.Encoder);
_encoder = new GZipMessageEncoder(messageEncoderFactory.Encoder);
}

//The service framework uses this property to obtain an encoder from this encoder factory
public override MessageEncoder Encoder
{
get { return encoder; }
}
public override MessageEncoder Encoder => _encoder;

public override MessageVersion MessageVersion
{
get { return encoder.MessageVersion; }
}
public override MessageVersion MessageVersion => _encoder.MessageVersion;

//This is the actual GZip encoder
class GZipMessageEncoder : MessageEncoder
private class GZipMessageEncoder : MessageEncoder
{
static string GZipContentType = "application/x-gzip";
private const string GZipContentType = "application/x-gzip";

//This implementation wraps an inner encoder that actually converts a WCF Message
//into textual XML, binary XML or some other format. This implementation then compresses the results.
//The opposite happens when reading messages.
//This member stores this inner encoder.
MessageEncoder innerEncoder;
private readonly MessageEncoder _innerEncoder;

//We require an inner encoder to be supplied (see comment above)
internal GZipMessageEncoder(MessageEncoder messageEncoder)
: base()
{
if (messageEncoder == null)
throw new ArgumentNullException("messageEncoder", "A valid message encoder must be passed to the GZipEncoder");
innerEncoder = messageEncoder;
_innerEncoder = messageEncoder;
}

public override string ContentType
{
get { return GZipContentType; }
}
public override string ContentType => GZipContentType;

public override string MediaType
{
get { return GZipContentType; }
}
public override string MediaType => GZipContentType;

//SOAP version to use - we delegate to the inner encoder for this
public override MessageVersion MessageVersion
{
get { return innerEncoder.MessageVersion; }
}
public override MessageVersion MessageVersion => _innerEncoder.MessageVersion;

//Helper method to compress an array of bytes
static ArraySegment<byte> CompressBuffer(ArraySegment<byte> buffer, BufferManager bufferManager, int messageOffset)
private static ArraySegment<byte> CompressBuffer(ArraySegment<byte> buffer, BufferManager bufferManager, int messageOffset)
{
MemoryStream memoryStream = new MemoryStream();

using (GZipStream gzStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
{
gzStream.Write(buffer.Array, buffer.Offset, buffer.Count);
Expand All @@ -93,7 +78,7 @@ static ArraySegment<byte> CompressBuffer(ArraySegment<byte> buffer, BufferManage
}

//Helper method to decompress an array of bytes
static ArraySegment<byte> DecompressBuffer(ArraySegment<byte> buffer, BufferManager bufferManager)
private static ArraySegment<byte> DecompressBuffer(ArraySegment<byte> buffer, BufferManager bufferManager)
{
MemoryStream memoryStream = new MemoryStream(buffer.Array, buffer.Offset, buffer.Count);
MemoryStream decompressedStream = new MemoryStream();
Expand Down Expand Up @@ -130,7 +115,7 @@ public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager buf
//Decompress the buffer
ArraySegment<byte> decompressedBuffer = DecompressBuffer(buffer, bufferManager);
//Use the inner encoder to decode the decompressed buffer
Message returnMessage = innerEncoder.ReadMessage(decompressedBuffer, bufferManager);
Message returnMessage = _innerEncoder.ReadMessage(decompressedBuffer, bufferManager);
returnMessage.Properties.Encoder = this;
return returnMessage;
}
Expand All @@ -139,7 +124,7 @@ public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager buf
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
{
//Use the inner encoder to encode a Message into a buffered byte array
ArraySegment<byte> buffer = innerEncoder.WriteMessage(message, maxMessageSize, bufferManager, 0);
ArraySegment<byte> buffer = _innerEncoder.WriteMessage(message, maxMessageSize, bufferManager, 0);
//Compress the resulting byte array
return CompressBuffer(buffer, bufferManager, messageOffset);
}
Expand All @@ -150,14 +135,14 @@ public override Message ReadMessage(System.IO.Stream stream, int maxSizeOfHeader
//This will ensure that the inner stream gets closed when the message gets closed, which
//will ensure that resources are available for reuse/release.
GZipStream gzStream = new GZipStream(stream, CompressionMode.Decompress, false);
return innerEncoder.ReadMessage(gzStream, maxSizeOfHeaders);
return _innerEncoder.ReadMessage(gzStream, maxSizeOfHeaders);
}

public override void WriteMessage(Message message, System.IO.Stream stream)
{
using (GZipStream gzStream = new GZipStream(stream, CompressionMode.Compress, true))
{
innerEncoder.WriteMessage(message, gzStream);
_innerEncoder.WriteMessage(message, gzStream);
}

// innerEncoder.WriteMessage(message, gzStream) depends on that it can flush data by flushing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,80 +11,63 @@
namespace Microsoft.Samples.GZipEncoder
{
// This is constants for GZip message encoding policy.
static class GZipMessageEncodingPolicyConstants
internal static class GZipMessageEncodingPolicyConstants
{
public const string GZipEncodingName = "GZipEncoding";
public const string GZipEncodingNamespace = "http://schemas.microsoft.com/ws/06/2004/mspolicy/netgzip1";
public const string GZipEncodingPrefix = "gzip";
}

//This is the binding element that, when plugged into a custom binding, will enable the GZip encoder
#if NET462_OR_GREATER
public sealed class GZipMessageEncodingBindingElement
: MessageEncodingBindingElement //BindingElement
, IPolicyExportExtension
#elif NET6_0_OR_GREATER
public sealed class GZipMessageEncodingBindingElement
: MessageEncodingBindingElement //BindingElement
#if NET462_OR_GREATER
, IPolicyExportExtension
#endif
{

//We will use an inner binding element to store information required for the inner encoder
MessageEncodingBindingElement innerBindingElement;
//By default, use the default text encoder as the inner encoder
public GZipMessageEncodingBindingElement()
: this(new TextMessageEncodingBindingElement()) { }

//By default, use the default text encoder as the inner encoder
public GZipMessageEncodingBindingElement()
: this(new TextMessageEncodingBindingElement()) { }
public GZipMessageEncodingBindingElement(MessageEncodingBindingElement messageEncoderBindingElement) => InnerMessageEncodingBindingElement = messageEncoderBindingElement;

public GZipMessageEncodingBindingElement(MessageEncodingBindingElement messageEncoderBindingElement)
{
this.innerBindingElement = messageEncoderBindingElement;
}

public MessageEncodingBindingElement InnerMessageEncodingBindingElement
{
get { return innerBindingElement; }
set { innerBindingElement = value; }
}
//We will use an inner binding element to store information required for the inner encoder
public MessageEncodingBindingElement InnerMessageEncodingBindingElement { get; set; }

//Main entry point into the encoder binding element. Called by WCF to get the factory that will create the
//message encoder
public override MessageEncoderFactory CreateMessageEncoderFactory()
{
return new GZipMessageEncoderFactory(innerBindingElement.CreateMessageEncoderFactory());
}
//Main entry point into the encoder binding element. Called by WCF to get the factory that will create the
//message encoder
public override MessageEncoderFactory CreateMessageEncoderFactory() => new GZipMessageEncoderFactory(InnerMessageEncodingBindingElement.CreateMessageEncoderFactory());

public override MessageVersion MessageVersion
{
get { return innerBindingElement.MessageVersion; }
set { innerBindingElement.MessageVersion = value; }
}
public override MessageVersion MessageVersion
{
get => InnerMessageEncodingBindingElement.MessageVersion;
set => InnerMessageEncodingBindingElement.MessageVersion = value;
}

public override BindingElement Clone()
{
return new GZipMessageEncodingBindingElement(this.innerBindingElement);
}
public override BindingElement Clone() => new GZipMessageEncodingBindingElement(this.InnerMessageEncodingBindingElement);

public override T GetProperty<T>(BindingContext context)
{
if (typeof(T) == typeof(XmlDictionaryReaderQuotas))
public override T GetProperty<T>(BindingContext context)
{
return innerBindingElement.GetProperty<T>(context);
if (typeof(T) == typeof(XmlDictionaryReaderQuotas))
{
return InnerMessageEncodingBindingElement.GetProperty<T>(context);
}
else
{
return base.GetProperty<T>(context);
}
}
else

public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
return base.GetProperty<T>(context);
}
}
if (context == null)
throw new ArgumentNullException("context");

public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
if (context == null)
throw new ArgumentNullException("context");
context.BindingParameters.Add(this);
return context.BuildInnerChannelFactory<TChannel>();
}

context.BindingParameters.Add(this);
return context.BuildInnerChannelFactory<TChannel>();
}
#if NET462_OR_GREATER
public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
Expand Down Expand Up @@ -117,7 +100,7 @@ void IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConver
GZipMessageEncodingPolicyConstants.GZipEncodingNamespace));
}
#endif
}
}

#if NET462_OR_GREATER
//This class is necessary to be able to plug in the GZip encoder binding element through
Expand All @@ -129,18 +112,15 @@ public GZipMessageEncodingElement()
}

//Called by the WCF to discover the type of binding element this config section enables
public override Type BindingElementType
{
get { return typeof(GZipMessageEncodingBindingElement); }
}
public override Type BindingElementType => typeof(GZipMessageEncodingBindingElement);

//The only property we need to configure for our binding element is the type of
//inner encoder to use. Here, we support text and binary.
[ConfigurationProperty("innerMessageEncoding", DefaultValue = "textMessageEncoding")]
public string InnerMessageEncoding
{
get { return (string)base["innerMessageEncoding"]; }
set { base["innerMessageEncoding"] = value; }
get => (string)base["innerMessageEncoding"];
set => base["innerMessageEncoding"] = value;
}

//Called by the WCF to apply the configuration settings (the property above) to the binding element
Expand Down

0 comments on commit 213e27b

Please sign in to comment.