module Parry.Util(
encode16,decode16,encode16l,decode16l
) where
import qualified Data.ByteString.Lazy.Internal as ILB
import qualified Data.ByteString.Internal as IB
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as UB
import qualified Data.ByteString.Char8 as B8
import Foreign.Ptr
import Foreign.Storable
import Data.Bits
import Data.Word
encode16 :: B.ByteString -> B.ByteString
encode16 bytes=
let { len=B.length bytes } in
IB.unsafeCreate (len*2) $ \pp->
let { fill p0 i
| i>=len=return ()
| otherwise=do {
let { c=UB.unsafeIndex bytes i;
c0=c`shiftR`4;
c1=c.&.0xf };
poke p0 $ if c0<=9 then 48+c0 else 97+c010;
poke (p0`plusPtr`1) $ if c1<=9 then 48+c1 else 97+c110;
fill (p0`plusPtr`2) $ i+1
}}
in
fill pp 0
atomHex::Word8->Word8
atomHex c=
if c<=(fromIntegral $ fromEnum '9') then
c(fromIntegral $ fromEnum '0')
else
c(fromIntegral $ fromEnum 'a')+10
decode16::B8.ByteString->B8.ByteString
decode16 bytes=
let { len=B.length bytes } in
IB.unsafeCreate (len`quot`2) $ \pp->
let { fill p0 i
| i>=len=return ()
| otherwise=do {
let { c0=atomHex $ UB.unsafeIndex bytes i; c1=atomHex $ UB.unsafeIndex bytes (i+1) };
poke p0 $ (c0`shiftL`4) .|. c1;
fill (p0`plusPtr`1) $ i+2
}}
in
fill pp 0
encode16l::ILB.ByteString->ILB.ByteString
encode16l ILB.Empty=ILB.Empty
encode16l (ILB.Chunk x xs)=ILB.Chunk (encode16 x) (encode16l xs)
decode16l::ILB.ByteString->ILB.ByteString
decode16l ILB.Empty=ILB.Empty
decode16l (ILB.Chunk x xs)=ILB.Chunk (decode16 x) (decode16l xs)