summaryrefslogtreecommitdiff
path: root/src/Data/ByteString/Base32/Internal.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Data/ByteString/Base32/Internal.hs')
-rw-r--r--src/Data/ByteString/Base32/Internal.hs19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/Data/ByteString/Base32/Internal.hs b/src/Data/ByteString/Base32/Internal.hs
index 5902f60..78b1146 100644
--- a/src/Data/ByteString/Base32/Internal.hs
+++ b/src/Data/ByteString/Base32/Internal.hs
@@ -22,6 +22,7 @@ module Data.ByteString.Base32.Internal
22 , invIx 22 , invIx
23 ) where 23 ) where
24 24
25import Control.Exception hiding (mask)
25import Data.Bits.Extras 26import Data.Bits.Extras
26import Data.ByteString as BS 27import Data.ByteString as BS
27import Data.ByteString.Internal as BS 28import Data.ByteString.Internal as BS
@@ -151,9 +152,17 @@ unpack5 (PS fptr off len) bs
151invIx :: Word5 152invIx :: Word5
152invIx = 255 153invIx = 255
153 154
154pack5Ptr :: Ptr Word5 -> ByteString -> ByteString 155type Result = Either String
156
157cleanup :: IO a -> Result a
158cleanup io = unsafePerformIO $
159 catch (io >>= evaluate >>= return . Right) handler
160 where
161 handler (ErrorCall msg) = return (Left msg)
162
163pack5Ptr :: Ptr Word5 -> ByteString -> Result ByteString
155pack5Ptr !tbl bs @ (PS fptr off sz) = 164pack5Ptr !tbl bs @ (PS fptr off sz) =
156 unsafePerformIO $ do 165 cleanup $ do
157 let packedSize = dstSize $ BS.length bs 166 let packedSize = dstSize $ BS.length bs
158 BS.createAndTrim packedSize $ \ dst -> do 167 BS.createAndTrim packedSize $ \ dst -> do
159 withForeignPtr fptr $ \ ptr -> do 168 withForeignPtr fptr $ \ ptr -> do
@@ -162,7 +171,7 @@ pack5Ptr !tbl bs @ (PS fptr off sz) =
162 where 171 where
163 lookupTable :: Word8 -> Word5 172 lookupTable :: Word8 -> Word5
164 lookupTable ix 173 lookupTable ix
165 | x == invIx = error $ "base32: decode: invalid character" ++ show ix 174 | x == invIx = error $ show (w2c ix) ++ " is not base32 character"
166 | otherwise = x 175 | otherwise = x
167 where x = inlinePerformIO (peekByteOff tbl (fromIntegral ix)) 176 where x = inlinePerformIO (peekByteOff tbl (fromIntegral ix))
168 {-# INLINE lookupTable #-} 177 {-# INLINE lookupTable #-}
@@ -221,7 +230,7 @@ pack5Ptr !tbl bs @ (PS fptr off sz) =
221 230
222type DecTable = ByteString 231type DecTable = ByteString
223 232
224pack5 :: DecTable -> ByteString -> ByteString 233pack5 :: DecTable -> ByteString -> Result ByteString
225pack5 (PS fptr off len) bs 234pack5 (PS fptr off len) bs
226 | len /= 256 235 | len /= 256
227 = error $ "base32: pack5: invalid lookup table size " ++ show len 236 = error $ "base32: pack5: invalid lookup table size " ++ show len
@@ -238,7 +247,7 @@ isInAlphabet :: Ptr Word5 -> Word8 -> Bool
238isInAlphabet !tbl !ix = 247isInAlphabet !tbl !ix =
239 inlinePerformIO (peekByteOff tbl (fromIntegral ix)) /= invIx 248 inlinePerformIO (peekByteOff tbl (fromIntegral ix)) /= invIx
240 249
241pack5Lenient :: DecTable -> ByteString -> ByteString 250pack5Lenient :: DecTable -> ByteString -> Either String ByteString
242pack5Lenient tbl @ (PS fptr _ _) bs = 251pack5Lenient tbl @ (PS fptr _ _) bs =
243 unsafePerformIO $ do 252 unsafePerformIO $ do
244 withForeignPtr fptr $ \ !tbl_ptr -> do 253 withForeignPtr fptr $ \ !tbl_ptr -> do