module Codec.Goat.TimeFrame.Decode
( timeDecode
) where
import Data.Int
import Data.List
import Data.Word
import qualified Data.ByteString as B
import Codec.Goat.TimeFrame.Types
import Codec.Goat.Util
timeDecode :: TimeFrame
-> [Word32]
timeDecode (TimeFrame Nothing _ _ _ ) = []
timeDecode (TimeFrame (Just x) Nothing _ _ ) = [x]
timeDecode (TimeFrame (Just x) (Just y) len bs)
| B.null bs || len == 0 = [x, y]
| otherwise = [x, y] ++ map fromIntegral times
where
times = apply (fromIntegral y) deltas :: [Int64]
deltas = apply (sub y x) dods :: [Int64]
dods = unfoldr decode bits :: [Int64]
bits = genericTake len (unpackBits bs) :: [Bool]
apply n xs = drop 1 $ scanl (+) n xs
decode :: [Bool]
-> Maybe (Int64, [Bool])
decode (False:xs) = Just (0, xs)
decode (True:False:xs) = Just $ extract xs 7
decode (True:True:False:xs) = Just $ extract xs 9
decode (True:True:True:False:xs) = Just $ extract xs 12
decode (True:True:True:True:xs) = Just $ first fromBools (splitAt 64 xs)
decode _ = Nothing
extract :: [Bool]
-> Int
-> (Int64, [Bool])
extract xs n = first (decodeNumber n) (splitAt n xs)
where decodeNumber valid bits = fromBools bits (2 ^ (valid 1))