I've developed mini utility, the source code can get reviewed here:
http://rle.codeplex.com/SourceControl/BrowseLatest
It's developed in C#, in the general page there is a description. I'm listening to well criticism to make code more elegant and better to work with.
/*
* GNU General Public License version 2 (GPLv2) http://rle.codeplex.com/license
* Oleg Orlov, 2013 (c), RLE encoding/decoding tool, version 1.0.1 (v1.01)
*
* C#, .NET 2.0 by default. It could be upgraded to any version of the .NET framework.
* I have downgraded the .NET version only for the compatibility aims
* and for the easy reproduction of the program to any other language.
*
* http://rle.codeplex.com/
*/
using System;
abstract class Contracts
{
public enum EncodingFormat
{
Old,
New,
};
}
class RLE : Contracts, IDisposable
{
private string str_base, str_rle;
private bool HasChar(ref string input)
{
bool status = false;
for (int i = 0; i < input.Length; i++)
{
if (Char.IsLetter(input[i]))
{
status = true;
break;
}
}
return status;
}
internal string Encode(ref string input, EncodingFormat format)
{
str_rle = null;
str_base = input;
if (format == EncodingFormat.New)
{
for (int i = 0; i < str_base.Length; i++)
{
char symbol = str_base[i];
int count = 1;
for (int j = i; j < str_base.Length - 1; j++)
{
if (str_base[j + 1] != symbol) break;
count++;
i++;
}
if (count == 1) str_rle += symbol;
else str_rle += count.ToString() + symbol;
}
}
else if (format == EncodingFormat.Old)
{
for (int i = 0; i < str_base.Length; i++)
{
char symbol = str_base[i];
int count = 1;
for (int j = i; j < str_base.Length - 1; j++)
{
if (str_base[j + 1] != symbol) break;
count++;
i++;
}
str_rle += count.ToString() + symbol;
}
}
return str_rle;
}
internal string Decode(ref string input)
{
str_rle = null;
str_base = input;
int radix = 0;
for (int i = 0; i < str_base.Length; i++)
{
if (Char.IsNumber(str_base[i]))
{
radix++;
}
else
{
if (radix > 0)
{
int value_repeat = Convert.ToInt32(str_base.Substring(i - radix, radix));
for (int j = 0; j < value_repeat; j++)
{
str_rle += str_base[i];
}
radix = 0;
}
else if (radix == 0)
{
str_rle += str_base[i];
}
}
}
if (str_rle == null || !HasChar(ref str_rle)) throw new Exception("\r\nCan't to decode! Input string has the wrong syntax. There isn't any char (e.g. 'a'->'z') in your input string, there was/were only number(s).\r\n");
return str_rle;
}
internal double GetPercentage(double x, double y)
{
return (100 * (x - y)) / x;
}
public void Dispose()
{
if (str_rle != null || str_base != null)
{
str_rle = str_base = null;
}
}
}
class Program : Contracts
{
private static string str_welcome = "\r\nRLE encoding/decoding tool, Oleg Orlov 2013(c).",
str_notice = "\r\nPlease, use the next syntax: <action> <string>\r\n(e.g. \"encode my_string\" or \"decode my_string\").\r\n\r\nWarning! The 2nd parameter (the string for encoding/decoding)\r\nmust not content any whitespaces!\r\n\r\nYou may also use the option \"-old\" to encode your string\r\n(e.g. \"encode my_string -old\") in such way, where before\r\nsingle char inserting the value: '1' (e.g. \"abbcddd\" -> \"1a2b1c3d\").";
private static void EncodeString(ref string str, EncodingFormat format)
{
using (RLE inst_rle = new RLE())
{
string str_encoded = inst_rle.Encode(ref str, format);
if (format == EncodingFormat.New)
{
Console.WriteLine("\r\nBase string ({0} chars): {1}\r\nAfter RLE-encoding ({2} chars): {3}\r\nCompression percentage: %{4}",
str.Length, str, str_encoded.Length, str_encoded,
inst_rle.GetPercentage((double)str.Length, (double)str_encoded.Length).ToString());
}
else if (format == EncodingFormat.Old)
{
Console.WriteLine("\r\nBase string ({0} chars): {1}\r\nAfter RLE-encoding with the \"-old\" option ({2} chars): {3}\r\nCompression percentage: %{4}",
str.Length, str, str_encoded.Length, str_encoded,
inst_rle.GetPercentage((double)str.Length, (double)str_encoded.Length).ToString());
}
}
}
private static void DecodeString(ref string str)
{
using (RLE inst_rle = new RLE())
{
string str_decoded = inst_rle.Decode(ref str);
Console.WriteLine("\r\nBase string ({0} chars): {1}\r\nAfter RLE-decoding ({2} chars): {3}\r\nDecompression percentage: %{4}",
str.Length, str, str_decoded.Length, str_decoded,
Math.Abs(inst_rle.GetPercentage((double)str.Length, (double)str_decoded.Length)).ToString());
}
}
[STAThread]
public static void Main(string[] args)
{
try
{
Console.WriteLine(str_welcome);
if (args.Length > 1)
{
if (args[0] == "encode")
{
if (args.Length == 3)
{
if (args[2] == "-old")
{
EncodeString(ref args[1], EncodingFormat.Old);
}
}
else
{
EncodeString(ref args[1], EncodingFormat.New);
}
}
else if (args[0] == "decode")
{
DecodeString(ref args[1]);
}
else
{
throw (new Exception("\r\nThere are only two methods: encode (with the \"-old\" option), decode. No other actions are available.\r\n"
+ str_notice + "\r\n"));
}
}
else
{
Console.WriteLine(str_notice);
Environment.Exit(1);
}
}
catch (Exception exc)
{
Console.WriteLine("\r\n{0}", exc);
Environment.Exit(1);
}
}
}