///////////////////////////////////////////////////////////////////////
        #region Private Methods

        /// <summary>
        /// Reads an instance of a type from the buffer,
        /// </summary>
        private int ReadType(TsCCpxContext context, out TsCCpxComplexValue complexValue)
        {
            complexValue = null;

            TypeDescription type       = context.Type;
            int             startIndex = context.Index;

            byte bitOffset = 0;

            ArrayList fieldValues = new ArrayList();

            for (int ii = 0; ii < type.Field.Length; ii++)
            {
                FieldType field = type.Field[ii];

                TsCCpxComplexValue fieldValue = new TsCCpxComplexValue {
                    Name = (field.Name != null && field.Name.Length != 0) ? field.Name : String.Format("[{0}]", ii), Type = null, Value = null
                };

                // check if additional padding is required after the end of a bit field.
                if (bitOffset != 0)
                {
                    if (field.GetType() != typeof(BitString))
                    {
                        context.Index++;
                        bitOffset = 0;
                    }
                }

                int bytesRead = 0;

                if (IsArrayField(field))
                {
                    bytesRead = ReadArrayField(context, field, ii, fieldValues, out fieldValue.Value);
                }
                else if (field.GetType() == typeof(TypeReference))
                {
                    object typeValue = null;

                    bytesRead = ReadField(context, (TypeReference)field, out typeValue);

                    // assign a name appropriate for the current context.
                    fieldValue.Name  = field.Name;
                    fieldValue.Type  = ((TsCCpxComplexValue)typeValue).Type;
                    fieldValue.Value = ((TsCCpxComplexValue)typeValue).Value;
                }
                else
                {
                    bytesRead = ReadField(context, field, ii, fieldValues, out fieldValue.Value, ref bitOffset);
                }

                if (bytesRead == 0 && bitOffset == 0)
                {
                    throw new TsCCpxInvalidDataInBufferException(String.Format("Could not read field '{0}' in type '{1}'.", field.Name, type.TypeID));
                }

                context.Index += bytesRead;

                // assign a value for field type.
                if (fieldValue.Type == null)
                {
                    fieldValue.Type = Technosoftware.DaAeHdaClient.OpcConvert.ToString(fieldValue.Value.GetType());
                }

                fieldValues.Add(fieldValue);
            }

            // skip padding bits at the end of a type.
            if (bitOffset != 0)
            {
                context.Index++;
            }

            complexValue = new TsCCpxComplexValue();

            complexValue.Name  = type.TypeID;
            complexValue.Type  = type.TypeID;
            complexValue.Value = (TsCCpxComplexValue[])fieldValues.ToArray(typeof(TsCCpxComplexValue));

            return(context.Index - startIndex);
        }
예제 #2
0
        ///////////////////////////////////////////////////////////////////////
        #region Private Methods

        /// <summary>
        /// Writes an instance of a type to the buffer.
        /// </summary>
        private int WriteType(TsCCpxContext context, TsCCpxComplexValue namedValue)
        {
            TypeDescription type       = context.Type;
            int             startIndex = context.Index;

            TsCCpxComplexValue[] fieldValues = null;

            if (namedValue.Value == null || namedValue.Value.GetType() != typeof(TsCCpxComplexValue[]))
            {
                throw new TsCCpxInvalidDataToWriteException("Type instance does not contain field values.");
            }

            fieldValues = (TsCCpxComplexValue[])namedValue.Value;

            if (fieldValues.Length != type.Field.Length)
            {
                throw new TsCCpxInvalidDataToWriteException("Type instance does not contain the correct number of fields.");
            }

            byte bitOffset = 0;

            for (int ii = 0; ii < type.Field.Length; ii++)
            {
                FieldType          field      = type.Field[ii];
                TsCCpxComplexValue fieldValue = fieldValues[ii];

                if (bitOffset != 0)
                {
                    if (field.GetType() != typeof(BitString))
                    {
                        context.Index++;
                        bitOffset = 0;
                    }
                }

                int bytesWritten = 0;

                if (IsArrayField(field))
                {
                    bytesWritten = WriteArrayField(context, field, ii, fieldValues, fieldValue.Value);
                }
                else if (field.GetType() == typeof(TypeReference))
                {
                    bytesWritten = WriteField(context, (TypeReference)field, fieldValue);
                }
                else
                {
                    bytesWritten = WriteField(context, field, ii, fieldValues, fieldValue.Value, ref bitOffset);
                }

                if (bytesWritten == 0 && bitOffset == 0)
                {
                    throw new TsCCpxInvalidDataToWriteException(String.Format("Could not write field '{0}' in type '{1}'.", field.Name, type.TypeID));
                }

                context.Index += bytesWritten;
            }

            if (bitOffset != 0)
            {
                context.Index++;
            }

            return(context.Index - startIndex);
        }