Ejemplo n.º 1
0
        /// <summary>
        /// Converts a message's data into the message. This method is thread-safe!
        /// </summary>
        /// <param name="data">The message's data.</param>
        /// <param name="messagePrototype">The empty message prototype.</param>
        /// <returns>The message containing the data or null.</returns>
        public IICCCMessage convertData2Message(NameValueCollection data, IICCCMessage messagePrototype)
        {
            try
            {
                // Check the preconditions:
                if(data == null || data.Count < 2 || messagePrototype == null) // channel + command = 2
                {
                    return null;
                }

                // Get the type of the message:
                var type = messagePrototype.GetType();

                // Get all properties:
                var properties = type.GetProperties();

                // The .NET ICCC driver is based on properties.
                // In case that the type has no properties, we are
                // done here.
                if (!properties.Any())
                {
                    // We return the prototype, because there are many
                    // messages without any data. Thus, this is a valid case.
                    return messagePrototype;
                }

                // Loop over all data entries:
                foreach(var key in data.AllKeys)
                {
                    // Get the data for this key:
                    var value = data[key];

                    if(key.Contains(':'))
                    {
                        // Decode the base64 encoding. Thus, get the bytes:
                        var valueBytes = Convert.FromBase64String(value);

                        // Split the key into data type and name:
                        var elements = key.Split(':');
                        var dataType = elements[0];
                        var name = elements[1];

                        // Get the matching property:
                        var property = properties.FirstOrDefault(n => n.Name == name);

                        // No property found?
                        if(property == null)
                        {
                            continue;
                        }

                        // Store for the final value:
                        var messageValue = null as object;

                        // For some array convertions:
                        var countNumbers = 0;

                        // Choose the right decoding regarding the data type:
                        switch(dataType)
                        {
                            case "str":
                                // Decode the value:
                                messageValue = Uri.UnescapeDataString(Encoding.UTF8.GetString(valueBytes));
                                break;

                            case "f64":
                                // Decode the value:
                                messageValue = BitConverter.ToDouble(valueBytes, 0);
                                break;

                            case "int":
                                // Decode the value:
                                messageValue = BitConverter.ToInt64(valueBytes, 0);
                                break;

                            case "bool":
                                // Decode the value:
                                messageValue = valueBytes[0] == 0x1 ? true : false;
                                break;

                            case "ui8":
                                // Decode the value:
                                messageValue = valueBytes[0];
                                break;

                            case "ui8[]":
                                // Decode the value:
                                messageValue = valueBytes;
                                break;

                            case "int[]":
                                // Decode the value:
                                countNumbers = valueBytes.Length / 8; // 8 byte per int64 i.e. long
                                messageValue = new long[countNumbers];
                                Buffer.BlockCopy(valueBytes, 0, (Array)messageValue, 0, countNumbers * 8);
                                break;

                            case "bool[]":
                                // Decode the value:
                                messageValue = valueBytes.Select(n => n == 0x0 ? false : true).ToArray();
                                break;

                            case "str[]":
                                // Decode the value:
                                messageValue = Encoding.UTF8.GetString(valueBytes).Split('\n').Select(n => Uri.UnescapeDataString(n)).ToArray();
                                break;

                            case "f64[]":
                                // Decode the value:
                                countNumbers = valueBytes.Length / 8; // 8 byte per float 64 i.e. double
                                messageValue = new double[countNumbers];
                                Buffer.BlockCopy(valueBytes, 0, (Array)messageValue, 0, countNumbers * 8);
                                break;
                        }

                        // Store the value in the message:
                        property.SetValue(messagePrototype, messageValue);
                    }
                }

                return messagePrototype;
            }
            catch
            {
                return null;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Converts a message into data. This method is thread-safe!
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>The data object which is may empty.</returns>
        public NameValueCollection convertMessage2Data(IICCCMessage message)
        {
            try
            {
                // The result's data:
                var data = new NameValueCollection();

                // No message?
                if(message == null)
                {
                    return data;
                }

                // Store the channel:
                data.Add("channel", message.getChannel());

                // Store the command:
                data.Add("command", message.getCommand());

                // Get the type of the message:
                var type = message.GetType();

                // Get all properties:
                var properties = type.GetProperties();

                // The .NET ICCC driver is based on properties.
                // In case that the type has no properties, we are
                // done here.
                if(!properties.Any())
                {
                    // We return the current data, because there are many
                    // messages without any additional data. Thus, this is a valid case.
                    return data;
                }

                // Loop over all properties:
                foreach(var property in properties)
                {
                    // Read the type of this property:
                    var dataType = property.PropertyType;

                    // Read the value:
                    var value = property.GetValue(message);

                    // Read the name:
                    var name = property.Name;

                    // Find the matching encoding:
                    switch(dataType.Name)
                    {
                        case "String":
                            data.Add("str:" + name, Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(value as string))));
                            break;

                        case "Int64":
                            data.Add("int:" + name, Convert.ToBase64String(BitConverter.GetBytes((long)value)));
                            break;

                        case "Double":
                            data.Add("f64:" + name, Convert.ToBase64String(BitConverter.GetBytes((double)value)));
                            break;

                        case "Boolean":
                            var boolValue = (bool)value;
                            data.Add("bool:" + name, Convert.ToBase64String(new byte[] { boolValue ? (byte)0x1 : (byte)0x0 }));
                            break;

                        case "Byte":
                            data.Add("ui8:" + name, Convert.ToBase64String(new byte[] { (byte)value }));
                            break;

                        case "Byte[]":
                            data.Add("ui8[]:" + name, Convert.ToBase64String(value as byte[]));
                            break;

                        case "Boolean[]":
                            data.Add("bool[]:" + name, Convert.ToBase64String((value as bool[]).Select(n => n ? (byte)0x1 : (byte)0x0).ToArray()));
                            break;

                        case "Double[]":
                            var doubleData = value as double[];
                            var doubleBuffer = new byte[doubleData.Length*8];
                            Buffer.BlockCopy(doubleData, 0, doubleBuffer, 0, doubleData.Length*8);
                            data.Add("f64[]:" + name, Convert.ToBase64String(doubleBuffer));
                            break;

                        case "Int64[]":
                            var longData = value as long[];
                            var longBuffer = new byte[longData.Length*8];
                            Buffer.BlockCopy(longData, 0, longBuffer, 0, longData.Length*8);
                            data.Add("int[]:" + name, Convert.ToBase64String(longBuffer));
                            break;

                        case "String[]":
                            var strings = value as string[];
                            data.Add("str[]:" + name, Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Join("\n", strings.Select(n => Uri.EscapeDataString(n))))));
                            break;
                    }
                }

                return data;
            }
            catch
            {
                return new NameValueCollection();
            }
        }