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.List ( length )
42
data ByteArray ix = ByteArray ix ix ByteArray#
43
data MutableByteArray s ix = MutableByteArray ix ix (MutableByteArray# s)
45
unpackCString :: Ptr a -> [Char]
46
unpackCString a@(Ptr addr)
48
| otherwise = unpackCString# addr
50
packCString# :: [Char] -> ByteArray#
51
packCString# str = case (packString str) of { ByteArray _ _ bytes -> bytes }
53
packString :: [Char] -> ByteArray Int
54
packString str = runST (packStringST str)
56
packStringST :: [Char] -> ST s (ByteArray Int)
58
let len = length str in
61
packNBytesST :: Int -> [Char] -> ST s (ByteArray Int)
62
packNBytesST (I# length#) str =
64
allocate an array that will hold the string
65
(not forgetting the NUL byte at the end)
67
new_ps_array (length# +# 1#) >>= \ ch_array ->
68
-- fill in packed string from "str"
69
fill_in ch_array 0# str >>
71
freeze_ps_array ch_array length#
73
fill_in :: MutableByteArray s Int -> Int# -> [Char] -> ST s ()
74
fill_in arr_in# idx [] =
75
write_ps_array arr_in# idx (chr# 0#) >>
78
fill_in arr_in# idx (C# c : cs) =
79
write_ps_array arr_in# idx c >>
80
fill_in arr_in# (idx +# 1#) cs
82
-- (Very :-) ``Specialised'' versions of some CharArray things...
84
new_ps_array :: Int# -> ST s (MutableByteArray s Int)
85
write_ps_array :: MutableByteArray s Int -> Int# -> Char# -> ST s ()
86
freeze_ps_array :: MutableByteArray s Int -> Int# -> ST s (ByteArray Int)
88
new_ps_array size = ST $ \ s ->
89
case (newByteArray# size s) of { (# s2#, barr# #) ->
90
(# s2#, MutableByteArray bot bot barr# #) }
92
bot = error "new_ps_array"
94
write_ps_array (MutableByteArray _ _ barr#) n ch = ST $ \ s# ->
95
case writeCharArray# barr# n ch s# of { s2# ->
98
-- same as unsafeFreezeByteArray
99
freeze_ps_array (MutableByteArray _ _ arr#) len# = ST $ \ s# ->
100
case unsafeFreezeByteArray# arr# s# of { (# s2#, frozen# #) ->
101
(# s2#, ByteArray 0 (I# len#) frozen# #) }