Logo Search packages:      
Sourcecode: galaxium version File versions  Download package

AbstractMsnCommand.cs

/*
 * Galaxium Messenger
 * Copyright (C) 2003-2007 Philippe Durand <draekz@gmail.com>
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2007 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;
using System.Text;

using Anculus.Core;

using Galaxium.Core;

namespace Galaxium.Protocol.Msn
{
      public abstract class AbstractMsnCommand: IMsnCommand
      {
            MsnSession _session;
            int _trid = -1;
            List<string> _arguments = new List<string> ();
            bool _incoming = false;
            MsnCommandAttribute _cmdAttribute;
            TransactionCommandAttribute _transAttribute;
            PayloadCommandAttribute _payloadAttribute;
            ExpectResponseAttribute _expectResponseAttribute;
            
            public virtual string Command
            {
                  get { return _cmdAttribute.Command; }
            }
            
            public int TransactionID
            {
                  get { return _trid; }
                  set { _trid = value; }
            }
            
            public List<string> Arguments
            {
                  get { return _arguments; }
                  protected set { _arguments = value; }
            }
            
            public virtual byte[] Payload
            {
                  get { return null; }
                  set { }
            }
            
            public MsnSession Session
            {
                  get { return _session; }
            }
            
            public bool Incoming
            {
                  get { return _incoming; }
            }
            
            public virtual bool IsPayloadIn
            {
                  get { return (_payloadAttribute != null) && _payloadAttribute.IsIn; }
            }
            
            public virtual bool IsPayloadOut
            {
                  get { return (_payloadAttribute != null) && _payloadAttribute.IsOut; }
            }
            
            public virtual bool IsTransIn
            {
                  get { return (_transAttribute != null) && _transAttribute.IsIn; }
            }
            
            public virtual bool IsTransOut
            {
                  get { return (_transAttribute != null) && _transAttribute.IsOut; }
            }
            
            public virtual bool ExpectResponse
            {
                  get { return _expectResponseAttribute != null; }
            }
            
            public AbstractMsnCommand (MsnSession session)
            {
                  _session = session;
                  
                  foreach (MsnCommandAttribute att in GetType ().GetCustomAttributes (typeof (MsnCommandAttribute), false))
                        _cmdAttribute = att;
                  foreach (TransactionCommandAttribute att in GetType ().GetCustomAttributes (typeof (TransactionCommandAttribute), false))
                        _transAttribute = att;
                  foreach (PayloadCommandAttribute att in GetType ().GetCustomAttributes (typeof (PayloadCommandAttribute), false))
                        _payloadAttribute = att;
                  foreach (ExpectResponseAttribute att in GetType ().GetCustomAttributes (typeof (ExpectResponseAttribute), false))
                        _expectResponseAttribute = att;

                  ThrowUtility.ThrowIfNull ("cmdAttribute", _cmdAttribute);
            }
            
            public AbstractMsnCommand (MsnSession session, byte[] data)
                  : this (session)
            {
                  _incoming = true;
                  
                  int lineLen = MsnByteArrayUtility.IndexOf (data, "\r\n");
                  
                  if (lineLen < 0)
                        lineLen = data.Length;
                  
                  byte[] lineData = new byte[lineLen];
                  Array.Copy (data, lineData, lineLen);
                  
                  string line = Encoding.UTF8.GetString (lineData);
                  string[] args = line.Split (new char[] { ' ' });
                  
                  if ((!string.IsNullOrEmpty (Command)) && (!(this is ErrorCommand)))
                        ThrowUtility.ThrowIfFalse (string.Format ("Wrong command ({0} not {1})", args[0], Command), args[0] == Command);
                  
                  int i = 1;
                  
                  if (IsTransIn)
                        _trid = int.Parse (args[i++]);
                  
                  // We need to provide arguments before we can get a correct value for IsPayloadIn
                  // eg. ListCommand needs to know if the first argument is OK
                  for (; i < args.Length; i++)
                        _arguments.Add (args[i]);
                  
                  int argEnd = args.Length - (IsPayloadIn ? 1 : 0);
                  
                  // Now IsPayloadIn is ok and we know the correct number of arguments
                  
                  if (argEnd != args.Length)
                  {
                        // This is a payload command, so we need to remove the last item (payload length)
                        _arguments.RemoveAt (_arguments.Count - 1);
                        i--;
                  }
                  
                  if (IsPayloadIn)
                  {
                        int payloadLen = int.Parse (args[i]);
                        
                        // Multipacket messaging means MSG commands can have the wrong payload length
                        if (this is MSGCommand)
                              payloadLen = data.Length - lineLen - 2;
                        
                        ThrowUtility.ThrowIfFalse (string.Format ("Wrong payload length ({0} not {1})", data.Length - lineLen - 2, payloadLen), data.Length - lineLen - 2 == payloadLen);
                        
                        byte[] payloadData = new byte[payloadLen];
                        
                        Array.Copy(data, lineLen + 2, payloadData, 0, payloadLen);
                        
                        Payload = payloadData;
                  }
            }
            
            public virtual string ToCommandString ()
            {
                  StringBuilder sb = new StringBuilder();
                  
                  sb.Append (Command);
                  
                  if ((_incoming && IsTransIn) || ((!_incoming) && IsTransOut))
                        sb.Append (" " + _trid.ToString ());
                  
                  foreach (string arg in Arguments)
                        sb.Append (" " + arg);
                  
                  if ((_incoming && IsPayloadIn) || ((!_incoming) && IsPayloadOut))
                  {
                        if (Payload != null)
                              sb.Append (" " + Payload.Length.ToString ());
                        else
                              sb.Append (" 0");
                  }
                  
                  return sb.ToString ();
            }
            
            public virtual byte[] ToByteArray ()
            {
                  MessageBuilder mb = new Galaxium.Protocol.MessageBuilder ();
                  
                  mb.Append (ToCommandString ());
                  mb.Append ("\r\n");
                  
                  if ((_incoming && IsPayloadIn) || ((!_incoming) && IsPayloadOut))
                        mb.Append (Payload);
                  
                  return mb.GetByteArray ();
            }
            
            public override string ToString ()
            {
                  return ToCommandString ();
            }
            
            protected void SetArgument (int i, string val)
            {
                  while (_arguments.Count <= i)
                        _arguments.Add (string.Empty);
                  
                  _arguments[i] = val;
            }
            
            protected string GetArgument (int i)
            {
                  if (_arguments.Count <= i)
                        return string.Empty;
                  
                  return _arguments[i];
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index