{-|
Module: GoPro.GPMF
Description: Parser for GoPro GPMF telemetry data.
Copyright: (c) Dustin Sallings, 2020
License: BSD3
Maintanier: dustin@spy.net
Stability: experimental

A low-level parser for <https://github.com/gopro/gpmf-parser GPMF> telemetry data.
-}

{-# LANGUAGE TupleSections #-}

module GoPro.GPMF (parseGPMF, Value(..), FourCC(..)) where

import           Control.Monad                    (replicateM)
import           Control.Monad.State              (StateT, evalStateT, get, lift, put)
import           Data.Attoparsec.Binary           (anyWord16be, anyWord32be, anyWord64be)
import qualified Data.Attoparsec.ByteString       as A
import qualified Data.Attoparsec.ByteString.Char8 as AC
import           Data.Binary.Get                  (runGet)
import           Data.Binary.IEEE754              (getFloat32be)
import qualified Data.ByteString                  as BS
import qualified Data.ByteString.Lazy             as BL
import           Data.Int                         (Int16, Int32, Int64, Int8)
import           Data.String                      (IsString (..))
import           Data.Time.Clock                  (UTCTime)
import           Data.Time.Format                 (defaultTimeLocale, parseTimeM)
import           Data.Word                        (Word16, Word32, Word64, Word8)
{-
Type Char	Definition	typedef	Comment
b	single byte signed integer	int8_t	-128 to 127
B	single byte unsigned integer	uint8_t	0 to 255
c	single byte 'c' style ASCII character string	char	Optionally NULL terminated - size/repeat sets the length
d	64-bit double precision (IEEE 754)	double
f	32-bit float (IEEE 754)	float
F	32-bit four character key -- FourCC	char fourcc[4]
G	128-bit ID (like UUID)	uint8_t guid[16]
j	64-bit signed unsigned number	int64_t
J	64-bit unsigned unsigned number	uint64_t
l	32-bit signed integer	int32_t
L	32-bit unsigned integer	uint32_t
q	32-bit Q Number Q15.16	uint32_t	16-bit integer (A) with 16-bit fixed point (B) for A.B value (range -32768.0 to 32767.99998)
Q	64-bit Q Number Q31.32	uint64_t	32-bit integer (A) with 32-bit fixed point (B) for A.B value.
s	16-bit signed integer	int16_t	-32768 to 32768
S	16-bit unsigned integer	uint16_t	0 to 65536
U	UTC Date and Time string	char utcdate[16]	Date + UTC Time format yymmddhhmmss.sss - (years 20xx covered)
?	data structure is complex	TYPE	Structure is defined with a preceding TYPE
null	Nested metadata	uint32_t	The data within is GPMF structured KLV data
-}

newtype FourCC = FourCC (Char, Char, Char, Char) deriving (Int -> FourCC -> ShowS
[FourCC] -> ShowS
FourCC -> String
(Int -> FourCC -> ShowS)
-> (FourCC -> String) -> ([FourCC] -> ShowS) -> Show FourCC
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FourCC] -> ShowS
$cshowList :: [FourCC] -> ShowS
show :: FourCC -> String
$cshow :: FourCC -> String
showsPrec :: Int -> FourCC -> ShowS
$cshowsPrec :: Int -> FourCC -> ShowS
Show, FourCC -> FourCC -> Bool
(FourCC -> FourCC -> Bool)
-> (FourCC -> FourCC -> Bool) -> Eq FourCC
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FourCC -> FourCC -> Bool
$c/= :: FourCC -> FourCC -> Bool
== :: FourCC -> FourCC -> Bool
$c== :: FourCC -> FourCC -> Bool
Eq)

instance IsString FourCC where
  fromString :: String -> FourCC
fromString [Char
a,Char
b,Char
c,Char
d] = (Char, Char, Char, Char) -> FourCC
FourCC (Char
a,Char
b,Char
c,Char
d)
  fromString String
_         = String -> FourCC
forall a. HasCallStack => String -> a
error String
"invalid FourCC"

data Value = GInt8 [Int8]
    | GUint8 [Word8]
    | GString String
    | GDouble Double
    | GFloat [Float]
    | GFourCC FourCC
    | GUUID [Word8]
    | GInt64 [Int64]
    | GUint64 [Word64]
    | GInt32 [Int32]
    | GUint32 [Word32]
    | GQ32 [Word32]
    | GQ64 [Word64]
    | GInt16 [Int16]
    | GUint16 [Word16]
    | GTimestamp UTCTime
    | GComplex String [Value]
    | GNested (FourCC, [Value])
    | GUnknown (Char, Int, Int, [[Word8]])
    deriving (Int -> Value -> ShowS
[Value] -> ShowS
Value -> String
(Int -> Value -> ShowS)
-> (Value -> String) -> ([Value] -> ShowS) -> Show Value
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Value] -> ShowS
$cshowList :: [Value] -> ShowS
show :: Value -> String
$cshow :: Value -> String
showsPrec :: Int -> Value -> ShowS
$cshowsPrec :: Int -> Value -> ShowS
Show)

type Parser = StateT String A.Parser

anyInt8 :: A.Parser Int8
anyInt8 :: Parser Int8
anyInt8 = Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int8) -> Parser ByteString Word8 -> Parser Int8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word8
A.anyWord8

-- | Parse GPMF data from a telemetry stream.  A successful return
-- value contains a list of FourCC tagged value lists.
--
-- Note that the input is the telemetry stream itself, not the
-- container that contains it.
parseGPMF :: BS.ByteString -> Either String [(FourCC, [Value])]
parseGPMF :: ByteString -> Either String [(FourCC, [Value])]
parseGPMF = Parser [(FourCC, [Value])]
-> ByteString -> Either String [(FourCC, [Value])]
forall a. Parser a -> ByteString -> Either String a
A.parseOnly (StateT String Parser [(FourCC, [Value])]
-> String -> Parser [(FourCC, [Value])]
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (StateT String Parser (FourCC, [Value])
-> StateT String Parser [(FourCC, [Value])]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
A.many1 StateT String Parser (FourCC, [Value])
parseNested) String
"")

parseNested :: Parser (FourCC, [Value])
parseNested :: StateT String Parser (FourCC, [Value])
parseNested = do
  FourCC
fourcc <- Parser ByteString FourCC -> StateT String Parser FourCC
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Parser ByteString FourCC
parseFourCC
  Char
t <- Parser ByteString Char -> StateT String Parser Char
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Parser ByteString Char
AC.anyChar
  Int
ss <- Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int)
-> StateT String Parser Word8 -> StateT String Parser Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word8 -> StateT String Parser Word8
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Parser ByteString Word8
A.anyWord8
  Int
rpt <- Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int)
-> StateT String Parser Word16 -> StateT String Parser Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word16 -> StateT String Parser Word16
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Parser ByteString Word16
anyWord16be
  let padding :: Int
padding = (Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ss Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
rpt) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
4) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
4

  [Value]
stuffs <- Char -> Int -> Int -> Parser [Value]
parseValue Char
t Int
ss Int
rpt

  case (FourCC
fourcc, [Value]
stuffs) of
    (FourCC
"TYPE", [GString String
x]) -> String -> StateT String Parser ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put String
x
    (FourCC, [Value])
_                     -> () -> StateT String Parser ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

  [Word8]
_ <- Parser ByteString [Word8] -> StateT String Parser [Word8]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser ByteString [Word8] -> StateT String Parser [Word8])
-> Parser ByteString [Word8] -> StateT String Parser [Word8]
forall a b. (a -> b) -> a -> b
$ Int -> Parser ByteString Word8 -> Parser ByteString [Word8]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
padding Parser ByteString Word8
A.anyWord8
  (FourCC, [Value]) -> StateT String Parser (FourCC, [Value])
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FourCC
fourcc, [Value]
stuffs)

parseString :: Int -> A.Parser Value
parseString :: Int -> Parser Value
parseString Int
l = String -> Value
GString (String -> Value) -> ShowS -> String -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
forall a. [a] -> [a]
reverse  ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\0') ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
forall a. [a] -> [a]
reverse (String -> Value) -> Parser ByteString String -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser ByteString Char -> Parser ByteString String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
l Parser ByteString Char
AC.anyChar

parseFloat :: A.Parser Float
parseFloat :: Parser Float
parseFloat = Get Float -> ByteString -> Float
forall a. Get a -> ByteString -> a
runGet Get Float
getFloat32be (ByteString -> Float)
-> (ByteString -> ByteString) -> ByteString -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BL.fromStrict (ByteString -> Float)
-> Parser ByteString ByteString -> Parser Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser ByteString ByteString
A.take Int
4

replicatedParser :: Int -> Int -> Int -> A.Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser :: Int -> Int -> Int -> Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser Int
0 Int
l Int
rpt Parser a
_ [a] -> Value
_ = Parser ByteString [Value] -> Parser [Value]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser ByteString [Value] -> Parser [Value])
-> Parser ByteString [Value] -> Parser [Value]
forall a b. (a -> b) -> a -> b
$ Int -> Parser ByteString Word8 -> Parser ByteString [Word8]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
rpt) Parser ByteString Word8
A.anyWord8 Parser ByteString [Word8]
-> Parser ByteString [Value] -> Parser ByteString [Value]
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Value] -> Parser ByteString [Value]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
replicatedParser Int
one Int
l Int
rpt Parser a
p [a] -> Value
cons =
  ([a] -> Value) -> [[a]] -> [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [a] -> Value
cons ([[a]] -> [Value]) -> StateT String Parser [[a]] -> Parser [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString [[a]] -> StateT String Parser [[a]]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Int -> Parser ByteString [a] -> Parser ByteString [[a]]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
rpt (Int -> Parser a -> Parser ByteString [a]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Int
l Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
one) Parser a
p))

parseTimestamp :: A.Parser UTCTime
parseTimestamp :: Parser UTCTime
parseTimestamp = Bool -> TimeLocale -> String -> String -> Parser UTCTime
forall (m :: * -> *) t.
(MonadFail m, ParseTime t) =>
Bool -> TimeLocale -> String -> String -> m t
parseTimeM Bool
False TimeLocale
defaultTimeLocale String
"%y%m%d%H%M%S%Q" (String -> Parser UTCTime)
-> Parser ByteString String -> Parser UTCTime
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int -> Parser ByteString Char -> Parser ByteString String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
16 Parser ByteString Char
AC.anyChar

singleParser :: Char -> (Int, A.Parser Value)
singleParser :: Char -> (Int, Parser Value)
singleParser Char
'F' = (Int
4, FourCC -> Value
GFourCC (FourCC -> Value) -> Parser ByteString FourCC -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString FourCC
parseFourCC)
singleParser Char
'f' = (Int
4, [Float] -> Value
GFloat ([Float] -> Value) -> (Float -> [Float]) -> Float -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> [Float] -> [Float]
forall a. a -> [a] -> [a]
:[]) (Float -> Value) -> Parser Float -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Float
parseFloat)
singleParser Char
'L' = (Int
4, [Word32] -> Value
GUint32 ([Word32] -> Value) -> (Word32 -> [Word32]) -> Word32 -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32 -> [Word32] -> [Word32]
forall a. a -> [a] -> [a]
:[]) (Word32 -> Value) -> Parser ByteString Word32 -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word32
anyWord32be)
singleParser Char
'B' = (Int
1, [Word8] -> Value
GUint8 ([Word8] -> Value) -> (Word8 -> [Word8]) -> Word8 -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[]) (Word8 -> Value) -> Parser ByteString Word8 -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word8
A.anyWord8)
singleParser Char
'b' = (Int
1, [Int8] -> Value
GInt8 ([Int8] -> Value) -> (Int8 -> [Int8]) -> Int8 -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int8 -> [Int8] -> [Int8]
forall a. a -> [a] -> [a]
:[]) (Int8 -> Value) -> Parser Int8 -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Int8
anyInt8)
singleParser Char
'S' = (Int
1, [Word16] -> Value
GUint16 ([Word16] -> Value) -> (Word16 -> [Word16]) -> Word16 -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16 -> [Word16] -> [Word16]
forall a. a -> [a] -> [a]
:[]) (Word16 -> Value) -> Parser ByteString Word16 -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word16
anyWord16be)
singleParser Char
's' = (Int
1, [Word16] -> Value
GUint16 ([Word16] -> Value) -> (Word16 -> [Word16]) -> Word16 -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16 -> [Word16] -> [Word16]
forall a. a -> [a] -> [a]
:[]) (Word16 -> [Word16]) -> (Word16 -> Word16) -> Word16 -> [Word16]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Value) -> Parser ByteString Word16 -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word16
anyWord16be)
singleParser Char
x   = String -> (Int, Parser Value)
forall a. HasCallStack => String -> a
error (String
"unsupported parser: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Char -> String
forall a. Show a => a -> String
show Char
x)

parseComplex :: Int -> Int -> Parser [Value]
parseComplex :: Int -> Int -> Parser [Value]
parseComplex Int
l Int
rpt = do
  String
fmt <- StateT String Parser String
forall s (m :: * -> *). MonadState s m => m s
get
  let sz :: Int
sz = (Char -> Int -> Int) -> Int -> String -> Int
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Char
x Int
o -> ((Int, Parser Value) -> Int
forall a b. (a, b) -> a
fst ((Int, Parser Value) -> Int)
-> (Char -> (Int, Parser Value)) -> Char -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> (Int, Parser Value)
singleParser) Char
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
o) Int
0 String
fmt
  let parsers :: Parser ByteString [Value]
parsers = (Char -> Parser Value) -> String -> Parser ByteString [Value]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((Int, Parser Value) -> Parser Value
forall a b. (a, b) -> b
snd ((Int, Parser Value) -> Parser Value)
-> (Char -> (Int, Parser Value)) -> Char -> Parser Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> (Int, Parser Value)
singleParser) String
fmt
  Int
-> Int
-> Int
-> Parser ByteString [Value]
-> ([[Value]] -> Value)
-> Parser [Value]
forall a.
Int -> Int -> Int -> Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser Int
sz Int
l Int
rpt Parser ByteString [Value]
parsers (String -> [Value] -> Value
GComplex String
fmt ([Value] -> Value) -> ([[Value]] -> [Value]) -> [[Value]] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Value]] -> [Value]
forall a. Monoid a => [a] -> a
mconcat)

parseValue :: Char -> Int -> Int -> Parser [Value]
parseValue :: Char -> Int -> Int -> Parser [Value]
parseValue Char
'\0' Int
l Int
rpt = do
  ByteString
inp <- Parser ByteString ByteString -> StateT String Parser ByteString
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser ByteString ByteString -> StateT String Parser ByteString)
-> Parser ByteString ByteString -> StateT String Parser ByteString
forall a b. (a -> b) -> a -> b
$ Int -> Parser ByteString ByteString
A.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
rpt)
  String
t <- StateT String Parser String
forall s (m :: * -> *). MonadState s m => m s
get
  ((FourCC, [Value]) -> Value) -> [(FourCC, [Value])] -> [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FourCC, [Value]) -> Value
GNested ([(FourCC, [Value])] -> [Value])
-> StateT String Parser [(FourCC, [Value])] -> Parser [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> StateT String Parser [(FourCC, [Value])])
-> ([(FourCC, [Value])]
    -> StateT String Parser [(FourCC, [Value])])
-> Either String [(FourCC, [Value])]
-> StateT String Parser [(FourCC, [Value])]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> StateT String Parser [(FourCC, [Value])]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail [(FourCC, [Value])] -> StateT String Parser [(FourCC, [Value])]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Parser [(FourCC, [Value])]
-> ByteString -> Either String [(FourCC, [Value])]
forall a. Parser a -> ByteString -> Either String a
A.parseOnly (StateT String Parser [(FourCC, [Value])]
-> String -> Parser [(FourCC, [Value])]
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (StateT String Parser (FourCC, [Value])
-> StateT String Parser [(FourCC, [Value])]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
A.many1 StateT String Parser (FourCC, [Value])
parseNested) String
t) ByteString
inp)
parseValue Char
'F' Int
4 Int
rpt = Parser ByteString [Value] -> Parser [Value]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser ByteString [Value] -> Parser [Value])
-> Parser ByteString [Value] -> Parser [Value]
forall a b. (a -> b) -> a -> b
$ Int -> Parser Value -> Parser ByteString [Value]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
rpt (FourCC -> Value
GFourCC (FourCC -> Value) -> Parser ByteString FourCC -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString FourCC
parseFourCC)
parseValue Char
'L' Int
l Int
rpt = Int
-> Int
-> Int
-> Parser ByteString Word32
-> ([Word32] -> Value)
-> Parser [Value]
forall a.
Int -> Int -> Int -> Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser Int
4 Int
l Int
rpt Parser ByteString Word32
anyWord32be [Word32] -> Value
GUint32
parseValue Char
'l' Int
l Int
rpt = Int
-> Int
-> Int
-> Parser Int32
-> ([Int32] -> Value)
-> Parser [Value]
forall a.
Int -> Int -> Int -> Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser Int
4 Int
l Int
rpt (Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int32) -> Parser ByteString Word32 -> Parser Int32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word32
anyWord32be) [Int32] -> Value
GInt32
parseValue Char
'c' Int
l Int
rpt = (Value -> [Value] -> [Value]
forall a. a -> [a] -> [a]
:[]) (Value -> [Value]) -> StateT String Parser Value -> Parser [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Value -> StateT String Parser Value
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser Value -> StateT String Parser Value)
-> (Int -> Parser Value) -> Int -> StateT String Parser Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Parser Value
parseString (Int -> StateT String Parser Value)
-> Int -> StateT String Parser Value
forall a b. (a -> b) -> a -> b
$ (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
rpt))
parseValue Char
's' Int
l Int
rpt = Int
-> Int
-> Int
-> Parser Int16
-> ([Int16] -> Value)
-> Parser [Value]
forall a.
Int -> Int -> Int -> Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser Int
2 Int
l Int
rpt (Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int16) -> Parser ByteString Word16 -> Parser Int16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Word16
anyWord16be) [Int16] -> Value
GInt16
parseValue Char
'S' Int
l Int
rpt = Int
-> Int
-> Int
-> Parser ByteString Word16
-> ([Word16] -> Value)
-> Parser [Value]
forall a.
Int -> Int -> Int -> Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser Int
2 Int
l Int
rpt Parser ByteString Word16
anyWord16be [Word16] -> Value
GUint16
parseValue Char
'J' Int
l Int
rpt = Int
-> Int
-> Int
-> Parser Word64
-> ([Word64] -> Value)
-> Parser [Value]
forall a.
Int -> Int -> Int -> Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser Int
8 Int
l Int
rpt Parser Word64
anyWord64be [Word64] -> Value
GUint64
parseValue Char
'f' Int
l Int
rpt = Int
-> Int
-> Int
-> Parser Float
-> ([Float] -> Value)
-> Parser [Value]
forall a.
Int -> Int -> Int -> Parser a -> ([a] -> Value) -> Parser [Value]
replicatedParser Int
4 Int
l Int
rpt Parser Float
parseFloat [Float] -> Value
GFloat
parseValue Char
'b' Int
l Int
rpt = Parser ByteString [Value] -> Parser [Value]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser ByteString [Value] -> Parser [Value])
-> Parser ByteString [Value] -> Parser [Value]
forall a b. (a -> b) -> a -> b
$ Int -> Parser Value -> Parser ByteString [Value]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
rpt ([Int8] -> Value
GInt8 ([Int8] -> Value) -> Parser ByteString [Int8] -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser Int8 -> Parser ByteString [Int8]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
l Parser Int8
anyInt8)
parseValue Char
'B' Int
l Int
rpt = Parser ByteString [Value] -> Parser [Value]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser ByteString [Value] -> Parser [Value])
-> Parser ByteString [Value] -> Parser [Value]
forall a b. (a -> b) -> a -> b
$ Int -> Parser Value -> Parser ByteString [Value]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
rpt ([Word8] -> Value
GUint8 ([Word8] -> Value) -> Parser ByteString [Word8] -> Parser Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser ByteString Word8 -> Parser ByteString [Word8]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
l Parser ByteString Word8
A.anyWord8)
parseValue Char
'U' Int
16 Int
1 = (Value -> [Value] -> [Value]
forall a. a -> [a] -> [a]
:[]) (Value -> [Value]) -> (UTCTime -> Value) -> UTCTime -> [Value]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> Value
GTimestamp (UTCTime -> [Value])
-> StateT String Parser UTCTime -> Parser [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser UTCTime -> StateT String Parser UTCTime
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Parser UTCTime
parseTimestamp
parseValue Char
'?' Int
l Int
rpt = Int -> Int -> Parser [Value]
parseComplex Int
l Int
rpt
parseValue Char
x Int
l Int
rpt = do
  [[Word8]]
u <- Parser ByteString [[Word8]] -> StateT String Parser [[Word8]]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser ByteString [[Word8]] -> StateT String Parser [[Word8]])
-> Parser ByteString [[Word8]] -> StateT String Parser [[Word8]]
forall a b. (a -> b) -> a -> b
$ Int -> Parser ByteString [Word8] -> Parser ByteString [[Word8]]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
rpt (Int -> Parser ByteString Word8 -> Parser ByteString [Word8]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
l Parser ByteString Word8
A.anyWord8)
  [Value] -> Parser [Value]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(Char, Int, Int, [[Word8]]) -> Value
GUnknown (Char
x, Int
l, Int
rpt, [[Word8]]
u)]

parseFourCC :: A.Parser FourCC
parseFourCC :: Parser ByteString FourCC
parseFourCC = do
  Char
a <- Parser ByteString Char
AC.anyChar
  Char
b <- Parser ByteString Char
AC.anyChar
  Char
c <- Parser ByteString Char
AC.anyChar
  Char
d <- Parser ByteString Char
AC.anyChar
  FourCC -> Parser ByteString FourCC
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FourCC -> Parser ByteString FourCC)
-> FourCC -> Parser ByteString FourCC
forall a b. (a -> b) -> a -> b
$ (Char, Char, Char, Char) -> FourCC
FourCC (Char
a,Char
b,Char
c,Char
d)