Push encoder and decoder handling down into the connection objects

This keeps the reader and writer objects clean and simple protocol
decoders/encoders.
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index d7f57b5..f542062 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -1,6 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright 2009-2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright 2009-2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
 
 #include <rfb/CMsgWriter.h>
 #include <rfb/encodings.h>
+#include <rfb/Decoder.h>
 #include <rfb/Hostname.h>
 #include <rfb/LogWriter.h>
 #include <rfb/util.h>
@@ -80,6 +81,8 @@
   setShared(::shared);
   sock = socket;
 
+  memset(decoders, 0, sizeof(decoders));
+
   int encNum = encodingNum(preferredEncoding);
   if (encNum != -1)
     currentEncoding = encNum;
@@ -131,6 +134,9 @@
 {
   OptionsDialog::removeCallback(handleOptions);
 
+  for (int i = 0; i < sizeof(decoders)/sizeof(decoders[0]); i++)
+    delete decoders[i];
+
   if (desktop)
     delete desktop;
 
@@ -380,19 +386,27 @@
   delete [] buffer;
 }
 
-// We start timing on beginRect and stop timing on endRect, to
-// avoid skewing the bandwidth estimation as a result of the server
-// being slow or the network having high latency
-void CConn::beginRect(const Rect& r, int encoding)
+void CConn::dataRect(const Rect& r, int encoding)
 {
   sock->inStream().startTiming();
-  if (encoding != encodingCopyRect) {
-    lastServerEncoding = encoding;
-  }
-}
 
-void CConn::endRect(const Rect& r, int encoding)
-{
+  if (encoding != encodingCopyRect)
+    lastServerEncoding = encoding;
+
+  if (!Decoder::supported(encoding)) {
+    fprintf(stderr, "Unknown rect encoding %d\n", encoding);
+    throw Exception("Unknown rect encoding");
+  }
+
+  if (!decoders[encoding]) {
+    decoders[encoding] = Decoder::createDecoder(encoding, reader());
+    if (!decoders[encoding]) {
+      fprintf(stderr, "Unknown rect encoding %d\n", encoding);
+      throw Exception("Unknown rect encoding");
+    }
+  }
+  decoders[encoding]->readRect(r, this);
+
   sock->inStream().stopTiming();
 }