asn1-types 0.2.1 → 0.2.2
raw patch · 2 files changed
+31/−18 lines, 2 files
Files
- Data/ASN1/Types/String.hs +30/−17
- asn1-types.cabal +1/−1
Data/ASN1/Types/String.hs view
@@ -19,6 +19,7 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import Data.Bits+import Data.Word -- a note on T61 encodings. The actual specification of a T61 character set seems -- to be lost in time, as such it will be considered an ascii like encoding.@@ -78,23 +79,35 @@ fromString s = ASN1CharacterString UTF8 (encodeUTF8 s) decodeUTF8 :: ByteString -> String-decodeUTF8 b- | B.null b = []- | otherwise =- case B.index b 0 of- v | v `isClear` 7 -> toEnum (fromIntegral v) : decodeUTF8 (B.drop 1 b)- | v `isClear` 6 -> error "continuation byte"- | v `isClear` 5 -> uncont 1 (v .&. 0x1f)- | v `isClear` 4 -> uncont 2 (v .&. 0xf)- | v `isClear` 3 -> uncont 3 (v .&. 0x7)- | otherwise -> error "too many byte"- where uncont n iniV- | B.length b < (n+1) = error "cannot decode"- | otherwise = let z = flip map [1..n] $ \i ->- case B.index b (i+1) of- v | v `testBit` 7 && v `isClear` 6 -> v .&. 0x3f- | otherwise -> error "not a continuation byte"- in (toEnum $ fromIntegral $ foldl (\acc v -> (acc `shiftL` 6) + v) iniV z) : decodeUTF8 (B.drop (1+n) b)+decodeUTF8 b = loop 0 $ B.unpack b+ where loop :: Int -> [Word8] -> [Char]+ loop _ [] = []+ loop pos (x:xs)+ | x `isClear` 7 = toEnum (fromIntegral x) : loop (pos+1) xs+ | x `isClear` 6 = error "continuation byte in heading context"+ | x `isClear` 5 = uncont 1 (x .&. 0x1f) pos xs+ | x `isClear` 4 = uncont 2 (x .&. 0xf) pos xs+ | x `isClear` 3 = uncont 3 (x .&. 0x7) pos xs+ | otherwise = error "too many byte"+ uncont :: Int -> Word8 -> Int -> [Word8] -> [Char]+ uncont 1 iniV pos xs =+ case xs of+ c1:xs' -> decodeCont iniV [c1] : loop (pos+2) xs'+ _ -> error "truncated continuation, expecting 1 byte"+ uncont 2 iniV pos xs =+ case xs of+ c1:c2:xs' -> decodeCont iniV [c1,c2] : loop (pos+3) xs'+ _ -> error "truncated continuation, expecting 2 bytes"+ uncont 3 iniV pos xs =+ case xs of+ c1:c2:c3:xs' -> decodeCont iniV [c1,c2,c3] : loop (pos+4) xs'+ _ -> error "truncated continuation, expecting 3 bytes"+ uncont _ _ _ _ = error "invalid number of bytes for continuation"+ decodeCont :: Word8 -> [Word8] -> Char+ decodeCont iniV l+ | all isContByte l = toEnum $ foldl (\acc v -> (acc `shiftL` 6) + fromIntegral v) (fromIntegral iniV) $ map (\v -> v .&. 0x3f) l+ | otherwise = error "continuation bytes invalid"+ isContByte v = v `testBit` 7 && v `isClear` 6 isClear v i = not (v `testBit` i) encodeUTF8 :: String -> ByteString
asn1-types.cabal view
@@ -1,5 +1,5 @@ Name: asn1-types-Version: 0.2.1+Version: 0.2.2 Description: ASN.1 standard types License: BSD3 License-file: LICENSE