예제 #1
0
            public static List <Variable> DecodeVarBindList(byte[] Data)
            {
                List <Variable> ret = new List <Variable>();

                using (var stream = new MemoryStream(Data))
                    using (var read = new BigEndianReader(stream))
                    {
                        while (true)
                        {
                            byte fieldID = read.ReadByte();
                            if (fieldID == 255)
                            {
                                break;
                            }

                            ushort fieldLength = read.ReadUInt16();
                            switch (fieldID)
                            {
                            case 1: // Error status
                            {
                                var errorStatus = read.ReadUInt16();
                                Console.WriteLine($"Error status: {errorStatus}");
                            }
                            break;

                            case 2: // Error
                            {
                                var errorType = read.ReadUInt16() == 1;
                                Console.WriteLine($"Error: {errorType}");
                            }
                            break;

                            case 3: // VarBind
                            {
                                var vb = DecodeVarBind(read.ReadBytes(fieldLength));
                                ret.Add(vb);
                            }
                            break;
                            }

                            if (fieldID == 255 || read.PeekChar() < 0)
                            {
                                break;
                            }
                        }
                    }

                return(ret);
            }
예제 #2
0
                public static void ReadFromReader(this ICommand command, BigEndianReader read)
                {
                    var properties = command.GetType().GetProperties()
                                     .Where(f => f.GetCustomAttribute <CommandFieldAttribute>() != null)
                                     .Select(f => new { Property = f, Metadata = f.GetCustomAttribute <CommandFieldAttribute>() });

                    while (true)
                    {
                        byte fieldID = read.ReadByte();
                        if (fieldID == 255 || read.PeekChar() < 0)
                        {
                            break;
                        }

                        ushort fieldLength = read.ReadUInt16();

                        var fieldInfo         = properties.First(f => f.Metadata.FieldID == fieldID);
                        var serializationType = fieldInfo.Property.PropertyType;
                        if (fieldInfo.Metadata.SerializeAs != null)
                        {
                            serializationType = fieldInfo.Metadata.SerializeAs;
                        }

                        if (Nullable.GetUnderlyingType(serializationType) != null)
                        {
                            serializationType = Nullable.GetUnderlyingType(serializationType);
                        }

                        if (fieldInfo.Metadata.Repeated)
                        {
                            if (!serializationType.GetInterfaces().Any(i => i == typeof(IList)))
                            {
                                throw new Exception("Repeated field is not of a list type");
                            }

                            var listType = serializationType.GetInterfaces().First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList <>));
                            var internalSerializationType = listType.GetGenericArguments()[0];

                            var cur = fieldInfo.Property.GetValue(command) as IList;
                            if (!serializationType.IsArray)
                            {
                                if (cur == null)
                                {
                                    cur = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(internalSerializationType));
                                }
                                cur.Add(read.ReadOfType(fieldLength, internalSerializationType));
                            }
                            else
                            {
                                if (cur == null)
                                {
                                    cur = Array.CreateInstance(internalSerializationType, 1);
                                }
                                else
                                {
                                    var arr = Array.CreateInstance(internalSerializationType, cur.Count + 1);
                                    Array.Copy((Array)cur, arr, cur.Count);
                                    cur = arr;
                                }

                                cur[cur.Count - 1] = read.ReadOfType(fieldLength, internalSerializationType);
                            }

                            fieldInfo.Property.SetValue(command, cur);
                        }
                        else
                        {
                            var value = read.ReadOfType(fieldLength, serializationType);
                            if (serializationType != fieldInfo.Property.PropertyType)
                            {
                                if (!fieldInfo.Property.PropertyType.IsEnum)
                                {
                                    value = Convert.ChangeType(value, fieldInfo.Property.PropertyType);
                                }
                            }

                            fieldInfo.Property.SetValue(command, value);
                        }
                    }
                }