Copyright | (c) Dong Han 2017-2018 |
---|---|
License | BSD |
Maintainer | winterland1989@gmail.com |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
This module provides CBytes
with some useful instances / tools for retrieving, storing or processing
short byte sequences, such as file path, environment variables, etc.
Synopsis
- data CBytes where
- rawPrimArray :: CBytes -> PrimArray Word8
- fromPrimArray :: PrimArray Word8 -> CBytes
- fromMutablePrimArray :: PrimMonad m => MutablePrimArray (PrimState m) Word8 -> m CBytes
- toBytes :: CBytes -> Bytes
- toBytes' :: CBytes -> Bytes
- fromBytes :: Bytes -> CBytes
- toText :: HasCallStack => CBytes -> Text
- toTextMaybe :: CBytes -> Maybe Text
- fromText :: Text -> CBytes
- toBuilder :: CBytes -> Builder ()
- toBuilder' :: CBytes -> Builder ()
- buildCBytes :: Builder a -> CBytes
- pack :: String -> CBytes
- unpack :: CBytes -> String
- null :: CBytes -> Bool
- length :: CBytes -> Int
- empty :: CBytes
- singleton :: Word8 -> CBytes
- append :: CBytes -> CBytes -> CBytes
- concat :: [CBytes] -> CBytes
- intercalate :: CBytes -> [CBytes] -> CBytes
- intercalateElem :: Word8 -> [CBytes] -> CBytes
- fromCString :: CString -> IO CBytes
- fromCStringN :: CString -> Int -> IO CBytes
- fromStdString :: IO (Ptr StdString) -> IO CBytes
- withCBytesUnsafe :: CBytes -> (BA# Word8 -> IO a) -> IO a
- withCBytes :: CBytes -> (Ptr Word8 -> IO a) -> IO a
- allocCBytesUnsafe :: HasCallStack => Int -> (MBA# Word8 -> IO a) -> IO (CBytes, a)
- allocCBytes :: HasCallStack => Int -> (CString -> IO a) -> IO (CBytes, a)
- withCBytesListUnsafe :: [CBytes] -> (BAArray# Word8 -> Int -> IO a) -> IO a
- withCBytesList :: [CBytes] -> (Ptr (Ptr Word8) -> Int -> IO a) -> IO a
- pokeMBACBytes :: MBA# Word8 -> Int -> CBytes -> IO ()
- peekMBACBytes :: MBA# Word8 -> Int -> IO CBytes
- indexBACBytes :: BA# Word8 -> Int -> CBytes
- type CString = Ptr CChar
The CBytes type
A efficient wrapper for short immutable null-terminated byte sequences which can be automatically freed by ghc garbage collector.
The main use case of this type is to ease the bridging of C FFI APIs, since most of the unix APIs use null-terminated string. On windows you're encouraged to use a compatibility layer like 'WideCharToMultiByte/MultiByteToWideChar' and keep the same interface, e.g. libuv do this when deal with file paths.
CBytes
don't support O(1) slicing, it's not suitable to use it to store large byte
chunk, If you need advance editing, convert CBytes
to/from Bytes
with CB
pattern or
toBytes
/ fromBytes
, then use vector combinators.
When textual represatation is needed e.g. converting to String
, Text
, Show
instance, etc.,
we assume CBytes
using UTF-8 encodings, CBytes
can be used with OverloadedString
,
literal encoding is UTF-8 with some modifications: \NUL
is encoded to 'C0 80',
and \xD800
~ \xDFFF
is encoded as a three bytes normal utf-8 codepoint.
Note most of the unix API is not unicode awared though, you may find a scandir
call
return a filename which is not proper encoded in any unicode encoding at all.
But still, UTF-8 is recommanded to be used when text represatation is needed.
pattern CB :: Bytes -> CBytes | Use this pattern to match or construct |
Instances
Eq CBytes Source # | |
Ord CBytes Source # | |
Read CBytes Source # | |
Show CBytes Source # | |
IsString CBytes Source # | |
Defined in Z.Data.CBytes fromString :: String -> CBytes # | |
Semigroup CBytes Source # | |
Monoid CBytes Source # | |
Arbitrary CBytes Source # | |
CoArbitrary CBytes Source # | |
Defined in Z.Data.CBytes coarbitrary :: CBytes -> Gen b -> Gen b # | |
NFData CBytes Source # | |
Defined in Z.Data.CBytes | |
Hashable CBytes Source # | |
Defined in Z.Data.CBytes | |
Print CBytes Source # | This instance provide UTF8 guarantee, illegal codepoints will be written as Escaping rule is same with |
Defined in Z.Data.CBytes | |
JSON CBytes Source # | JSON instances check if > encodeText ("hello" :: CBytes)
""hello""
> encodeText ("hello\NUL" :: CBytes) -- |
rawPrimArray :: CBytes -> PrimArray Word8 Source #
Convert to a \NUL
terminated PrimArray
,
There's an invariance that this array never contains extra \NUL
except terminator.
fromPrimArray :: PrimArray Word8 -> CBytes Source #
Construct a CBytes
from arbitrary array, result will be trimmed down to first \NUL
byte if there's any.
fromMutablePrimArray :: PrimMonad m => MutablePrimArray (PrimState m) Word8 -> m CBytes Source #
Construct a CBytes
from a MutablePrimArray
.
Result will be shrinked to first \NUL
byte without copy. If there is no
\NUL
found in the array, We will resize the origin MutablePrimArray, so,
to avoid undefined behaviour, the original MutablePrimArray shall not be
accessed anymore. Moreover, no reference to the old one should be kept in
order to allow garbage collection of the original MutablePrimArray in case
a new MutablePrimArray had to be allocated.
toBytes :: CBytes -> Bytes Source #
O(1), convert to Bytes
, which can be processed by vector combinators.
fromBytes :: Bytes -> CBytes Source #
O(n), convert from Bytes
Result will be trimmed down to first \NUL
byte if there's any.
toText :: HasCallStack => CBytes -> Text Source #
O(n), convert to Text
using UTF8 encoding assumption.
Throw InvalidUTF8Exception
in case of invalid codepoint.
fromText :: Text -> CBytes Source #
O(n), convert from Text
,
Result will be trimmed down to first \NUL
byte if there's any.
toBuilder' :: CBytes -> Builder () Source #
Write CBytes
's byte sequence to buffer, with its NULL terminator.
buildCBytes :: Builder a -> CBytes Source #
Build a CBytes
with builder, will automatically be trimmed down to first \NUL
byte if there's any,
or append with one if there's none.
unpack :: CBytes -> String Source #
O(n) Convert cbytes to a char list using UTF8 encoding assumption.
This function is much tolerant than toText
, it simply decoding codepoints using UTF8 decodeChar
without checking errors such as overlong or invalid range.
Unpacking is done lazily. i.e. we will retain reference to the array until all element are consumed.
This function is a good producer in the sense of build/foldr fusion.
intercalate :: CBytes -> [CBytes] -> CBytes Source #
O(n) The intercalate
function takes a CBytes
and a list of
CBytes
s and concatenates the list after interspersing the first
argument between each element of the list.
Note: intercalate
will force the entire CBytes
list.
intercalateElem :: Word8 -> [CBytes] -> CBytes Source #
O(n) An efficient way to join CByte
s with a byte.
Intercalate bytes list with \NUL
will effectively leave the first bytes in the list.
fromCStringN :: CString -> Int -> IO CBytes Source #
Same with fromCString
, but only take at most N bytes.
Result will be trimmed down to first \NUL
byte if there's any.
fromStdString :: IO (Ptr StdString) -> IO CBytes Source #
Run FFI in bracket and marshall std::string*
result into CBytes
,
memory pointed by std::string*
will be delete
ed.
withCBytesUnsafe :: CBytes -> (BA# Word8 -> IO a) -> IO a Source #
Pass CBytes
to foreign function as a const char*
.
USE THIS FUNCTION WITH UNSAFE FFI CALL ONLY.
:: HasCallStack | |
=> Int | capacity n(including the |
-> (MBA# Word8 -> IO a) | initialization function, |
-> IO (CBytes, a) |
Create a CBytes
with IO action.
If (<=0) capacity is provided, a pointer pointing to \NUL
is passed to initialize function
and empty
will be returned. This behavior is different from allocCBytes
, which may cause
trouble for some FFI functions.
USE THIS FUNCTION WITH UNSAFE FFI CALL ONLY.
withCBytesListUnsafe :: [CBytes] -> (BAArray# Word8 -> Int -> IO a) -> IO a Source #
Pass CBytes
list to foreign function as a StgArrBytes**
.
Enable UnliftedFFITypes
extension in your haskell code, use StgArrBytes**
(>=8.10)
or StgMutArrPtrs*
(<8.10) pointer type and HsInt
to marshall BAArray#
and Int
arguments on C side, check the example with BAArray#
.
USE THIS FUNCTION WITH UNSAFE FFI CALL ONLY.
peekMBACBytes :: MBA# Word8 -> Int -> IO CBytes Source #
Poke CBytes
until a \NUL terminator(or to the end of the array if there's none).
indexBACBytes :: BA# Word8 -> Int -> CBytes Source #
Index a CBytes
until a \NUL terminator(or to the end of the array if there's none).