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

EncodingUtility.cs

/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2007 Paul Burton <paulburton89@gmail.com>
 * Copyright (C) 2008 Philippe Durand <draekz@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
{
      // WARNING: DO NOT MODIFY THESE IN ANY WAY AT ALL UNLESS DISCUSSING WITH PAUL BURTON FIRST!
      
      public class EncodingUtility
      {
            static string urlAllowedChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$-_.+!*'(),;/?:@=&";
            
            public static string UrlEncode (string str, Encoding enc)
            {
                  string result = string.Empty;
                  
                  foreach (char ch in str)
                  {
                        if (urlAllowedChars.IndexOf (ch) >= 0)
                              result += ch;
                        else
                        {
                              byte[] bytes = enc.GetBytes (new char[] { ch });
                              
                              foreach (byte b in bytes)
                                    result += string.Format ("%{0:x2}", b);
                        }
                  }
                  
                  return result;
            }
            
            
            public static string UrlEncode (string str)
            {
                  return UrlEncode (str, Encoding.UTF8);
            }
            
            public static string UrlDecode (string str, Encoding enc, char prefix)
            {
                  string result = string.Empty;
                  
                  while (str.Length > 0)
                  {
                        if (str[0] == prefix)
                        {
                              List<byte> bytes = new List<byte> ();
                              
                              while ((str.Length > 0) && (str[0] == prefix))
                              {
                                    str = str.Substring (1);

                                    try
                                    {
                                          byte val = byte.Parse (str.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
                                          bytes.Add (val);
                                          
                                          str = str.Substring (2);
                                    }
                                    catch (Exception)
                                    {
                                          throw new ApplicationException ("Invalid URL Encoded String, % not followed by 2 digits");
                                    }
                              }
                              
                              try
                              {
                                    result += new string (enc.GetChars (bytes.ToArray ()));
                              }
                              catch (Exception)
                              {
                                    string bytestr = string.Empty;
                                    
                                    foreach (byte b in bytes)
                                          bytestr += string.Format ("0x{0:00} ", b);
                                    
                                    throw new ApplicationException (string.Format ("Invalid URL Encoded String, bytes not valid for encoding\n{0}", bytestr));
                              }
                        }
                        else
                        {
                              result += str[0];
                              str = str.Substring (1);
                        }
                  }
                  
                  return result;
            }
            
            public static string UrlDecode (string str, Encoding enc)
            {
                  return UrlDecode (str, enc, '%');
            }
            
            public static string UrlDecode (string str)
            {
                  return UrlDecode (str, Encoding.UTF8);
            }
            
            public static string UrlDecodeSafe (string str, Encoding enc)
            {
                  try
                  {
                        return UrlDecode (str, enc);
                  }
                  catch (Exception)
                  {
                        return str;
                  }
            }
            
            public static string UrlDecodeSafe (string str)
            {
                  return UrlDecodeSafe (str, Encoding.UTF8);
            }
            
            public static string Base64Encode (string str, Encoding enc)
            {
                  return Convert.ToBase64String (enc.GetBytes (str));
            }
            
            public static string Base64Encode (string str)
            {
                  return Base64Encode (str, Encoding.UTF8);
            }
            
            public static string Base64Decode (string str, Encoding enc)
            {
                  Base64Decoder dec = new Base64Decoder (str);
                  return enc.GetString (dec.GetDecoded ());
            }
            
            public static string Base64DecodeSafe (string str, Encoding enc)
            {
                  try
                  {
                        return Base64Decode (str, enc);
                  }
                  catch
                  {
                        return str;
                  }
            }
            
            public static string Base64Decode (string str)
            {
                  return Base64Decode (str, Encoding.UTF8);
            }
            
            public static string Base64DecodeSafe (string str)
            {
                  try
                  {
                        return Base64Decode (str);
                  }
                  catch
                  {
                        return str;
                  }
            }
            
            public static string DecodeMailField (string str)
            {
                  string[] chunks = str.Split (new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries);
                  Encoding enc = Encoding.UTF8;
                  
                  try
                  {
                        enc = Encoding.GetEncoding (chunks[1]);
                  }
                  catch (ArgumentException)
                  {
                        Log.Warn ("Unable to find encoding {0}", chunks[1]);
                  }
                  
                  if (chunks[2] == "B")
                        return Base64Decode (chunks[3], enc);
                  else
                        return UrlDecode (chunks[3], enc, '=');
            }
            
            public static string EncodeMailField (string str)
            {
                  return string.Format ("=?utf-8?B?{0}?=", Base64Encode (str, Encoding.UTF8));
            }
            
            public static string GetEncodedString (string str)
            {
                  ThrowUtility.ThrowIfNull ("str", str);
                  
                  return System.Web.HttpUtility.UrlEncode (str, Encoding.UTF8);
            }
            
            public static string GetDecodedString (string str)
            {
                  ThrowUtility.ThrowIfNull ("str", str);
                  
                  return System.Web.HttpUtility.UrlDecode (str, Encoding.UTF8);
            }
      }
      
      // Convert.FromBase64String seems to fail with KMess MsnObjects for some reason
      // The code below doesn't, although somewhere the closing "/>" gets cut off
      // I don't know if thats KMess' fault or ours...
      // 
      // Based on http://lists.ximian.com/pipermail/mono-list/2006-March/031023.html
      public class Base64Decoder
      {
            char[] source;
            int length1;
            int blockCount;
            int paddingCount;
            
            public Base64Decoder (string input)
            {
                  input = BaseUtility.ReplaceString (input, " ", "", true);
                  input = BaseUtility.ReplaceString (input, "\r", "", true);
                  input = BaseUtility.ReplaceString (input, "\n", "", true);
                  
                  source = input.ToCharArray ();
                  
                  for (int i = 0; i < 2; i++)
                  {
                        if (source[source.Length - i - 1] == '=')
                              paddingCount++;
                  }
                  
                  blockCount = source.Length / 4;
                  length1 = blockCount * 3;
            }
            
            public byte[] GetDecoded ()
            {
                  byte[] buffer = new byte[source.Length];
                  byte[] buffer2 = new byte[length1];
                  
                  for (int x = 0; x < source.Length; x++)
                        buffer[x] = ToSixBit (source[x]);
                  
                  byte b, b1, b2, b3;
                  byte temp1, temp2, temp3, temp4;
                  
                  for (int x = 0; x < blockCount; x++)
                  {
                        temp1 = buffer[x * 4];
                        temp2 = buffer[x * 4 + 1];
                        temp3 = buffer[x * 4 + 2];
                        temp4 = buffer[x * 4 + 3];
                        
                        b = (byte)(temp1 << 2);
                        b1 = (byte)((temp2 & 48) >> 4);
                        b1 += b;
                        
                        b = (byte)((temp2 & 15) << 4);
                        b2 = (byte)((temp3 & 60) >> 2);
                        b2 += b;
                        
                        b = (byte)((temp3 & 3) << 6);
                        b3 = temp4;
                        b3 += b;
                        
                        buffer2[x * 3] = b1;
                        buffer2[x * 3 + 1] = b2;
                        buffer2[x * 3 + 2] = b3;
                  }
                  
                  // Remove padding
                  byte[] result = new byte[length1 - paddingCount];
                  Array.Copy (buffer2, result, result.Length);
                  
                  return result;
            }
            
            private byte ToSixBit (char c)
            {
                  char[] lookupTable = new char[64]
                  {
                        'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
                        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
                        '0','1','2','3','4','5','6','7','8','9','+','/'
                  };
                  
                  for (byte x = 0; x < 64; x++)
                  {
                        if (lookupTable[x] == c)
                              return x;
                  }
                        
                  return 0;
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index