/////////////////////////////////////////////////////////////////////// #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); }
/////////////////////////////////////////////////////////////////////// #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); }