diff --git a/csrc/codec.c b/csrc/codec.c
--- a/csrc/codec.c
+++ b/csrc/codec.c
@@ -1114,8 +1114,9 @@
 // {{{1 quoted-printable
 
 static char const qp_encmap[] = "0123456789ABCDEF";
+#define QP_MAX_CHARS 71
 
-void qp_enc(uint8_t const *src, size_t srclen,
+void qp_enc(uint8_t split, uint8_t const *src, size_t srclen,
     uint8_t *dst, size_t *dstlen,
     uint8_t const **rem, size_t *remlen)
 {
@@ -1125,9 +1126,16 @@
     assert(rem);
     assert(remlen);
 
-    size_t od = *dstlen, i;
+    size_t od = *dstlen, i, l;
 
-    for(i = 0, *dstlen = 0; i < srclen && *dstlen < od; i++, (*dstlen)++) {
+    for(i = 0, *dstlen = 0, l = 0; i < srclen && *dstlen < od; i++, (*dstlen)++, l++) {
+        if(split && (l >= QP_MAX_CHARS) && (*dstlen + 3 < od)) {
+            dst[*dstlen] = '=';
+            dst[*dstlen + 1] = 13;
+            dst[*dstlen + 2] = 10;
+            *dstlen += 3;
+            l = 0;
+        }
         if((33 <= src[i] && src[i] <= 60) ||
             (62 <= src[i] && src[i] <= 126)) {
             dst[*dstlen] = src[i];
@@ -1138,6 +1146,7 @@
             dst[*dstlen + 1] = qp_encmap[o0];
             dst[*dstlen + 2] = qp_encmap[o1];
             *dstlen += 2;
+            l += 2;
         }
     }
 
@@ -1185,10 +1194,18 @@
             dst[*dstlen] = src[i];
         } else if('=' == src[i]) {
             if(i + 2 >= srclen) { res = 0; goto exit; }
-            uint8_t o0 = qp_decmap[src[i + 1]], o1 = qp_decmap[src[i + 2]];
-            if((o0 | o1) & 0xf0) { res = 1; break; }
-            dst[*dstlen] = o0 << 4 | o1;
-            i += 2;
+            if(13 == src[i + 1] && 10 == src[i + 2]) {
+              i += 2;
+              (*dstlen)--;
+            } else {
+              uint8_t o0 = qp_decmap[src[i + 1]], o1 = qp_decmap[src[i + 2]];
+              if((o0 | o1) & 0xf0) { res = 1; break; }
+              dst[*dstlen] = o0 << 4 | o1;
+              i += 2;
+            }
+        } else if(13 == src[i] && i + 1 < srclen && 10 == src[i + 1]) {
+            dst[(*dstlen)++] = src[i++];
+            dst[*dstlen] = src[i];
         } else { res = 1; goto exit; }
     }
 
diff --git a/csrc/codec.h b/csrc/codec.h
--- a/csrc/codec.h
+++ b/csrc/codec.h
@@ -69,7 +69,7 @@
 int b85_dec_final(uint8_t const *src, size_t srclen,
     uint8_t *dst, size_t *dstlen);
 
-void qp_enc(uint8_t const *src, size_t srclen,
+void qp_enc(uint8_t split, uint8_t const *src, size_t srclen,
     uint8_t *dst, size_t *dstlen,
     uint8_t const **rem, size_t *remlen);
 int qp_dec(uint8_t const *src, size_t srclen,
diff --git a/sandi.cabal b/sandi.cabal
--- a/sandi.cabal
+++ b/sandi.cabal
@@ -1,5 +1,5 @@
 name: sandi
-version: 0.3.6
+version: 0.4.0
 license: BSD3
 license-file: LICENSE
 cabal-version: >= 1.8
@@ -8,7 +8,7 @@
 maintainer: magnus@therning.org
 homepage: http://hackage.haskell.org/package/sandi
 copyright: Magnus Therning, 2012
-category: Codec Conduit
+category: Codec, Conduit
 synopsis: Data encoding library
 description: Reasonably fast data encoding library.
 extra-source-files: csrc/*.h
@@ -26,10 +26,11 @@
     c-sources: csrc/codec.c
     include-dirs: csrc
     ghc-options: -Wall
-    cc-options: -Wall -Wextra
+    cc-options: -fPIC -Wall -Wextra
     build-depends:
-        base >= 4.7 && <4.9,
-        bytestring ==0.10.*
+        base >= 4.7 && < 4.10,
+        bytestring ==0.10.*,
+        stringsearch ==0.3.*
     exposed-modules:
         Codec.Binary.Base16
         Codec.Binary.Base32
diff --git a/src/Codec/Binary/Base16.hs b/src/Codec/Binary/Base16.hs
--- a/src/Codec/Binary/Base16.hs
+++ b/src/Codec/Binary/Base16.hs
@@ -8,8 +8,8 @@
 -- Implemention of base 16 encoding (hex encoding) as specified in RFC 4648
 -- (<http://tools.ietf.org/html/rfc4648>).
 module Codec.Binary.Base16
-    ( b16_enc
-    , b16_dec
+    ( b16Enc
+    , b16Dec
     , encode
     , decode
     ) where
@@ -35,14 +35,14 @@
 -- cannot fail.  Double the length of the input string is allocated for the
 -- encoded data, which is guaranteed to hold the result.
 --
--- >>> b16_enc $ Data.ByteString.pack [0x00]
+-- >>> b16Enc $ Data.ByteString.pack [0x00]
 -- "00"
 --
--- >>> b16_enc $ Data.ByteString.Char8.pack "foobar"
+-- >>> b16Enc $ Data.ByteString.Char8.pack "foobar"
 -- "666F6F626172"
-b16_enc :: BS.ByteString
+b16Enc :: BS.ByteString
     -> BS.ByteString -- ^ The encoded string
-b16_enc bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b16Enc bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen * 2
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -51,8 +51,7 @@
                 poke pOutLen (castEnum maxOutLen)
                 c_b16_enc (castPtr inBuf) (castEnum inLen) outBuf pOutLen pRemBuf pRemLen
                 outLen <- peek pOutLen
-                outBs <- BSU.unsafePackCStringFinalizer outBuf (castEnum outLen) (free outBuf)
-                return outBs
+                BSU.unsafePackCStringFinalizer outBuf (castEnum outLen) (free outBuf)
 
 -- | Decoding function.
 --
@@ -62,18 +61,18 @@
 -- the length of the input string is allocated, which is more than enough to
 -- hold the decoded data.
 --
--- >>> b16_dec $ Data.ByteString.Char8.pack "00"
+-- >>> b16Dec $ Data.ByteString.Char8.pack "00"
 -- Right ("\NUL","")
 --
--- >>> b16_dec $ Data.ByteString.Char8.pack "666F6F626172"
+-- >>> b16Dec $ Data.ByteString.Char8.pack "666F6F626172"
 -- Right ("foobar","")
 --
--- >>> b16_dec $ Data.ByteString.Char8.pack "666F6F62617"
+-- >>> b16Dec $ Data.ByteString.Char8.pack "666F6F62617"
 -- Right ("fooba","7")
--- >>> b16_dec $ Data.ByteString.Char8.pack "666F6F62617g"
+-- >>> b16Dec $ Data.ByteString.Char8.pack "666F6F62617g"
 -- Left ("fooba","g")
-b16_dec :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-b16_dec bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b16Dec :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+b16Dec bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes inLen
     alloca $ \ pOutLen ->
         alloca $ \ pRemBuf ->
@@ -92,11 +91,11 @@
 
 -- | A synonym for 'b16_enc'.
 encode :: BS.ByteString -> BS.ByteString
-encode = b16_enc
+encode = b16Enc
 
 -- | A synonum for 'b16_dec'.
 decode :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) BS.ByteString
-decode bs = case b16_dec bs of
+decode bs = case b16Dec bs of
     Right a@(d, r) -> if BS.null r
             then Right d
             else Left a
diff --git a/src/Codec/Binary/Base32.hs b/src/Codec/Binary/Base32.hs
--- a/src/Codec/Binary/Base32.hs
+++ b/src/Codec/Binary/Base32.hs
@@ -12,10 +12,10 @@
 -- encoded data to make sure the size of the final block of encoded data is 8
 -- bytes too.
 module Codec.Binary.Base32
-    ( b32_encode_part
-    , b32_encode_final
-    , b32_decode_part
-    , b32_decode_final
+    ( b32EncodePart
+    , b32EncodeFinal
+    , b32DecodePart
+    , b32DecodeFinal
     , encode
     , decode
     ) where
@@ -48,12 +48,12 @@
 -- allocated for the encoding to make sure that the remaining part is less than
 -- 5 bytes long, which means it can be passed to 'b32_encode_final' as is.
 --
--- >>> b32_encode_part $ Data.ByteString.Char8.pack "fooba"
+-- >>> b32EncodePart $ Data.ByteString.Char8.pack "fooba"
 -- ("MZXW6YTB","")
--- >>> b32_encode_part $ Data.ByteString.Char8.pack "foobar"
+-- >>> b32EncodePart $ Data.ByteString.Char8.pack "foobar"
 -- ("MZXW6YTB","r")
-b32_encode_part :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-b32_encode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b32EncodePart :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+b32EncodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 5 * 8
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -72,15 +72,15 @@
 --
 -- The final block has to have a size less than 5.
 --
--- >>> b32_encode_final $ Data.ByteString.Char8.pack "r"
+-- >>> b32EncodeFinal $ Data.ByteString.Char8.pack "r"
 -- Just "OI======"
 --
 -- Trying to pass in too large a block result in failure:
 --
--- >>> b32_encode_final $ Data.ByteString.Char8.pack "fooba"
+-- >>> b32EncodeFinal $ Data.ByteString.Char8.pack "fooba"
 -- Nothing
-b32_encode_final :: BS.ByteString -> Maybe BS.ByteString
-b32_encode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b32EncodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b32EncodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 8
     alloca $ \ pOutLen -> do
         r <- c_b32_enc_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -98,17 +98,17 @@
 -- allocated for the output to ensure that the remainder is less than 8 bytes
 -- in size.  Success result in a @Right@ value:
 --
--- >>> b32_decode_part $ Data.ByteString.Char8.pack "MZXW6YTB"
+-- >>> b32DecodePart $ Data.ByteString.Char8.pack "MZXW6YTB"
 -- Right ("fooba","")
--- >>> b32_decode_part $ Data.ByteString.Char8.pack "MZXW6YTBOI======"
+-- >>> b32DecodePart $ Data.ByteString.Char8.pack "MZXW6YTBOI======"
 -- Right ("fooba","OI======")
 --
 -- Failures occur on bad input and result in a @Left@ value:
 --
--- >>> b32_decode_part $ Data.ByteString.Char8.pack "M=XW6YTB"
+-- >>> b32DecodePart $ Data.ByteString.Char8.pack "M=XW6YTB"
 -- Left ("","M=XW6YTB")
-b32_decode_part :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-b32_decode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b32DecodePart :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+b32DecodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 8 * 5
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -130,19 +130,19 @@
 --
 -- The final block has to have a size of 0 or 8:
 --
--- >>> b32_decode_final $ Data.ByteString.Char8.pack "MZXW6YQ="
+-- >>> b32DecodeFinal $ Data.ByteString.Char8.pack "MZXW6YQ="
 -- Just "foob"
--- >>> b32_decode_final $ Data.ByteString.Char8.pack ""
+-- >>> b32DecodeFinal $ Data.ByteString.Char8.pack ""
 -- Just ""
--- >>> b32_decode_final $ Data.ByteString.Char8.pack "MZXW6Y="
+-- >>> b32DecodeFinal $ Data.ByteString.Char8.pack "MZXW6Y="
 -- Nothing
 --
 -- But it must be the encoding of a block that is less than 5 bytes:
 --
--- >>> b32_decode_final $ encode $ Data.ByteString.Char8.pack "fooba"
+-- >>> b32DecodeFinal $ encode $ Data.ByteString.Char8.pack "fooba"
 -- Nothing
-b32_decode_final :: BS.ByteString -> Maybe BS.ByteString
-b32_decode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b32DecodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b32DecodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 5
     alloca $ \ pOutLen -> do
         r <- c_b32_dec_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -162,10 +162,10 @@
 -- >>> encode $ Data.ByteString.Char8.pack "foobar"
 -- "MZXW6YTBOI======"
 encode :: BS.ByteString -> BS.ByteString
-encode bs = let
-        (first, rest) = b32_encode_part bs
-        Just final = b32_encode_final rest
-    in first `BS.append` final
+encode bs = first `BS.append` final
+    where
+        (first, rest) = b32EncodePart bs
+        Just final = b32EncodeFinal rest
 
 -- | Convenience function that combines 'b32_decode_part' and
 -- 'b32_decode_final' to decode a complete string.
@@ -186,5 +186,5 @@
         maybe
             (Left (first, rest))
             (\ fin -> Right (first `BS.append` fin))
-            (b32_decode_final rest))
-    (b32_decode_part bs)
+            (b32DecodeFinal rest))
+    (b32DecodePart bs)
diff --git a/src/Codec/Binary/Base32Hex.hs b/src/Codec/Binary/Base32Hex.hs
--- a/src/Codec/Binary/Base32Hex.hs
+++ b/src/Codec/Binary/Base32Hex.hs
@@ -10,10 +10,10 @@
 -- This encoding is closely related to base 32 and so is its implementation, so
 -- please refer to "Codec.Binary.Base32" for further details.
 module Codec.Binary.Base32Hex
-   ( b32h_encode_part
-   , b32h_encode_final
-   , b32h_decode_part
-   , b32h_decode_final
+   ( b32hEncodePart
+   , b32hEncodeFinal
+   , b32hDecodePart
+   , b32hDecodeFinal
    , encode
    , decode
    ) where
@@ -43,12 +43,12 @@
 --
 -- See 'Codec.Binary.Base32.b32_encode_part'.
 --
--- >>> b32h_encode_part $ Data.ByteString.Char8.pack "fooba"
+-- >>> b32hEncodePart $ Data.ByteString.Char8.pack "fooba"
 -- ("CPNMUOJ1","")
--- >>> b32h_encode_part $ Data.ByteString.Char8.pack "foobar"
+-- >>> b32hEncodePart $ Data.ByteString.Char8.pack "foobar"
 -- ("CPNMUOJ1","r")
-b32h_encode_part :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-b32h_encode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b32hEncodePart :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+b32hEncodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 5 * 8
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -67,12 +67,12 @@
 --
 -- See 'Codec.Binary.Base32.b32_encode_final'.
 --
--- >>> b32h_encode_final $ Data.ByteString.Char8.pack "r"
+-- >>> b32hEncodeFinal $ Data.ByteString.Char8.pack "r"
 -- Just "E8======"
--- >>> b32h_encode_final $ Data.ByteString.Char8.pack "fooba"
+-- >>> b32hEncodeFinal $ Data.ByteString.Char8.pack "fooba"
 -- Nothing
-b32h_encode_final :: BS.ByteString -> Maybe BS.ByteString
-b32h_encode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b32hEncodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b32hEncodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 8
     alloca $ \ pOutLen -> do
         r <- c_b32h_enc_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -88,14 +88,14 @@
 --
 -- See 'Codec.Binary.Base32.b32_decode_part'.
 --
--- >>> b32h_decode_part $ Data.ByteString.Char8.pack "CPNMUOJ1"
+-- >>> b32hDecodePart $ Data.ByteString.Char8.pack "CPNMUOJ1"
 -- Right ("fooba","")
--- >>> b32h_decode_part $ Data.ByteString.Char8.pack "CPNMUOJ1E8======"
+-- >>> b32hDecodePart $ Data.ByteString.Char8.pack "CPNMUOJ1E8======"
 -- Right ("fooba","E8======")
--- >>> b32h_decode_part $ Data.ByteString.Char8.pack "C=NMUOJ1"
+-- >>> b32hDecodePart $ Data.ByteString.Char8.pack "C=NMUOJ1"
 -- Left ("","C=NMUOJ1")
-b32h_decode_part :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-b32h_decode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b32hDecodePart :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+b32hDecodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 8 * 5
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -117,16 +117,16 @@
 --
 -- See 'Codec.Binary.Base32.b32_decode_final'.
 --
--- >>> b32h_decode_final $ Data.ByteString.Char8.pack "CPNMUOG="
+-- >>> b32hDecodeFinal $ Data.ByteString.Char8.pack "CPNMUOG="
 -- Just "foob"
--- >>> b32h_decode_final $ Data.ByteString.Char8.pack ""
+-- >>> b32hDecodeFinal $ Data.ByteString.Char8.pack ""
 -- Just ""
--- >>> b32h_decode_final $ Data.ByteString.Char8.pack "CPNMUO="
+-- >>> b32hDecodeFinal $ Data.ByteString.Char8.pack "CPNMUO="
 -- Nothing
--- >>> b32h_decode_final $ encode $ Data.ByteString.Char8.pack "fooba"
+-- >>> b32hDecodeFinal $ encode $ Data.ByteString.Char8.pack "fooba"
 -- Nothing
-b32h_decode_final :: BS.ByteString -> Maybe BS.ByteString
-b32h_decode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b32hDecodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b32hDecodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 5
     alloca $ \ pOutLen -> do
         r <- c_b32h_dec_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -146,10 +146,10 @@
 -- >>> encode $ Data.ByteString.Char8.pack "foobar"
 -- "CPNMUOJ1E8======"
 encode :: BS.ByteString -> BS.ByteString
-encode bs = let
-        (first, rest) = b32h_encode_part bs
-        Just final = b32h_encode_final rest
-    in first `BS.append` final
+encode bs = first `BS.append` final
+    where
+        (first, rest) = b32hEncodePart bs
+        Just final = b32hEncodeFinal rest
 
 -- | Convenience function that combines 'b32h_decode_part' and
 -- 'b32h_decode_final' to decode a complete string.
@@ -170,5 +170,5 @@
         maybe
             (Left (first, rest))
             (\ fin -> Right (first `BS.append` fin))
-            (b32h_decode_final rest))
-    (b32h_decode_part bs)
+            (b32hDecodeFinal rest))
+    (b32hDecodePart bs)
diff --git a/src/Codec/Binary/Base64.hs b/src/Codec/Binary/Base64.hs
--- a/src/Codec/Binary/Base64.hs
+++ b/src/Codec/Binary/Base64.hs
@@ -12,10 +12,10 @@
 -- encoded data to make sure the size of the final block of encoded data is 4
 -- bytes too.
 module Codec.Binary.Base64
-    ( b64_encode_part
-    , b64_encode_final
-    , b64_decode_part
-    , b64_decode_final
+    ( b64EncodePart
+    , b64EncodeFinal
+    , b64DecodePart
+    , b64DecodeFinal
     , encode
     , decode
     ) where
@@ -48,12 +48,12 @@
 -- allocated for the encoding to make sure that the remaining part is less than
 -- 3 bytes long, which means it can be passed to 'b64_encode_final' as is.
 --
--- >>> b64_encode_part $ Data.ByteString.Char8.pack "foo"
+-- >>> b64EncodePart $ Data.ByteString.Char8.pack "foo"
 -- ("Zm9v","")
--- >>> b64_encode_part $ Data.ByteString.Char8.pack "foob"
+-- >>> b64EncodePart $ Data.ByteString.Char8.pack "foob"
 -- ("Zm9v","b")
-b64_encode_part :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-b64_encode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b64EncodePart :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+b64EncodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 3 * 4
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -72,15 +72,15 @@
 --
 -- The final block has to have a size less than 3.
 --
--- >>> b64_encode_final $ Data.ByteString.Char8.pack "r"
+-- >>> b64EncodeFinal $ Data.ByteString.Char8.pack "r"
 -- Just "cg=="
 --
 -- Trying to pass in too large a block result in failure:
 --
--- >>> b64_encode_final $ Data.ByteString.Char8.pack "foo"
+-- >>> b64EncodeFinal $ Data.ByteString.Char8.pack "foo"
 -- Nothing
-b64_encode_final :: BS.ByteString -> Maybe BS.ByteString
-b64_encode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b64EncodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b64EncodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 4
     alloca $ \ pOutLen -> do
         r <- c_b64_enc_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -98,17 +98,17 @@
 -- allocated for the output to ensure that the remainder is less than 4 bytes
 -- in size.  Success result in a @Right@ value:
 --
--- >>> b64_decode_part $ Data.ByteString.Char8.pack "Zm9v"
+-- >>> b64DecodePart $ Data.ByteString.Char8.pack "Zm9v"
 -- Right ("foo","")
--- >>> b64_decode_part $ Data.ByteString.Char8.pack "Zm9vYmE="
+-- >>> b64DecodePart $ Data.ByteString.Char8.pack "Zm9vYmE="
 -- Right ("foo","YmE=")
 --
 -- Failures occur on bad input and result in a @Left@ value:
 --
--- >>> b64_decode_part $ Data.ByteString.Char8.pack "Z=9v"
+-- >>> b64DecodePart $ Data.ByteString.Char8.pack "Z=9v"
 -- Left ("","Z=9v")
-b64_decode_part :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-b64_decode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b64DecodePart :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+b64DecodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 4 * 3
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -130,19 +130,19 @@
 --
 -- The final block has to have a size of 0 or 4:
 --
--- >>> b64_decode_final $ Data.ByteString.Char8.pack "Zm8="
+-- >>> b64DecodeFinal $ Data.ByteString.Char8.pack "Zm8="
 -- Just "fo"
--- >>> b64_decode_final $ Data.ByteString.Char8.pack ""
+-- >>> b64DecodeFinal $ Data.ByteString.Char8.pack ""
 -- Just ""
--- >>> b64_decode_final $ Data.ByteString.Char8.pack "Zm="
+-- >>> b64DecodeFinal $ Data.ByteString.Char8.pack "Zm="
 -- Nothing
 --
 -- But it must be the encoding of a block that is less than 3 bytes:
 --
--- >>> b64_decode_final $ encode $ Data.ByteString.Char8.pack "foo"
+-- >>> b64DecodeFinal $ encode $ Data.ByteString.Char8.pack "foo"
 -- Nothing
-b64_decode_final :: BS.ByteString -> Maybe BS.ByteString
-b64_decode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b64DecodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b64DecodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 3
     alloca $ \ pOutLen -> do
         r <- c_b64_dec_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -162,10 +162,10 @@
 -- >>> encode $ Data.ByteString.Char8.pack "foobar"
 -- "Zm9vYmFy"
 encode :: BS.ByteString -> BS.ByteString
-encode bs = let
-        (first, rest) = b64_encode_part bs
-        Just final = b64_encode_final rest
-    in first `BS.append` final
+encode bs = first `BS.append` final
+    where
+        (first, rest) = b64EncodePart bs
+        Just final = b64EncodeFinal rest
 
 -- | Convenience function that combines 'b64_decode_part' and
 -- 'b64_decode_final' to decode a complete string.
@@ -186,5 +186,5 @@
         maybe
             (Left (first, rest))
             (\ fin -> Right (first `BS.append` fin))
-            (b64_decode_final rest))
-    (b64_decode_part bs)
+            (b64DecodeFinal rest))
+    (b64DecodePart bs)
diff --git a/src/Codec/Binary/Base64Url.hs b/src/Codec/Binary/Base64Url.hs
--- a/src/Codec/Binary/Base64Url.hs
+++ b/src/Codec/Binary/Base64Url.hs
@@ -14,10 +14,10 @@
 -- Please refer to "Codec.Binary.Base64" for the details of all functions in
 -- this module.
 module Codec.Binary.Base64Url
-    ( b64u_encode_part
-    , b64u_encode_final
-    , b64u_decode_part
-    , b64u_decode_final
+    ( b64uEncodePart
+    , b64uEncodeFinal
+    , b64uDecodePart
+    , b64uDecodeFinal
     , encode
     , decode
     ) where
@@ -43,8 +43,8 @@
 foreign import ccall "static b64.h b64u_dec_final"
     c_b64u_dec_final :: Ptr Word8 -> CSize -> Ptr Word8 -> Ptr CSize -> IO CInt
 
-b64u_encode_part :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-b64u_encode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b64uEncodePart :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+b64uEncodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 3 * 4
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -59,8 +59,8 @@
                 outBs <- unsafePackCStringFinalizer outBuf (castEnum outLen) (free outBuf)
                 return (outBs, remBs)
 
-b64u_encode_final :: BS.ByteString -> Maybe BS.ByteString
-b64u_encode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b64uEncodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b64uEncodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 4
     alloca $ \ pOutLen -> do
         r <- c_b64u_enc_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -72,8 +72,8 @@
                 return $ Just outBs
             else free outBuf >> return Nothing
 
-b64u_decode_part :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-b64u_decode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b64uDecodePart :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+b64uDecodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 4 * 3
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -91,8 +91,8 @@
                     then return $ Right (outBs, remBs)
                     else return $ Left (outBs, remBs)
 
-b64u_decode_final :: BS.ByteString -> Maybe BS.ByteString
-b64u_decode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b64uDecodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b64uDecodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 3
     alloca $ \ pOutLen -> do
         r <- c_b64u_dec_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -105,10 +105,10 @@
             else free outBuf >> return Nothing
 
 encode :: BS.ByteString -> BS.ByteString
-encode bs = let
-        (first, rest) = b64u_encode_part bs
-        Just final = b64u_encode_final rest
-    in first `BS.append` final
+encode bs = first `BS.append` final
+    where
+        (first, rest) = b64uEncodePart bs
+        Just final = b64uEncodeFinal rest
 
 decode :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) BS.ByteString
 decode bs = either
@@ -117,5 +117,5 @@
         maybe
             (Left (first, rest))
             (\ fin -> Right (first `BS.append` fin))
-            (b64u_decode_final rest))
-    (b64u_decode_part bs)
+            (b64uDecodeFinal rest))
+    (b64uDecodePart bs)
diff --git a/src/Codec/Binary/Base85.hs b/src/Codec/Binary/Base85.hs
--- a/src/Codec/Binary/Base85.hs
+++ b/src/Codec/Binary/Base85.hs
@@ -7,10 +7,10 @@
 --
 -- Implemented as described at <http://en.wikipedia.org/wiki/Ascii85>.
 module Codec.Binary.Base85
-   ( b85_encode_part
-   , b85_encode_final
-   , b85_decode_part
-   , b85_decode_final
+   ( b85EncodePart
+   , b85EncodeFinal
+   , b85DecodePart
+   , b85DecodeFinal
    , encode
    , decode
    ) where
@@ -40,17 +40,17 @@
 --
 -- Encodes as large a part as possible of the indata.
 --
--- >>> b85_encode_part $ Data.ByteString.Char8.pack "foobar"
+-- >>> b85EncodePart $ Data.ByteString.Char8.pack "foobar"
 -- ("AoDTs","ar")
 --
 -- It supports special handling of both all-zero groups and all-space groups.
 --
--- >>> b85_encode_part $ Data.ByteString.Char8.pack "    "
+-- >>> b85EncodePart $ Data.ByteString.Char8.pack "    "
 -- ("y", "")
--- >>> b85_encode_part $ Data.ByteString.Char8.pack "\0\0\0\0"
+-- >>> b85EncodePart $ Data.ByteString.Char8.pack "\0\0\0\0"
 -- ("z", "")
-b85_encode_part :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-b85_encode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b85EncodePart :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+b85EncodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 4 * 5
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -68,10 +68,10 @@
 
 -- | Encoding function for the final block.
 --
--- >>> b85_encode_final $ Data.ByteString.Char8.pack "ar"
+-- >>> b85EncodeFinal $ Data.ByteString.Char8.pack "ar"
 -- Just "@<)"
-b85_encode_final :: BS.ByteString -> Maybe BS.ByteString
-b85_encode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b85EncodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b85EncodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 5
     alloca $ \ pOutLen -> do
         r <- c_b85_enc_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -87,11 +87,11 @@
 --
 -- Decode as large a portion of the input as possible.
 --
--- >>> b85_decode_part $ Data.ByteString.Char8.pack "AoDTs"
+-- >>> b85DecodePart $ Data.ByteString.Char8.pack "AoDTs"
 -- Right ("foob","")
--- >>> b85_decode_part $ Data.ByteString.Char8.pack "AoDTs@<)"
+-- >>> b85DecodePart $ Data.ByteString.Char8.pack "AoDTs@<)"
 -- Right ("foob","@<)")
--- >>> b85_decode_part $ Data.ByteString.Char8.pack "@<)"
+-- >>> b85DecodePart $ Data.ByteString.Char8.pack "@<)"
 -- Right ("","@<)")
 --
 -- At least 512 bytes of data is allocated for the output, but because of the
@@ -100,10 +100,10 @@
 -- to allocate 5 times the length of the input.  It seemed a good trade-off to
 -- sometimes have to call the function more than once instead.)
 --
--- >>> either snd snd $ b85_decode_part $ Data.ByteString.Char8.pack $ Prelude.take 129 $ repeat 'y'
+-- >>> either snd snd $ b85DecodePart $ Data.ByteString.Char8.pack $ Prelude.take 129 $ repeat 'y'
 -- "y"
-b85_decode_part :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-b85_decode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b85DecodePart :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+b85DecodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = max 512 $ inLen `div` 5 * 4
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -123,14 +123,14 @@
 
 -- | Decoding function for the final block.
 --
--- >>> b85_decode_final $ Data.ByteString.Char8.pack "@<)"
+-- >>> b85DecodeFinal $ Data.ByteString.Char8.pack "@<)"
 -- Just "ar"
--- >>> b85_decode_final $ Data.ByteString.Char8.pack ""
+-- >>> b85DecodeFinal $ Data.ByteString.Char8.pack ""
 -- Just ""
--- >>> b85_decode_final $ Data.ByteString.Char8.pack "AoDTs"
+-- >>> b85DecodeFinal $ Data.ByteString.Char8.pack "AoDTs"
 -- Nothing
-b85_decode_final :: BS.ByteString -> Maybe BS.ByteString
-b85_decode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+b85DecodeFinal :: BS.ByteString -> Maybe BS.ByteString
+b85DecodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 4
     alloca $ \ pOutLen -> do
         r <- c_b85_dec_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -150,10 +150,10 @@
 -- >>> encode  $ Data.ByteString.Char8.pack "foobar"
 -- "AoDTs@<)"
 encode :: BS.ByteString -> BS.ByteString
-encode bs = let
-        (first, rest) = b85_encode_part bs
-        Just final = b85_encode_final rest
-    in first `BS.append` final
+encode bs = first `BS.append` final
+    where
+        (first, rest) = b85EncodePart bs
+        Just final = b85EncodeFinal rest
 
 -- | Convenience function that combines 'b85_decode_part' and
 -- 'b85_decode_final' to decode a complete string.
@@ -163,8 +163,9 @@
 -- >>> encode  $ Data.ByteString.Char8.pack "AoDTs@<)"
 -- "foobar"
 decode :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) BS.ByteString
-decode bs = let
-        iterateDecode bss re = case b85_decode_part re of
+decode bs = either Left handleFinal (iterateDecode [] bs)
+    where
+        iterateDecode bss re = case b85DecodePart re of
             Right (d, r) ->
                 if BS.null d
                     then Right (BS.concat (reverse bss), r)
@@ -174,9 +175,5 @@
         handleFinal a@(first, rest) = maybe
             (Left a)
             (\ final -> Right (first `BS.append` final))
-            (b85_decode_final rest)
+            (b85DecodeFinal rest)
 
-    in either
-            Left
-            handleFinal
-            (iterateDecode [] bs)
diff --git a/src/Codec/Binary/QuotedPrintable.hs b/src/Codec/Binary/QuotedPrintable.hs
--- a/src/Codec/Binary/QuotedPrintable.hs
+++ b/src/Codec/Binary/QuotedPrintable.hs
@@ -7,14 +7,10 @@
 --
 -- Implementation of Quoted-Printable based on RFC 2045
 -- (<http://tools.ietf.org/html/rfc2045>).
---
--- This encoding encodes /everything/ that is passed in, it will not try to
--- guess the native line ending for your architecture.  In other words, if you
--- are using this to encode text you need to split it into separate lines
--- before encoding.
 module Codec.Binary.QuotedPrintable
-    ( qp_enc
-    , qp_dec
+    ( qpEncode
+    , qpEncodeSL
+    , qpDecode
     , encode
     , decode
     ) where
@@ -30,31 +26,61 @@
 castEnum = toEnum . fromEnum
 
 foreign import ccall "static qp.h qp_enc"
-    c_qp_enc :: Ptr Word8 -> CSize -> Ptr Word8 -> Ptr CSize -> Ptr (Ptr Word8) -> Ptr CSize -> IO ()
+    c_qp_enc :: Word8 -> Ptr Word8 -> CSize -> Ptr Word8 -> Ptr CSize -> Ptr (Ptr Word8) -> Ptr CSize -> IO ()
 
 foreign import ccall "static qp.h qp_dec"
     c_qp_dec :: Ptr Word8 -> CSize -> Ptr Word8 -> Ptr CSize -> Ptr (Ptr Word8) -> Ptr CSize -> IO CInt
 
 -- | Encoding function.
 --
+-- This function encodes /everything/ that is passed in, it will not try to
+-- guess the native line ending for your architecture.  In other words, if you
+-- are using this to encode text you need to split it into separate lines
+-- before encoding.
+--
 -- This function allocates enough space to hold twice the size of the indata
 -- (or at least 512 bytes) and then encodes as much as possible of the indata.
 -- That means there is a risk that the encoded data won't fit and in that case
 -- the second part of the pair contains the remainder of the indata.
 --
--- >>> qp_enc $ Data.ByteString.Char8.pack "="
+-- >>> qpEncode $ Data.ByteString.Char8.pack "="
 -- ("=3D","")
--- >>> snd $ qp_enc $ Data.ByteString.Char8.pack $ Data.List.take 171 $ repeat '='
+-- >>> snd $ qpEncode $ Data.ByteString.Char8.pack $ Data.List.take 171 $ repeat '='
 -- "="
-qp_enc :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-qp_enc bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+--
+-- All space (0x20) and tab (0x9) characters are encoded:
+--
+-- >>> qpEncode $ Data.ByteString.Char8.pack " \t"
+-- ("=20=09","")
+--
+-- Since the input is supposed to have been split prior to calling this
+-- function all occurances of CR and LF are encoded.
+--
+-- >>> qpEncode $ Data.ByteString.Char8.pack "\n\r\r\n\n\r"
+-- ("=0A=0D=0D=0A=0A=0D","")
+--
+-- Soft line breaks are inserted as needed
+--
+-- >>> qpEncode $ Data.ByteString.Char8.pack "========================="
+-- ("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=\r\n=3D","")
+qpEncode :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+qpEncode = qpEnc' 1
+
+-- | Single line encoding function.
+--
+-- Like 'qpEncode', but without inserting soft line breaks.
+qpEncodeSL :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+qpEncodeSL = qpEnc' 0
+
+qpEnc' :: Word8 -> BS.ByteString -> (BS.ByteString, BS.ByteString)
+qpEnc' split bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutBuf = max 512 (2 * inLen)
     outBuf <- mallocBytes maxOutBuf
     alloca $ \ pOutLen ->
         alloca $ \ pRemBuf ->
             alloca $ \ pRemLen -> do
                 poke pOutLen (castEnum maxOutBuf)
-                c_qp_enc (castPtr inBuf) (castEnum inLen) outBuf pOutLen pRemBuf pRemLen
+                c_qp_enc split (castPtr inBuf) (castEnum inLen) outBuf pOutLen pRemBuf pRemLen
                 outLen <- peek pOutLen
                 newOutBuf <- reallocBytes outBuf (castEnum outLen)
                 remBuf <- peek pRemBuf
@@ -65,36 +91,56 @@
 
 -- | Decoding function.
 --
--- >>> qp_dec $ Data.ByteString.Char8.pack "foobar"
+-- >>> qpDecode $ Data.ByteString.Char8.pack "foobar"
 -- Right "foobar"
--- >>> qp_dec $ Data.ByteString.Char8.pack "1=20+=201=20=3D=202"
+-- >>> qpDecode $ Data.ByteString.Char8.pack "1=20+=201=20=3D=202"
 -- Right "1 + 1 = 2"
 --
 -- The input data is allowed to use lowercase letters in the hexadecimal
 -- representation of an octets value, even though the standard says that only
 -- uppercase letters may be used:
 --
--- >>> qp_dec $ Data.ByteString.Char8.pack "=3D"
+-- >>> qpDecode $ Data.ByteString.Char8.pack "=3D"
 -- Right "="
--- >>> qp_dec $ Data.ByteString.Char8.pack "=3d"
+-- >>> qpDecode $ Data.ByteString.Char8.pack "=3d"
 -- Right "="
 --
 -- It also allows the input to encode _all_ octets in the hexadecimal
 -- representation:
 --
--- >>> qp_dec $ Data.ByteString.Char8.pack "=20!"
+-- >>> qpDecode $ Data.ByteString.Char8.pack "=20!"
 -- Right (" !","")
--- >>> qp_dec $ Data.ByteString.Char8.pack "=20=21"
+-- >>> qpDecode $ Data.ByteString.Char8.pack "=20=21"
 -- Right (" !","")
 --
 -- A @Left@ value is only ever returned on decoding errors.
 --
--- >>> qp_dec $ Data.ByteString.Char8.pack "=2"
+-- >>> qpDecode $ Data.ByteString.Char8.pack "=2"
 -- Right ("","=2")
--- >>> qp_dec $ Data.ByteString.Char8.pack "=2g"
+-- >>> qpDecode $ Data.ByteString.Char8.pack "=2g"
 -- Left ("","=2g")
-qp_dec :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-qp_dec bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+--
+-- Per the specification a CRLF pair is left in, but a single CR or LF is an
+-- error.
+--
+-- >>> qpDecode $ Data.ByteString.Char8.pack "\r\n"
+-- Right ("\r\n","")
+-- >>> qpDecode $ Data.ByteString.Char8.pack "\n"
+-- Left ("","\n")
+-- >>> qpDecode $ Data.ByteString.Char8.pack "\r"
+-- Left ("","\r")
+--
+-- the same goes for space and tab characters
+--
+-- >>> qpDecode $ Data.ByteString.Char8.pack " \t"
+-- Right (" \t","")
+--
+-- The function deals properly with soft line breaks.
+--
+-- >>> qpDecode $ Data.ByteString.Char8.pack " =\r\n"
+-- Right (" ","")
+qpDecode :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+qpDecode bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes inLen
     alloca $ \ pOutLen ->
         alloca $ \ pRemBuf ->
@@ -111,15 +157,13 @@
                     then return $ Right (outBs, remBs)
                     else return $ Left (outBs, remBs)
 
--- | Convenient function that calls 'qp_enc' repeatedly until the whole input
+-- | Convenient function that calls 'qpEncode' repeatedly until the whole input
 -- data is encoded.
 encode :: BS.ByteString -> BS.ByteString
-encode = BS.concat . takeWhile (not . BS.null) . unfoldr (Just . qp_enc)
+encode = BS.concat . takeWhile (not . BS.null) . unfoldr (Just . qpEncode)
 
--- | A synonym for 'qp_dec'.
+-- | A synonym for 'qpDec'.
 decode :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) BS.ByteString
-decode bs = case qp_dec bs of
-    Right a@(d, r) -> if BS.null r
-            then Right d
-            else Left a
-    Left a -> Left a
+decode = either Left goR . qpDecode
+  where
+    goR a@(d, r) = if BS.null r then Right d else Left a
diff --git a/src/Codec/Binary/Uu.hs b/src/Codec/Binary/Uu.hs
--- a/src/Codec/Binary/Uu.hs
+++ b/src/Codec/Binary/Uu.hs
@@ -18,10 +18,10 @@
 -- data into lines, and unchopping lines into encoded data is left as an
 -- exercise to the reader.  (Patches are welcome.)
 module Codec.Binary.Uu
-    ( uu_encode_part
-    , uu_encode_final
-    , uu_decode_part
-    , uu_decode_final
+    ( uuEncodePart
+    , uuEncodeFinal
+    , uuDecodePart
+    , uuDecodeFinal
     , encode
     , decode
     ) where
@@ -54,12 +54,12 @@
 -- allocated for the encoding to make sure that the remaining part is less than
 -- 3 bytes long, which means it can be passed to 'uu_encode_final' as is.
 --
--- >>> uu_encode_part $ Data.ByteString.Char8.pack "foo"
+-- >>> uuEncodePart $ Data.ByteString.Char8.pack "foo"
 -- ("9F]O","")
--- >>> uu_encode_part $ Data.ByteString.Char8.pack "foob"
+-- >>> uuEncodePart $ Data.ByteString.Char8.pack "foob"
 -- ("9F]O","b")
-uu_encode_part :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-uu_encode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+uuEncodePart :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+uuEncodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 3 * 4
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -78,15 +78,15 @@
 --
 -- The final block has to have a size less than 3.
 --
--- >>> uu_encode_final $ Data.ByteString.Char8.pack "r"
+-- >>> uuEncodeFinal $ Data.ByteString.Char8.pack "r"
 -- Just "<@"
 --
 -- Trying to pass in too large a block result in failure:
 --
--- >>> uu_encode_final $ Data.ByteString.Char8.pack "foo"
+-- >>> uuEncodeFinal $ Data.ByteString.Char8.pack "foo"
 -- Nothing
-uu_encode_final :: BS.ByteString -> Maybe BS.ByteString
-uu_encode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+uuEncodeFinal :: BS.ByteString -> Maybe BS.ByteString
+uuEncodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 4
     alloca $ \ pOutLen -> do
         r <- c_uu_enc_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -104,17 +104,17 @@
 -- allocated for the output to ensure that the remainder is less than 4 bytes
 -- in size.  Success result in a @Right@ value:
 --
--- >>> uu_decode_part $ Data.ByteString.Char8.pack "9F]O"
+-- >>> uuDecodePart $ Data.ByteString.Char8.pack "9F]O"
 -- Right ("foo","")
--- >>> uu_decode_part $ Data.ByteString.Char8.pack "9F]O8F$"
+-- >>> uuDecodePart $ Data.ByteString.Char8.pack "9F]O8F$"
 -- Right ("foo","8F$")
 --
 -- Failures occur on bad input and result in a @Left@ value:
 --
--- >>> uu_decode_part $ Data.ByteString.Char8.pack "9F 0"
+-- >>> uuDecodePart $ Data.ByteString.Char8.pack "9F 0"
 -- Left ("","9F 0")
-uu_decode_part :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-uu_decode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+uuDecodePart :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+uuDecodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 4 * 3
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -136,19 +136,19 @@
 --
 -- The final block has to have a size of 0 or 4:
 --
--- >>> uu_decode_final $ Data.ByteString.Char8.pack "9F\\"
+-- >>> uuDecodeFinal $ Data.ByteString.Char8.pack "9F\\"
 -- Just "fo"
--- >>> uu_decode_final $ Data.ByteString.Char8.pack ""
+-- >>> uuDecodeFinal $ Data.ByteString.Char8.pack ""
 -- Just ""
--- >>> uu_decode_final $ Data.ByteString.Char8.pack "9F¬"
+-- >>> uuDecodeFinal $ Data.ByteString.Char8.pack "9F¬"
 -- Nothing
 --
 -- But it must be the encoding of a block that is less than 3 bytes:
 --
--- >>> uu_decode_final $ encode $ Data.ByteString.Char8.pack "foo"
+-- >>> uuDecodeFinal $ encode $ Data.ByteString.Char8.pack "foo"
 -- Nothing
-uu_decode_final :: BS.ByteString -> Maybe BS.ByteString
-uu_decode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+uuDecodeFinal :: BS.ByteString -> Maybe BS.ByteString
+uuDecodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 3
     alloca $ \ pOutLen -> do
         r <- c_uu_dec_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -168,10 +168,10 @@
 -- >>> encode $ Data.ByteString.Char8.pack "foobar"
 -- "9F]O8F%R"
 encode :: BS.ByteString -> BS.ByteString
-encode bs = let
-        (first, rest) = uu_encode_part bs
-        Just final = uu_encode_final rest
-    in first `BS.append` final
+encode bs = first `BS.append` final
+    where
+        (first, rest) = uuEncodePart bs
+        Just final = uuEncodeFinal rest
 
 -- | Convenience function that combines 'uu_decode_part' and
 -- 'uu_decode_final' to decode a complete string.
@@ -192,5 +192,5 @@
         maybe
             (Left (first, rest))
             (\ fin -> Right (first `BS.append` fin))
-            (uu_decode_final rest))
-    (uu_decode_part bs)
+            (uuDecodeFinal rest))
+    (uuDecodePart bs)
diff --git a/src/Codec/Binary/Xx.hs b/src/Codec/Binary/Xx.hs
--- a/src/Codec/Binary/Xx.hs
+++ b/src/Codec/Binary/Xx.hs
@@ -14,10 +14,10 @@
 -- regarding the functions can be found in the documentation of
 -- "Codec.Binary.Uu".
 module Codec.Binary.Xx
-    ( xx_encode_part
-    , xx_encode_final
-    , xx_decode_part
-    , xx_decode_final
+    ( xxEncodePart
+    , xxEncodeFinal
+    , xxDecodePart
+    , xxDecodeFinal
     , encode
     , decode
     ) where
@@ -45,12 +45,12 @@
 
 -- | Encoding function.
 --
--- >>> xx_encode_part $ Data.ByteString.Char8.pack "foo"
+-- >>> xxEncodePart $ Data.ByteString.Char8.pack "foo"
 -- ("Naxj","")
--- >>> xx_encode_part $ Data.ByteString.Char8.pack "foob"
+-- >>> xxEncodePart $ Data.ByteString.Char8.pack "foob"
 -- ("Naxj","b")
-xx_encode_part :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-xx_encode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+xxEncodePart :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+xxEncodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 3 * 4
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -67,12 +67,12 @@
 
 -- | Encoding function for the final block.
 --
--- >>> xx_encode_final $ Data.ByteString.Char8.pack "r"
+-- >>> xxEncodeFinal $ Data.ByteString.Char8.pack "r"
 -- Just "QU"
--- >>> xx_encode_final $ Data.ByteString.Char8.pack "foo"
+-- >>> xxEncodeFinal $ Data.ByteString.Char8.pack "foo"
 -- Nothing
-xx_encode_final :: BS.ByteString -> Maybe BS.ByteString
-xx_encode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+xxEncodeFinal :: BS.ByteString -> Maybe BS.ByteString
+xxEncodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 4
     alloca $ \ pOutLen -> do
         r <- c_xx_enc_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -86,15 +86,15 @@
 
 -- | Decoding function.
 --
--- >>> xx_decode_part $ Data.ByteString.Char8.pack "Naxj"
+-- >>> xxDecodePart $ Data.ByteString.Char8.pack "Naxj"
 -- Right ("foo","")
--- >>> xx_decode_part $ Data.ByteString.Char8.pack "NaxjMa3"
+-- >>> xxDecodePart $ Data.ByteString.Char8.pack "NaxjMa3"
 -- Right ("foo","Ma3")
 --
--- >>> xx_decode_part $ Data.ByteString.Char8.pack "Na j"
+-- >>> xxDecodePart $ Data.ByteString.Char8.pack "Na j"
 -- Left ("","Na J")
-xx_decode_part :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-xx_decode_part bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+xxDecodePart :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+xxDecodePart bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = inLen `div` 4 * 3
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -114,17 +114,17 @@
 
 -- | Decoding function for the final block.
 --
--- >>> xx_decode_final $ Data.ByteString.Char8.pack "Naw"
+-- >>> xxDecodeFinal $ Data.ByteString.Char8.pack "Naw"
 -- Just "fo"
--- >>> xx_decode_final $ Data.ByteString.Char8.pack ""
+-- >>> xxDecodeFinal $ Data.ByteString.Char8.pack ""
 -- Just ""
--- >>> xx_decode_final $ Data.ByteString.Char8.pack "Na "
+-- >>> xxDecodeFinal $ Data.ByteString.Char8.pack "Na "
 -- Nothing
 --
--- >>> xx_decode_final $ encode $ Data.ByteString.Char8.pack "foo"
+-- >>> xxDecodeFinal $ encode $ Data.ByteString.Char8.pack "foo"
 -- Nothing
-xx_decode_final :: BS.ByteString -> Maybe BS.ByteString
-xx_decode_final bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+xxDecodeFinal :: BS.ByteString -> Maybe BS.ByteString
+xxDecodeFinal bs = U.unsafePerformIO $ unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes 3
     alloca $ \ pOutLen -> do
         r <- c_xx_dec_final (castPtr inBuf) (castEnum inLen) outBuf pOutLen
@@ -137,10 +137,10 @@
             else free outBuf >> return Nothing
 
 encode :: BS.ByteString -> BS.ByteString
-encode bs = let
-        (first, rest) = xx_encode_part bs
-        Just final = xx_encode_final rest
-    in first `BS.append` final
+encode bs = first `BS.append` final
+    where
+        (first, rest) = xxEncodePart bs
+        Just final = xxEncodeFinal rest
 
 decode :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) BS.ByteString
 decode bs = either
@@ -149,5 +149,5 @@
         maybe
             (Left (first, rest))
             (\ fin -> Right (first `BS.append` fin))
-            (xx_decode_final rest))
-    (xx_decode_part bs)
+            (xxDecodeFinal rest))
+    (xxDecodePart bs)
diff --git a/src/Codec/Binary/Yenc.hs b/src/Codec/Binary/Yenc.hs
--- a/src/Codec/Binary/Yenc.hs
+++ b/src/Codec/Binary/Yenc.hs
@@ -8,8 +8,8 @@
 -- Implementation based on the specification found at
 -- <http://yence.sourceforge.net/docs/protocol/version1_3_draft.html>.
 module Codec.Binary.Yenc
-    ( y_enc
-    , y_dec
+    ( yEncode
+    , yDecode
     , encode
     , decode
     ) where
@@ -37,12 +37,12 @@
 -- indata.  That means there is a risk that the encoded data won't fit and in
 -- that case the second part of the pair contains the remainder of the indata.
 --
--- >>> y_enc $ Data.ByteString.Char8.pack "foobar"
+-- >>> yEncode $ Data.ByteString.Char8.pack "foobar"
 -- ("\144\153\153\140\139\156","")
--- >>> snd $ y_enc $ Data.ByteString.Char8.pack $ Data.List.take 257 $ repeat '\x13'
+-- >>> snd $ yEncode $ Data.ByteString.Char8.pack $ Data.List.take 257 $ repeat '\x13'
 -- "\DC3"
-y_enc :: BS.ByteString -> (BS.ByteString, BS.ByteString)
-y_enc bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+yEncode :: BS.ByteString -> (BS.ByteString, BS.ByteString)
+yEncode bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     let maxOutLen = max 512 (ceiling $ (toRational inLen) * 1.2)
     outBuf <- mallocBytes maxOutLen
     alloca $ \ pOutLen ->
@@ -60,18 +60,18 @@
 
 -- | Decoding function.
 --
--- >>> y_dec $ Data.ByteString.pack [144,153,153,140,139,156]
+-- >>> yDecode $ Data.ByteString.pack [144,153,153,140,139,156]
 -- Right ("foobar","")
--- >>> y_dec $ Data.ByteString.Char8.pack "=}"
+-- >>> yDecode $ Data.ByteString.Char8.pack "=}"
 -- Right ("\DC3","")
 --
 -- A @Left@ value is only ever returned on decoding errors which, due to
 -- characteristics of the encoding, can never happen.
 --
--- >>> y_dec $ Data.ByteString.Char8.pack "="
+-- >>> yDecode $ Data.ByteString.Char8.pack "="
 -- Right ("","=")
-y_dec :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
-y_dec bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
+yDecode :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) (BS.ByteString, BS.ByteString)
+yDecode bs = U.unsafePerformIO $ BSU.unsafeUseAsCStringLen bs $ \ (inBuf, inLen) -> do
     outBuf <- mallocBytes inLen
     alloca $ \ pOutLen ->
         alloca $ \ pRemBuf ->
@@ -91,11 +91,11 @@
 -- | Convenient function that calls 'y_enc' repeatedly until the whole input
 -- data is encoded.
 encode :: BS.ByteString -> BS.ByteString
-encode = BS.concat . takeWhile (not . BS.null) . unfoldr (Just . y_enc)
+encode = BS.concat . takeWhile (not . BS.null) . unfoldr (Just . yEncode)
 
 -- | A synonym for 'y_dec'.
 decode :: BS.ByteString -> Either (BS.ByteString, BS.ByteString) BS.ByteString
-decode bs = case y_dec bs of
+decode bs = case yDecode bs of
     Right a@(d, r) -> if BS.null r
         then Right d
         else Left a
diff --git a/src/Data/Conduit/Codec/Base16.hs b/src/Data/Conduit/Codec/Base16.hs
--- a/src/Data/Conduit/Codec/Base16.hs
+++ b/src/Data/Conduit/Codec/Base16.hs
@@ -15,4 +15,4 @@
 encode = U.encodeII B16.encode
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeII B16.b16_dec empty
+decode = U.decodeII B16.b16Dec empty
diff --git a/src/Data/Conduit/Codec/Base32.hs b/src/Data/Conduit/Codec/Base32.hs
--- a/src/Data/Conduit/Codec/Base32.hs
+++ b/src/Data/Conduit/Codec/Base32.hs
@@ -12,7 +12,7 @@
 import Data.Conduit (Conduit)
 
 encode :: (Monad m) => Conduit ByteString m ByteString
-encode = U.encodeI B32.b32_encode_part B32.b32_encode_final empty
+encode = U.encodeI B32.b32EncodePart B32.b32EncodeFinal empty
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeI B32.b32_decode_part B32.b32_decode_final empty
+decode = U.decodeI B32.b32DecodePart B32.b32DecodeFinal empty
diff --git a/src/Data/Conduit/Codec/Base32Hex.hs b/src/Data/Conduit/Codec/Base32Hex.hs
--- a/src/Data/Conduit/Codec/Base32Hex.hs
+++ b/src/Data/Conduit/Codec/Base32Hex.hs
@@ -12,7 +12,7 @@
 import Data.Conduit (Conduit)
 
 encode :: (Monad m) => Conduit ByteString m ByteString
-encode = U.encodeI B32H.b32h_encode_part B32H.b32h_encode_final empty
+encode = U.encodeI B32H.b32hEncodePart B32H.b32hEncodeFinal empty
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeI B32H.b32h_decode_part B32H.b32h_decode_final empty
+decode = U.decodeI B32H.b32hDecodePart B32H.b32hDecodeFinal empty
diff --git a/src/Data/Conduit/Codec/Base64.hs b/src/Data/Conduit/Codec/Base64.hs
--- a/src/Data/Conduit/Codec/Base64.hs
+++ b/src/Data/Conduit/Codec/Base64.hs
@@ -12,7 +12,7 @@
 import Data.Conduit (Conduit)
 
 encode :: (Monad m) => Conduit ByteString m ByteString
-encode = U.encodeI B64.b64_encode_part B64.b64_encode_final empty
+encode = U.encodeI B64.b64EncodePart B64.b64EncodeFinal empty
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeI B64.b64_decode_part B64.b64_decode_final empty
+decode = U.decodeI B64.b64DecodePart B64.b64DecodeFinal empty
diff --git a/src/Data/Conduit/Codec/Base64Url.hs b/src/Data/Conduit/Codec/Base64Url.hs
--- a/src/Data/Conduit/Codec/Base64Url.hs
+++ b/src/Data/Conduit/Codec/Base64Url.hs
@@ -12,7 +12,7 @@
 import Data.Conduit (Conduit)
 
 encode :: (Monad m) => Conduit ByteString m ByteString
-encode = U.encodeI B64U.b64u_encode_part B64U.b64u_encode_final empty
+encode = U.encodeI B64U.b64uEncodePart B64U.b64uEncodeFinal empty
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeI B64U.b64u_decode_part B64U.b64u_decode_final empty
+decode = U.decodeI B64U.b64uDecodePart B64U.b64uDecodeFinal empty
diff --git a/src/Data/Conduit/Codec/Base85.hs b/src/Data/Conduit/Codec/Base85.hs
--- a/src/Data/Conduit/Codec/Base85.hs
+++ b/src/Data/Conduit/Codec/Base85.hs
@@ -12,7 +12,7 @@
 import Data.Conduit (Conduit)
 
 encode :: (Monad m) => Conduit ByteString m ByteString
-encode = U.encodeI B85.b85_encode_part B85.b85_encode_final empty
+encode = U.encodeI B85.b85EncodePart B85.b85EncodeFinal empty
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeI B85.b85_decode_part B85.b85_decode_final empty
+decode = U.decodeI B85.b85DecodePart B85.b85DecodeFinal empty
diff --git a/src/Data/Conduit/Codec/QuotedPrintable.hs b/src/Data/Conduit/Codec/QuotedPrintable.hs
--- a/src/Data/Conduit/Codec/QuotedPrintable.hs
+++ b/src/Data/Conduit/Codec/QuotedPrintable.hs
@@ -15,4 +15,4 @@
 encode = U.encodeII Qp.encode
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeII Qp.qp_dec empty
+decode = U.decodeII Qp.qpDecode empty
diff --git a/src/Data/Conduit/Codec/Util.hs b/src/Data/Conduit/Codec/Util.hs
--- a/src/Data/Conduit/Codec/Util.hs
+++ b/src/Data/Conduit/Codec/Util.hs
@@ -1,8 +1,8 @@
+{-# LANGUAGE DeriveDataTypeable #-}
 -- |
 -- Module: Data.Conduit.Codec.Util
 -- Copyright: (c) 2014 Magnus Therning
 -- License: BSD3
-{-# OPTIONS_GHC -XDeriveDataTypeable #-}
 
 module Data.Conduit.Codec.Util
     ( CodecDecodeException(..)
@@ -17,7 +17,7 @@
 import Data.ByteString as BS (ByteString, append, null)
 import Data.Conduit (Conduit, await, yield)
 import Data.Maybe (fromJust)
-import Control.Monad (unless)
+import Control.Monad (unless, void)
 import Control.Monad.Catch (MonadThrow, throwM)
 
 type EncFunc = ByteString -> ByteString
@@ -35,7 +35,7 @@
 encodeI enc_part enc_final i = do
     clear <- await
     case clear of
-        Nothing -> (yield $ fromJust $ enc_final i) >> return ()
+        Nothing -> void (yield $ fromJust $ enc_final i)
         Just s -> let
                 (a, b) = enc_part (i `append` s)
             in do
@@ -46,10 +46,10 @@
 decodeI dec_part dec_final i = do
     enc <- await
     case enc of
-        Nothing -> 
+        Nothing ->
             case dec_final i of
                 Nothing -> throwM (CodecDecodeException i)
-                Just s -> yield s >> return ()
+                Just s -> void (yield s)
         Just s ->
             case dec_part (i `append` s) of
                 Left (a, b) -> do
@@ -72,10 +72,8 @@
 decodeII dec i = do
     enc <- await
     case enc of
-        Nothing -> if BS.null i
-            then return ()
-            else throwM $ CodecDecodeException i
-        Just s -> case (dec $ i `append` s) of
+        Nothing -> unless (BS.null i) (throwM $ CodecDecodeException i)
+        Just s -> case dec $ i `append` s of
             Left (c, b) -> do
                 unless (BS.null c) $ yield c
                 throwM $ CodecDecodeException b
diff --git a/src/Data/Conduit/Codec/Uu.hs b/src/Data/Conduit/Codec/Uu.hs
--- a/src/Data/Conduit/Codec/Uu.hs
+++ b/src/Data/Conduit/Codec/Uu.hs
@@ -12,7 +12,7 @@
 import Data.Conduit (Conduit)
 
 encode :: (Monad m) => Conduit ByteString m ByteString
-encode = U.encodeI Uu.uu_encode_part Uu.uu_encode_final empty
+encode = U.encodeI Uu.uuEncodePart Uu.uuEncodeFinal empty
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeI Uu.uu_decode_part Uu.uu_decode_final empty
+decode = U.decodeI Uu.uuDecodePart Uu.uuDecodeFinal empty
diff --git a/src/Data/Conduit/Codec/Xx.hs b/src/Data/Conduit/Codec/Xx.hs
--- a/src/Data/Conduit/Codec/Xx.hs
+++ b/src/Data/Conduit/Codec/Xx.hs
@@ -12,7 +12,7 @@
 import Data.Conduit (Conduit)
 
 encode :: (Monad m) => Conduit ByteString m ByteString
-encode = U.encodeI Xx.xx_encode_part Xx.xx_encode_final empty
+encode = U.encodeI Xx.xxEncodePart Xx.xxEncodeFinal empty
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeI Xx.xx_decode_part Xx.xx_decode_final empty
+decode = U.decodeI Xx.xxDecodePart Xx.xxDecodeFinal empty
diff --git a/src/Data/Conduit/Codec/Yenc.hs b/src/Data/Conduit/Codec/Yenc.hs
--- a/src/Data/Conduit/Codec/Yenc.hs
+++ b/src/Data/Conduit/Codec/Yenc.hs
@@ -15,4 +15,4 @@
 encode = U.encodeII Y.encode
 
 decode :: (Monad m, MonadThrow m) => Conduit ByteString m ByteString
-decode = U.decodeII Y.y_dec empty
+decode = U.decodeII Y.yDecode empty
diff --git a/test-src/Codec/Binary/Base16Test.hs b/test-src/Codec/Binary/Base16Test.hs
--- a/test-src/Codec/Binary/Base16Test.hs
+++ b/test-src/Codec/Binary/Base16Test.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -37,12 +37,12 @@
     Right (BSC.pack "foobar") @=? B16.decode (BSC.pack "666F6F626172")
 
 case_b16_dec_failure :: IO ()
-case_b16_dec_failure = do
+case_b16_dec_failure =
     -- odd number of input bytes
-    (Left (BSC.pack "fooba", BS.pack [55])) @=? (B16.decode $ BS.pack [54,54,54,70,54,70,54,50,54,49,55])
+    Left (BSC.pack "fooba", BS.pack [55]) @=? B16.decode (BS.pack [54,54,54,70,54,70,54,50,54,49,55])
 
 prop_b16_encdec :: [Word8] -> Bool
-prop_b16_encdec ws = (BS.pack ws) == (fromRight $ B16.decode $ B16.encode $ BS.pack ws)
+prop_b16_encdec ws = BS.pack ws == fromRight (B16.decode $ B16.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base32HexTest.hs b/test-src/Codec/Binary/Base32HexTest.hs
--- a/test-src/Codec/Binary/Base32HexTest.hs
+++ b/test-src/Codec/Binary/Base32HexTest.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -39,14 +39,14 @@
 case_dec_failures :: IO ()
 case_dec_failures = do
     --  illegal char
-    Left (BS.empty, BSC.pack "C=NMUOJ1") @=? (B32H.b32h_decode_part $ BSC.pack "C=NMUOJ1")
+    Left (BS.empty, BSC.pack "C=NMUOJ1") @=? B32H.b32hDecodePart (BSC.pack "C=NMUOJ1")
     -- full block
-    Nothing @=? (B32H.b32h_decode_final $ BSC.pack "CPNMUOJ1")
+    Nothing @=? B32H.b32hDecodeFinal (BSC.pack "CPNMUOJ1")
     -- too short
-    Nothing @=? (B32H.b32h_decode_final $ BSC.pack "CPNMUO=")
+    Nothing @=? B32H.b32hDecodeFinal (BSC.pack "CPNMUO=")
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ B32H.decode $ B32H.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (B32H.decode $ B32H.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base32Test.hs b/test-src/Codec/Binary/Base32Test.hs
--- a/test-src/Codec/Binary/Base32Test.hs
+++ b/test-src/Codec/Binary/Base32Test.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -39,14 +39,14 @@
 case_dec_failures :: IO ()
 case_dec_failures = do
     -- illegal char
-    Left (BSC.empty, BSC.pack "M=XW6YTB") @=? (B32.b32_decode_part $ BSC.pack "M=XW6YTB")
+    Left (BSC.empty, BSC.pack "M=XW6YTB") @=? B32.b32DecodePart (BSC.pack "M=XW6YTB")
     -- full block
-    Nothing @=? (B32.b32_decode_final $ BSC.pack "MZXW6YTB")
+    Nothing @=? B32.b32DecodeFinal (BSC.pack "MZXW6YTB")
     -- too short
-    Nothing @=? (B32.b32_decode_final $ BSC.pack "MZXW6Y=")
+    Nothing @=? B32.b32DecodeFinal (BSC.pack "MZXW6Y=")
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ B32.decode $ B32.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (B32.decode $ B32.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base64Test.hs b/test-src/Codec/Binary/Base64Test.hs
--- a/test-src/Codec/Binary/Base64Test.hs
+++ b/test-src/Codec/Binary/Base64Test.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -27,7 +27,7 @@
     BSC.pack "Zm9vYmFy" @=? B64.encode (BSC.pack "foobar")
 
 case_enc_specials :: IO ()
-case_enc_specials = do
+case_enc_specials =
     -- /++/
     BSC.pack "/++/" @=? B64.encode (BS.pack [255,239,191])
 
@@ -42,12 +42,12 @@
     Right (BSC.pack "foobar") @=? B64.decode (BSC.pack "Zm9vYmFy")
 
 case_dec_specials :: IO ()
-case_dec_specials = do
+case_dec_specials =
     -- /++/
     Right (BS.pack [255,239,191]) @=? B64.decode (BSC.pack "/++/")
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ B64.decode $ B64.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (B64.decode $ B64.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base64UrlTest.hs b/test-src/Codec/Binary/Base64UrlTest.hs
--- a/test-src/Codec/Binary/Base64UrlTest.hs
+++ b/test-src/Codec/Binary/Base64UrlTest.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -27,9 +27,9 @@
     BSC.pack "Zm9vYmFy" @=? B64U.encode (BSC.pack "foobar")
 
 case_enc_specials :: IO ()
-case_enc_specials = do
+case_enc_specials =
     -- _--_
-    BSC.pack "_--_" @=? (B64U.encode $ BS.pack [255,239,191])
+    BSC.pack "_--_" @=? B64U.encode (BS.pack [255,239,191])
 
 case_dec_foobar :: IO ()
 case_dec_foobar = do
@@ -42,12 +42,12 @@
     Right (BSC.pack "foobar") @=? B64U.decode (BSC.pack "Zm9vYmFy")
 
 case_dec_specials :: IO ()
-case_dec_specials = do
+case_dec_specials =
     -- _--_
     Right (BS.pack [255,239,191]) @=? B64U.decode (BSC.pack "_--_")
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ B64U.decode $ B64U.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (B64U.decode $ B64U.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base85Test.hs b/test-src/Codec/Binary/Base85Test.hs
--- a/test-src/Codec/Binary/Base85Test.hs
+++ b/test-src/Codec/Binary/Base85Test.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -56,7 +56,7 @@
     Right (BS.pack [32,32,32,32,0,0,0,0]) @=? B85.decode (BSC.pack "yz")
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ B85.decode $ B85.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (B85.decode $ B85.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/QuotedPrintableTest.hs b/test-src/Codec/Binary/QuotedPrintableTest.hs
--- a/test-src/Codec/Binary/QuotedPrintableTest.hs
+++ b/test-src/Codec/Binary/QuotedPrintableTest.hs
@@ -1,5 +1,5 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
--- Copyright: (c) Magnus Therning, 2013
+{-# LANGUAGE TemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013-2015
 -- License: BSD3, found in the LICENSE file
 
 module Codec.Binary.QuotedPrintableTest where
@@ -21,16 +21,31 @@
     BS.empty          @=? QP.encode BS.empty
     BSC.pack "foobar" @=? QP.encode (BSC.pack "foobar")
     BSC.pack "foo=20bar" @=? QP.encode (BSC.pack "foo bar")
+    BSC.pack "foo=09bar" @=? QP.encode (BSC.pack "foo\tbar")
+    BSC.pack "foo=0Dbar" @=? QP.encode (BSC.pack "foo\rbar")
+    BSC.pack "foo=0Abar" @=? QP.encode (BSC.pack "foo\nbar")
 
+case_enc_splitting :: IO ()
+case_enc_splitting = do
+  BSC.pack "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=\r\n=3D=3D=3D" @=? QP.encode (BSC.pack "===========================")
+  (BSC.pack "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=\r\n=3D=3D=3D", BSC.pack "") @=? QP.qpEncode (BSC.pack "===========================")
+  (BSC.pack "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D", BSC.pack "") @=? QP.qpEncodeSL (BSC.pack "===========================")
+
 case_dec_foobar :: IO ()
 case_dec_foobar = do
     Right BS.empty            @=? QP.decode BS.empty
     Right (BSC.pack "foobar") @=? QP.decode (BSC.pack "foobar")
     Right (BSC.pack "foo bar") @=? QP.decode (BSC.pack "foo bar")
     Right (BSC.pack "foo bar") @=? QP.decode (BSC.pack "foo=20bar")
+    Right (BSC.pack "foo\tbar") @=? QP.decode (BSC.pack "foo\tbar")
+    Right (BSC.pack "foo\tbar") @=? QP.decode (BSC.pack "foo=09bar")
+    Right (BSC.pack "foo\r\nbar") @=? QP.decode (BSC.pack "foo\r\nbar")
+    Right (BSC.pack "foobar") @=? QP.decode (BSC.pack "foo=\r\nbar")
+    Left (BSC.pack "foo", BSC.pack "\nbar") @=? QP.decode (BSC.pack "foo\nbar")
+    Left (BSC.pack "foo", BSC.pack "\rbar") @=? QP.decode (BSC.pack "foo\rbar")
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ QP.decode $ QP.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (QP.decode $ QP.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/UuTest.hs b/test-src/Codec/Binary/UuTest.hs
--- a/test-src/Codec/Binary/UuTest.hs
+++ b/test-src/Codec/Binary/UuTest.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -37,7 +37,7 @@
     Right (BSC.pack "foobar") @=? Uu.decode (BSC.pack "9F]O8F%R")
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ Uu.decode $ Uu.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (Uu.decode $ Uu.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/XxTest.hs b/test-src/Codec/Binary/XxTest.hs
--- a/test-src/Codec/Binary/XxTest.hs
+++ b/test-src/Codec/Binary/XxTest.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -37,7 +37,7 @@
     Right (BSC.pack "foobar") @=? Xx.decode (BSC.pack "NaxjMa3m")
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ Xx.decode $ Xx.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (Xx.decode $ Xx.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/YencTest.hs b/test-src/Codec/Binary/YencTest.hs
--- a/test-src/Codec/Binary/YencTest.hs
+++ b/test-src/Codec/Binary/YencTest.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- Copyright: (c) Magnus Therning, 2013
 -- License: BSD3, found in the LICENSE file
 
@@ -53,7 +53,7 @@
     Right (BS.pack [19])  @=? Y.decode (BS.pack [61,125])
 
 prop_encdec :: [Word8] -> Bool
-prop_encdec ws = (BS.pack ws) == (fromRight $ Y.decode $ Y.encode $ BS.pack ws)
+prop_encdec ws = BS.pack ws == fromRight (Y.decode $ Y.encode $ BS.pack ws)
 
 tests :: TestTree
 tests = $(testGroupGenerator)
diff --git a/test-src/Main.hs b/test-src/Main.hs
--- a/test-src/Main.hs
+++ b/test-src/Main.hs
@@ -1,5 +1,3 @@
-{-# OPTIONS_GHC -XTemplateHaskell #-}
-
 -- Copyright: (c) Magnus Therning, 2012
 -- License: BSD3, found in the LICENSE file
 
