    {- | This is drop-in replacement for the read, write, and index functions
    present in @Data.Primitive.Ptr@. While the functions from those modules
    use native byte order, the functions in this one use big-endian byte order
    (most significant byte first).
    -}
    module Data.Primitive.Ptr.BigEndian
      ( -- * Aligned
        writeOffPtr
      , readOffPtr
      , indexOffPtr
      ) where

    import Control.Monad.Primitive (PrimMonad)
    import Data.Primitive (Prim)
    import Data.Primitive.Ptr (Ptr)
    import qualified Data.Primitive.Ptr as PM
    import System.ByteOrder (Bytes, fromBigEndian, toBigEndian)

    {- | Write a primitive value to the pointer. The offset is given
    in elements of type @a@ rather than in bytes. The most significant
    byte in the value comes first.
    -}
    writeOffPtr :: (PrimMonad m, Prim a, Bytes a) => Ptr a -> Int -> a -> m ()
    writeOffPtr :: forall (m :: * -> *) a.
    (PrimMonad m, Prim a, Bytes a) =>
    Ptr a -> Int -> a -> m ()
    writeOffPtr Ptr a
    arr Int
    ix a
    v = Ptr a -> Int -> a -> m ()
    forall a (m :: * -> *).
    (Prim a, PrimMonad m) =>
    Ptr a -> Int -> a -> m ()
    PM.writeOffPtr Ptr a
    arr Int
    ix (a -> a
    forall a. Bytes a => a -> a
    toBigEndian a
    v)

    {- | Read a primitive value from the pointer, interpreting the first
    byte as the most significant one. The offset is given in elements of
    type @a@ rather than in bytes.
    -}
    readOffPtr :: (PrimMonad m, Prim a, Bytes a) => Ptr a -> Int -> m a
    readOffPtr :: forall (m :: * -> *) a.
    (PrimMonad m, Prim a, Bytes a) =>
    Ptr a -> Int -> m a
    readOffPtr Ptr a
    arr Int
    ix = a -> a
    forall a. Bytes a => a -> a
    fromBigEndian (a -> a) -> m a -> m a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Ptr a -> Int -> m a
    forall a (m :: * -> *).
    (Prim a, PrimMonad m) =>
    Ptr a -> Int -> m a
    PM.readOffPtr Ptr a
    arr Int
    ix

    {- | Read a primitive value from the pointer, interpreting the first
    byte as the most significant one. The offset is given in elements of
    type @a@ rather than in bytes.
    -}
    indexOffPtr :: (Prim a, Bytes a) => Ptr a -> Int -> a
    indexOffPtr :: forall a. (Prim a, Bytes a) => Ptr a -> Int -> a
    indexOffPtr Ptr a
    arr Int
    ix = a -> a
    forall a. Bytes a => a -> a
    fromBigEndian (Ptr a -> Int -> a
    forall a. Prim a => Ptr a -> Int -> a
    PM.indexOffPtr Ptr a
    arr Int
    ix)