예제 #1
0
        /// <summary>
        /// Returns the next record to write in the DIME message. If the length of the payload data is not
        /// known upfront then use contentLength==-1 to specify chunked records. Otherwise the amount of data
        /// written to the record must match the content length specified. When the DimeWriter is closed then the
        /// message end flag is automatically set on the last record. If writing in non-chunked mode then
        /// an empty terminating record with TNF=TypeFormatEnum.None will be automatically sent when the
        /// DimeWriter is closed.
        /// </summary>
        /// <param name="id">The unique identifier of the record in the form of a URI.</param>
        /// <param name="type">The type of payload data in the record. The format of this type is
        /// specified by the typeFormat parameter. For example, if typeFormat is TypeFormatEnum.MediaType
        /// then a valid type is "plain/text; charset=utf-8"</param>
        /// <param name="typeFormat">The format of the type parameter.</param>
        /// <param name="contentLength">The count of bytes to be written to the DIME record, or -1 to specify
        /// writing a chunked payload record.
        /// </param>
        /// <returns>A write-only DimeRecord.</returns>
        private DimeRecord CreateRecord(Uri id, string type, TypeFormatEnum typeFormat, int contentLength)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (m_closed)
            {
                throw new InvalidOperationException("The writer is closed.");
            }

            // if a record currently exists, send it.
            if (m_currentRecord != null)
            {
                m_currentRecord.Close(false);
            }

            m_currentRecord = new DimeRecord(m_stream, id, type, typeFormat, m_firstRecord, contentLength, m_defaultChunkSize);
            m_firstRecord   = false;
            if (m_lastRecord == true)
            {
                m_currentRecord.EndOfMessage = true;
            }

            return(m_currentRecord);
        }
예제 #2
0
        /// <summary>
        /// Closes the DIME message. If writing chunked payloads then any buffered data is written to
        /// the underlying stream and the chunked record and message end flags are set. If writing
        /// non-chunked then a terminating empty record with TNF=TypeFormatEnum.None is written to
        /// end the DIME message..
        /// </summary>
        public void Close()
        {
            if (m_closed)
            {
                return;
            }

            // if a record currently exists, send it.
            if (m_currentRecord != null)
            {
                m_currentRecord.Close(true);
                m_currentRecord = null;
            }
            m_closed = true;
        }
예제 #3
0
        /// <summary>
        /// Returns the next record in the DIME message in read-only mode. If the DimeReader is closed then
        /// an InvalidOperationException will occur. When the end of
        /// the message is reached ReadRecord will return null. ReadRecord is a blocking i/o call in that the 
        /// DIME record header is read before the method returns.
        /// </summary>
        /// <returns>
        /// A read-only DimeRecord, or null if it's the end of the DIME message. If the record has TNF=None
        /// and it is the last record in the message null is also returned.
        /// </returns>
        public DimeRecord ReadRecord() {
            if (m_closed)
                throw new InvalidOperationException("DimeReader is closed.");

            if (m_currentRecord != null) {
                if (m_currentRecord.EndOfMessage)
                    return null;
                m_currentRecord.Close();
            }
            
            m_currentRecord = new DimeRecord(m_stream);
            if (m_currentRecord.TypeFormat == TypeFormatEnum.None && m_currentRecord.EndOfMessage) {
                m_currentRecord.Close();
                return null;
            }
            return m_currentRecord;
        }
예제 #4
0
        /// <summary>
        /// Encapsulates the SOAP message into a DIME message.  The stored attachments are added as DIME records.
        /// If an exception has been thrown, the soap message containing the exception is
        /// not encapsulated.
        /// </summary>
        private void AfterSerialize(SoapMessage message)
        {
            newStream.Position = 0;
            //if response only, then not on request
            if (dimeDir != DimeDir.Response && message.Exception == null)
            {
                DimeWriter dw            = new DimeWriter(networkStream);
                int        contentLength = (newStream.CanSeek && newStream.Length <= DefaultBufferSize) ? (int)newStream.Length : -1;
                DimeRecord record        = null;
                if (outputAttachments.Count > 0)
                {
                    record = dw.NewRecord(id, SoapContentType, TypeFormatEnum.AbsoluteUri, contentLength);
                }
                else
                {
                    record = dw.LastRecord(id, SoapContentType, TypeFormatEnum.AbsoluteUri, contentLength);
                }
                BinaryCopy(newStream, record.BodyStream);

                //add attachments
                for (int i = 0; i < outputAttachments.Count; i++)
                {
                    DimeAttachment attachment = (DimeAttachment)outputAttachments[i];
                    contentLength = attachment.Stream.CanSeek ? (int)attachment.Stream.Length : -1;
                    if (i == (outputAttachments.Count - 1))
                    {
                        record = dw.LastRecord(attachment.Id, attachment.Type, attachment.TypeFormat, contentLength);
                    }
                    else
                    {
                        record = dw.NewRecord(attachment.Id, attachment.Type, attachment.TypeFormat, contentLength);
                    }
                    BinaryCopy(attachment.Stream, record.BodyStream);
                }
                dw.Close();
            }
            else
            {
                BinaryCopy(newStream, networkStream);
            }
        }
예제 #5
0
        /// <summary>
        /// Returns the next record in the DIME message in read-only mode. If the DimeReader is closed then
        /// an InvalidOperationException will occur. When the end of
        /// the message is reached ReadRecord will return null. ReadRecord is a blocking i/o call in that the
        /// DIME record header is read before the method returns.
        /// </summary>
        /// <returns>
        /// A read-only DimeRecord, or null if it's the end of the DIME message. If the record has TNF=None
        /// and it is the last record in the message null is also returned.
        /// </returns>
        public DimeRecord ReadRecord()
        {
            if (m_closed)
            {
                throw new InvalidOperationException("DimeReader is closed.");
            }

            if (m_currentRecord != null)
            {
                if (m_currentRecord.EndOfMessage)
                {
                    return(null);
                }
                m_currentRecord.Close();
            }

            m_currentRecord = new DimeRecord(m_stream);
            if (m_currentRecord.TypeFormat == TypeFormatEnum.None && m_currentRecord.EndOfMessage)
            {
                m_currentRecord.Close();
                return(null);
            }
            return(m_currentRecord);
        }
예제 #6
0
        /// <summary>
        /// Retrieves the SOAP message from the DIME message.  DIME attachments
        /// are removed from the stream and stored for future use by the AfterDeserialize
        /// method.
        /// </summary>
        private void BeforeDeserialize(SoapMessage message)
        {
            if (message.ContentType == DimeContentType)
            {
                contentType      = message.ContentType;
                inputAttachments = new Hashtable();

                DimeReader dr     = new DimeReader(networkStream);
                DimeRecord record = dr.ReadRecord();
                if (record.Type != SoapContentType)
                {
                    throw new Exception(String.Format("Expected content type '{0}' in record containing SOAP payload.", SoapContentType));
                }
                message.ContentType = "text/xml";
                BinaryCopy(record.BodyStream, newStream);
                record.Close();

                //get attachments
                while ((record = dr.ReadRecord()) != null)
                {
                    //OutOfMemoryException
                    Stream stream = new MemoryStream(record.Chunked ? DefaultBufferSize : record.ContentLength);
                    BinaryCopy(record.BodyStream, stream);
                    stream.Position = 0;
                    DimeAttachment attachment = new DimeAttachment(record.Id.ToString(), record.Type, record.TypeFormat, stream);
                    inputAttachments.Add(attachment.Id, attachment);
                    record.Close();
                }
                dr.Close();
            }
            else
            {
                BinaryCopy(networkStream, newStream);
            }
            newStream.Position = 0;
        }
예제 #7
0
 /// <summary>
 /// Creates a DimeStream object
 /// </summary>
 /// <param name="stream">Must be open</param>
 /// <param name="dimeRecord">A valid header for the DIME record.</param>
 /// <param name="streamType">Specifies if the stream is read-only or write-only.</param>
 internal DimeStream (DimeRecord dimeRecord) {
     m_dimeRecord = dimeRecord;            
 }
예제 #8
0
 /// <summary>
 /// Creates a DimeStream object
 /// </summary>
 /// <param name="dimeRecord">A valid header for the DIME record.</param>
 internal DimeStream(DimeRecord dimeRecord)
 {
     m_dimeRecord = dimeRecord;
 }
예제 #9
0
        /// <summary>
        /// Returns the next record to write in the DIME message. If the length of the payload data is not
        /// known upfront then use contentLength==-1 to specify chunked records. Otherwise the amount of data
        /// written to the record must match the content length specified. When the DimeWriter is closed then the
        /// message end flag is automatically set on the last record. If writing in non-chunked mode then
        /// an empty terminating record with TNF=TypeFormatEnum.None will be automatically sent when the
        /// DimeWriter is closed.
        /// </summary>
        /// <param name="id">The unique identifier of the record in the form of a URI.</param>
        /// <param name="type">The type of payload data in the record. The format of this type is 
        /// specified by the typeFormat parameter. For example, if typeFormat is TypeFormatEnum.MediaType
        /// then a valid type is "plain/text; charset=utf-8"</param>
        /// <param name="typeFormat">The format of the type parameter.</param>
        /// <param name="contentLength">The count of bytes to be written to the DIME record, or -1 to specify
        /// writing a chunked payload record.
        /// </param>
        /// <returns>A write-only DimeRecord.</returns>
        private DimeRecord CreateRecord(Uri id, string type, TypeFormatEnum typeFormat, int contentLength) {
            if (type == null) throw new ArgumentNullException("type");
            if (m_closed) throw new InvalidOperationException("The writer is closed.");

            // if a record currently exists, send it.
            if (m_currentRecord != null)
                m_currentRecord.Close(false);

            m_currentRecord = new DimeRecord(m_stream, id, type, typeFormat, m_firstRecord, contentLength, m_defaultChunkSize);
            m_firstRecord = false;
			if(m_lastRecord == true)
				m_currentRecord.EndOfMessage = true;

            return m_currentRecord;
        }
예제 #10
0
        /// <summary>
        /// Closes the DIME message. If writing chunked payloads then any buffered data is written to
        /// the underlying stream and the chunked record and message end flags are set. If writing
        /// non-chunked then a terminating empty record with TNF=TypeFormatEnum.None is written to 
        /// end the DIME message..
        /// </summary>
        public void Close() {
            if (m_closed) return;

            // if a record currently exists, send it.
            if (m_currentRecord != null) {
                m_currentRecord.Close(true);
                m_currentRecord = null;
            }
            m_closed = true;
        }