Merge pull request #5198 from BrzVlad/fix-binprot-stats
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / BinaryMessageEncoder.cs
index 49b8a4f6df40a54fb0be111ae445e079df453b11..fc379b2e588c954c49948dd5a3c7285d66a6a69f 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Author: Atsushi Enomoto (atsushi@ximian.com)
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005,2009 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -39,19 +39,25 @@ namespace System.ServiceModel.Channels
                {
                }
 
-               public BinaryMessageEncoder (BinaryMessageEncoderFactory owner)
+               public BinaryMessageEncoder (BinaryMessageEncoderFactory owner, bool session)
                {
                        this.owner = owner;
+                       this.session = session;
                }
 
                BinaryMessageEncoderFactory owner;
+               bool session;
+
+               internal bool UseSession {
+                       get { return session; }
+               }
 
                public override string ContentType {
-                       get { return "application/soap+msbin1"; }
+                       get { return MediaType; }
                }
 
                public override string MediaType {
-                       get { return "application/soap+msbin1"; }
+                       get { return session ? "application/soap+msbinsession1" : "application/soap+msbin1"; }
                }
 
                public override MessageVersion MessageVersion {
@@ -62,28 +68,60 @@ namespace System.ServiceModel.Channels
                public override Message ReadMessage (ArraySegment<byte> buffer,
                        BufferManager bufferManager, string contentType)
                {
+                       if (contentType != null && contentType != ContentType)
+                               throw new ProtocolException ("Only content type 'application/soap+msbin1' is allowed.");
+
+                       // FIXME: retrieve reader session and message body.
+
+                       throw new NotImplementedException ();
+
+/*
                        // FIXME: use bufferManager
                        return Message.CreateMessage (
                                XmlDictionaryReader.CreateBinaryReader (
                                        buffer.Array, buffer.Offset, buffer.Count,
-                                       new XmlDictionary (),
+                                       soap_dictionary,
                                        owner != null ? owner.Owner.ReaderQuotas : new XmlDictionaryReaderQuotas ()),
                                int.MaxValue, MessageVersion);
+*/
                }
 
+               // It is sort of nasty hack, but there is no other way to provide reader/writer session from TCP stream.
+               internal XmlBinaryReaderSession CurrentReaderSession { get; set; }
+               internal XmlBinaryWriterSession CurrentWriterSession { get; set; }
+
                public override Message ReadMessage (Stream stream,
                        int maxSizeOfHeaders, string contentType)
                {
-                       return Message.CreateMessage (
-                               XmlDictionaryReader.CreateBinaryReader (stream, owner != null ? owner.Owner.ReaderQuotas : new XmlDictionaryReaderQuotas ()),
+                       if (contentType != null && contentType != ContentType)
+                               throw new ProtocolException ("Only content type 'application/soap+msbin1' is allowed.");
+
+                       // FIXME: remove this extraneous buffering. It is somehow required for HTTP + binary encoding binding. The culprit is probably in binary xml reader or writer, but not sure.
+                       if (!stream.CanSeek) {
+                               var tmpms = new MemoryStream ();
+                               var bytes = new byte [4096];
+                               int len;
+                               do {
+                                       len = stream.Read (bytes, 0, bytes.Length);
+                                       tmpms.Write (bytes, 0, len);
+                               } while (len > 0);
+                               tmpms.Seek (0, SeekOrigin.Begin);
+                               stream = tmpms;
+                       }
+
+                       var ret = Message.CreateMessage (
+                               XmlDictionaryReader.CreateBinaryReader (stream, Constants.SoapDictionary, owner != null ? owner.Owner.ReaderQuotas : new XmlDictionaryReaderQuotas (), session ? CurrentReaderSession : null),
                                maxSizeOfHeaders, MessageVersion);
+                       ret.Properties.Encoder = this;
+                       return ret;
                }
 
                public override void WriteMessage (Message message, Stream stream)
                {
                        VerifyMessageVersion (message);
 
-                       message.WriteMessage (XmlDictionaryWriter.CreateBinaryWriter (stream));
+                       using (var xw = XmlDictionaryWriter.CreateBinaryWriter (stream, Constants.SoapDictionary, session ? CurrentWriterSession : null, false))
+                               message.WriteMessage (xw);
                }
 
                [MonoTODO]