Click here to Skip to main content
15,881,882 members
Articles / Desktop Programming / WPF

WPF Version of IPMessager

Rate me:
Please Sign up or sign in to vote.
4.87/5 (10 votes)
27 Feb 2010CPOL2 min read 44K   2.7K   55  
Redeveloped the IPMessager program using C# and WPF
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Linq;
using System.Net;

namespace IPMessager
{
    public class Message
    {
        public int Version = 1;
        public int PacketNo;
        public string SenderName { get; set; }
        public string SenderHost { get; set; }
        public uint Command;
        public uint Option;
        public byte[] AdditionalSection;
        public List<Attachment> Attachments;

        public IPEndPoint SenderIP;

        public string Content
        {
            get
            {
                if (HasIconData)
                {
                    return "<Icon Data>";
                }
                return Messager.TextEncoding.GetString(AdditionalSection).TrimEnd('\0');
            }
            set
            {
                if (value != null)
                {
                    AdditionalSection = Messager.TextEncoding.GetBytes(value);
                }
                else
                {
                    AdditionalSection = new byte[1] { 0 };
                }
            }
        }

        public string Sender
        {
            get { return String.Format("{0} ({1})", SenderName, SenderHost); }
        }

        public uint CommandNo
        {
            get { return Option | Command; }
            set
            {
                Option = value & 0xFFFFFF00;
                Command = value & 0xFF;
            }
        }

        public bool HasAttachment
        {
            get
            {
                CommandOption option = (CommandOption)this.Option;
                return (option & CommandOption.IPMSG_FILEATTACHOPT) == CommandOption.IPMSG_FILEATTACHOPT
                    && this.Command == CommandID.IPMSG_SENDMSG;
            }
            set
            {
                if (value)
                {
                    Option = Option | (uint)CommandOption.IPMSG_FILEATTACHOPT;
                }
            }
        }

        public bool ConfirmReceive
        {
            get
            {
                SendCommandOption option = (SendCommandOption)this.Option;
                return (option & SendCommandOption.IPMSG_SENDCHECKOPT) == SendCommandOption.IPMSG_SENDCHECKOPT;
            }
            set
            {
                if (value)
                {
                    Option = Option | (uint)SendCommandOption.IPMSG_SENDCHECKOPT;
                }
            }
        }

        public bool HasIconData
        {
            get { return Command == CommandID.IPMSG_SENDINFO && Option == (uint)CommandOption.IPMSG_FILEATTACHOPT; }
        }

        public static Message Decode(byte[] data, IPEndPoint remoteEP)
        {
            List<string> items = new List<string>(5);
            int index = 0;
            int count = 0;
            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] == ':')
                {
                    items.Add(Encoding.UTF8.GetString(data, index, count));
                    count = 0;
                    index = i + 1;
                    if (items.Count == 5) break;
                }
                else
                {
                    count++;
                }
            }
            count = data.Length - index;
            byte[] additional = new byte[count];
            Array.Copy(data, index, additional, 0, count);

            Message message = new Message();
            if (items.Count >= 4)
            {
                int.TryParse(items[0], out message.Version);
                int.TryParse(items[1], out message.PacketNo);
                message.SenderName = items[2];
                message.SenderHost = items[3];
                message.CommandNo = uint.Parse(items[4]);
            }
            message.AdditionalSection = additional;
            message.SenderIP = remoteEP;

            if (message.HasAttachment)
            {
                index = Array.IndexOf<byte>(additional, 0);
                if (index > -1)
                {
                    index++;
                    count = additional.Length - index;
                    string attachment = Messager.TextEncoding.GetString(additional, index, count);
                    string[] files = attachment.Split('\a');
                    message.Attachments = new List<Attachment>(files.Length);
                    foreach (string file in files)
                    {
                        if (file.Contains(':'))
                        {
                            message.Attachments.Add(Attachment.Decode(file));
                        }
                    }
                }
                Array.Resize<byte>(ref message.AdditionalSection, index);
            }

            return message;
        }



        public static byte[] Encode(Message message)
        {
            string header = String.Concat(
                message.Version.ToString(),
                ":",
                message.PacketNo.ToString(),
                ":",
                message.SenderName,
                ":",
                message.SenderHost,
                ":",
                message.CommandNo.ToString(),
                ":"
                );
            List<byte> data = new List<byte>(Encoding.UTF8.GetByteCount(header) + message.AdditionalSection.Length);
            data.AddRange(Encoding.UTF8.GetBytes(header));
            data.AddRange(message.AdditionalSection);
            if (message.HasAttachment)
            {
                data.Add((byte)0);
                foreach (Attachment attachment in message.Attachments)
                {
                    data.AddRange(Messager.TextEncoding.GetBytes(Attachment.Encode(attachment)));
                    data.Add((byte)'\a');
                }
            }
            return data.ToArray();
        }

        public override string ToString()
        {
            return String.Format("{0}:{1}:{2}:{3}:{4}:{5}",
                Version, PacketNo, SenderName, SenderHost, CommandNo, Content);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect YunCheDa Hangzhou
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions