{-# 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
   GLsizei
len <- GettableStateVar GLsizei -> GettableStateVar GLsizei
forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
get (a -> GettableStateVar GLsizei
lengthVar a
obj)
   GLsizei -> (Ptr GLchar -> IO ()) -> IO ByteString
forall a. Integral a => a -> (Ptr GLchar -> IO ()) -> IO ByteString
createByteString GLsizei
len ((Ptr GLchar -> IO ()) -> IO ByteString)
-> (Ptr GLchar -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$
      a -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ()
getStr a
obj GLsizei
len Ptr GLsizei
forall a. Ptr a
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 (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 (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 (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 (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)