    {-# OPTIONS_HADDOCK hide #-}
    --------------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.OpenGL.GL.ByteString
    -- Copyright   :  (c) Sven Panne 2019
    -- License     :  BSD3
    --
    -- Maintainer  :  Sven Panne <svenpanne@gmail.com>
    -- Stability   :  stable
    -- Portability :  portable
    --
    -- This is a purely internal module for interfacing with ByteStrings.
    --
    --------------------------------------------------------------------------------

    module Graphics.Rendering.OpenGL.GL.ByteString (
       B.ByteString, stringQuery, createAndTrimByteString,
       withByteString, withGLstring,
       packUtf8, unpackUtf8,
       getStringWith
    ) where

    import Data.StateVar
    import Foreign.Ptr
    import Graphics.Rendering.OpenGL.GL.QueryUtils
    import Graphics.GL
    import qualified Data.ByteString as B
    import qualified Data.ByteString.Internal as BI
    import qualified Data.ByteString.Unsafe as BU
    import qualified Data.Text as T
    import qualified Data.Text.Encoding as TE

    --------------------------------------------------------------------------------

    stringQuery :: (a -> GettableStateVar GLsizei)
                -> (a -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ())
                -> a
                -> IO B.ByteString
    stringQuery :: forall a.
    (a -> GettableStateVar GLsizei)
    -> (a -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ())
    -> a
    -> IO ByteString
    stringQuery a -> GettableStateVar GLsizei
    lengthVar a -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ()
    getStr a
    obj = do
       len <- GettableStateVar GLsizei -> GettableStateVar GLsizei
    forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
    forall (m :: * -> *).
    MonadIO m =>
    GettableStateVar GLsizei -> m GLsizei
    get (a -> GettableStateVar GLsizei
    lengthVar a
    obj)
       createByteString len $
          getStr obj len nullPtr

    createByteString :: Integral a => a -> (Ptr GLchar -> IO ()) -> IO B.ByteString
    createByteString :: forall a. Integral a => a -> (Ptr GLchar -> IO ()) -> IO ByteString
    createByteString a
    size Ptr GLchar -> IO ()
    act = Int -> (Ptr Word8 -> IO ()) -> IO ByteString
    BI.create (a -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    size) (Ptr GLchar -> IO ()
    act (Ptr GLchar -> IO ())
    -> (Ptr Word8 -> Ptr GLchar) -> Ptr Word8 -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ptr Word8 -> Ptr GLchar
    forall a b. Ptr a -> Ptr b
    castPtr)

    createAndTrimByteString ::
       (Integral a, Integral b) => a -> (Ptr GLchar -> IO b) -> IO B.ByteString
    createAndTrimByteString :: forall a b.
    (Integral a, Integral b) =>
    a -> (Ptr GLchar -> IO b) -> IO ByteString
    createAndTrimByteString a
    maxLen Ptr GLchar -> IO b
    act =
       Int -> (Ptr Word8 -> IO Int) -> IO ByteString
    BI.createAndTrim (a -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    maxLen) ((b -> Int) -> IO b -> IO Int
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap b -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (IO b -> IO Int) -> (Ptr Word8 -> IO b) -> Ptr Word8 -> IO Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ptr GLchar -> IO b
    act (Ptr GLchar -> IO b)
    -> (Ptr Word8 -> Ptr GLchar) -> Ptr Word8 -> IO b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ptr Word8 -> Ptr GLchar
    forall a b. Ptr a -> Ptr b
    castPtr)

    withByteString :: B.ByteString -> (Ptr GLchar -> GLsizei -> IO b) -> IO b
    withByteString :: forall b. ByteString -> (Ptr GLchar -> GLsizei -> IO b) -> IO b
    withByteString ByteString
    bs Ptr GLchar -> GLsizei -> IO b
    act =
       ByteString -> (CStringLen -> IO b) -> IO b
    forall a. ByteString -> (CStringLen -> IO a) -> IO a
    BU.unsafeUseAsCStringLen ByteString
    bs ((CStringLen -> IO b) -> IO b) -> (CStringLen -> IO b) -> IO b
    forall a b. (a -> b) -> a -> b
    $ \(Ptr GLchar
    ptr, Int
    size) ->
          Ptr GLchar -> GLsizei -> IO b
    act (Ptr GLchar -> Ptr GLchar
    forall a b. Ptr a -> Ptr b
    castPtr Ptr GLchar
    ptr) (Int -> GLsizei
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size)

    withGLstring :: String -> (Ptr GLchar -> IO a) -> IO a
    withGLstring :: forall a. String -> (Ptr GLchar -> IO a) -> IO a
    withGLstring String
    s Ptr GLchar -> IO a
    act = ByteString -> (Ptr GLchar -> GLsizei -> IO a) -> IO a
    forall b. ByteString -> (Ptr GLchar -> GLsizei -> IO b) -> IO b
    withByteString (String -> ByteString
    packUtf8 (String
    s String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "\0")) (IO a -> GLsizei -> IO a
    forall a b. a -> b -> a
    const (IO a -> GLsizei -> IO a)
    -> (Ptr GLchar -> IO a) -> Ptr GLchar -> GLsizei -> IO a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ptr GLchar -> IO a
    act)

    packUtf8 :: String -> B.ByteString
    packUtf8 :: String -> ByteString
    packUtf8 = Text -> ByteString
    TE.encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    T.pack

    unpackUtf8 :: B.ByteString -> String
    unpackUtf8 :: ByteString -> String
    unpackUtf8 = Text -> String
    T.unpack (Text -> String) -> (ByteString -> Text) -> ByteString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Text
    TE.decodeUtf8

    getStringWith :: IO (Ptr GLubyte) -> IO String
    getStringWith :: IO (Ptr Word8) -> IO String
    getStringWith IO (Ptr Word8)
    getStr = IO (Ptr Word8)
    getStr IO (Ptr Word8) -> (Ptr Word8 -> IO String) -> IO String
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= IO String -> (Ptr Word8 -> IO String) -> Ptr Word8 -> IO String
    forall b a. b -> (Ptr a -> b) -> Ptr a -> b
    maybeNullPtr (String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    "") Ptr Word8 -> IO String
    peekGLstring

    peekGLstring :: Ptr GLubyte -> IO String
    peekGLstring :: Ptr Word8 -> IO String
    peekGLstring Ptr Word8
    p = (ByteString -> String) -> IO ByteString -> IO String
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ByteString -> String
    unpackUtf8 (IO ByteString -> IO String) -> IO ByteString -> IO String
    forall a b. (a -> b) -> a -> b
    $ Ptr GLchar -> IO ByteString
    BU.unsafePackCString (Ptr Word8 -> Ptr GLchar
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word8
    p)