diff options
Diffstat (limited to 'src/Data/ByteString/Base32/Internal.hs')
-rw-r--r-- | src/Data/ByteString/Base32/Internal.hs | 19 |
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 | ||
25 | import Control.Exception hiding (mask) | ||
25 | import Data.Bits.Extras | 26 | import Data.Bits.Extras |
26 | import Data.ByteString as BS | 27 | import Data.ByteString as BS |
27 | import Data.ByteString.Internal as BS | 28 | import Data.ByteString.Internal as BS |
@@ -151,9 +152,17 @@ unpack5 (PS fptr off len) bs | |||
151 | invIx :: Word5 | 152 | invIx :: Word5 |
152 | invIx = 255 | 153 | invIx = 255 |
153 | 154 | ||
154 | pack5Ptr :: Ptr Word5 -> ByteString -> ByteString | 155 | type Result = Either String |
156 | |||
157 | cleanup :: IO a -> Result a | ||
158 | cleanup io = unsafePerformIO $ | ||
159 | catch (io >>= evaluate >>= return . Right) handler | ||
160 | where | ||
161 | handler (ErrorCall msg) = return (Left msg) | ||
162 | |||
163 | pack5Ptr :: Ptr Word5 -> ByteString -> Result ByteString | ||
155 | pack5Ptr !tbl bs @ (PS fptr off sz) = | 164 | pack5Ptr !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 | ||
222 | type DecTable = ByteString | 231 | type DecTable = ByteString |
223 | 232 | ||
224 | pack5 :: DecTable -> ByteString -> ByteString | 233 | pack5 :: DecTable -> ByteString -> Result ByteString |
225 | pack5 (PS fptr off len) bs | 234 | pack5 (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 | |||
238 | isInAlphabet !tbl !ix = | 247 | isInAlphabet !tbl !ix = |
239 | inlinePerformIO (peekByteOff tbl (fromIntegral ix)) /= invIx | 248 | inlinePerformIO (peekByteOff tbl (fromIntegral ix)) /= invIx |
240 | 249 | ||
241 | pack5Lenient :: DecTable -> ByteString -> ByteString | 250 | pack5Lenient :: DecTable -> ByteString -> Either String ByteString |
242 | pack5Lenient tbl @ (PS fptr _ _) bs = | 251 | pack5Lenient tbl @ (PS fptr _ _) bs = |
243 | unsafePerformIO $ do | 252 | unsafePerformIO $ do |
244 | withForeignPtr fptr $ \ !tbl_ptr -> do | 253 | withForeignPtr fptr $ \ !tbl_ptr -> do |