Beispiel #1
0
        /*
         * /// <summary>
         * /// Creates a DimeAttachment object and automatically specifies a new unique Id in the form
         * /// of a uuid:.
         * /// </summary>
         * /// <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="stream">The stream for reading or writing the payload data.</param>
         *      public DimeAttachment(String type, TypeFormatEnum typeFormat, Stream stream) {
         *  Id = "uuid:" + bNb.Sec.Rand.NewGuid().ToString("D");
         *              this.type = type;
         *  this.typeFormat = typeFormat;
         *  this.stream = stream;
         * }
         */

        /// <summary>
        /// Creates a DimeAttachment object
        /// </summary>
        /// <param name="id">The unique id for the DIME record.</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="stream">The stream for reading or writing the payload data.</param>
        public DimeAttachment(string id, String type, TypeFormatEnum typeFormat, Stream stream)
        {
            Id              = id;
            this.type       = type;
            this.typeFormat = typeFormat;
            this.stream     = stream;
        }
Beispiel #2
0
        /// <summary>
        /// Creates a write-only DimeRecord object.
        /// </summary>
        /// <param name="stream">stream must be open and writeable.</param>
        /// <param name="id">id must be null or a valid URI.</param>
        /// <param name="type">type must be a valid URI or a media type.</param>
        /// <param name="contentLength">contentLength is the length of the records content.  If contentLength
        /// equals -1, chunking is used.</param>
        /// <param name="beginOfMessage">beginOfMessage marks this record as the first record in a message.</param>
        internal DimeRecord(Stream stream, Uri id, String type, TypeFormatEnum typeFormat, bool beginOfMessage, int contentLength, int chunkSize)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (!stream.CanWrite)
            {
                throw new ArgumentException("Stream CanWrite property must be true.", "stream");
            }
            if (contentLength < -1)
            {
                throw new ArgumentException("contentLength must be -1 for chunked or a non-negative number", "contentLength");
            }

            SetType(type, typeFormat);
            m_id             = id;
            m_contentLength  = contentLength;
            m_chunked        = contentLength == -1;
            m_firstChunk     = m_chunked;
            m_beginOfMessage = beginOfMessage;
            m_stream         = stream;
            m_ioMode         = IOModeEnum.WriteOnly;
            m_chunkSize      = chunkSize;
        }
Beispiel #3
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);
        }
Beispiel #4
0
        public DimeRecord LastRecord(string id, string type, TypeFormatEnum typeFormat, int contentLength)
        {
            m_lastRecord = true;
            Uri daUri = new Uri(id);

            return(CreateRecord(daUri, type, typeFormat, contentLength));
        }
Beispiel #5
0
 internal DimeRecord(Stream stream, Uri id, string type, TypeFormatEnum typeFormat, bool beginOfMessage, int contentLength, int chunkSize)
 {
     if (stream == null)
     {
         throw new ArgumentNullException("stream");
     }
     if (type == null)
     {
         throw new ArgumentNullException("type");
     }
     if (!stream.CanWrite)
     {
         throw new ArgumentException(XmlaSR.DimeRecord_StreamShouldBeWriteable, "stream");
     }
     if (contentLength < -1)
     {
         throw new ArgumentException(XmlaSR.DimeRecord_InvalidContentLength, "contentLength");
     }
     this.SetType(type, typeFormat);
     this.m_id             = id;
     this.m_contentLength  = contentLength;
     this.m_chunked        = (contentLength == -1);
     this.m_firstChunk     = this.m_chunked;
     this.m_beginOfMessage = beginOfMessage;
     this.m_stream         = stream;
     this.m_ioMode         = IOModeEnum.WriteOnly;
     this.m_chunkSize      = chunkSize;
 }
 public DimeRecord CreateRecord(Uri id, string type, TypeFormatEnum typeFormat, int contentLength)
 {
     if (type == null)
     {
         throw new ArgumentNullException("type");
     }
     if (this.m_closed)
     {
         throw new InvalidOperationException(XmlaSR.DimeWriter_WriterIsClosed);
     }
     if (this.m_currentRecord != null)
     {
         this.m_currentRecord.Close(false);
     }
     this.m_currentRecord         = new DimeRecord(this.m_stream, id, type, typeFormat, this.m_firstRecord, contentLength, this.m_defaultChunkSize);
     this.m_currentRecord.Options = this.m_Options;
     this.m_firstRecord           = false;
     return(this.m_currentRecord);
 }
Beispiel #7
0
        private void SetType(string type, TypeFormatEnum typeFormat)
        {
            switch (typeFormat)
            {
            case TypeFormatEnum.Unchanged:
                throw new ArgumentException(XmlaSR.DimeRecord_TypeFormatEnumUnchangedNotAllowed, "typeFormat");

            case TypeFormatEnum.MediaType:
                if (type == null || type.Length == 0)
                {
                    throw new ArgumentException(XmlaSR.DimeRecord_MediaTypeNotDefined, "type");
                }
                break;

            case TypeFormatEnum.None:
                if (type != null || type.Length != 0)
                {
                    throw new ArgumentException(XmlaSR.DimeRecord_NameMustNotBeDefinedForFormatNone, "type");
                }
                break;
            }
            this.m_typeFormat = typeFormat;
            this.m_type       = type;
        }
Beispiel #8
0
        internal void SetType(string type, TypeFormatEnum typeFormat)
        {
            switch (typeFormat)
            {
            case TypeFormatEnum.Unchanged:
                throw new ArgumentException("The typeFormat parameter must not be TypeFormatEnum.Unchanged", "typeFormat");

            //break;
            case TypeFormatEnum.MediaType:
                if (type == null || type.Length == 0)
                {
                    throw new ArgumentException("Media type name must be greater than length zero.", "type");
                }
                break;

            case TypeFormatEnum.AbsoluteUri:
                try { Uri u = new Uri(type); }
                catch (Exception e) {
                    //throw new ArgumentExceptionString.Format("Invalid uri format for uri: '{0}'", type), "type", e);
                    throw new ArgumentException("Invalid uri format for uri: " + type + "exc: " + e.ToString(), "type");
                }
                break;

            case TypeFormatEnum.None:
                if (type != null || type.Length != 0)
                {
                    throw new ArgumentException("Type name for TypeFormatEnum.None must be null or zero-length.", "type");
                }
                break;

            case TypeFormatEnum.Unknown:
                break;
            }
            m_typeFormat = typeFormat;
            m_type       = type;
        }
Beispiel #9
0
        /// <summary>
        /// Reads the header's properties from a stream
        /// </summary>
        /// <param name="stream">Must be an open and readable stream.</param>
        internal void ReadHeader()
        {
            //1st 3 (4-byte) chunks are
            //5-Version 1-MB 1-ME 1-ChunkFlag 4-type_t 4-reserved 16-optionsLength
            //16-idLength 16-typeLength
            //32-data length

            byte[] buffer = new byte[BaseHeaderSize];
            ForceRead(m_stream, buffer, BaseHeaderSize);
            //check version
            byte version = (byte)(buffer[0] & 248);

            if (version != 8)             //WTF
            {
                object [] local13 = new Object[2];
                local13[0] = version >> 3;
                local13[1] = 1;
                throw new Exception("dime_WrongVersion");
            }
            //get flags
            FlagsEnum flags = (FlagsEnum)(buffer[0] & 7);              //FlagMask

            m_beginOfMessage = (flags & FlagsEnum.BeginOfMessage) != 0;
            m_endOfMessage   = (flags & FlagsEnum.EndOfMessage) != 0;
            m_chunked        = (flags & FlagsEnum.ChunkedRecord) != 0;
            //get type flag
            //m_typeFormat = (TypeFormatEnum) ((buffer[2] & FlagMask) >> 5);
            TypeFormatEnum lTypeFormat = (TypeFormatEnum)(buffer[1] & 240);

            if (lTypeFormat != 0)
            {
                this.m_typeFormat = lTypeFormat;
            }
            //check reserved
            int reserved = buffer[1] & 15;

            if (reserved != 0)
            {
                throw new Exception("dime_RESRVDMustBeZero");
            }
            //get options length
            int optionsLength = (buffer[2] << 8) + buffer[3];
            //get id length
            int idLength = (buffer[4] << 8) + buffer[5];
            //get type length
            int typeLength = (buffer[6] << 8) + buffer[7];
            //get content length;
            //this.m_contentLength = buffer[8] << 24;
            //this.m_contentLength = this.m_contentLength + buffer[9] << 16;
            //this.m_contentLength = this.m_contentLength + buffer[10] << 8;
            //this.m_contentLength = this.m_contentLength + buffer[11];
            //this.m_contentLength = (int) BitConverter.ToInt32(buffer, 8);
            int n = 0;

            for (int i = 8; i < 11; i++)
            {
                n = (n | buffer[i]) << 8;
            }
            n = n | buffer[11];
            this.m_contentLength = n;
            //content length
            this.m_chunkSize = this.m_contentLength;

            //get options
            if (optionsLength > 0)
            {
                //the number of bytes received must be a multiple of 4.
                buffer = new byte[optionsLength + (((optionsLength % PaddingMultiple) > 0)?(PaddingMultiple - (optionsLength % PaddingMultiple)):0)];
                ForceRead(m_stream, buffer, buffer.Length);
                string value = Encoding.ASCII.GetString(buffer, 0, optionsLength);
                //TODO do something with this
            }

            //get id
            if (idLength > 0)
            {
                //the number of bytes received must be a multiple of 4.
                buffer = new byte[idLength + (((idLength % PaddingMultiple) > 0)?(PaddingMultiple - (idLength % PaddingMultiple)):0)];
                ForceRead(m_stream, buffer, buffer.Length);
                string value = Encoding.ASCII.GetString(buffer, 0, idLength);
                m_id = new Uri(value);
            }

            //get type
            if (typeLength > 0)
            {
                //the number of bytes received must be a multiple of 4.
                buffer = new byte[typeLength + (((typeLength % PaddingMultiple) > 0)?(PaddingMultiple - (typeLength % PaddingMultiple)):0)];
                ForceRead(m_stream, buffer, buffer.Length);
                string value = Encoding.ASCII.GetString(buffer, 0, typeLength);
                m_type = value;
            }

            //TODO CheckValid(type, id, typeFormat);
        }
Beispiel #10
0
 /// <summary>
 /// Returns the next record to write in the DIME message. The record payload will be written
 /// in chunked mode since no contentLength is specified. When the DimeWriter is closed then the
 /// message end flag is automatically set on the last record.
 /// </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>
 /// <returns>a write-only DimeRecord.</returns>
 private DimeRecord CreateRecord(Uri id, string type, TypeFormatEnum typeFormat)
 {
     return(CreateRecord(id, type, typeFormat, -1));
 }
        /// <summary>
        /// Creates a write-only DimeRecord object.
        /// </summary>
        /// <param name="stream">stream must be open and writeable.</param>
        /// <param name="id">id must be null or a valid URI.</param>
        /// <param name="type">type must be a valid URI or a media type.</param>
        /// <param name="contentLength">contentLength is the length of the records content.  If contentLength
        /// equals -1, chunking is used.</param>
        /// <param name="beginOfMessage">beginOfMessage marks this record as the first record in a message.</param>
        internal DimeRecord (Stream stream, Uri id, String type, TypeFormatEnum typeFormat, bool beginOfMessage, int contentLength, int chunkSize) {
            if (stream == null) throw new ArgumentNullException("stream");
            if (type == null) throw new ArgumentNullException("type");
            if (!stream.CanWrite) throw new ArgumentException("Stream CanWrite property must be true.", "stream");
            if (contentLength < -1) throw new ArgumentException("contentLength must be -1 for chunked or a non-negative number", "contentLength");

            SetType(type, typeFormat);
            m_id = id;            
            m_contentLength = contentLength;
            m_chunked = contentLength == -1;
            m_firstChunk = m_chunked;
            m_beginOfMessage = beginOfMessage;
            m_stream = stream;                        
            m_ioMode = IOModeEnum.WriteOnly;            
            m_chunkSize = chunkSize;
        }
        internal void SetType(string type, TypeFormatEnum typeFormat) {            
            switch (typeFormat) {
                case TypeFormatEnum.Unchanged:
                    throw new ArgumentException("The typeFormat parameter must not be TypeFormatEnum.Unchanged", "typeFormat");
                    //break;
                case TypeFormatEnum.MediaType:
                    if (type == null || type.Length == 0)
                        throw new ArgumentException("Media type name must be greater than length zero.", "type");                                        
                    break;
                case TypeFormatEnum.AbsoluteUri:
                    try { Uri u = new Uri(type); }
                    catch (Exception e) {
                        //throw new ArgumentExceptionString.Format("Invalid uri format for uri: '{0}'", type), "type", e);
						throw new ArgumentException("Invalid uri format for uri: " + type + "exc: " + e.ToString(), "type");
                    }                    
                    break;
                case TypeFormatEnum.None:
                    if (type != null || type.Length != 0)
                        throw new ArgumentException("Type name for TypeFormatEnum.None must be null or zero-length.", "type");                    
                    break;
                case TypeFormatEnum.Unknown:                    
                    break;
            }
            m_typeFormat = typeFormat;
            m_type = type;
        }
        /// <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;
        }
		public DimeRecord LastRecord(string id, string type, TypeFormatEnum typeFormat, int contentLength) 
		{
			m_lastRecord = true;
			Uri daUri = new Uri(id);
			return CreateRecord(daUri, type, typeFormat, contentLength);
		}
        /// <summary>
        /// Creates a DimeAttachment object and automatically specifies a new unique Id in the form
        /// of a uuid:.
        /// </summary>
        /// <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="stream">The stream for reading or writing the payload data.</param>
        /*
		public DimeAttachment(String type, TypeFormatEnum typeFormat, Stream stream) {
            Id = "uuid:" + bNb.Sec.Rand.NewGuid().ToString("D");
			this.type = type;
            this.typeFormat = typeFormat;
            this.stream = stream;
        }
		*/

        /// <summary>
        /// Creates a DimeAttachment object
        /// </summary>
        /// <param name="id">The unique id for the DIME record.</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="stream">The stream for reading or writing the payload data.</param>
        public DimeAttachment(string id, String type, TypeFormatEnum typeFormat, Stream stream) {
            Id = id;
            this.type = type;
            this.typeFormat = typeFormat;
            this.stream = stream;
        }
Beispiel #16
0
        private void ReadHeader()
        {
            byte[] array = new byte[12];
            DimeRecord.ForceRead(this.m_stream, array, 12);
            this.m_version = (byte)((array[0] & 248) >> 3);
            if (this.m_version != 1)
            {
                throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_VersionNotSupported((int)this.m_version), "");
            }
            DimeRecord.HeaderFlagsEnum headerFlagsEnum = (DimeRecord.HeaderFlagsEnum)(array[0] & 7);
            this.m_chunked        = ((byte)(headerFlagsEnum & DimeRecord.HeaderFlagsEnum.ChunkedRecord) != 0);
            this.m_beginOfMessage = ((byte)(headerFlagsEnum & DimeRecord.HeaderFlagsEnum.BeginOfMessage) != 0);
            this.m_endOfMessage   = ((byte)(headerFlagsEnum & DimeRecord.HeaderFlagsEnum.EndOfMessage) != 0);
            if (this.m_chunked && this.m_endOfMessage)
            {
                throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_InvalidHeaderFlags(this.m_beginOfMessage ? 1 : 0, 1, 1), "");
            }
            if ((!this.m_chunked && !this.m_endOfMessage) || (!this.m_firstChunk && this.m_beginOfMessage))
            {
                throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_OnlySingleRecordMessagesAreSupported, "");
            }
            this.m_typeFormat = (TypeFormatEnum)((array[1] & 240) >> 4);
            this.m_reserved   = (byte)(array[1] & 15);
            int num  = ((int)array[2] << 8) + (int)array[3];
            int num2 = ((int)array[4] << 8) + (int)array[5];
            int num3 = ((int)array[6] << 8) + (int)array[7];

            this.m_contentLength = ((int)array[8] << 24) + ((int)array[9] << 16) + ((int)array[10] << 8) + (int)array[11];
            if (this.m_firstChunk)
            {
                if (this.m_typeFormat != TypeFormatEnum.MediaType)
                {
                    throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_TypeFormatShouldBeMedia(this.m_typeFormat.ToString()), "");
                }
                if (num3 <= 0)
                {
                    throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_DataTypeShouldBeSpecifiedOnTheFirstChunk, "");
                }
            }
            else
            {
                if (this.m_typeFormat != TypeFormatEnum.Unchanged)
                {
                    throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_TypeFormatShouldBeUnchanged(this.m_typeFormat.ToString()), "");
                }
                if (num3 != 0)
                {
                    throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_DataTypeIsOnlyForTheFirstChunk, "");
                }
                if (num2 != 0)
                {
                    throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_IDIsOnlyForFirstChunk, "");
                }
                if (num != 0)
                {
                    throw new AdomdUnknownResponseException(XmlaSR.UnknownServerResponseFormat, "Unexpected non-zero options length");
                }
            }
            if (this.m_reserved != 0)
            {
                throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_ReservedFlagShouldBeZero(this.m_reserved), "");
            }
            if (num > 0)
            {
                array = new byte[DimeRecord.RoundUp(num)];
                DimeRecord.ForceRead(this.m_stream, array, array.Length);
                this.m_Options.FromBytes(array);
            }
            if (num2 > 0)
            {
                array = new byte[DimeRecord.RoundUp(num2)];
                DimeRecord.ForceRead(this.m_stream, array, array.Length);
            }
            if (num3 > 0)
            {
                array = new byte[DimeRecord.RoundUp(num3)];
                DimeRecord.ForceRead(this.m_stream, array, array.Length);
                this.m_type = Encoding.ASCII.GetString(array, 0, num3);
                if (!DataTypes.IsSupportedDataType(this.m_type))
                {
                    throw new AdomdUnknownResponseException(XmlaSR.DimeRecord_DataTypeNotSupported(this.m_type), "");
                }
            }
            this.m_firstChunk = false;
        }
        /// <summary>
        /// Reads the header's properties from a stream
        /// </summary>
        /// <param name="stream">Must be an open and readable stream.</param>
		internal void ReadHeader() 
		{ 
			//1st 3 (4-byte) chunks are
			//5-Version 1-MB 1-ME 1-ChunkFlag 4-type_t 4-reserved 16-optionsLength
			//16-idLength 16-typeLength
			//32-data length
			
			byte[] buffer = new byte[BaseHeaderSize];
			ForceRead(m_stream, buffer, BaseHeaderSize);
			//check version
			byte version = (byte) (buffer[0] & 248);
			if (version != 8) //WTF
			{
				object [] local13 = new Object[2];
				local13[0] = version >> 3;
				local13[1] = 1;
				throw new Exception("dime_WrongVersion");
			}
			//get flags
			FlagsEnum flags = (FlagsEnum) (buffer[0] & 7); //FlagMask
			m_beginOfMessage = (flags & FlagsEnum.BeginOfMessage) != 0;
			m_endOfMessage = (flags & FlagsEnum.EndOfMessage) != 0;
			m_chunked = (flags & FlagsEnum.ChunkedRecord) != 0;
			//get type flag
			//m_typeFormat = (TypeFormatEnum) ((buffer[2] & FlagMask) >> 5); 
			TypeFormatEnum lTypeFormat = (TypeFormatEnum) (buffer[1] & 240);
			if (lTypeFormat != 0)
				this.m_typeFormat = lTypeFormat;
			//check reserved
			int reserved = buffer[1] & 15;
			if (reserved != 0)
				throw new Exception("dime_RESRVDMustBeZero");
			//get options length
			int optionsLength = (buffer[2] << 8) + buffer[3];
			//get id length
			int idLength = (buffer[4] << 8) + buffer[5];
			//get type length
			int typeLength = (buffer[6] << 8) + buffer[7];
			//get content length;
			//this.m_contentLength = buffer[8] << 24;
			//this.m_contentLength = this.m_contentLength + buffer[9] << 16;
			//this.m_contentLength = this.m_contentLength + buffer[10] << 8;
			//this.m_contentLength = this.m_contentLength + buffer[11];
			//this.m_contentLength = (int) BitConverter.ToInt32(buffer, 8);
			int n = 0;
			for (int i=8;i<11;i++)
				n = (n | buffer[i]) << 8;
			n = n | buffer[11];
			this.m_contentLength = n;
			//content length
			this.m_chunkSize = this.m_contentLength;

			//get options
			if (optionsLength > 0) 
			{
				//the number of bytes received must be a multiple of 4.
				buffer = new byte[optionsLength + (((optionsLength % PaddingMultiple) > 0)?(PaddingMultiple - (optionsLength % PaddingMultiple)):0)];
				ForceRead(m_stream, buffer, buffer.Length);
				string value = Encoding.ASCII.GetString(buffer, 0, optionsLength);
				//TODO do something with this
			}

			//get id
			if (idLength > 0) 
			{
				//the number of bytes received must be a multiple of 4.
				buffer = new byte[idLength + (((idLength % PaddingMultiple) > 0)?(PaddingMultiple - (idLength % PaddingMultiple)):0)];
				ForceRead(m_stream, buffer, buffer.Length);
				string value = Encoding.ASCII.GetString(buffer, 0, idLength);
				m_id = new Uri(value);
			}

			//get type
			if (typeLength > 0) 
			{
				//the number of bytes received must be a multiple of 4.
				buffer = new byte[typeLength + (((typeLength % PaddingMultiple) > 0)?(PaddingMultiple - (typeLength % PaddingMultiple)):0)];
				ForceRead(m_stream, buffer, buffer.Length);
				string value = Encoding.ASCII.GetString(buffer, 0, typeLength);
				m_type = value;
			}
			
			//TODO CheckValid(type, id, typeFormat);
		} 
		public DimeRecord NewRecord(string id, string type, TypeFormatEnum typeFormat, int contentLength) 
		{
			Uri daUri = new Uri(id);
			return CreateRecord(daUri, type, typeFormat, contentLength);
		}
 /// <summary>
 /// Returns the next record to write in the DIME message. The record payload will be written
 /// in chunked mode since no contentLength is specified. When the DimeWriter is closed then the
 /// message end flag is automatically set on the last record.
 /// </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>
 /// <returns>a write-only DimeRecord.</returns>
 private DimeRecord CreateRecord(Uri id, string type, TypeFormatEnum typeFormat) {
     return CreateRecord(id, type, typeFormat, -1);
 }