Run-length encoding

You are encouraged to solve this task according to the task description, using any language you may know.


Task

Given a string containing uppercase characters (A-Z), compress repeated 'runs' of the same character by storing the length of that run, and provide a function to reverse the compression.

The output can be anything, as long as you can recreate the input with it.



Example

 Input: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
 Output: 12W1B12W3B24W1B14W


Note: the encoding step in the above example is the same as a step of the Look-and-say sequence.




BYTE FUNC GetLength(CHAR ARRAY s BYTE pos)
  CHAR c
  BYTE len
 
  c=s(pos)
  len=1
  DO
    pos==+1
    IF pos<=s(0) AND s(pos)=c THEN
      len==+1
    ELSE
      EXIT
    FI
  OD
RETURN (len)
 
BYTE FUNC GetNumber(CHAR ARRAY s BYTE POINTER pos)
  BYTE num,len
  CHAR ARRAY tmp(5)
 
  len=0
  DO
    len==+1
    tmp(len)=s(pos^)
    pos^==+1
    IF s(pos^)<'0 OR s(pos^)>'9 THEN
      EXIT
    FI
  OD
  tmp(0)=len
  num=ValB(tmp)
RETURN (num)
 
PROC Append(CHAR ARRAY text,suffix)
  BYTE POINTER srcPtr,dstPtr
  BYTE len
 
  len=suffix(0)
  IF text(0)+len>255 THEN
    len=255-text(0)
  FI
  IF len THEN
    srcPtr=suffix+1
    dstPtr=text+text(0)+1
    MoveBlock(dstPtr,srcPtr,len)
    text(0)==+suffix(0)
  FI
RETURN
 
PROC Encode(CHAR ARRAY in,out)
  BYTE pos,len
  CHAR ARRAY tmp(5)
 
  pos=1 len=0 out(0)=0
  WHILE pos<=in(0)
  DO
    len=GetLength(in,pos)
    StrB(len,tmp)
    Append(out,tmp)
    out(0)==+1
    out(out(0))=in(pos)
    pos==+len
  OD
RETURN
 
PROC Decode(CHAR ARRAY in,out)
  BYTE pos,num,i
  CHAR c
 
  pos=1 out(0)=0
  WHILE pos<=in(0)
  DO
    num=GetNumber(in,@pos)
    c=in(pos)
    pos==+1
    FOR i=1 TO num
    DO
      out(0)==+1
      out(out(0))=c
    OD
  OD
RETURN
 
PROC Main()
  CHAR ARRAY data="WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
  CHAR ARRAY encoded(256),decoded(256)
 
  PrintE("original:")
  PrintE(data)
  PutE()
 
  Encode(data,encoded)
  PrintE("encoded:")
  PrintE(encoded)
  PutE()
 
  Decode(encoded,decoded)
  PrintE("decoded:")
  PrintE(decoded)
RETURN