module Sound.MIDI.Parser.Primitive
(getByte,
getN, getString, getBigN, getNByteInt,
get1, get2, get3, get4,
getNByteCardinal,
getVar, getVarBytes,
getEnum, makeEnum, ) where
import qualified Sound.MIDI.Parser.Class as Parser
import Control.Monad (replicateM, liftM, )
import Sound.MIDI.IO (ByteList, listCharFromByte, )
import qualified Sound.MIDI.Bit as Bit
import Data.Bits (testBit, clearBit)
import Data.Word (Word8)
import qualified Numeric.NonNegative.Wrapper as NonNeg
getByte :: Parser.C parser => Parser.Fragile parser Word8
getByte :: forall (parser :: * -> *). C parser => Fragile parser Word8
getByte = forall (parser :: * -> *). C parser => Fragile parser Word8
Parser.getByte
getN :: Parser.C parser => NonNeg.Int -> Parser.Fragile parser ByteList
getN :: forall (parser :: * -> *).
C parser =>
Int -> Fragile parser ByteList
getN Int
n = forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (forall a. T a -> a
NonNeg.toNumber Int
n) forall (parser :: * -> *). C parser => Fragile parser Word8
getByte
getString :: Parser.C parser => NonNeg.Integer -> Parser.Fragile parser String
getString :: forall (parser :: * -> *).
C parser =>
Integer -> Fragile parser UserMessage
getString Integer
n = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ByteList -> UserMessage
listCharFromByte (forall (parser :: * -> *).
C parser =>
Integer -> Fragile parser ByteList
getBigN Integer
n)
getBigN :: Parser.C parser => NonNeg.Integer -> Parser.Fragile parser ByteList
getBigN :: forall (parser :: * -> *).
C parser =>
Integer -> Fragile parser ByteList
getBigN Integer
n =
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence forall a b. (a -> b) -> a -> b
$
forall a. Integer -> Integer -> a -> [a]
Bit.replicateBig
(Integer
1 forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound :: NonNeg.Int))
(forall a. T a -> a
NonNeg.toNumber Integer
n)
forall (parser :: * -> *). C parser => Fragile parser Word8
getByte
get1 :: Parser.C parser => Parser.Fragile parser Int
get1 :: forall (parser :: * -> *). C parser => Fragile parser Int
get1 = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (parser :: * -> *). C parser => Fragile parser Word8
getByte
getNByteInt :: Parser.C parser => NonNeg.Int -> Parser.Fragile parser Int
getNByteInt :: forall (parser :: * -> *). C parser => Int -> Fragile parser Int
getNByteInt Int
n =
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. Integral a => [a] -> a
Bit.fromBytes (forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (forall a. T a -> a
NonNeg.toNumber Int
n) forall (parser :: * -> *). C parser => Fragile parser Int
get1)
get2, get3, get4 :: Parser.C parser => Parser.Fragile parser Int
get2 :: forall (parser :: * -> *). C parser => Fragile parser Int
get2 = forall (parser :: * -> *). C parser => Int -> Fragile parser Int
getNByteInt Int
2
get3 :: forall (parser :: * -> *). C parser => Fragile parser Int
get3 = forall (parser :: * -> *). C parser => Int -> Fragile parser Int
getNByteInt Int
3
get4 :: forall (parser :: * -> *). C parser => Fragile parser Int
get4 = forall (parser :: * -> *). C parser => Int -> Fragile parser Int
getNByteInt Int
4
getByteAsCardinal :: Parser.C parser => Parser.Fragile parser NonNeg.Integer
getByteAsCardinal :: forall (parser :: * -> *). C parser => Fragile parser Integer
getByteAsCardinal = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (parser :: * -> *). C parser => Fragile parser Word8
getByte
getNByteCardinal :: Parser.C parser => NonNeg.Int -> Parser.Fragile parser NonNeg.Integer
getNByteCardinal :: forall (parser :: * -> *).
C parser =>
Int -> Fragile parser Integer
getNByteCardinal Int
n =
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. Integral a => [a] -> a
Bit.fromBytes (forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (forall a. T a -> a
NonNeg.toNumber Int
n) forall (parser :: * -> *). C parser => Fragile parser Integer
getByteAsCardinal)
getVar :: Parser.C parser => Parser.Fragile parser NonNeg.Integer
getVar :: forall (parser :: * -> *). C parser => Fragile parser Integer
getVar =
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a. Integral a => a -> [a] -> a
Bit.fromBase (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^(Int
7::Int)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a b. (Integral a, Num b) => a -> b
fromIntegral) forall (parser :: * -> *). C parser => Fragile parser ByteList
getVarBytes
getVarBytes :: Parser.C parser => Parser.Fragile parser [Word8]
getVarBytes :: forall (parser :: * -> *). C parser => Fragile parser ByteList
getVarBytes =
do
Word8
digit <- forall (parser :: * -> *). C parser => Fragile parser Word8
getByte
if forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> Bool
testBit Int
7 Word8
digit
then forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
clearBit Int
7 Word8
digit forall a. a -> [a] -> [a]
:) forall (parser :: * -> *). C parser => Fragile parser ByteList
getVarBytes
else forall (m :: * -> *) a. Monad m => a -> m a
return [Word8
digit]
getEnum :: (Parser.C parser, Enum enum, Bounded enum) => Parser.Fragile parser enum
getEnum :: forall (parser :: * -> *) enum.
(C parser, Enum enum, Bounded enum) =>
Fragile parser enum
getEnum = forall (parser :: * -> *) enum.
(C parser, Enum enum, Bounded enum) =>
Int -> Fragile parser enum
makeEnum forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (parser :: * -> *). C parser => Fragile parser Int
get1
makeEnum :: (Parser.C parser, Enum enum, Bounded enum) => Int -> Parser.Fragile parser enum
makeEnum :: forall (parser :: * -> *) enum.
(C parser, Enum enum, Bounded enum) =>
Int -> Fragile parser enum
makeEnum Int
n =
let go :: (Parser.C parser, Enum a) => a -> a -> Parser.Fragile parser a
go :: forall (parser :: * -> *) a.
(C parser, Enum a) =>
a -> a -> Fragile parser a
go a
lower a
upper =
if forall a. Enum a => a -> Int
fromEnum a
lower forall a. Ord a => a -> a -> Bool
<= Int
n Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= forall a. Enum a => a -> Int
fromEnum a
upper
then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Enum a => Int -> a
toEnum Int
n)
else forall (m :: * -> *) a. Monad m => UserMessage -> T m a
Parser.giveUp (UserMessage
"value " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> UserMessage
show Int
n forall a. [a] -> [a] -> [a]
++ UserMessage
" is out of range for enumeration")
in forall (parser :: * -> *) a.
(C parser, Enum a) =>
a -> a -> Fragile parser a
go forall a. Bounded a => a
minBound forall a. Bounded a => a
maxBound