{-# LANGUAGE MultiWayIf #-}{-# LANGUAGE NoImplicitPrelude #-}-- |-- Module : System.OsString.Data.ByteString.Short-- Copyright : (c) Duncan Coutts 2012-2013, Julian Ospald 2022-- License : BSD-style---- Maintainer : hasufell@posteo.de-- Stability : stable-- Portability : ghc only---- A compact representation suitable for storing short byte strings in memory.---- In typical use cases it can be imported alongside "Data.ByteString", e.g.---- > import qualified Data.ByteString as B-- > import qualified Data.ByteString.Short as B-- > (ShortByteString, toShort, fromShort)---- Other 'ShortByteString' operations clash with "Data.ByteString" or "Prelude"-- functions however, so they should be imported @qualified@ with a different-- alias e.g.---- > import qualified Data.ByteString.Short as B.Short--moduleSystem.OsString.Data.ByteString.Short(-- * The @ShortByteString@ typeShortByteString(..),-- ** Memory overhead-- | With GHC, the memory overheads are as follows, expressed in words and-- in bytes (words are 4 and 8 bytes on 32 or 64bit machines respectively).---- * 'B.ByteString' unshared: 8 words; 32 or 64 bytes.---- * 'B.ByteString' shared substring: 4 words; 16 or 32 bytes.---- * 'ShortByteString': 4 words; 16 or 32 bytes.---- For the string data itself, both 'ShortByteString' and 'B.ByteString' use-- one byte per element, rounded up to the nearest word. For example,-- including the overheads, a length 10 'ShortByteString' would take-- @16 + 12 = 28@ bytes on a 32bit platform and @32 + 16 = 48@ bytes on a-- 64bit platform.---- These overheads can all be reduced by 1 word (4 or 8 bytes) when the-- 'ShortByteString' or 'B.ByteString' is unpacked into another constructor.---- For example:---- > data ThingId = ThingId {-# UNPACK #-} !Int-- > {-# UNPACK #-} !ShortByteString---- This will take @1 + 1 + 3@ words (the @ThingId@ constructor +-- unpacked @Int@ + unpacked @ShortByteString@), plus the words for the-- string data.-- ** Heap fragmentation-- | With GHC, the 'B.ByteString' representation uses /pinned/ memory,-- meaning it cannot be moved by the GC. This is usually the right thing to-- do for larger strings, but for small strings using pinned memory can-- lead to heap fragmentation which wastes space. The 'ShortByteString'-- type (and the @Text@ type from the @text@ package) use /unpinned/ memory-- so they do not contribute to heap fragmentation. In addition, with GHC,-- small unpinned strings are allocated in the same way as normal heap-- allocations, rather than in a separate pinned area.-- * Introducing and eliminating 'ShortByteString'sempty,singleton,pack,unpack,fromShort,toShort,-- * Basic interfacesnoc,cons,append,last,tail,uncons,uncons2 ,head,init,unsnoc,null,length,-- * Transforming ShortByteStringsmap,reverse,intercalate,-- * Reducing 'ShortByteString's (folds)foldl,foldl',foldl1,foldl1',foldr,foldr',foldr1,foldr1',-- ** Special foldsall,any,concat,-- ** Generating and unfolding ByteStringsreplicate,unfoldr,unfoldrN,-- * Substrings-- ** Breaking stringstake,takeEnd,takeWhileEnd,takeWhile,drop,dropEnd,dropWhile,dropWhileEnd,breakEnd,break,span,spanEnd,splitAt,split,splitWith,stripSuffix,stripPrefix,-- * PredicatesisInfixOf,isPrefixOf,isSuffixOf,-- ** Search for arbitrary substringsbreakSubstring,-- * Searching ShortByteStrings-- ** Searching by equalityelem,-- ** Searching with a predicatefind,filter,partition,-- * Indexing ShortByteStringsindex,indexMaybe,(!?),elemIndex,elemIndices,count,findIndex,findIndices,-- * Low level conversions-- ** Packing 'Foreign.C.String.CString's and pointerspackCString,packCStringLen,-- ** Using ShortByteStrings as 'Foreign.C.String.CString'suseAsCString,useAsCStringLen,)whereimportData.ByteString.Short.InternalimportSystem.OsString.Data.ByteString.Short.Internal importPrelude(Maybe(..),Ord(..),Num(..),($),otherwise)importData.Word(Word8)uncons2 ::ShortByteString->Maybe(Word8,Word8,ShortByteString)uncons2 :: ShortByteString -> Maybe (Word8, Word8, ShortByteString) uncons2 =\ShortByteString sbs ->letl :: Int l =ShortByteString -> Int lengthShortByteString sbs nl :: Int nl =Int l Int -> Int -> Int forall a. Num a => a -> a -> a -Int 2inif|Int l Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <=Int 1->Maybe (Word8, Word8, ShortByteString) forall a. Maybe a Nothing|Bool otherwise->leth :: Word8 h =BA -> Int -> Word8 indexWord8Array (ShortByteString -> BA asBA ShortByteString sbs )Int 0h' :: Word8 h' =BA -> Int -> Word8 indexWord8Array (ShortByteString -> BA asBA ShortByteString sbs )Int 1t :: ShortByteString t =Int -> (forall s. MBA s -> ST s ()) -> ShortByteString create Int nl ((forall s. MBA s -> ST s ()) -> ShortByteString) -> (forall s. MBA s -> ST s ()) -> ShortByteString forall a b. (a -> b) -> a -> b $\MBA s mba ->BA -> Int -> MBA s -> Int -> Int -> ST s () forall s. BA -> Int -> MBA s -> Int -> Int -> ST s () copyByteArray (ShortByteString -> BA asBA ShortByteString sbs )Int 1MBA s mba Int 0Int nl in(Word8, Word8, ShortByteString) -> Maybe (Word8, Word8, ShortByteString) forall a. a -> Maybe a Just(Word8 h ,Word8 h' ,ShortByteString t )