-- | -- Module : Data.CompactString.Unsafe -- License : BSD-style -- Maintainer : twanvl@gmail.com -- Stability : experimental -- Portability : untested -- -- Unsafe functions on 'CompactString's. -- All these functions can lead to crashes if not used properly. -- module Data.CompactString.Unsafe ( -- * Basic interface unsafeHead, -- :: Encoding a => CompactString a -> Char unsafeLast, -- :: Encoding a => CompactString a -> Char unsafeTail, -- :: Encoding a => CompactString a -> CompactString unsafeInit, -- :: Encoding a => CompactString a -> CompactString -- * Conversion from 'ByteString' unsafeFromByteString -- :: ByteString -> CompactString a ) where import Data.CompactString.Internal -- ----------------------------------------------------------------------------- -- -- Basic interface -- -- | A variety of 'head' for non-empty CompactString. 'unsafeHead' omits the -- check for the empty case, so there is an obligation on the programmer -- to provide a proof that the CompactString is non-empty. unsafeHead :: Encoding a => CompactString a -> Char unsafeHead cs = snd $ unsafeWithBuffer cs $ peekChar (encoding cs) {-# INLINE unsafeHead #-} -- | A variety of 'tail' for non-empty CompactString. 'unsafeTail' omits the -- check for the empty case, so there is an obligation on the programmer -- to provide a proof that the CompactString is non-empty. unsafeTail :: Encoding a => CompactString a -> CompactString a unsafeTail cs@(CS (PS x s l)) = let headlen = unsafeWithBuffer cs $ peekCharLen (encoding cs) in CS (PS x (s+headlen) (l-headlen)) {-# INLINE unsafeTail #-} -- | A variety of 'last' for non-empty CompactString. 'unsafeLast' omits the -- check for the empty case, so there is an obligation on the programmer -- to provide a proof that the CompactString is non-empty. unsafeLast :: Encoding a => CompactString a -> Char unsafeLast cs = snd $ unsafeWithBufferEnd cs $ peekCharRev (encoding cs) {-# INLINE unsafeLast #-} -- | A variety of 'init' for non-empty CompactString. 'unsafeInit' omits the -- check for the empty case, so there is an obligation on the programmer -- to provide a proof that the CompactString is non-empty. unsafeInit :: Encoding a => CompactString a -> CompactString a unsafeInit cs@(CS (PS x s l)) = let lastlen = unsafeWithBufferEnd cs $ peekCharLenRev (encoding cs) in CS (PS x s (l-lastlen)) {-# INLINE unsafeInit #-} -- ----------------------------------------------------------------------------- -- -- Conversion -- -- | Convert a ByteString to a CompactString, -- does not check whether the ByteString represents a valid string in the encoding a. unsafeFromByteString :: ByteString -> CompactString a unsafeFromByteString = CS