Skip to content

Commit a26c49b

Browse files
Add asCWStringUnsafe
1 parent eb1163d commit a26c49b

3 files changed

Lines changed: 53 additions & 13 deletions

File tree

core/src/Streamly/Internal/Data/Array.hs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ module Streamly.Internal.Data.Array
4343
, cast
4444
, asBytes
4545
, unsafeCast
46-
, asCStringUnsafe
46+
, asCStringUnsafe -- XXX asCString
47+
, asCWString
4748

4849
-- * Subarrays
4950
-- , sliceOffLen
@@ -114,8 +115,7 @@ import Control.Monad.IO.Class (MonadIO(..))
114115
import Data.Functor.Identity (Identity(..))
115116
import Data.Proxy (Proxy(..))
116117
import Data.Word (Word8)
117-
import Foreign.C.String (CString)
118-
import Foreign.Ptr (castPtr)
118+
import Foreign.C.String (CString, CWString)
119119
import GHC.Types (SPEC(..))
120120
import Streamly.Internal.Data.Unbox (Unbox(..))
121121
import Prelude hiding (length, null, last, map, (!!), read, concat)
@@ -424,9 +424,8 @@ cast arr =
424424
then Nothing
425425
else Just $ unsafeCast arr
426426

427-
-- | Convert an array of any type into a null terminated CString Ptr. If the
428-
-- array is unpinned it is first converted to a pinned array which requires a
429-
-- copy.
427+
-- | Convert an array of any element type into a null terminated CString Ptr.
428+
-- The array is copied to pinned memory.
430429
--
431430
-- /Unsafe/
432431
--
@@ -435,10 +434,19 @@ cast arr =
435434
-- /Pre-release/
436435
--
437436
asCStringUnsafe :: Array a -> (CString -> IO b) -> IO b
438-
asCStringUnsafe arr act = do
439-
let arr1 = asBytes arr <> fromList [0]
440-
-- unsafePinnedAsPtr makes sure the array is pinned
441-
unsafePinnedAsPtr arr1 $ \ptr _ -> act (castPtr ptr)
437+
asCStringUnsafe arr = MA.asCString (unsafeThaw arr)
438+
439+
-- | Convert an array of any element type into a null terminated CWString Ptr.
440+
-- The array is copied to pinned memory.
441+
--
442+
-- /Unsafe/
443+
--
444+
-- /O(n) Time: (creates a copy of the array)/
445+
--
446+
-- /Pre-release/
447+
--
448+
asCWString :: Array a -> (CWString -> IO b) -> IO b
449+
asCWString arr = MA.asCWString (unsafeThaw arr)
442450

443451
-------------------------------------------------------------------------------
444452
-- Folds

core/src/Streamly/Internal/Data/MutArray/Type.hs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ module Streamly.Internal.Data.MutArray.Type
4444
, cast
4545
, unsafeCast
4646
, asBytes
47-
, unsafeAsPtr
47+
, unsafeAsPtr -- XXX asPtr
48+
, asCString
49+
, asCWString
4850

4951
-- ** Construction
5052
, empty
@@ -466,8 +468,9 @@ import Data.Char (ord)
466468
import Data.Functor.Identity (Identity(..))
467469
import Data.Proxy (Proxy(..))
468470
import Data.Word (Word8, Word16)
469-
import Foreign.C.Types (CSize(..))
470-
import Foreign.Ptr (plusPtr)
471+
import Foreign.C.String (CString, CWString)
472+
import Foreign.C.Types (CSize(..), CChar, CWchar)
473+
import Foreign.Ptr (plusPtr, castPtr)
471474
import Streamly.Internal.Data.MutByteArray.Type
472475
( MutByteArray(..)
473476
, PinnedState(..)
@@ -3569,6 +3572,28 @@ unsafeCreateWithPtr' cap pop = do
35693572
++ "length = " ++ show len ++ ", "
35703573
++ "capacity = " ++ show cap
35713574

3575+
asCString :: MutArray a -> (CString -> IO b) -> IO b
3576+
asCString arr act = do
3577+
let pinned = isPinned arr
3578+
req = byteLength arr + SIZE_OF(CChar)
3579+
arr1 <-
3580+
if byteCapacity arr < req || not pinned
3581+
then reallocExplicitAs Pinned 1 req arr
3582+
else return arr
3583+
arr2 :: MutArray CChar <- snocUnsafe (unsafeCast arr1) (0 :: CChar)
3584+
unsafeAsPtr arr2 $ \ptr _ -> act (castPtr ptr)
3585+
3586+
asCWString :: MutArray a -> (CWString -> IO b) -> IO b
3587+
asCWString arr act = do
3588+
let pinned = isPinned arr
3589+
req = byteLength arr + SIZE_OF(CWchar)
3590+
arr1 <-
3591+
if byteCapacity arr < req || not pinned
3592+
then reallocExplicitAs Pinned 1 req arr
3593+
else return arr
3594+
arr2 :: MutArray CWchar <- snocUnsafe (unsafeCast arr1) (0 :: CWchar)
3595+
unsafeAsPtr arr2 $ \ptr _ -> act (castPtr ptr)
3596+
35723597
-------------------------------------------------------------------------------
35733598
-- Equality
35743599
-------------------------------------------------------------------------------

core/src/Streamly/Internal/Data/Unbox.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ module Streamly.Internal.Data.Unbox
4242
) where
4343

4444
#include "MachDeps.h"
45+
#include "HsBaseConfig.h"
4546
#include "ArrayMacros.h"
4647

4748
import Control.Monad (void, when)
@@ -51,6 +52,7 @@ import Data.Functor.Const (Const(..))
5152
import Data.Functor.Identity (Identity(..))
5253
import Data.Kind (Type)
5354
import Data.Proxy (Proxy (..))
55+
import Foreign.C.Types (CChar(..), CWchar(..))
5456
import Foreign.Ptr (IntPtr(..), WordPtr(..))
5557
import GHC.Base (IO(..))
5658
import GHC.Fingerprint.Type (Fingerprint(..))
@@ -445,6 +447,11 @@ DERIVE_WRAPPED_UNBOX(Unbox a =>,(Identity a),Identity,a)
445447
DERIVE_WRAPPED_UNBOX(Unbox a =>,(Down a),Down,a)
446448
#endif
447449
DERIVE_WRAPPED_UNBOX(Unbox a =>,(Const a b),Const,a)
450+
451+
-- XXX Add more CTypes
452+
DERIVE_WRAPPED_UNBOX(,CChar,CChar,HTYPE_CHAR)
453+
DERIVE_WRAPPED_UNBOX(,CWchar,CWchar,HTYPE_WCHAR_T)
454+
448455
DERIVE_BINARY_UNBOX(forall a. Unbox a =>,(Complex a),(:+),a)
449456
DERIVE_BINARY_UNBOX(forall a. Unbox a =>,(Ratio a),(:%),a)
450457
DERIVE_BINARY_UNBOX(,Fingerprint,Fingerprint,Word64)

0 commit comments

Comments
 (0)