コード例 #1
0
ファイル: SizeofHelper.cs プロジェクト: toschkin/MIO
        /// <summary>
        /// Calculates total size in bytes of all public properties of an object
        /// </summary>
        /// <param name="obj">object which properties size should be calculated</param>
        /// <returns>size in bytes of all public properties of an object</returns>
        public static UInt32 SizeOfPublicPropertiesWithModbusAttribute(object obj, ModbusRegisterAccessType accessType = ModbusRegisterAccessType.AccessRead, bool processSubproperties = false)
        {
            if (obj is List<object>)
                return SizeOfPublicPropertiesWithModbusAttribute(((List<object>)obj).ToArray(), accessType);

            if (obj == null)
                throw new ArgumentNullException();

            UInt32 totalLengthInBytes = 0;
            foreach (var field in OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj))
            {

                if ((field.CanWrite) &&
                    (field.GetCustomAttributes(typeof(ModbusPropertyAttribute), false).Length != 0))
                {
                    foreach (var attr in field.GetCustomAttributes(typeof(ModbusPropertyAttribute), false))
                    {
                        if (((ModbusPropertyAttribute)attr).Access >= accessType)
                        {
                            totalLengthInBytes += (UInt32)Marshal.SizeOf(field.PropertyType);
                            break;
                        }
                    }
                }
                else
                {
                    if ((processSubproperties)&&(field.CanWrite))
                    {
                        if (!field.PropertyType.IsValueType && !field.PropertyType.IsEnum &&
                        field.PropertyType == typeof(String))
                        {
                            Type typeSource = field.GetType();
                            object objTarget = Activator.CreateInstance(typeSource);
                            totalLengthInBytes += SizeOfPublicPropertiesWithModbusAttribute(objTarget, accessType);
                        }
                    }
                }
            }
            return totalLengthInBytes;
        }
コード例 #2
0
        /// <summary>
        /// Sets all public properties of the object array to values from arrayValues
        /// </summary>
        /// <param name="obj">Destination object</param>
        /// <param name="arrayValues">Values to which this function sets properties of the object array</param>
        /// <returns>true on success, false otherwise</returns>
        /// <remarks>Values in arrayValues should be placed sequentionaly in the same order with object's properties definitions</remarks>
        public static bool SetObjectPropertiesValuesFromArray(ref object obj, object[] arrayValues, ModbusRegisterAccessType accessType = ModbusRegisterAccessType.AccessRead)
        {
            if (obj == null)
                throw new ArgumentNullException();
            if (arrayValues == null)
                throw new ArgumentNullException();

            if (OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj).Length >= arrayValues.Length)
            {
                //first we check that arrayValues has same value types with object properties
                int i = 0;
                foreach (var item in OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj))
                {
                    if ((item.CanWrite) && (item.GetCustomAttributes(typeof(ModbusPropertyAttribute), false).Length != 0))
                    {
                        foreach (var attr in item.GetCustomAttributes(typeof(ModbusPropertyAttribute), false))
                        {
                            if (((ModbusPropertyAttribute)attr).Access >= accessType)
                            {
                                if (item.PropertyType == arrayValues[i].GetType())
                                {
                                    item.SetValue(obj, Convert.ChangeType(arrayValues[i], item.PropertyType),null);
                                    i++;
                                }
                                else
                                    return false;
                                break;
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
コード例 #3
0
        /// <summary>
        /// Extracts values of object's public properties
        /// </summary>
        /// <param name="obj">object which properties values should be extracted</param>
        /// <returns>array of public properties values</returns>
        public static object[] GetObjectModbusPropertiesValuesArray(object obj, ModbusRegisterAccessType accessType = ModbusRegisterAccessType.AccessRead)
        {
            if (obj == null)
                throw new ArgumentNullException();

            List<object> lstTypesOfClassMembers = new List<object>();
            PropertyInfo[] membersOfClass = OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj);
            foreach (var item in membersOfClass)
            {
                if (GetTypeHelper.IsNumericType(item.PropertyType))
                {
                    if ((item.CanWrite) && (item.GetIndexParameters().Length == 0)
                        && (item.GetCustomAttributes(typeof (ModbusPropertyAttribute), false).Length != 0))
                    {
                        foreach (var attr in item.GetCustomAttributes(typeof(ModbusPropertyAttribute), false))
                        {
                            if (((ModbusPropertyAttribute)attr).Access >= accessType)
                            {
                                lstTypesOfClassMembers.Add(item.GetValue(obj,null));
                                break;
                            }
                        }
                    }
                }
            }
            return lstTypesOfClassMembers.ToArray<object>();
        }
コード例 #4
0
        /// <summary>
        /// Extracts types of public properties of objects in array
        /// </summary>
        /// <param name="obj">array of objects which properties should be extracted</param>
        /// <returns>array of public properties types</returns>       
        public static Type[] GetObjectModbusPropertiesTypeArray(object[] obj, ModbusRegisterAccessType accessType = ModbusRegisterAccessType.AccessRead)
        {
            if (obj == null)
                throw new ArgumentNullException();
            List<Type> lstTypesOfClassMembers = new List<Type>();
            foreach (var item in obj)
            {
                if (item == null)
                    throw new ArgumentNullException();

                PropertyInfo[] membersOfClass = OrderedGetter.GetObjectPropertiesInDeclarationOrder(item);
                foreach (var property in membersOfClass)
                {
                    if (GetTypeHelper.IsNumericType(property.PropertyType))
                    {
                        if ((property.CanWrite) &&
                            (property.GetCustomAttributes(typeof (ModbusPropertyAttribute), false).Length != 0))
                        {
                            foreach (var attr in property.GetCustomAttributes(typeof(ModbusPropertyAttribute), false))
                            {
                                if (((ModbusPropertyAttribute)attr).Access >= accessType)
                                {
                                    lstTypesOfClassMembers.Add(property.PropertyType);
                                    break;
                                }
                            }
                        }

                    }
                }
            }
            return lstTypesOfClassMembers.ToArray<Type>();
        }
コード例 #5
0
        public static Byte GetModbusObjectsHighestByte(object obj, ModbusRegisterAccessType accessType = ModbusRegisterAccessType.AccessRead)
        {
            if (obj == null)
                throw new ArgumentNullException();

            if (!GetTypeHelper.IsNumericType(obj.GetType()))
            {
                for (int i = OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj).Length-1; i >=0; i--)
                {
                    if ((OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj)[i].CanWrite) &&
                       (OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj)[i].GetCustomAttributes(typeof(ModbusPropertyAttribute), false).Length != 0))
                    {
                        foreach (var attr in OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj)[i].GetCustomAttributes(typeof(ModbusPropertyAttribute), false))
                        {
                            if (((ModbusPropertyAttribute)attr).Access >= accessType)
                            {
                                obj = OrderedGetter.GetObjectPropertiesInDeclarationOrder(obj)[i].GetValue(obj,null);
                                break;
                            }
                        }
                        break;
                    }
                }
            }

            switch (obj.GetType().Name)
            {
                case "Byte":
                    {
                        return (Byte)obj;
                    }
                case "SByte":
                    {
                        return unchecked((Byte)((SByte)obj));
                    }
                case "UInt16":
                    {
                        return BitConverter.GetBytes((UInt16)obj).ElementAt<Byte>(BitConverter.GetBytes((UInt16)obj).Length - 1);
                    }
                case "Int16":
                    {
                        return BitConverter.GetBytes((Int16)obj).ElementAt<Byte>(BitConverter.GetBytes((Int16)obj).Length - 1);
                    }
                case "UInt32":
                    {
                        return BitConverter.GetBytes((UInt32)obj).ElementAt<Byte>(BitConverter.GetBytes((UInt32)obj).Length - 1);
                    }
                case "Int32":
                    {
                        return BitConverter.GetBytes((Int32)obj).ElementAt<Byte>(BitConverter.GetBytes((Int32)obj).Length - 1);
                    }
                case "UInt64":
                    {
                        return BitConverter.GetBytes((UInt64)obj).ElementAt<Byte>(BitConverter.GetBytes((UInt64)obj).Length - 1);
                    }
                case "Int64":
                    {
                        return BitConverter.GetBytes((Int64)obj).ElementAt<Byte>(BitConverter.GetBytes((Int64)obj).Length - 1);
                    }
                case "Single":
                    {
                        return BitConverter.GetBytes((Single)obj).ElementAt<Byte>(BitConverter.GetBytes((Single)obj).Length - 1);
                    }
                case "Double":
                    {
                        return BitConverter.GetBytes((Double)obj).ElementAt<Byte>(BitConverter.GetBytes((Double)obj).Length - 1);
                    }
                case "Decimal":
                    {
                        return BitConverterEx.GetBytes((Decimal)obj).ElementAt<Byte>(BitConverterEx.GetBytes((Decimal)obj).Length - 1);
                    }
                default:
                    {
                        throw new ArgumentException();
                    }
            }
        }
コード例 #6
0
        public static void ConvertObjectsVaulesToRegisters(object[] values, uint startIndex, uint objectsCount,
            bool bigEndianOrder, out ModbusDataPoint<UInt16>[] forcedValues, Type firstElementType, ModbusRegisterAccessType accessType = ModbusRegisterAccessType.AccessRead)
        {
            //array of output 16bit values
            forcedValues = null;
            bool[] boolValues = null;
            //if firstElementType is boolean then all elements of array are considered to be boolean type also
            if (firstElementType == typeof(bool))
            {
                if (startIndex + objectsCount > 2000) //can force maximum 2000 coils
                    throw new ArgumentException();

                Array.Resize(ref forcedValues, (int)(startIndex + objectsCount + 15) / 16);
                Array.Resize(ref boolValues, (int)(startIndex + objectsCount));
            }
            Byte[] tempArrayOfBytes = null;
            int i = 0;
            //foreach (var value in values)
            for (UInt32 regVal = startIndex; regVal < startIndex + objectsCount; regVal++)
            {
                //if arrayType is bool - all elements must be bool
                if ((firstElementType == typeof(bool)) && (firstElementType != values[regVal].GetType()))
                    throw new ArgumentException();

                if (firstElementType == typeof(bool))
                    boolValues[i] = (bool)values[regVal];

                //if another type
                if (values[regVal].GetType().IsValueType) //here we will process simple (only numeric) types
                {
                    if (GetTypeHelper.IsNumericType(values[regVal].GetType()))
                    {
                        ConvertObjectValueAndAppendToArray(ref tempArrayOfBytes, values[regVal],
                            bigEndianOrder);
                    }
                    else if (values[regVal].GetType() != typeof (bool))
                        throw new ArgumentException();

                }
                else //here we will process properties (only numeric) from complex (class) types
                {
                    object[] arrayOfObjectPropsValues =
                        GetObjectModbusPropertiesValuesArray(values[regVal], accessType);

                    for (int k = 0; k < arrayOfObjectPropsValues.Length; k++)
                    {
                        ConvertObjectValueAndAppendToArray(ref tempArrayOfBytes,
                            arrayOfObjectPropsValues[k],
                            bigEndianOrder);
                    }
                }
                i++;
            }

            if (firstElementType == typeof(bool))
            {
                Byte[] temp = new Byte[forcedValues.Length * 2];
                new BitArray(boolValues).CopyTo(temp, 0);
                for (int valIndex = 0, byteIndex = 0; valIndex < forcedValues.Length && byteIndex < temp.Length; valIndex++, byteIndex += 2)
                {
                    forcedValues[valIndex] = new ModbusDataPoint<UInt16>();
                    forcedValues[valIndex].Value = (UInt16)(temp[byteIndex] | temp[byteIndex + 1] << 8);
                }
                //Buffer.BlockCopy(temp, 0, forcedValues, 0, temp.Length);
            }
            else
            {
                Array.Resize(ref forcedValues, (tempArrayOfBytes.Length + 1) / 2);
                for (int valIndex = 0, byteIndex = 0; valIndex < forcedValues.Length && byteIndex < tempArrayOfBytes.Length; valIndex++, byteIndex += 2)
                {
                    forcedValues[valIndex] = new ModbusDataPoint<UInt16>();
                    forcedValues[valIndex].Value = (UInt16)(tempArrayOfBytes[byteIndex] | tempArrayOfBytes[byteIndex+1] << 8);
                }
            }
        }