Movatterモバイル変換
[0]ホーム
{-# LANGUAGE CPP, ForeignFunctionInterface, BangPatterns #-}{-# LANGUAGE UnliftedFFITypes, MagicHash, UnboxedTuples, DeriveDataTypeable #-}{-# LANGUAGE TupleSections #-}{-# LANGUAGE TypeFamilies #-}{-# LANGUAGE PatternSynonyms, ViewPatterns #-}{-# LANGUAGE Unsafe #-}{-# LANGUAGE TemplateHaskellQuotes #-}{-# OPTIONS_HADDOCK not-home #-}-- |-- Module : Data.ByteString.Internal-- Copyright : (c) Don Stewart 2006-2008-- (c) Duncan Coutts 2006-2012-- License : BSD-style-- Maintainer : dons00@gmail.com, duncan@community.haskell.org-- Stability : unstable-- Portability : non-portable---- A module containing semi-public 'ByteString' internals. This exposes the-- 'ByteString' representation and low level construction functions. As such-- all the functions in this module are unsafe. The API is also not stable.---- Where possible application should instead use the functions from the normal-- public interface modules, such as "Data.ByteString.Unsafe". Packages that-- extend the ByteString system at a low level will need to use this module.--moduleData.ByteString.Internal(-- * The @ByteString@ type and representationByteString(BS,PS-- backwards compatibility shim),StrictByteString,-- * Internal indexingfindIndexOrLength,-- * Conversion with lists: packing and unpackingpackBytes,packUptoLenBytes,unsafePackLenBytes,packChars,packUptoLenChars,unsafePackLenChars,unpackBytes,unpackAppendBytesLazy,unpackAppendBytesStrict,unpackChars,unpackAppendCharsLazy,unpackAppendCharsStrict,unsafePackAddress,unsafePackLenAddress,unsafePackLiteral,unsafePackLenLiteral,-- * Low level imperative constructionempty,create,createUptoN,createUptoN',createAndTrim,createAndTrim',unsafeCreate,unsafeCreateUptoN,unsafeCreateUptoN',mallocByteString,-- * Conversion to and from ForeignPtrsfromForeignPtr,toForeignPtr,fromForeignPtr0,toForeignPtr0,-- * UtilitiesnullForeignPtr,checkedAdd,-- * Standard C Functionsc_strlen,c_free_finalizer,memchr,memcmp,memcpy,memset,-- * cbits functionsc_reverse,c_intersperse,c_maximum,c_minimum,c_count,c_sort,-- * Charsw2c,c2w,isSpaceWord8,isSpaceChar8,-- * Deprecated and unmentionableaccursedUnutterablePerformIO,-- * Exported compatibility shimplusForeignPtr,unsafeWithForeignPtr)whereimportPreludehiding(concat,null)importqualifiedData.ListasListimportControl.Monad(void)importForeign.ForeignPtr(ForeignPtr,withForeignPtr)importForeign.Ptr(Ptr,FunPtr,plusPtr,minusPtr)importForeign.Storable(Storable(..))importForeign.C.Types(CInt(..),CSize(..))importForeign.C.String(CString)#if MIN_VERSION_base(4,13,0)importData.Semigroup(Semigroup(sconcat,stimes))#elseimportData.Semigroup(Semigroup((<>),sconcat,stimes))#endifimportData.List.NonEmpty(NonEmpty((:|)))importControl.DeepSeq(NFData(rnf))importData.String(IsString(..))importControl.Exception(assert)importData.Bits((.&.))importData.Char(ord)importData.WordimportData.Typeable(Typeable)importData.Data(Data(..),mkNoRepType)importGHC.Base(nullAddr#,realWorld#,unsafeChr)importGHC.Exts(IsList(..))importGHC.CString(unpackCString#)importGHC.Prim(Addr#)importGHC.IO(IO(IO),unsafeDupablePerformIO)importGHC.ForeignPtr(ForeignPtr(ForeignPtr)#if __GLASGOW_HASKELL__ < 900,newForeignPtr_#endif,mallocPlainForeignPtrBytes)#if MIN_VERSION_base(4,10,0)importGHC.ForeignPtr(plusForeignPtr)#elseimportGHC.Prim(plusAddr#)#endif#if __GLASGOW_HASKELL__ >= 811importGHC.CString(cstringLength#)importGHC.ForeignPtr(ForeignPtrContents(FinalPtr))#elseimportGHC.Ptr(Ptr(..))#endif#if (__GLASGOW_HASKELL__ < 802) || (__GLASGOW_HASKELL__ >= 811)importGHC.Types(Int(..))#endif#if MIN_VERSION_base(4,15,0)importGHC.ForeignPtr(unsafeWithForeignPtr)#endifimportqualifiedLanguage.Haskell.TH.LibasTHimportqualifiedLanguage.Haskell.TH.SyntaxasTH#if !MIN_VERSION_base(4,15,0)unsafeWithForeignPtr::ForeignPtra->(Ptra->IOb)->IObunsafeWithForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtr=ForeignPtr a -> (Ptr a -> IO b) -> IO bforall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bwithForeignPtr#endif-- CFILES stuff is Hugs only{-# CFILES cbits/fpstring.c #-}#if !MIN_VERSION_base(4,10,0)-- |Advances the given address by the given offset in bytes.---- The new 'ForeignPtr' shares the finalizer of the original,-- equivalent from a finalization standpoint to just creating another-- reference to the original. That is, the finalizer will not be-- called before the new 'ForeignPtr' is unreachable, nor will it be-- called an additional time due to this call, and the finalizer will-- be called with the same address that it would have had this call-- not happened, *not* the new address.plusForeignPtr::ForeignPtra->Int->ForeignPtrbplusForeignPtr(ForeignPtraddrguts)(I#offset)=ForeignPtr(plusAddr#addroffset)guts{-# INLINE[0]plusForeignPtr#-}{-# RULES"ByteString plusForeignPtr/0"forallfp.plusForeignPtrfp0=fp#-}#endif-- ------------------------------------------------------------------------------- | A space-efficient representation of a 'Word8' vector, supporting many-- efficient operations.---- A 'ByteString' contains 8-bit bytes, or by using the operations from-- "Data.ByteString.Char8" it can be interpreted as containing 8-bit-- characters.--dataByteString=BS{-# UNPACK#-}!(ForeignPtrWord8)-- payload{-# UNPACK#-}!Int-- length-- ^ @since 0.11.0.0deriving(Typeable)-- | Type synonym for the strict flavour of 'ByteString'.---- @since 0.11.2.0typeStrictByteString=ByteString-- |-- @'PS' foreignPtr offset length@ represents a 'ByteString' with data-- backed by a given @foreignPtr@, starting at a given @offset@ in bytes-- and of a specified @length@.---- This pattern is used to emulate the legacy 'ByteString' data-- constructor, so that pre-existing code generally doesn't need to-- change to benefit from the simplified 'BS' constructor and can-- continue to function unchanged.---- /Note:/ Matching with this constructor will always be given a 0 offset,-- as the base will be manipulated by 'plusForeignPtr' instead.--patternPS::ForeignPtrWord8->Int->Int->ByteStringpattern$bPS :: ForeignPtr Word8 -> Int -> Int -> ByteString$mPS :: forall r.ByteString-> (ForeignPtr Word8 -> Int -> Int -> r) -> (Void# -> r) -> rPSfpzerolen<-BSfp((0,)->(zero,len))wherePSForeignPtr Word8fpIntoIntlen=ForeignPtr Word8 -> Int -> ByteStringBS(ForeignPtr Word8 -> Int -> ForeignPtr Word8forall a b. ForeignPtr a -> Int -> ForeignPtr bplusForeignPtrForeignPtr Word8fpInto)Intlen#if __GLASGOW_HASKELL__ >= 802{-# COMPLETEPS#-}#endifinstanceEqByteStringwhere== :: ByteString -> ByteString -> Bool(==)=ByteString -> ByteString -> BooleqinstanceOrdByteStringwherecompare :: ByteString -> ByteString -> Orderingcompare=ByteString -> ByteString -> OrderingcompareBytesinstanceSemigroupByteStringwhere<> :: ByteString -> ByteString -> ByteString(<>)=ByteString -> ByteString -> ByteStringappendsconcat :: NonEmpty ByteString -> ByteStringsconcat(ByteStringb:|[ByteString]bs)=[ByteString] -> ByteStringconcat(ByteStringbByteString -> [ByteString] -> [ByteString]forall a. a -> [a] -> [a]:[ByteString]bs)stimes :: b -> ByteString -> ByteStringstimes=b -> ByteString -> ByteStringforall b. Integral b => b -> ByteString -> ByteStringtimesinstanceMonoidByteStringwheremempty :: ByteStringmempty=ByteStringemptymappend :: ByteString -> ByteString -> ByteStringmappend=ByteString -> ByteString -> ByteStringforall a. Semigroup a => a -> a -> a(<>)mconcat :: [ByteString] -> ByteStringmconcat=[ByteString] -> ByteStringconcatinstanceNFDataByteStringwherernf :: ByteString -> ()rnfBS{}=()instanceShowByteStringwhereshowsPrec :: Int -> ByteString -> ShowSshowsPrecIntpByteStringpsStringr=Int -> String -> ShowSforall a. Show a => Int -> a -> ShowSshowsPrecIntp(ByteString -> StringunpackCharsByteStringps)StringrinstanceReadByteStringwherereadsPrec :: Int -> ReadS ByteStringreadsPrecIntpStringstr=[(String -> ByteStringpackCharsStringx,Stringy)|(Stringx,Stringy)<-Int -> ReadS Stringforall a. Read a => Int -> ReadS areadsPrecIntpStringstr]-- | @since 0.10.12.0instanceIsListByteStringwheretypeItemByteString=Word8fromList :: [Item ByteString] -> ByteStringfromList=[Word8] -> ByteString[Item ByteString] -> ByteStringpackBytestoList :: ByteString -> [Item ByteString]toList=ByteString -> [Word8]ByteString -> [Item ByteString]unpackBytes-- | Beware: 'fromString' truncates multi-byte characters to octets.-- e.g. "枯朶に烏のとまりけり秋の暮" becomes �6k�nh~�Q��n�instanceIsStringByteStringwhere{-# INLINEfromString#-}fromString :: String -> ByteStringfromString=String -> ByteStringpackCharsinstanceDataByteStringwheregfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)-> (forall g. g -> c g) -> ByteString -> c ByteStringgfoldlforall d b. Data d => c (d -> b) -> d -> c bfforall g. g -> c gzByteStringtxt=([Word8] -> ByteString) -> c ([Word8] -> ByteString)forall g. g -> c gz[Word8] -> ByteStringpackBytesc ([Word8] -> ByteString) -> [Word8] -> c ByteStringforall d b. Data d => c (d -> b) -> d -> c b`f`ByteString -> [Word8]unpackBytesByteStringtxttoConstr :: ByteString -> ConstrtoConstrByteString_=String -> Constrforall a. HasCallStack => String -> aerrorString"Data.ByteString.ByteString.toConstr"gunfold :: (forall b r. Data b => c (b -> r) -> c r)-> (forall r. r -> c r) -> Constr -> c ByteStringgunfoldforall b r. Data b => c (b -> r) -> c r_forall r. r -> c r_=String -> Constr -> c ByteStringforall a. HasCallStack => String -> aerrorString"Data.ByteString.ByteString.gunfold"dataTypeOf :: ByteString -> DataTypedataTypeOfByteString_=String -> DataTypemkNoRepTypeString"Data.ByteString.ByteString"-- | @since 0.11.2.0instanceTH.LiftByteStringwhere#if MIN_VERSION_template_haskell(2,16,0)lift :: ByteString -> Q Explift(BSForeignPtr Word8ptrIntlen)=[|unsafePackLenLiteral|]Q Exp -> Q Exp -> Q Exp`TH.appE`Lit -> Q ExpTH.litE(Integer -> LitTH.integerL(Int -> Integerforall a b. (Integral a, Num b) => a -> bfromIntegralIntlen))Q Exp -> Q Exp -> Q Exp`TH.appE`Lit -> Q ExpTH.litE(Bytes -> LitTH.BytesPrimL(Bytes -> Lit) -> Bytes -> Litforall a b. (a -> b) -> a -> b$ForeignPtr Word8 -> Word -> Word -> BytesTH.BytesForeignPtr Word8ptrWord0(Int -> Wordforall a b. (Integral a, Num b) => a -> bfromIntegralIntlen))#elseliftbs@(BS_len)=[|unsafePackLenLiteral|]`TH.appE`TH.litE(TH.integerL(fromIntegrallen))`TH.appE`TH.litE(TH.StringPrimL$unpackBytesbs)#endif#if MIN_VERSION_template_haskell(2,17,0)liftTyped=TH.unsafeCodeCoerce.TH.lift#elif MIN_VERSION_template_haskell(2,16,0)liftTyped :: ByteString -> Q (TExp ByteString)liftTyped=Q Exp -> Q (TExp ByteString)forall a. Q Exp -> Q (TExp a)TH.unsafeTExpCoerce(Q Exp -> Q (TExp ByteString))-> (ByteString -> Q Exp) -> ByteString -> Q (TExp ByteString)forall b c a. (b -> c) -> (a -> b) -> a -> c.ByteString -> Q Expforall t. Lift t => t -> Q ExpTH.lift#endif-------------------------------------------------------------------------- Internal indexing-- | 'findIndexOrLength' is a variant of findIndex, that returns the length-- of the string if no element is found, rather than Nothing.findIndexOrLength::(Word8->Bool)->ByteString->IntfindIndexOrLength :: (Word8 -> Bool) -> ByteString -> IntfindIndexOrLengthWord8 -> Boolk(BSForeignPtr Word8xIntl)=IO Int -> Intforall a. IO a -> aaccursedUnutterablePerformIO(IO Int -> Int) -> IO Int -> Intforall a b. (a -> b) -> a -> b$ForeignPtr Word8 -> (Ptr Word8 -> IO Int) -> IO Intforall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8xPtr Word8 -> IO Intgwhereg :: Ptr Word8 -> IO IntgPtr Word8ptr=Int -> IO IntgoInt0wherego :: Int -> IO Intgo!Intn|IntnInt -> Int -> Boolforall a. Ord a => a -> a -> Bool>=Intl=Int -> IO Intforall (m :: * -> *) a. Monad m => a -> m areturnIntl|Boolotherwise=doWord8w<-Ptr Word8 -> IO Word8forall a. Storable a => Ptr a -> IO apeek(Ptr Word8 -> IO Word8) -> Ptr Word8 -> IO Word8forall a b. (a -> b) -> a -> b$Ptr Word8ptrPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`IntnifWord8 -> BoolkWord8wthenInt -> IO Intforall (m :: * -> *) a. Monad m => a -> m areturnIntnelseInt -> IO Intgo(IntnInt -> Int -> Intforall a. Num a => a -> a -> a+Int1){-# INLINEfindIndexOrLength#-}-------------------------------------------------------------------------- Packing and unpacking from listspackBytes::[Word8]->ByteStringpackBytes :: [Word8] -> ByteStringpackBytes[Word8]ws=Int -> [Word8] -> ByteStringunsafePackLenBytes([Word8] -> Intforall (t :: * -> *) a. Foldable t => t a -> IntList.length[Word8]ws)[Word8]wspackChars::[Char]->ByteStringpackChars :: String -> ByteStringpackCharsStringcs=Int -> String -> ByteStringunsafePackLenChars(String -> Intforall (t :: * -> *) a. Foldable t => t a -> IntList.lengthStringcs)Stringcs{-# INLINE[0]packChars#-}{-# RULES"ByteString packChars/packAddress"foralls.packChars(unpackCString#s)=unsafePackLiterals#-}unsafePackLenBytes::Int->[Word8]->ByteStringunsafePackLenBytes :: Int -> [Word8] -> ByteStringunsafePackLenBytesIntlen[Word8]xs0=Int -> (Ptr Word8 -> IO ()) -> ByteStringunsafeCreateIntlen((Ptr Word8 -> IO ()) -> ByteString)-> (Ptr Word8 -> IO ()) -> ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8p->Ptr Word8 -> [Word8] -> IO ()forall b. Storable b => Ptr b -> [b] -> IO ()goPtr Word8p[Word8]xs0wherego :: Ptr b -> [b] -> IO ()go!Ptr b_[]=() -> IO ()forall (m :: * -> *) a. Monad m => a -> m areturn()go!Ptr bp(bx:[b]xs)=Ptr b -> b -> IO ()forall a. Storable a => Ptr a -> a -> IO ()pokePtr bpbxIO () -> IO () -> IO ()forall (m :: * -> *) a b. Monad m => m a -> m b -> m b>>Ptr b -> [b] -> IO ()go(Ptr bpPtr b -> Int -> Ptr bforall a b. Ptr a -> Int -> Ptr b`plusPtr`Int1)[b]xsunsafePackLenChars::Int->[Char]->ByteStringunsafePackLenChars :: Int -> String -> ByteStringunsafePackLenCharsIntlenStringcs0=Int -> (Ptr Word8 -> IO ()) -> ByteStringunsafeCreateIntlen((Ptr Word8 -> IO ()) -> ByteString)-> (Ptr Word8 -> IO ()) -> ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8p->Ptr Word8 -> String -> IO ()goPtr Word8pStringcs0wherego :: Ptr Word8 -> String -> IO ()go!Ptr Word8_[]=() -> IO ()forall (m :: * -> *) a. Monad m => a -> m areturn()go!Ptr Word8p(Charc:Stringcs)=Ptr Word8 -> Word8 -> IO ()forall a. Storable a => Ptr a -> a -> IO ()pokePtr Word8p(Char -> Word8c2wCharc)IO () -> IO () -> IO ()forall (m :: * -> *) a b. Monad m => m a -> m b -> m b>>Ptr Word8 -> String -> IO ()go(Ptr Word8pPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`Int1)Stringcs-- | /O(n)/ Pack a null-terminated sequence of bytes, pointed to by an-- Addr\# (an arbitrary machine address assumed to point outside the-- garbage-collected heap) into a @ByteString@. A much faster way to-- create an 'Addr#' is with an unboxed string literal, than to pack a-- boxed string. A unboxed string literal is compiled to a static @char-- []@ by GHC. Establishing the length of the string requires a call to-- @strlen(3)@, so the 'Addr#' must point to a null-terminated buffer (as-- is the case with @\"string\"\#@ literals in GHC). Use 'Data.ByteString.Unsafe.unsafePackAddressLen'-- if you know the length of the string statically.---- An example:---- > literalFS = unsafePackAddress "literal"#---- This function is /unsafe/. If you modify the buffer pointed to by the-- original 'Addr#' this modification will be reflected in the resulting-- @ByteString@, breaking referential transparency.---- Note this also won't work if your 'Addr#' has embedded @\'\\0\'@ characters in-- the string, as @strlen@ will return too short a length.--unsafePackAddress::Addr#->IOByteStringunsafePackAddress :: Addr# -> IO ByteStringunsafePackAddressAddr#addr#=do#if __GLASGOW_HASKELL__ >= 811unsafePackLenAddress(I#(cstringLength#addr#))addr##elseCSizel<-CString -> IO CSizec_strlen(Addr# -> CStringforall a. Addr# -> Ptr aPtrAddr#addr#)Int -> Addr# -> IO ByteStringunsafePackLenAddress(CSize -> Intforall a b. (Integral a, Num b) => a -> bfromIntegralCSizel)Addr#addr##endif{-# INLINEunsafePackAddress#-}-- | See 'unsafePackAddress'. This function is similar,-- but takes an additional length argument rather then computing-- it with @strlen@.-- Therefore embedding @\'\\0\'@ characters is possible.---- @since 0.11.2.0unsafePackLenAddress::Int->Addr#->IOByteStringunsafePackLenAddress :: Int -> Addr# -> IO ByteStringunsafePackLenAddressIntlenAddr#addr#=do#if __GLASGOW_HASKELL__ >= 811return(BS(ForeignPtraddr#FinalPtr)len)#elseForeignPtr Word8p<-Ptr Word8 -> IO (ForeignPtr Word8)forall a. Ptr a -> IO (ForeignPtr a)newForeignPtr_(Addr# -> Ptr Word8forall a. Addr# -> Ptr aPtrAddr#addr#)ByteString -> IO ByteStringforall (m :: * -> *) a. Monad m => a -> m areturn(ByteString -> IO ByteString) -> ByteString -> IO ByteStringforall a b. (a -> b) -> a -> b$ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8pIntlen#endif{-# INLINEunsafePackLenAddress#-}-- | See 'unsafePackAddress'. This function has similar behavior. Prefer-- this function when the address in known to be an @Addr#@ literal. In-- that context, there is no need for the sequencing guarantees that 'IO'-- provides. On GHC 9.0 and up, this function uses the @FinalPtr@ data-- constructor for @ForeignPtrContents@.---- @since 0.11.1.0unsafePackLiteral::Addr#->ByteStringunsafePackLiteral :: Addr# -> ByteStringunsafePackLiteralAddr#addr#=#if __GLASGOW_HASKELL__ >= 811unsafePackLenLiteral(I#(cstringLength#addr#))addr##elseletlen :: CSizelen=IO CSize -> CSizeforall a. IO a -> aaccursedUnutterablePerformIO(CString -> IO CSizec_strlen(Addr# -> CStringforall a. Addr# -> Ptr aPtrAddr#addr#))inInt -> Addr# -> ByteStringunsafePackLenLiteral(CSize -> Intforall a b. (Integral a, Num b) => a -> bfromIntegralCSizelen)Addr#addr##endif{-# INLINEunsafePackLiteral#-}-- | See 'unsafePackLiteral'. This function is similar,-- but takes an additional length argument rather then computing-- it with @strlen@.-- Therefore embedding @\'\\0\'@ characters is possible.---- @since 0.11.2.0unsafePackLenLiteral::Int->Addr#->ByteStringunsafePackLenLiteral :: Int -> Addr# -> ByteStringunsafePackLenLiteralIntlenAddr#addr#=#if __GLASGOW_HASKELL__ >= 811BS(ForeignPtraddr#FinalPtr)len#elseForeignPtr Word8 -> Int -> ByteStringBS(IO (ForeignPtr Word8) -> ForeignPtr Word8forall a. IO a -> aaccursedUnutterablePerformIO(Ptr Word8 -> IO (ForeignPtr Word8)forall a. Ptr a -> IO (ForeignPtr a)newForeignPtr_(Addr# -> Ptr Word8forall a. Addr# -> Ptr aPtrAddr#addr#)))Intlen#endif{-# INLINEunsafePackLenLiteral#-}packUptoLenBytes::Int->[Word8]->(ByteString,[Word8])packUptoLenBytes :: Int -> [Word8] -> (ByteString, [Word8])packUptoLenBytesIntlen[Word8]xs0=Int -> (Ptr Word8 -> IO (Int, [Word8])) -> (ByteString, [Word8])forall a. Int -> (Ptr Word8 -> IO (Int, a)) -> (ByteString, a)unsafeCreateUptoN'Intlen((Ptr Word8 -> IO (Int, [Word8])) -> (ByteString, [Word8]))-> (Ptr Word8 -> IO (Int, [Word8])) -> (ByteString, [Word8])forall a b. (a -> b) -> a -> b$\Ptr Word8p0->letp_end :: Ptr Word8p_end=Ptr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr bplusPtrPtr Word8p0Intlengo :: Ptr Word8 -> [Word8] -> IO (Int, [Word8])go!Ptr Word8p[]=(Int, [Word8]) -> IO (Int, [Word8])forall (m :: * -> *) a. Monad m => a -> m areturn(Ptr Word8pPtr Word8 -> Ptr Word8 -> Intforall a b. Ptr a -> Ptr b -> Int`minusPtr`Ptr Word8p0,[])go!Ptr Word8p[Word8]xs|Ptr Word8pPtr Word8 -> Ptr Word8 -> Boolforall a. Eq a => a -> a -> Bool==Ptr Word8p_end=(Int, [Word8]) -> IO (Int, [Word8])forall (m :: * -> *) a. Monad m => a -> m areturn(Intlen,[Word8]xs)go!Ptr Word8p(Word8x:[Word8]xs)=Ptr Word8 -> Word8 -> IO ()forall a. Storable a => Ptr a -> a -> IO ()pokePtr Word8pWord8xIO () -> IO (Int, [Word8]) -> IO (Int, [Word8])forall (m :: * -> *) a b. Monad m => m a -> m b -> m b>>Ptr Word8 -> [Word8] -> IO (Int, [Word8])go(Ptr Word8pPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`Int1)[Word8]xsinPtr Word8 -> [Word8] -> IO (Int, [Word8])goPtr Word8p0[Word8]xs0packUptoLenChars::Int->[Char]->(ByteString,[Char])packUptoLenChars :: Int -> String -> (ByteString, String)packUptoLenCharsIntlenStringcs0=Int -> (Ptr Word8 -> IO (Int, String)) -> (ByteString, String)forall a. Int -> (Ptr Word8 -> IO (Int, a)) -> (ByteString, a)unsafeCreateUptoN'Intlen((Ptr Word8 -> IO (Int, String)) -> (ByteString, String))-> (Ptr Word8 -> IO (Int, String)) -> (ByteString, String)forall a b. (a -> b) -> a -> b$\Ptr Word8p0->letp_end :: Ptr Word8p_end=Ptr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr bplusPtrPtr Word8p0Intlengo :: Ptr Word8 -> String -> IO (Int, String)go!Ptr Word8p[]=(Int, String) -> IO (Int, String)forall (m :: * -> *) a. Monad m => a -> m areturn(Ptr Word8pPtr Word8 -> Ptr Word8 -> Intforall a b. Ptr a -> Ptr b -> Int`minusPtr`Ptr Word8p0,[])go!Ptr Word8pStringcs|Ptr Word8pPtr Word8 -> Ptr Word8 -> Boolforall a. Eq a => a -> a -> Bool==Ptr Word8p_end=(Int, String) -> IO (Int, String)forall (m :: * -> *) a. Monad m => a -> m areturn(Intlen,Stringcs)go!Ptr Word8p(Charc:Stringcs)=Ptr Word8 -> Word8 -> IO ()forall a. Storable a => Ptr a -> a -> IO ()pokePtr Word8p(Char -> Word8c2wCharc)IO () -> IO (Int, String) -> IO (Int, String)forall (m :: * -> *) a b. Monad m => m a -> m b -> m b>>Ptr Word8 -> String -> IO (Int, String)go(Ptr Word8pPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`Int1)StringcsinPtr Word8 -> String -> IO (Int, String)goPtr Word8p0Stringcs0-- Unpacking bytestrings into lists efficiently is a tradeoff: on the one hand-- we would like to write a tight loop that just blasts the list into memory, on-- the other hand we want it to be unpacked lazily so we don't end up with a-- massive list data structure in memory.---- Our strategy is to combine both: we will unpack lazily in reasonable sized-- chunks, where each chunk is unpacked strictly.---- unpackBytes and unpackChars do the lazy loop, while unpackAppendBytes and-- unpackAppendChars do the chunks strictly.unpackBytes::ByteString->[Word8]unpackBytes :: ByteString -> [Word8]unpackBytesByteStringbs=ByteString -> [Word8] -> [Word8]unpackAppendBytesLazyByteStringbs[]unpackChars::ByteString->[Char]unpackChars :: ByteString -> StringunpackCharsByteStringbs=ByteString -> ShowSunpackAppendCharsLazyByteStringbs[]unpackAppendBytesLazy::ByteString->[Word8]->[Word8]unpackAppendBytesLazy :: ByteString -> [Word8] -> [Word8]unpackAppendBytesLazy(BSForeignPtr Word8fpIntlen)[Word8]xs|IntlenInt -> Int -> Boolforall a. Ord a => a -> a -> Bool<=Int100=ByteString -> [Word8] -> [Word8]unpackAppendBytesStrict(ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpIntlen)[Word8]xs|Boolotherwise=ByteString -> [Word8] -> [Word8]unpackAppendBytesStrict(ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpInt100)[Word8]remainderwhereremainder :: [Word8]remainder=ByteString -> [Word8] -> [Word8]unpackAppendBytesLazy(ForeignPtr Word8 -> Int -> ByteStringBS(ForeignPtr Word8 -> Int -> ForeignPtr Word8forall a b. ForeignPtr a -> Int -> ForeignPtr bplusForeignPtrForeignPtr Word8fpInt100)(IntlenInt -> Int -> Intforall a. Num a => a -> a -> a-Int100))[Word8]xs-- Why 100 bytes you ask? Because on a 64bit machine the list we allocate-- takes just shy of 4k which seems like a reasonable amount.-- (5 words per list element, 8 bytes per word, 100 elements = 4000 bytes)unpackAppendCharsLazy::ByteString->[Char]->[Char]unpackAppendCharsLazy :: ByteString -> ShowSunpackAppendCharsLazy(BSForeignPtr Word8fpIntlen)Stringcs|IntlenInt -> Int -> Boolforall a. Ord a => a -> a -> Bool<=Int100=ByteString -> ShowSunpackAppendCharsStrict(ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpIntlen)Stringcs|Boolotherwise=ByteString -> ShowSunpackAppendCharsStrict(ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpInt100)Stringremainderwhereremainder :: Stringremainder=ByteString -> ShowSunpackAppendCharsLazy(ForeignPtr Word8 -> Int -> ByteStringBS(ForeignPtr Word8 -> Int -> ForeignPtr Word8forall a b. ForeignPtr a -> Int -> ForeignPtr bplusForeignPtrForeignPtr Word8fpInt100)(IntlenInt -> Int -> Intforall a. Num a => a -> a -> a-Int100))Stringcs-- For these unpack functions, since we're unpacking the whole list strictly we-- build up the result list in an accumulator. This means we have to build up-- the list starting at the end. So our traversal starts at the end of the-- buffer and loops down until we hit the sentinal:unpackAppendBytesStrict::ByteString->[Word8]->[Word8]unpackAppendBytesStrict :: ByteString -> [Word8] -> [Word8]unpackAppendBytesStrict(BSForeignPtr Word8fpIntlen)[Word8]xs=IO [Word8] -> [Word8]forall a. IO a -> aaccursedUnutterablePerformIO(IO [Word8] -> [Word8]) -> IO [Word8] -> [Word8]forall a b. (a -> b) -> a -> b$ForeignPtr Word8 -> (Ptr Word8 -> IO [Word8]) -> IO [Word8]forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO [Word8]) -> IO [Word8])-> (Ptr Word8 -> IO [Word8]) -> IO [Word8]forall a b. (a -> b) -> a -> b$\Ptr Word8base->Ptr Word8 -> Ptr Word8 -> [Word8] -> IO [Word8]forall b. Storable b => Ptr b -> Ptr b -> [b] -> IO [b]loop(Ptr Word8basePtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`(-Int1))(Ptr Word8basePtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`(-Int1Int -> Int -> Intforall a. Num a => a -> a -> a+Intlen))[Word8]xswhereloop :: Ptr b -> Ptr b -> [b] -> IO [b]loop!Ptr bsentinal!Ptr bp[b]acc|Ptr bpPtr b -> Ptr b -> Boolforall a. Eq a => a -> a -> Bool==Ptr bsentinal=[b] -> IO [b]forall (m :: * -> *) a. Monad m => a -> m areturn[b]acc|Boolotherwise=dobx<-Ptr b -> IO bforall a. Storable a => Ptr a -> IO apeekPtr bpPtr b -> Ptr b -> [b] -> IO [b]loopPtr bsentinal(Ptr bpPtr b -> Int -> Ptr bforall a b. Ptr a -> Int -> Ptr b`plusPtr`(-Int1))(bxb -> [b] -> [b]forall a. a -> [a] -> [a]:[b]acc)unpackAppendCharsStrict::ByteString->[Char]->[Char]unpackAppendCharsStrict :: ByteString -> ShowSunpackAppendCharsStrict(BSForeignPtr Word8fpIntlen)Stringxs=IO String -> Stringforall a. IO a -> aaccursedUnutterablePerformIO(IO String -> String) -> IO String -> Stringforall a b. (a -> b) -> a -> b$ForeignPtr Word8 -> (Ptr Word8 -> IO String) -> IO Stringforall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO String) -> IO String)-> (Ptr Word8 -> IO String) -> IO Stringforall a b. (a -> b) -> a -> b$\Ptr Word8base->Ptr Word8 -> Ptr Word8 -> String -> IO Stringloop(Ptr Word8basePtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`(-Int1))(Ptr Word8basePtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`(-Int1Int -> Int -> Intforall a. Num a => a -> a -> a+Intlen))Stringxswhereloop :: Ptr Word8 -> Ptr Word8 -> String -> IO Stringloop!Ptr Word8sentinal!Ptr Word8pStringacc|Ptr Word8pPtr Word8 -> Ptr Word8 -> Boolforall a. Eq a => a -> a -> Bool==Ptr Word8sentinal=String -> IO Stringforall (m :: * -> *) a. Monad m => a -> m areturnStringacc|Boolotherwise=doWord8x<-Ptr Word8 -> IO Word8forall a. Storable a => Ptr a -> IO apeekPtr Word8pPtr Word8 -> Ptr Word8 -> String -> IO StringloopPtr Word8sentinal(Ptr Word8pPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`(-Int1))(Word8 -> Charw2cWord8xChar -> ShowSforall a. a -> [a] -> [a]:Stringacc)-------------------------------------------------------------------------- | The 0 pointer. Used to indicate the empty Bytestring.nullForeignPtr::ForeignPtrWord8#if __GLASGOW_HASKELL__ >= 811nullForeignPtr=ForeignPtrnullAddr#FinalPtr#elsenullForeignPtr :: ForeignPtr Word8nullForeignPtr=Addr# -> ForeignPtrContents -> ForeignPtr Word8forall a. Addr# -> ForeignPtrContents -> ForeignPtr aForeignPtrAddr#nullAddr#(String -> ForeignPtrContentsforall a. HasCallStack => String -> aerrorString"nullForeignPtr")#endif-- ----------------------------------------------------------------------- Low level constructors-- | /O(1)/ Build a ByteString from a ForeignPtr.---- If you do not need the offset parameter then you should be using-- 'Data.ByteString.Unsafe.unsafePackCStringLen' or-- 'Data.ByteString.Unsafe.unsafePackCStringFinalizer' instead.--fromForeignPtr::ForeignPtrWord8->Int-- ^ Offset->Int-- ^ Length->ByteStringfromForeignPtr :: ForeignPtr Word8 -> Int -> Int -> ByteStringfromForeignPtrForeignPtr Word8fpInto=ForeignPtr Word8 -> Int -> ByteStringBS(ForeignPtr Word8 -> Int -> ForeignPtr Word8forall a b. ForeignPtr a -> Int -> ForeignPtr bplusForeignPtrForeignPtr Word8fpInto){-# INLINEfromForeignPtr#-}-- | @since 0.11.0.0fromForeignPtr0::ForeignPtrWord8->Int-- ^ Length->ByteStringfromForeignPtr0 :: ForeignPtr Word8 -> Int -> ByteStringfromForeignPtr0=ForeignPtr Word8 -> Int -> ByteStringBS{-# INLINEfromForeignPtr0#-}-- | /O(1)/ Deconstruct a ForeignPtr from a ByteStringtoForeignPtr::ByteString->(ForeignPtrWord8,Int,Int)-- ^ (ptr, offset, length)toForeignPtr :: ByteString -> (ForeignPtr Word8, Int, Int)toForeignPtr(BSForeignPtr Word8psIntl)=(ForeignPtr Word8ps,Int0,Intl){-# INLINEtoForeignPtr#-}-- | /O(1)/ Deconstruct a ForeignPtr from a ByteString---- @since 0.11.0.0toForeignPtr0::ByteString->(ForeignPtrWord8,Int)-- ^ (ptr, length)toForeignPtr0 :: ByteString -> (ForeignPtr Word8, Int)toForeignPtr0(BSForeignPtr Word8psIntl)=(ForeignPtr Word8ps,Intl){-# INLINEtoForeignPtr0#-}-- | A way of creating ByteStrings outside the IO monad. The @Int@-- argument gives the final size of the ByteString.unsafeCreate::Int->(PtrWord8->IO())->ByteStringunsafeCreate :: Int -> (Ptr Word8 -> IO ()) -> ByteStringunsafeCreateIntlPtr Word8 -> IO ()f=IO ByteString -> ByteStringforall a. IO a -> aunsafeDupablePerformIO(Int -> (Ptr Word8 -> IO ()) -> IO ByteStringcreateIntlPtr Word8 -> IO ()f){-# INLINEunsafeCreate#-}-- | Like 'unsafeCreate' but instead of giving the final size of the-- ByteString, it is just an upper bound. The inner action returns-- the actual size. Unlike 'createAndTrim' the ByteString is not-- reallocated if the final size is less than the estimated size.unsafeCreateUptoN::Int->(PtrWord8->IOInt)->ByteStringunsafeCreateUptoN :: Int -> (Ptr Word8 -> IO Int) -> ByteStringunsafeCreateUptoNIntlPtr Word8 -> IO Intf=IO ByteString -> ByteStringforall a. IO a -> aunsafeDupablePerformIO(Int -> (Ptr Word8 -> IO Int) -> IO ByteStringcreateUptoNIntlPtr Word8 -> IO Intf){-# INLINEunsafeCreateUptoN#-}-- | @since 0.10.12.0unsafeCreateUptoN'::Int->(PtrWord8->IO(Int,a))->(ByteString,a)unsafeCreateUptoN' :: Int -> (Ptr Word8 -> IO (Int, a)) -> (ByteString, a)unsafeCreateUptoN'IntlPtr Word8 -> IO (Int, a)f=IO (ByteString, a) -> (ByteString, a)forall a. IO a -> aunsafeDupablePerformIO(Int -> (Ptr Word8 -> IO (Int, a)) -> IO (ByteString, a)forall a. Int -> (Ptr Word8 -> IO (Int, a)) -> IO (ByteString, a)createUptoN'IntlPtr Word8 -> IO (Int, a)f){-# INLINEunsafeCreateUptoN'#-}-- | Create ByteString of size @l@ and use action @f@ to fill its contents.create::Int->(PtrWord8->IO())->IOByteStringcreate :: Int -> (Ptr Word8 -> IO ()) -> IO ByteStringcreateIntlPtr Word8 -> IO ()action=doForeignPtr Word8fp<-Int -> IO (ForeignPtr Word8)forall a. Int -> IO (ForeignPtr a)mallocByteStringIntl-- Cannot use unsafeWithForeignPtr, because action can divergeForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bwithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()forall a b. (a -> b) -> a -> b$\Ptr Word8p->Ptr Word8 -> IO ()actionPtr Word8pByteString -> IO ByteStringforall (m :: * -> *) a. Monad m => a -> m areturn(ByteString -> IO ByteString) -> ByteString -> IO ByteStringforall a b. (a -> b) -> a -> b$!ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpIntl{-# INLINEcreate#-}-- | Given a maximum size @l@ and an action @f@ that fills the 'ByteString'-- starting at the given 'Ptr' and returns the actual utilized length,-- @`createUptoN'` l f@ returns the filled 'ByteString'.createUptoN::Int->(PtrWord8->IOInt)->IOByteStringcreateUptoN :: Int -> (Ptr Word8 -> IO Int) -> IO ByteStringcreateUptoNIntlPtr Word8 -> IO Intaction=doForeignPtr Word8fp<-Int -> IO (ForeignPtr Word8)forall a. Int -> IO (ForeignPtr a)mallocByteStringIntl-- Cannot use unsafeWithForeignPtr, because action can divergeIntl'<-ForeignPtr Word8 -> (Ptr Word8 -> IO Int) -> IO Intforall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bwithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO Int) -> IO Int)-> (Ptr Word8 -> IO Int) -> IO Intforall a b. (a -> b) -> a -> b$\Ptr Word8p->Ptr Word8 -> IO IntactionPtr Word8pBool -> IO ByteString -> IO ByteStringforall a. HasCallStack => Bool -> a -> aassert(Intl'Int -> Int -> Boolforall a. Ord a => a -> a -> Bool<=Intl)(IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteStringforall a b. (a -> b) -> a -> b$ByteString -> IO ByteStringforall (m :: * -> *) a. Monad m => a -> m areturn(ByteString -> IO ByteString) -> ByteString -> IO ByteStringforall a b. (a -> b) -> a -> b$!ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpIntl'{-# INLINEcreateUptoN#-}-- | Like 'createUptoN', but also returns an additional value created by the-- action.---- @since 0.10.12.0createUptoN'::Int->(PtrWord8->IO(Int,a))->IO(ByteString,a)createUptoN' :: Int -> (Ptr Word8 -> IO (Int, a)) -> IO (ByteString, a)createUptoN'IntlPtr Word8 -> IO (Int, a)action=doForeignPtr Word8fp<-Int -> IO (ForeignPtr Word8)forall a. Int -> IO (ForeignPtr a)mallocByteStringIntl-- Cannot use unsafeWithForeignPtr, because action can diverge(Intl',ares)<-ForeignPtr Word8 -> (Ptr Word8 -> IO (Int, a)) -> IO (Int, a)forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bwithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO (Int, a)) -> IO (Int, a))-> (Ptr Word8 -> IO (Int, a)) -> IO (Int, a)forall a b. (a -> b) -> a -> b$\Ptr Word8p->Ptr Word8 -> IO (Int, a)actionPtr Word8pBool -> IO (ByteString, a) -> IO (ByteString, a)forall a. HasCallStack => Bool -> a -> aassert(Intl'Int -> Int -> Boolforall a. Ord a => a -> a -> Bool<=Intl)(IO (ByteString, a) -> IO (ByteString, a))-> IO (ByteString, a) -> IO (ByteString, a)forall a b. (a -> b) -> a -> b$(ByteString, a) -> IO (ByteString, a)forall (m :: * -> *) a. Monad m => a -> m areturn(ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpIntl',ares){-# INLINEcreateUptoN'#-}-- | Given the maximum size needed and a function to make the contents-- of a ByteString, createAndTrim makes the 'ByteString'. The generating-- function is required to return the actual final size (<= the maximum-- size), and the resulting byte array is reallocated to this size.---- createAndTrim is the main mechanism for creating custom, efficient-- ByteString functions, using Haskell or C functions to fill the space.--createAndTrim::Int->(PtrWord8->IOInt)->IOByteStringcreateAndTrim :: Int -> (Ptr Word8 -> IO Int) -> IO ByteStringcreateAndTrimIntlPtr Word8 -> IO Intaction=doForeignPtr Word8fp<-Int -> IO (ForeignPtr Word8)forall a. Int -> IO (ForeignPtr a)mallocByteStringIntl-- Cannot use unsafeWithForeignPtr, because action can divergeForeignPtr Word8 -> (Ptr Word8 -> IO ByteString) -> IO ByteStringforall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bwithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO ByteString) -> IO ByteString)-> (Ptr Word8 -> IO ByteString) -> IO ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8p->doIntl'<-Ptr Word8 -> IO IntactionPtr Word8pifBool -> Bool -> Boolforall a. HasCallStack => Bool -> a -> aassert(Intl'Int -> Int -> Boolforall a. Ord a => a -> a -> Bool<=Intl)(Bool -> Bool) -> Bool -> Boolforall a b. (a -> b) -> a -> b$Intl'Int -> Int -> Boolforall a. Ord a => a -> a -> Bool>=IntlthenByteString -> IO ByteStringforall (m :: * -> *) a. Monad m => a -> m areturn(ByteString -> IO ByteString) -> ByteString -> IO ByteStringforall a b. (a -> b) -> a -> b$!ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpIntlelseInt -> (Ptr Word8 -> IO ()) -> IO ByteStringcreateIntl'((Ptr Word8 -> IO ()) -> IO ByteString)-> (Ptr Word8 -> IO ()) -> IO ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8p'->Ptr Word8 -> Ptr Word8 -> Int -> IO ()memcpyPtr Word8p'Ptr Word8pIntl'{-# INLINEcreateAndTrim#-}createAndTrim'::Int->(PtrWord8->IO(Int,Int,a))->IO(ByteString,a)createAndTrim' :: Int -> (Ptr Word8 -> IO (Int, Int, a)) -> IO (ByteString, a)createAndTrim'IntlPtr Word8 -> IO (Int, Int, a)action=doForeignPtr Word8fp<-Int -> IO (ForeignPtr Word8)forall a. Int -> IO (ForeignPtr a)mallocByteStringIntl-- Cannot use unsafeWithForeignPtr, because action can divergeForeignPtr Word8-> (Ptr Word8 -> IO (ByteString, a)) -> IO (ByteString, a)forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bwithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO (ByteString, a)) -> IO (ByteString, a))-> (Ptr Word8 -> IO (ByteString, a)) -> IO (ByteString, a)forall a b. (a -> b) -> a -> b$\Ptr Word8p->do(Intoff,Intl',ares)<-Ptr Word8 -> IO (Int, Int, a)actionPtr Word8pifBool -> Bool -> Boolforall a. HasCallStack => Bool -> a -> aassert(Intl'Int -> Int -> Boolforall a. Ord a => a -> a -> Bool<=Intl)(Bool -> Bool) -> Bool -> Boolforall a b. (a -> b) -> a -> b$Intl'Int -> Int -> Boolforall a. Ord a => a -> a -> Bool>=Intlthen(ByteString, a) -> IO (ByteString, a)forall (m :: * -> *) a. Monad m => a -> m areturn(ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpIntl,ares)elsedoByteStringps<-Int -> (Ptr Word8 -> IO ()) -> IO ByteStringcreateIntl'((Ptr Word8 -> IO ()) -> IO ByteString)-> (Ptr Word8 -> IO ()) -> IO ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8p'->Ptr Word8 -> Ptr Word8 -> Int -> IO ()memcpyPtr Word8p'(Ptr Word8pPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`Intoff)Intl'(ByteString, a) -> IO (ByteString, a)forall (m :: * -> *) a. Monad m => a -> m areturn(ByteStringps,ares){-# INLINEcreateAndTrim'#-}-- | Wrapper of 'Foreign.ForeignPtr.mallocForeignPtrBytes' with faster implementation for GHC--mallocByteString::Int->IO(ForeignPtra)mallocByteString :: Int -> IO (ForeignPtr a)mallocByteString=Int -> IO (ForeignPtr a)forall a. Int -> IO (ForeignPtr a)mallocPlainForeignPtrBytes{-# INLINEmallocByteString#-}-------------------------------------------------------------------------- Implementations for Eq, Ord and Monoid instanceseq::ByteString->ByteString->Booleq :: ByteString -> ByteString -> Booleqa :: ByteStringa@(BSForeignPtr Word8fpIntlen)b :: ByteStringb@(BSForeignPtr Word8fp'Intlen')|IntlenInt -> Int -> Boolforall a. Eq a => a -> a -> Bool/=Intlen'=BoolFalse-- short cut on length|ForeignPtr Word8fpForeignPtr Word8 -> ForeignPtr Word8 -> Boolforall a. Eq a => a -> a -> Bool==ForeignPtr Word8fp'=BoolTrue-- short cut for the same string|Boolotherwise=ByteString -> ByteString -> OrderingcompareBytesByteStringaByteStringbOrdering -> Ordering -> Boolforall a. Eq a => a -> a -> Bool==OrderingEQ{-# INLINEeq#-}-- ^ still neededcompareBytes::ByteString->ByteString->OrderingcompareBytes :: ByteString -> ByteString -> OrderingcompareBytes(BSForeignPtr Word8_Int0)(BSForeignPtr Word8_Int0)=OrderingEQ-- short cut for empty stringscompareBytes(BSForeignPtr Word8fp1Intlen1)(BSForeignPtr Word8fp2Intlen2)=IO Ordering -> Orderingforall a. IO a -> aaccursedUnutterablePerformIO(IO Ordering -> Ordering) -> IO Ordering -> Orderingforall a b. (a -> b) -> a -> b$ForeignPtr Word8 -> (Ptr Word8 -> IO Ordering) -> IO Orderingforall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp1((Ptr Word8 -> IO Ordering) -> IO Ordering)-> (Ptr Word8 -> IO Ordering) -> IO Orderingforall a b. (a -> b) -> a -> b$\Ptr Word8p1->ForeignPtr Word8 -> (Ptr Word8 -> IO Ordering) -> IO Orderingforall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp2((Ptr Word8 -> IO Ordering) -> IO Ordering)-> (Ptr Word8 -> IO Ordering) -> IO Orderingforall a b. (a -> b) -> a -> b$\Ptr Word8p2->doCInti<-Ptr Word8 -> Ptr Word8 -> Int -> IO CIntmemcmpPtr Word8p1Ptr Word8p2(Int -> Int -> Intforall a. Ord a => a -> a -> aminIntlen1Intlen2)Ordering -> IO Orderingforall (m :: * -> *) a. Monad m => a -> m areturn(Ordering -> IO Ordering) -> Ordering -> IO Orderingforall a b. (a -> b) -> a -> b$!caseCIntiCInt -> CInt -> Orderingforall a. Ord a => a -> a -> Ordering`compare`CInt0ofOrderingEQ->Intlen1Int -> Int -> Orderingforall a. Ord a => a -> a -> Ordering`compare`Intlen2Orderingx->Orderingx-- | /O(1)/ The empty 'ByteString'empty::ByteString-- This enables bypassing #457 by not using (polymorphic) mempty in-- any definitions used by the (Monoid ByteString) instanceempty :: ByteStringempty=ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8nullForeignPtrInt0append::ByteString->ByteString->ByteStringappend :: ByteString -> ByteString -> ByteStringappend(BSForeignPtr Word8_Int0)ByteStringb=ByteStringbappendByteStringa(BSForeignPtr Word8_Int0)=ByteStringaappend(BSForeignPtr Word8fp1Intlen1)(BSForeignPtr Word8fp2Intlen2)=Int -> (Ptr Word8 -> IO ()) -> ByteStringunsafeCreate(Intlen1Int -> Int -> Intforall a. Num a => a -> a -> a+Intlen2)((Ptr Word8 -> IO ()) -> ByteString)-> (Ptr Word8 -> IO ()) -> ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8destptr1->doletdestptr2 :: Ptr Word8destptr2=Ptr Word8destptr1Ptr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`Intlen1ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp1((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()forall a b. (a -> b) -> a -> b$\Ptr Word8p1->Ptr Word8 -> Ptr Word8 -> Int -> IO ()memcpyPtr Word8destptr1Ptr Word8p1Intlen1ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp2((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()forall a b. (a -> b) -> a -> b$\Ptr Word8p2->Ptr Word8 -> Ptr Word8 -> Int -> IO ()memcpyPtr Word8destptr2Ptr Word8p2Intlen2concat::[ByteString]->ByteStringconcat :: [ByteString] -> ByteStringconcat=\[ByteString]bss0->[ByteString] -> [ByteString] -> ByteStringgoLen0[ByteString]bss0[ByteString]bss0-- The idea here is we first do a pass over the input list to determine:---- 1. is a copy necessary? e.g. @concat []@, @concat [mempty, "hello"]@,-- and @concat ["hello", mempty, mempty]@ can all be handled without-- copying.-- 2. if a copy is necessary, how large is the result going to be?---- If a copy is necessary then we create a buffer of the appropriate size-- and do another pass over the input list, copying the chunks into the-- buffer. Also, since foreign calls aren't entirely free we skip over-- empty chunks while copying.---- We pass the original [ByteString] (bss0) through as an argument through-- goLen0, goLen1, and goLen since we will need it again in goCopy. Passing-- it as an explicit argument avoids capturing it in these functions'-- closures which would result in unnecessary closure allocation.where-- It's still possible that the result is emptygoLen0 :: [ByteString] -> [ByteString] -> ByteStringgoLen0[ByteString]_[]=ByteStringemptygoLen0[ByteString]bss0(BSForeignPtr Word8_Int0:[ByteString]bss)=[ByteString] -> [ByteString] -> ByteStringgoLen0[ByteString]bss0[ByteString]bssgoLen0[ByteString]bss0(ByteStringbs:[ByteString]bss)=[ByteString] -> ByteString -> [ByteString] -> ByteStringgoLen1[ByteString]bss0ByteStringbs[ByteString]bss-- It's still possible that the result is a single chunkgoLen1 :: [ByteString] -> ByteString -> [ByteString] -> ByteStringgoLen1[ByteString]_ByteStringbs[]=ByteStringbsgoLen1[ByteString]bss0ByteStringbs(BSForeignPtr Word8_Int0:[ByteString]bss)=[ByteString] -> ByteString -> [ByteString] -> ByteStringgoLen1[ByteString]bss0ByteStringbs[ByteString]bssgoLen1[ByteString]bss0ByteStringbs(BSForeignPtr Word8_Intlen:[ByteString]bss)=[ByteString] -> Int -> [ByteString] -> ByteStringgoLen[ByteString]bss0(String -> Int -> Int -> IntcheckedAddString"concat"Intlen'Intlen)[ByteString]bsswhereBSForeignPtr Word8_Intlen'=ByteStringbs-- General case, just find the total length we'll needgoLen :: [ByteString] -> Int -> [ByteString] -> ByteStringgoLen[ByteString]bss0!Inttotal(BSForeignPtr Word8_Intlen:[ByteString]bss)=[ByteString] -> Int -> [ByteString] -> ByteStringgoLen[ByteString]bss0Inttotal'[ByteString]bsswheretotal' :: Inttotal'=String -> Int -> Int -> IntcheckedAddString"concat"InttotalIntlengoLen[ByteString]bss0Inttotal[]=Int -> (Ptr Word8 -> IO ()) -> ByteStringunsafeCreateInttotal((Ptr Word8 -> IO ()) -> ByteString)-> (Ptr Word8 -> IO ()) -> ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8ptr->[ByteString] -> Ptr Word8 -> IO ()goCopy[ByteString]bss0Ptr Word8ptr-- Copy the datagoCopy :: [ByteString] -> Ptr Word8 -> IO ()goCopy[]!Ptr Word8_=() -> IO ()forall (m :: * -> *) a. Monad m => a -> m areturn()goCopy(BSForeignPtr Word8_Int0:[ByteString]bss)!Ptr Word8ptr=[ByteString] -> Ptr Word8 -> IO ()goCopy[ByteString]bssPtr Word8ptrgoCopy(BSForeignPtr Word8fpIntlen:[ByteString]bss)!Ptr Word8ptr=doForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()forall a b. (a -> b) -> a -> b$\Ptr Word8p->Ptr Word8 -> Ptr Word8 -> Int -> IO ()memcpyPtr Word8ptrPtr Word8pIntlen[ByteString] -> Ptr Word8 -> IO ()goCopy[ByteString]bss(Ptr Word8ptrPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`Intlen){-# NOINLINEconcat#-}{-# RULES"ByteString concat [] -> empty"concat[]=empty"ByteString concat [bs] -> bs"forallx.concat[x]=x#-}-- | /O(log n)/ Repeats the given ByteString n times.times::Integrala=>a->ByteString->ByteStringtimes :: a -> ByteString -> ByteStringtimesan(BSForeignPtr Word8fpIntlen)|ana -> a -> Boolforall a. Ord a => a -> a -> Bool<a0=String -> ByteStringforall a. HasCallStack => String -> aerrorString"stimes: non-negative multiplier expected"|ana -> a -> Boolforall a. Eq a => a -> a -> Bool==a0=ByteStringempty|ana -> a -> Boolforall a. Eq a => a -> a -> Bool==a1=ForeignPtr Word8 -> Int -> ByteStringBSForeignPtr Word8fpIntlen|IntlenInt -> Int -> Boolforall a. Eq a => a -> a -> Bool==Int0=ByteStringempty|IntlenInt -> Int -> Boolforall a. Eq a => a -> a -> Bool==Int1=Int -> (Ptr Word8 -> IO ()) -> ByteStringunsafeCreateIntsize((Ptr Word8 -> IO ()) -> ByteString)-> (Ptr Word8 -> IO ()) -> ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8destptr->ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()forall a b. (a -> b) -> a -> b$\Ptr Word8p->doWord8byte<-Ptr Word8 -> IO Word8forall a. Storable a => Ptr a -> IO apeekPtr Word8pIO (Ptr Word8) -> IO ()forall (f :: * -> *) a. Functor f => f a -> f ()void(IO (Ptr Word8) -> IO ()) -> IO (Ptr Word8) -> IO ()forall a b. (a -> b) -> a -> b$Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)memsetPtr Word8destptrWord8byte(Int -> CSizeforall a b. (Integral a, Num b) => a -> bfromIntegralIntsize)|Boolotherwise=Int -> (Ptr Word8 -> IO ()) -> ByteStringunsafeCreateIntsize((Ptr Word8 -> IO ()) -> ByteString)-> (Ptr Word8 -> IO ()) -> ByteStringforall a b. (a -> b) -> a -> b$\Ptr Word8destptr->ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO bunsafeWithForeignPtrForeignPtr Word8fp((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()forall a b. (a -> b) -> a -> b$\Ptr Word8p->doPtr Word8 -> Ptr Word8 -> Int -> IO ()memcpyPtr Word8destptrPtr Word8pIntlenPtr Word8 -> Int -> IO ()fillFromPtr Word8destptrIntlenwheresize :: Intsize=IntlenInt -> Int -> Intforall a. Num a => a -> a -> a*a -> Intforall a b. (Integral a, Num b) => a -> bfromIntegralanfillFrom::PtrWord8->Int->IO()fillFrom :: Ptr Word8 -> Int -> IO ()fillFromPtr Word8destptrIntcopied|Int2Int -> Int -> Intforall a. Num a => a -> a -> a*IntcopiedInt -> Int -> Boolforall a. Ord a => a -> a -> Bool<Intsize=doPtr Word8 -> Ptr Word8 -> Int -> IO ()memcpy(Ptr Word8destptrPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`Intcopied)Ptr Word8destptrIntcopiedPtr Word8 -> Int -> IO ()fillFromPtr Word8destptr(IntcopiedInt -> Int -> Intforall a. Num a => a -> a -> a*Int2)|Boolotherwise=Ptr Word8 -> Ptr Word8 -> Int -> IO ()memcpy(Ptr Word8destptrPtr Word8 -> Int -> Ptr Word8forall a b. Ptr a -> Int -> Ptr b`plusPtr`Intcopied)Ptr Word8destptr(IntsizeInt -> Int -> Intforall a. Num a => a -> a -> a-Intcopied)-- | Add two non-negative numbers. Errors out on overflow.checkedAdd::String->Int->Int->IntcheckedAdd :: String -> Int -> Int -> IntcheckedAddStringfunIntxInty|IntrInt -> Int -> Boolforall a. Ord a => a -> a -> Bool>=Int0=Intr|Boolotherwise=String -> Intforall a. String -> aoverflowErrorStringfunwherer :: Intr=IntxInt -> Int -> Intforall a. Num a => a -> a -> a+Inty{-# INLINEcheckedAdd#-}-------------------------------------------------------------------------- | Conversion between 'Word8' and 'Char'. Should compile to a no-op.w2c::Word8->Charw2c :: Word8 -> Charw2c=Int -> CharunsafeChr(Int -> Char) -> (Word8 -> Int) -> Word8 -> Charforall b c a. (b -> c) -> (a -> b) -> a -> c.Word8 -> Intforall a b. (Integral a, Num b) => a -> bfromIntegral{-# INLINEw2c#-}-- | Unsafe conversion between 'Char' and 'Word8'. This is a no-op and-- silently truncates to 8 bits Chars > '\255'. It is provided as-- convenience for ByteString construction.c2w::Char->Word8c2w :: Char -> Word8c2w=Int -> Word8forall a b. (Integral a, Num b) => a -> bfromIntegral(Int -> Word8) -> (Char -> Int) -> Char -> Word8forall b c a. (b -> c) -> (a -> b) -> a -> c.Char -> Intord{-# INLINEc2w#-}-- | Selects words corresponding to white-space characters in the Latin-1 rangeisSpaceWord8::Word8->BoolisSpaceWord8 :: Word8 -> BoolisSpaceWord8Word8w8=-- Avoid the cost of narrowing arithmetic results to Word8,-- the conversion from Word8 to Word is free.letw::Word!w :: Wordw=Word8 -> Wordforall a b. (Integral a, Num b) => a -> bfromIntegralWord8w8inWordwWord -> Word -> Wordforall a. Bits a => a -> a -> a.&.Word0x50Word -> Word -> Boolforall a. Eq a => a -> a -> Bool==Word0-- Quick non-whitespace filterBool -> Bool -> Bool&&WordwWord -> Word -> Wordforall a. Num a => a -> a -> a-Word0x21Word -> Word -> Boolforall a. Ord a => a -> a -> Bool>Word0x7e-- Second non-whitespace filterBool -> Bool -> Bool&&(WordwWord -> Word -> Boolforall a. Eq a => a -> a -> Bool==Word0x20-- SPBool -> Bool -> Bool||WordwWord -> Word -> Boolforall a. Eq a => a -> a -> Bool==Word0xa0-- NBSPBool -> Bool -> Bool||WordwWord -> Word -> Wordforall a. Num a => a -> a -> a-Word0x09Word -> Word -> Boolforall a. Ord a => a -> a -> Bool<Word5)-- HT, NL, VT, FF, CR{-# INLINEisSpaceWord8#-}-- | Selects white-space characters in the Latin-1 rangeisSpaceChar8::Char->BoolisSpaceChar8 :: Char -> BoolisSpaceChar8=Word8 -> BoolisSpaceWord8(Word8 -> Bool) -> (Char -> Word8) -> Char -> Boolforall b c a. (b -> c) -> (a -> b) -> a -> c.Char -> Word8c2w{-# INLINEisSpaceChar8#-}overflowError::String->aoverflowError :: String -> aoverflowErrorStringfun=String -> aforall a. HasCallStack => String -> aerror(String -> a) -> String -> aforall a b. (a -> b) -> a -> b$String"Data.ByteString."String -> ShowSforall a. [a] -> [a] -> [a]++StringfunString -> ShowSforall a. [a] -> [a] -> [a]++String": size overflow"-------------------------------------------------------------------------- | This \"function\" has a superficial similarity to 'System.IO.Unsafe.unsafePerformIO' but-- it is in fact a malevolent agent of chaos. It unpicks the seams of reality-- (and the 'IO' monad) so that the normal rules no longer apply. It lulls you-- into thinking it is reasonable, but when you are not looking it stabs you-- in the back and aliases all of your mutable buffers. The carcass of many a-- seasoned Haskell programmer lie strewn at its feet.---- Witness the trail of destruction:---- * <https://github.com/haskell/bytestring/commit/71c4b438c675aa360c79d79acc9a491e7bbc26e7>---- * <https://github.com/haskell/bytestring/commit/210c656390ae617d9ee3b8bcff5c88dd17cef8da>---- * <https://ghc.haskell.org/trac/ghc/ticket/3486>---- * <https://ghc.haskell.org/trac/ghc/ticket/3487>---- * <https://ghc.haskell.org/trac/ghc/ticket/7270>---- Do not talk about \"safe\"! You do not know what is safe!---- Yield not to its blasphemous call! Flee traveller! Flee or you will be-- corrupted and devoured!--{-# INLINEaccursedUnutterablePerformIO#-}accursedUnutterablePerformIO::IOa->aaccursedUnutterablePerformIO :: IO a -> aaccursedUnutterablePerformIO(IOState# RealWorld -> (# State# RealWorld, a #)m)=caseState# RealWorld -> (# State# RealWorld, a #)mState# RealWorldrealWorld#of(#State# RealWorld_,ar#)->ar-- ------------------------------------------------------------------------- Standard C functions--foreignimportccallunsafe"string.h strlen"c_strlen::CString->IOCSizeforeignimportccallunsafe"static stdlib.h &free"c_free_finalizer::FunPtr(PtrWord8->IO())foreignimportccallunsafe"string.h memchr"c_memchr::PtrWord8->CInt->CSize->IO(PtrWord8)memchr::PtrWord8->Word8->CSize->IO(PtrWord8)memchr :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)memchrPtr Word8pWord8w=Ptr Word8 -> CInt -> CSize -> IO (Ptr Word8)c_memchrPtr Word8p(Word8 -> CIntforall a b. (Integral a, Num b) => a -> bfromIntegralWord8w)foreignimportccallunsafe"string.h memcmp"c_memcmp::PtrWord8->PtrWord8->CSize->IOCIntmemcmp::PtrWord8->PtrWord8->Int->IOCIntmemcmp :: Ptr Word8 -> Ptr Word8 -> Int -> IO CIntmemcmpPtr Word8pPtr Word8qInts=Ptr Word8 -> Ptr Word8 -> CSize -> IO CIntc_memcmpPtr Word8pPtr Word8q(Int -> CSizeforall a b. (Integral a, Num b) => a -> bfromIntegralInts)foreignimportccallunsafe"string.h memcpy"c_memcpy::PtrWord8->PtrWord8->CSize->IO(PtrWord8)memcpy::PtrWord8->PtrWord8->Int->IO()memcpy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()memcpyPtr Word8pPtr Word8qInts=IO (Ptr Word8) -> IO ()forall (f :: * -> *) a. Functor f => f a -> f ()void(IO (Ptr Word8) -> IO ()) -> IO (Ptr Word8) -> IO ()forall a b. (a -> b) -> a -> b$Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)c_memcpyPtr Word8pPtr Word8q(Int -> CSizeforall a b. (Integral a, Num b) => a -> bfromIntegralInts){-foreign import ccall unsafe "string.h memmove" c_memmove :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)memmove :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()memmove p q s = do c_memmove p q s return ()-}foreignimportccallunsafe"string.h memset"c_memset::PtrWord8->CInt->CSize->IO(PtrWord8)memset::PtrWord8->Word8->CSize->IO(PtrWord8)memset :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)memsetPtr Word8pWord8w=Ptr Word8 -> CInt -> CSize -> IO (Ptr Word8)c_memsetPtr Word8p(Word8 -> CIntforall a b. (Integral a, Num b) => a -> bfromIntegralWord8w)-- ------------------------------------------------------------------------- Uses our C code--foreignimportccallunsafe"static fpstring.h fps_reverse"c_reverse::PtrWord8->PtrWord8->CSize->IO()foreignimportccallunsafe"static fpstring.h fps_intersperse"c_intersperse::PtrWord8->PtrWord8->CSize->Word8->IO()foreignimportccallunsafe"static fpstring.h fps_maximum"c_maximum::PtrWord8->CSize->IOWord8foreignimportccallunsafe"static fpstring.h fps_minimum"c_minimum::PtrWord8->CSize->IOWord8foreignimportccallunsafe"static fpstring.h fps_count"c_count::PtrWord8->CSize->Word8->IOCSizeforeignimportccallunsafe"static fpstring.h fps_sort"c_sort::PtrWord8->CSize->IO()
[8]ページ先頭