diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-10-04 15:33:47 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-10-04 15:33:47 +0400 |
commit | 5ee4f7dd72e3a5c522572ab547049f2df528ec05 (patch) | |
tree | 924d3807be8c93c538369d2275b992a2fc740840 /src/Data | |
parent | 7d1381dc4a9f8bf83c80627251da3a65c79d7c20 (diff) |
Use simpler pack5Lenient implementation
Diffstat (limited to 'src/Data')
-rw-r--r-- | src/Data/ByteString/Base32/Internal.hs | 45 |
1 files changed, 7 insertions, 38 deletions
diff --git a/src/Data/ByteString/Base32/Internal.hs b/src/Data/ByteString/Base32/Internal.hs index 725be37..5902f60 100644 --- a/src/Data/ByteString/Base32/Internal.hs +++ b/src/Data/ByteString/Base32/Internal.hs | |||
@@ -234,43 +234,12 @@ pack5 (PS fptr off len) bs | |||
234 | -- Lenient Decoding | 234 | -- Lenient Decoding |
235 | -----------------------------------------------------------------------} | 235 | -----------------------------------------------------------------------} |
236 | 236 | ||
237 | pack5PtrLenient :: Ptr Word5 -> ByteString -> ByteString | 237 | isInAlphabet :: Ptr Word5 -> Word8 -> Bool |
238 | pack5PtrLenient !tbl bs @ (PS fptr off sz) = | 238 | isInAlphabet !tbl !ix = |
239 | unsafePerformIO $ do | 239 | inlinePerformIO (peekByteOff tbl (fromIntegral ix)) /= invIx |
240 | BS.createAndTrim (sz * 2) $ \ dst -> do | ||
241 | withForeignPtr fptr $ \ ptr -> do | ||
242 | dst_end <- smallStep dst (advancePtr ptr off) sz 0 0 | ||
243 | return (dst_end `minusPtr` dst) | ||
244 | where | ||
245 | lookupTable :: Word8 -> Word5 | ||
246 | lookupTable ix = inlinePerformIO (peekByteOff tbl (fromIntegral ix)) | ||
247 | {-# INLINE lookupTable #-} | ||
248 | |||
249 | smallStep :: Ptr Word8 -> Ptr Word5 -> Int -> Word -> Int | ||
250 | -> IO (Ptr Word5) | ||
251 | smallStep !dst !src !s !unused !un_cnt | ||
252 | | un_cnt >= 8 = do | ||
253 | poke dst $ fromIntegral (unused `unsafeShiftR` (un_cnt - 8)) | ||
254 | smallStep (dst `advancePtr` 1) src s unused (un_cnt - 8) | ||
255 | |||
256 | | s == 0 = return dst | ||
257 | | otherwise = do | ||
258 | w8 <- peek src | ||
259 | if w2c w8 == '=' | ||
260 | then if (bit un_cnt - 1) .&. unused == 0 | ||
261 | then smallStep dst src 0 0 0 | ||
262 | else smallStep dst src 0 (unused `shiftL` (8 - un_cnt)) 8 | ||
263 | else smallStep dst | ||
264 | (src `advancePtr` 1) (pred s) | ||
265 | ((unused `unsafeShiftL` 5) | ||
266 | .|. fromIntegral (lookupTable (fromIntegral w8))) | ||
267 | (un_cnt + 5) | ||
268 | 240 | ||
269 | pack5Lenient :: DecTable -> ByteString -> ByteString | 241 | pack5Lenient :: DecTable -> ByteString -> ByteString |
270 | pack5Lenient (PS fptr off len) bs | 242 | pack5Lenient tbl @ (PS fptr _ _) bs = |
271 | | len /= 256 | 243 | unsafePerformIO $ do |
272 | = error $ "base32: pack5: invalid lookup table size " ++ show len | 244 | withForeignPtr fptr $ \ !tbl_ptr -> do |
273 | | otherwise = | 245 | return $! pack5 tbl $ BS.filter (isInAlphabet tbl_ptr) bs |
274 | unsafePerformIO $ do | ||
275 | withForeignPtr fptr $ \ptr -> | ||
276 | return $ pack5Ptr (ptr `advancePtr` off) bs | ||