An 32-bit header for a compound object would indicate the start of a stream object
Inheritance: StreamObjectHeaderStart
        /// <summary>
        /// Deserialize sub response data from byte array.
        /// </summary>
        /// <param name="byteArray">The byte array which contains sub response data.</param>
        /// <param name="currentIndex">The index special where to start.</param>
        protected override void DeserializeSubResponseDataFromByteArray(byte[] byteArray, ref int currentIndex)
        {
            int index = currentIndex;

            this.ReadAccessResponse  = StreamObject.GetCurrent <ReadAccessResponse>(byteArray, ref index);
            this.WriteAccessResponse = StreamObject.GetCurrent <WriteAccessResponse>(byteArray, ref index);

            currentIndex = index;

            using (BitReader bitReader = new BitReader(byteArray, index))
            {
                int headertype = bitReader.ReadInt32(2);
                if (headertype == 0x2)
                {
                    StreamObjectHeaderStart32bit header = new StreamObjectHeaderStart32bit();
                    header.HeaderType = headertype;
                    header.Compound   = bitReader.ReadInt32(1);
                    int type = bitReader.ReadInt32(14);
                    header.Type   = (StreamObjectTypeHeaderStart)type;
                    header.Length = bitReader.ReadInt32(15);
                    index        += 4;
                    ResponseError responseError = StreamObject.GetCurrent <ResponseError>(byteArray, ref index);
                }

                // If header type is not 16-bit Stream Object Header End
                if (headertype != 0x3)
                {
                    currentIndex = index + 2;
                }
            }
        }
        /// <summary>
        /// This method is used to parse the actual 16bit or 32bit stream header.
        /// </summary>
        /// <param name="byteArray">Specify the Byte array.</param>
        /// <param name="startIndex">Specify the start position.</param>
        /// <param name="streamObjectHeader">Specify the out value for the parse result.</param>
        /// <returns>Return true if success, otherwise returns false. </returns>
        public static int TryParse(byte[] byteArray, int startIndex, out StreamObjectHeaderStart streamObjectHeader)
        {
            uint headerType = (uint)(byteArray[startIndex] & 0x3);

            if (headerType == StreamObjectHeaderStart.StreamObjectHeaderStart16bit)
            {
                streamObjectHeader = new StreamObjectHeaderStart16bit();
            }
            else
            {
                if (headerType == StreamObjectHeaderStart.StreamObjectHeaderStart32bit)
                {
                    streamObjectHeader = new StreamObjectHeaderStart32bit();
                }
                else
                {
                    streamObjectHeader = null;
                    return(0);
                }
            }

            try
            {
                return(streamObjectHeader.DeserializeFromByteArray(byteArray, startIndex));
            }
            catch (InvalidOperationException)
            {
                streamObjectHeader = null;
                return(0);
            }
        }
        /// <summary>
        /// This method is used to parse the actual 16bit or 32bit stream header.
        /// </summary>
        /// <param name="byteArray">Specify the Byte array.</param>
        /// <param name="startIndex">Specify the start position.</param>
        /// <param name="streamObjectHeader">Specify the out value for the parse result.</param>
        /// <returns>Return true if success, otherwise returns false. </returns>
        public static int TryParse(byte[] byteArray, int startIndex, out StreamObjectHeaderStart streamObjectHeader)
        {
            uint headerType = (uint)(byteArray[startIndex] & 0x3);
            if (headerType == StreamObjectHeaderStart.StreamObjectHeaderStart16bit)
            {
                streamObjectHeader = new StreamObjectHeaderStart16bit();
            }
            else
            {
                if (headerType == StreamObjectHeaderStart.StreamObjectHeaderStart32bit)
                {
                    streamObjectHeader = new StreamObjectHeaderStart32bit();
                }
                else
                {
                    streamObjectHeader = null;
                    return 0;
                }
            }

            try
            {
                return streamObjectHeader.DeserializeFromByteArray(byteArray, startIndex);
            }
            catch (InvalidOperationException)
            {
                streamObjectHeader = null;
                return 0;
            }
        }
Exemple #4
0
        /// <summary>
        /// Serialize item to byte list.
        /// </summary>
        /// <returns>The byte list.</returns>
        public List <byte> SerializeToByteList()
        {
            List <byte> byteList = new List <byte>();

            int lengthOfItems = this.SerializeItemsToByteList(byteList);

            StreamObjectHeaderStart header;

            if ((int)this.StreamObjectType <= 0x3F && lengthOfItems <= 127)
            {
                header = new StreamObjectHeaderStart16bit(this.StreamObjectType, lengthOfItems);
            }
            else
            {
                header = new StreamObjectHeaderStart32bit(this.StreamObjectType, lengthOfItems);
            }

            byteList.InsertRange(0, header.SerializeToByteList());

            if (CompoundTypes.Contains(this.StreamObjectType))
            {
                if ((int)this.StreamObjectType <= 0x3F)
                {
                    byteList.AddRange(new StreamObjectHeaderEnd8bit((int)this.StreamObjectType).SerializeToByteList());
                }
                else
                {
                    byteList.AddRange(new StreamObjectHeaderEnd16bit((int)this.StreamObjectType).SerializeToByteList());
                }
            }

            return(byteList);
        }
        /// <summary>
        /// This method is used to convert the element into a byte List
        /// </summary>
        /// <returns>Return the Byte List</returns>
        public virtual List <byte> SerializeToByteList()
        {
            // Request ID bytes
            List <byte> requestIDBytes = (new Compact64bitInt(this.RequestID)).SerializeToByteList();

            // Request Type bytes
            List <byte> requestTypeBytes = (new Compact64bitInt(this.RequestType)).SerializeToByteList();

            // Priority bytes
            List <byte> priorityBytes = (new Compact64bitInt(this.Priority)).SerializeToByteList();

            // Sub-request Start bytes
            int subRequstStartLength = requestIDBytes.Count + requestTypeBytes.Count + priorityBytes.Count;

            this.SubRequestStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.SubRequest, subRequstStartLength);

            List <byte> byteList = new List <byte>();

            // Sub-request Start
            byteList.AddRange(this.SubRequestStart.SerializeToByteList());

            // Request ID
            byteList.AddRange(requestIDBytes);

            // Request Type
            byteList.AddRange(requestTypeBytes);

            // Priority
            byteList.AddRange(priorityBytes);

            // Target partition ID
            if (this.IsPartitionIDGUIDUsed)
            {
                this.PartitionIdGUIDStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.TargetPartitionId, 16);
                byteList.AddRange(this.PartitionIdGUIDStart.SerializeToByteList());
                byteList.AddRange(this.PartitionIdGUID.ToByteArray());

                this.PartitionIdGUIDEnd = new StreamObjectHeaderEnd16bit(StreamObjectTypeHeaderEnd.TargetPartitionId);
                byteList.AddRange(this.PartitionIdGUIDEnd.SerializeToByteList());
            }

            return(byteList);
        }
        /// <summary>
        /// This method is used to convert the element into a byte List 
        /// </summary>
        /// <returns>Return the Byte List</returns>
        public virtual List<byte> SerializeToByteList()
        {
            // Request ID bytes
            List<byte> requestIDBytes = (new Compact64bitInt(this.RequestID)).SerializeToByteList();
            
            // Request Type bytes
            List<byte> requestTypeBytes = (new Compact64bitInt(this.RequestType)).SerializeToByteList();
            
            // Priority bytes
            List<byte> priorityBytes = (new Compact64bitInt(this.Priority)).SerializeToByteList();

            // Sub-request Start bytes
            int subRequstStartLength = requestIDBytes.Count + requestTypeBytes.Count + priorityBytes.Count;
            this.SubRequestStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.SubRequest, subRequstStartLength);

            List<byte> byteList = new List<byte>();
            
            // Sub-request Start
            byteList.AddRange(this.SubRequestStart.SerializeToByteList());
            
            // Request ID
            byteList.AddRange(requestIDBytes);
            
            // Request Type
            byteList.AddRange(requestTypeBytes);
            
            // Priority
            byteList.AddRange(priorityBytes);

            // Target partition ID
            if (this.IsPartitionIDGUIDUsed)
            {
                this.PartitionIdGUIDStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.TargetPartitionId, 16);
                byteList.AddRange(this.PartitionIdGUIDStart.SerializeToByteList());
                byteList.AddRange(this.PartitionIdGUID.ToByteArray());

                this.PartitionIdGUIDEnd = new StreamObjectHeaderEnd16bit(StreamObjectTypeHeaderEnd.TargetPartitionId);
                byteList.AddRange(this.PartitionIdGUIDEnd.SerializeToByteList());
            }

            return byteList;
        }
        /// <summary>
        /// This method is used to convert the element into a byte List 
        /// </summary>
        /// <returns>Return the Byte List</returns>
        public override List<byte> SerializeToByteList()
        {
            // Storage Index Extended GUID
            this.StorageIndexExtendedGUID = this.StorageIndexExtendedGUID ?? new ExGuid();
            List<byte> storageIndexExtendedGUIDBytes = this.StorageIndexExtendedGUID.SerializeToByteList();

            // Expect Storage Index Extended GUID
            List<byte> expectedStorageIndexExtendedGUIDBytes = this.ExpectedStorageIndexExtendedGUID.SerializeToByteList();
            
            // Put Changes Request
            this.PutChangesRequestStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.PutChangesRequest, 1 + storageIndexExtendedGUIDBytes.Count + expectedStorageIndexExtendedGUIDBytes.Count);
            List<byte> putChangesRequestBytes = this.PutChangesRequestStart.SerializeToByteList();
            
            // reserved
            BitWriter bitWriter = new BitWriter(1);
            bitWriter.AppendInit32(this.ImplyNullExpectedIfNoMapping, 1);
            bitWriter.AppendInit32(this.Partial, 1);
            bitWriter.AppendInit32(this.PartialLast, 1);
            bitWriter.AppendInit32(this.FavorCoherencyFailureOverNotFound, 1);
            bitWriter.AppendInit32(this.AbortRemainingPutChangesOnFailure, 1);
            bitWriter.AppendInit32(this.MultiRequestPutHint, 1);
            bitWriter.AppendInit32(this.ReturnCompleteKnowledgeIfPossible, 1);
            bitWriter.AppendInit32(this.LastWriterWinsOnNextChange, 1);

            List<byte> reservedBytes = new List<byte>(bitWriter.Bytes);

            List<byte> byteList = new List<byte>();
            
            // sub-request start
            byteList.AddRange(base.SerializeToByteList());
            
            // put change request
            byteList.AddRange(putChangesRequestBytes);
            
            // Storage Index Extended GUID
            byteList.AddRange(storageIndexExtendedGUIDBytes);

            // Expected Storage Index Extended GUID
            byteList.AddRange(expectedStorageIndexExtendedGUIDBytes);
            
            // reserved
            byteList.AddRange(reservedBytes);

            if (this.IsAdditionalFlagsUsed)
            {
                this.AdditionalFlagsStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.AdditionalFlags, 2);
                byteList.AddRange(this.AdditionalFlagsStart.SerializeToByteList());

                BitWriter additionalFlagsWriter = new BitWriter(2);
                additionalFlagsWriter.AppendInit32(this.ReturnAppliedStorageIndexIdEntries, 1);
                additionalFlagsWriter.AppendInit32(this.ReturnDataElementsAdded, 1);
                additionalFlagsWriter.AppendInit32(this.CheckForIdReuse, 1);
                additionalFlagsWriter.AppendInit32(this.CoherencyCheckOnlyAppliedIndexEntries, 1);
                additionalFlagsWriter.AppendInit32(this.FullFileReplacePut, 1);
                additionalFlagsWriter.AppendInit32(this.Reserve, 11);
                byteList.AddRange(additionalFlagsWriter.Bytes);
            }

            if (this.IsLockIdUsed)
            {
                this.LockIdStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.PutChangesLockId, 16);
                byteList.AddRange(this.LockIdStart.SerializeToByteList());
                byteList.AddRange(this.LockID.ToByteArray());
            }

            if (this.OptionalClientKnowledge != null)
            {
                byteList.AddRange(this.OptionalClientKnowledge.SerializeToByteList());
            }

            // sub-request end
            byteList.AddRange(this.ToBytesEnd());

            return byteList;
        }
        /// <summary>
        /// This method is used to convert the element into a byte List
        /// </summary>
        /// <returns>Return the Byte List</returns>
        public override List <byte> SerializeToByteList()
        {
            // Storage Index Extended GUID
            this.StorageIndexExtendedGUID = this.StorageIndexExtendedGUID ?? new ExGuid();
            List <byte> storageIndexExtendedGUIDBytes = this.StorageIndexExtendedGUID.SerializeToByteList();

            // Expect Storage Index Extended GUID
            List <byte> expectedStorageIndexExtendedGUIDBytes = this.ExpectedStorageIndexExtendedGUID.SerializeToByteList();

            // Put Changes Request
            this.PutChangesRequestStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.PutChangesRequest, 1 + storageIndexExtendedGUIDBytes.Count + expectedStorageIndexExtendedGUIDBytes.Count);
            List <byte> putChangesRequestBytes = this.PutChangesRequestStart.SerializeToByteList();

            // reserved
            BitWriter bitWriter = new BitWriter(1);

            bitWriter.AppendInit32(this.ImplyNullExpectedIfNoMapping, 1);
            bitWriter.AppendInit32(this.Partial, 1);
            bitWriter.AppendInit32(this.PartialLast, 1);
            bitWriter.AppendInit32(this.FavorCoherencyFailureOverNotFound, 1);
            bitWriter.AppendInit32(this.AbortRemainingPutChangesOnFailure, 1);
            bitWriter.AppendInit32(this.MultiRequestPutHint, 1);
            bitWriter.AppendInit32(this.ReturnCompleteKnowledgeIfPossible, 1);
            bitWriter.AppendInit32(this.LastWriterWinsOnNextChange, 1);

            List <byte> reservedBytes = new List <byte>(bitWriter.Bytes);

            List <byte> byteList = new List <byte>();

            // sub-request start
            byteList.AddRange(base.SerializeToByteList());

            // put change request
            byteList.AddRange(putChangesRequestBytes);

            // Storage Index Extended GUID
            byteList.AddRange(storageIndexExtendedGUIDBytes);

            // Expected Storage Index Extended GUID
            byteList.AddRange(expectedStorageIndexExtendedGUIDBytes);

            // reserved
            byteList.AddRange(reservedBytes);

            if (this.IsAdditionalFlagsUsed)
            {
                this.AdditionalFlagsStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.AdditionalFlags, 2);
                byteList.AddRange(this.AdditionalFlagsStart.SerializeToByteList());

                BitWriter additionalFlagsWriter = new BitWriter(2);
                additionalFlagsWriter.AppendInit32(this.ReturnAppliedStorageIndexIdEntries, 1);
                additionalFlagsWriter.AppendInit32(this.ReturnDataElementsAdded, 1);
                additionalFlagsWriter.AppendInit32(this.CheckForIdReuse, 1);
                additionalFlagsWriter.AppendInit32(this.CoherencyCheckOnlyAppliedIndexEntries, 1);
                additionalFlagsWriter.AppendInit32(this.FullFileReplacePut, 1);
                additionalFlagsWriter.AppendInit32(this.RequireStorageMappingsRooted, 1);
                additionalFlagsWriter.AppendInit32(this.Reserve, 10);
                byteList.AddRange(additionalFlagsWriter.Bytes);
            }

            if (this.IsLockIdUsed)
            {
                this.LockIdStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.PutChangesLockId, 16);
                byteList.AddRange(this.LockIdStart.SerializeToByteList());
                byteList.AddRange(this.LockID.ToByteArray());
            }

            if (this.OptionalClientKnowledge != null)
            {
                byteList.AddRange(this.OptionalClientKnowledge.SerializeToByteList());
            }

            if (this.IsDiagnosticRequestOptionInputUsed)
            {
                this.DiagnosticRequestOptionInputStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.DiagnosticRequestOptionInput, 2);
                byteList.AddRange(this.DiagnosticRequestOptionInputStart.SerializeToByteList());

                BitWriter diagnosticRequestOptionWriter = new BitWriter(2);
                diagnosticRequestOptionWriter.AppendInit32(this.ForceRevisionChainOptimization, 1);
                diagnosticRequestOptionWriter.AppendInit32(this.Reserve, 7);
                byteList.AddRange(diagnosticRequestOptionWriter.Bytes);
            }

            // sub-request end
            byteList.AddRange(this.ToBytesEnd());

            return(byteList);
        }