2 {-# OPTIONS_GHC -XNoImplicitPrelude #-}
3 {-# OPTIONS_HADDOCK hide #-}
4 -----------------------------------------------------------------------------
7 -- Copyright : (c) The University of Glasgow 1997-2002
8 -- License : see libraries/base/LICENSE
10 -- Maintainer : cvs-ghc@haskell.org
11 -- Stability : internal
12 -- Portability : non-portable (GHC Extensions)
14 -- This module provides a small set of low-level functions for packing
15 -- and unpacking a chunk of bytes. Used by code emitted by the compiler
16 -- plus the prelude libraries.
18 -- The programmer level view of packed strings is provided by a GHC
19 -- system library PackedString.
21 -----------------------------------------------------------------------------
26 -- (**) - emitted by compiler.
28 packCString#, -- :: [Char] -> ByteArray# (**)
30 unpackCString#, -- :: Addr# -> [Char] (**)
31 unpackNBytes#, -- :: Addr# -> Int# -> [Char] (**)
32 unpackFoldrCString#, -- (**)
33 unpackAppendCString#, -- (**)
38 import GHC.Err ( error )
39 import GHC.List ( length )
44 data ByteArray ix = ByteArray ix ix ByteArray#
45 data MutableByteArray s ix = MutableByteArray ix ix (MutableByteArray# s)
47 unpackCString :: Ptr a -> [Char]
48 unpackCString a@(Ptr addr)
50 | otherwise = unpackCString# addr
52 packCString# :: [Char] -> ByteArray#
53 packCString# str = case (packString str) of { ByteArray _ _ bytes -> bytes }
55 packString :: [Char] -> ByteArray Int
56 packString str = runST (packStringST str)
58 packStringST :: [Char] -> ST s (ByteArray Int)
60 let len = length str in
63 packNBytesST :: Int -> [Char] -> ST s (ByteArray Int)
64 packNBytesST (I# length#) str =
66 allocate an array that will hold the string
67 (not forgetting the NUL byte at the end)
69 new_ps_array (length# +# 1#) >>= \ ch_array ->
70 -- fill in packed string from "str"
71 fill_in ch_array 0# str >>
73 freeze_ps_array ch_array length#
75 fill_in :: MutableByteArray s Int -> Int# -> [Char] -> ST s ()
76 fill_in arr_in# idx [] =
77 write_ps_array arr_in# idx (chr# 0#) >>
80 fill_in arr_in# idx (C# c : cs) =
81 write_ps_array arr_in# idx c >>
82 fill_in arr_in# (idx +# 1#) cs
84 -- (Very :-) ``Specialised'' versions of some CharArray things...
86 new_ps_array :: Int# -> ST s (MutableByteArray s Int)
87 write_ps_array :: MutableByteArray s Int -> Int# -> Char# -> ST s ()
88 freeze_ps_array :: MutableByteArray s Int -> Int# -> ST s (ByteArray Int)
90 new_ps_array size = ST $ \ s ->
91 case (newByteArray# size s) of { (# s2#, barr# #) ->
92 (# s2#, MutableByteArray bot bot barr# #) }
94 bot = error "new_ps_array"
96 write_ps_array (MutableByteArray _ _ barr#) n ch = ST $ \ s# ->
97 case writeCharArray# barr# n ch s# of { s2# ->
100 -- same as unsafeFreezeByteArray
101 freeze_ps_array (MutableByteArray _ _ arr#) len# = ST $ \ s# ->
102 case unsafeFreezeByteArray# arr# s# of { (# s2#, frozen# #) ->
103 (# s2#, ByteArray 0 (I# len#) frozen# #) }