{-# LANGUAGE CPP #-}{-# LANGUAGE Unsafe #-}{-# OPTIONS_HADDOCK not-home #-}{-# LANGUAGE TypeFamilies #-}-- |-- Module : Data.ByteString.Lazy.Internal-- Copyright : (c) Don Stewart 2006-2008-- (c) Duncan Coutts 2006-2011-- 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.-- Modules which extend the 'ByteString' system will need to use this module-- while ideally most users will be able to make do with the public interface-- modules.--moduleData.ByteString.Lazy.Internal(-- * The lazy @ByteString@ type and representationByteString (Empty ,Chunk ),LazyByteString ,chunk ,foldrChunks ,foldlChunks ,-- * Data type invariant and abstraction functioninvariant ,checkInvariant ,-- * Chunk allocation sizesdefaultChunkSize ,smallChunkSize ,chunkOverhead ,-- * Conversion with lists: packing and unpackingpackBytes ,packChars ,unpackBytes ,unpackChars ,-- * Conversions with strict ByteStringfromStrict ,toStrict ,)whereimportPreludehiding(concat)importqualifiedData.ByteString.Internal.Type asSimportData.Word(Word8)importForeign.Storable(Storable(sizeOf))importData.Semigroup(Semigroup(..))importData.List.NonEmpty(NonEmpty((:|)))importControl.DeepSeq(NFData,rnf)importData.String(IsString(..))importData.Data(Data(..),mkConstr,mkNoRepType,Constr,DataType,Fixity(Prefix),constrIndex)importGHC.Exts(IsList(..))importqualifiedLanguage.Haskell.TH.SyntaxasTH
#ifdef HS_BYTESTRING_ASSERTIONS
importControl.Exception(assert)
#endif
-- | A space-efficient representation of a 'Word8' vector, supporting many-- efficient operations.---- A 'LazyByteString' contains 8-bit bytes, or by using the operations-- from "Data.ByteString.Lazy.Char8" it can be interpreted as containing-- 8-bit characters.--
#ifndef HS_BYTESTRING_ASSERTIONS
dataByteString =Empty |Chunk {-# UNPACK#-}!S.StrictByteString ByteString -- INVARIANT: The S.StrictByteString field of any Chunk is not empty.-- (See also the 'invariant' and 'checkInvariant' functions.)-- To make testing of this invariant convenient, we add an-- assertion to that effect when the HS_BYTESTRING_ASSERTIONS-- preprocessor macro is defined, by renaming the actual constructor-- and providing a pattern synonym that does the checking:
#else
dataByteString=Empty|Chunk_{-# UNPACK#-}!S.StrictByteStringByteStringpatternChunk::S.StrictByteString->ByteString->ByteStringpatternChunkccs<-Chunk_ccswhereChunkc@(S.BS_len)cs=assert(len>0)Chunk_ccs{-# COMPLETEEmpty,Chunk#-}
#endif
derivinginstanceTH.LiftByteString -- | Type synonym for the lazy flavour of 'ByteString'.---- @since 0.11.2.0typeLazyByteString =ByteString instanceEqByteString where== :: ByteString -> ByteString -> Bool
(==)=ByteString -> ByteString -> Bool
eq instanceOrdByteString wherecompare :: ByteString -> ByteString -> Ordering
compare =ByteString -> ByteString -> Ordering
cmp instanceSemigroupByteString where<> :: ByteString -> ByteString -> ByteString
(<>)=ByteString -> ByteString -> ByteString
append sconcat :: NonEmpty ByteString -> ByteString
sconcat (ByteString
b :|[ByteString]
bs )=[ByteString] -> ByteString
concat (ByteString
b ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
bs )stimes :: forall b. Integral b => b -> ByteString -> ByteString
stimes =b -> ByteString -> ByteString
forall b. Integral b => b -> ByteString -> ByteString
times instanceMonoidByteString wheremempty :: ByteString
mempty=ByteString
Empty mappend :: ByteString -> ByteString -> ByteString
mappend=ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
(<>)mconcat :: [ByteString] -> ByteString
mconcat=[ByteString] -> ByteString
concat instanceNFDataByteString wherernf :: ByteString -> ()
rnfByteString
Empty =()rnf(Chunk StrictByteString
_ByteString
b )=ByteString -> ()
forall a. NFData a => a -> ()
rnfByteString
b instanceShowByteString whereshowsPrec :: Int -> ByteString -> ShowS
showsPrec Int
p ByteString
ps String
r =Int -> String -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrecInt
p (ByteString -> String
unpackChars ByteString
ps )String
r instanceReadByteString wherereadsPrec :: Int -> ReadS ByteString
readsPrec Int
p String
str =[(String -> ByteString
packChars String
x ,String
y )|(String
x ,String
y )<-Int -> ReadS String
forall a. Read a => Int -> ReadS a
readsPrecInt
p String
str ]-- | @since 0.10.12.0instanceIsListByteString wheretypeItemByteString =Word8fromList :: [Item ByteString] -> ByteString
fromList=[Word8] -> ByteString
[Item ByteString] -> ByteString
packBytes toList :: 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�instanceIsStringByteString wherefromString :: String -> ByteString
fromString=String -> ByteString
packChars instanceDataByteString wheregfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ByteString -> c ByteString
gfoldl forall d b. Data d => c (d -> b) -> d -> c b
f forall g. g -> c g
z ByteString
txt =([Word8] -> ByteString) -> c ([Word8] -> ByteString)
forall g. g -> c g
z [Word8] -> ByteString
packBytes c ([Word8] -> ByteString) -> [Word8] -> c ByteString
forall d b. Data d => c (d -> b) -> d -> c b
`f` ByteString -> [Word8]
unpackBytes ByteString
txt toConstr :: ByteString -> Constr
toConstr ByteString
_=Constr
packConstr gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ByteString
gunfold forall b r. Data b => c (b -> r) -> c r
k forall r. r -> c r
z Constr
c =caseConstr -> Int
constrIndexConstr
c ofInt
1->c ([Word8] -> ByteString) -> c ByteString
forall b r. Data b => c (b -> r) -> c r
k (([Word8] -> ByteString) -> c ([Word8] -> ByteString)
forall r. r -> c r
z [Word8] -> ByteString
packBytes )Int
_->String -> c ByteString
forall a. HasCallStack => String -> a
errorString
"gunfold: unexpected constructor of lazy ByteString"dataTypeOf :: ByteString -> DataType
dataTypeOf ByteString
_=DataType
byteStringDataType packConstr ::ConstrpackConstr :: Constr
packConstr =DataType -> String -> [String] -> Fixity -> Constr
mkConstrDataType
byteStringDataType String
"pack"[]Fixity
PrefixbyteStringDataType ::DataTypebyteStringDataType :: DataType
byteStringDataType =String -> DataType
mkNoRepTypeString
"Data.ByteString.Lazy.ByteString"-------------------------------------------------------------------------- Packing and unpacking from listspackBytes ::[Word8]->ByteString packBytes :: [Word8] -> ByteString
packBytes [Word8]
cs0 =Int -> [Word8] -> ByteString
packChunks Int
32[Word8]
cs0 wherepackChunks :: Int -> [Word8] -> ByteString
packChunks Int
n [Word8]
cs =caseInt -> [Word8] -> (StrictByteString, [Word8])
S.packUptoLenBytes Int
n [Word8]
cs of(StrictByteString
bs ,[])->StrictByteString -> ByteString -> ByteString
chunk StrictByteString
bs ByteString
Empty (StrictByteString
bs ,[Word8]
cs' )->StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
bs (Int -> [Word8] -> ByteString
packChunks (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min(Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
2)Int
smallChunkSize )[Word8]
cs' )packChars ::[Char]->ByteString packChars :: String -> ByteString
packChars String
cs0 =Int -> String -> ByteString
packChunks Int
32String
cs0 wherepackChunks :: Int -> String -> ByteString
packChunks Int
n String
cs =caseInt -> String -> (StrictByteString, String)
S.packUptoLenChars Int
n String
cs of(StrictByteString
bs ,[])->StrictByteString -> ByteString -> ByteString
chunk StrictByteString
bs ByteString
Empty (StrictByteString
bs ,String
cs' )->StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
bs (Int -> String -> ByteString
packChunks (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min(Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
2)Int
smallChunkSize )String
cs' )unpackBytes ::ByteString ->[Word8]unpackBytes :: ByteString -> [Word8]
unpackBytes ByteString
Empty =[]unpackBytes (Chunk StrictByteString
c ByteString
cs )=StrictByteString -> [Word8] -> [Word8]
S.unpackAppendBytesLazy StrictByteString
c (ByteString -> [Word8]
unpackBytes ByteString
cs )unpackChars ::ByteString ->[Char]unpackChars :: ByteString -> String
unpackChars ByteString
Empty =[]unpackChars (Chunk StrictByteString
c ByteString
cs )=StrictByteString -> ShowS
S.unpackAppendCharsLazy StrictByteString
c (ByteString -> String
unpackChars ByteString
cs )-------------------------------------------------------------------------- We no longer use these invariant-checking functions internally,-- preferring an assertion on `Chunk` itself, controlled by the-- HS_BYTESTRING_ASSERTIONS preprocessor macro.-- | The data type invariant:-- Every ByteString is either 'Empty' or consists of non-null-- 'S.StrictByteString's. All functions must preserve this.--invariant ::ByteString ->Boolinvariant :: ByteString -> Bool
invariant ByteString
Empty =Bool
Trueinvariant (Chunk (S.BS ForeignPtr Word8
_Int
len )ByteString
cs )=Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
0Bool -> Bool -> Bool
&&ByteString -> Bool
invariant ByteString
cs -- | Lazily checks that the given 'ByteString' satisfies the data type's-- "no empty chunks" invariant, raising an exception in place of the-- first chunk that does not satisfy the invariant.checkInvariant ::ByteString ->ByteString checkInvariant :: ByteString -> ByteString
checkInvariant ByteString
Empty =ByteString
Empty checkInvariant (Chunk c :: StrictByteString
c @(S.BS ForeignPtr Word8
_Int
len )ByteString
cs )|Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
0=StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
c (ByteString -> ByteString
checkInvariant ByteString
cs )|Bool
otherwise=String -> ByteString
forall a. HasCallStack => String -> a
error(String -> ByteString) -> String -> ByteString
forall a b. (a -> b) -> a -> b
$String
"Data.ByteString.Lazy: invariant violation:"String -> ShowS
forall a. [a] -> [a] -> [a]
++ByteString -> String
forall a. Show a => a -> String
show(StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
c ByteString
cs )-------------------------------------------------------------------------- | Smart constructor for 'Chunk'. Guarantees the data type invariant.chunk ::S.StrictByteString ->ByteString ->ByteString chunk :: StrictByteString -> ByteString -> ByteString
chunk c :: StrictByteString
c @(S.BS ForeignPtr Word8
_Int
len )ByteString
cs |Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0=ByteString
cs |Bool
otherwise=StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
c ByteString
cs {-# INLINEchunk #-}-- | Consume the chunks of a lazy ByteString with a natural right fold.foldrChunks ::(S.StrictByteString ->a ->a )->a ->ByteString ->a foldrChunks :: forall a. (StrictByteString -> a -> a) -> a -> ByteString -> a
foldrChunks StrictByteString -> a -> a
f a
z =ByteString -> a
go wherego :: ByteString -> a
go ByteString
Empty =a
z go (Chunk StrictByteString
c ByteString
cs )=StrictByteString -> a -> a
f StrictByteString
c (ByteString -> a
go ByteString
cs ){-# INLINEfoldrChunks #-}-- | Consume the chunks of a lazy ByteString with a strict, tail-recursive,-- accumulating left fold.foldlChunks ::(a ->S.StrictByteString ->a )->a ->ByteString ->a foldlChunks :: forall a. (a -> StrictByteString -> a) -> a -> ByteString -> a
foldlChunks a -> StrictByteString -> a
f =a -> ByteString -> a
go wherego :: a -> ByteString -> a
go !a
a ByteString
Empty =a
a go !a
a (Chunk StrictByteString
c ByteString
cs )=a -> ByteString -> a
go (a -> StrictByteString -> a
f a
a StrictByteString
c )ByteString
cs {-# INLINEfoldlChunks #-}-------------------------------------------------------------------------- The representation uses lists of packed chunks. When we have to convert from-- a lazy list to the chunked representation, then by default we use this-- chunk size. Some functions give you more control over the chunk size.---- Measurements here:-- http://www.cse.unsw.edu.au/~dons/tmp/chunksize_v_cache.png---- indicate that a value around 0.5 to 1 x your L2 cache is best.-- The following value assumes people have something greater than 128k,-- and need to share the cache with other programs.-- | The chunk size used for I\/O. Currently set to 32k, less the memory management overheaddefaultChunkSize ::IntdefaultChunkSize :: Int
defaultChunkSize =Int
32Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
chunkOverhead wherek :: Int
k =Int
1024-- | The recommended chunk size. Currently set to 4k, less the memory management overheadsmallChunkSize ::IntsmallChunkSize :: Int
smallChunkSize =Int
4Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
chunkOverhead wherek :: Int
k =Int
1024-- | The memory management overhead. Currently this is tuned for GHC only.chunkOverhead ::IntchunkOverhead :: Int
chunkOverhead =Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int -> Int
forall a. Storable a => a -> Int
sizeOf(Int
forall a. HasCallStack => a
undefined::Int)-------------------------------------------------------------------------- Implementations for Eq, Ord and Monoid instanceseq ::ByteString ->ByteString ->Booleq :: ByteString -> ByteString -> Bool
eq ByteString
Empty ByteString
Empty =Bool
Trueeq ByteString
Empty ByteString
_=Bool
Falseeq ByteString
_ByteString
Empty =Bool
Falseeq (Chunk a :: StrictByteString
a @(S.BS ForeignPtr Word8
ap Int
al )ByteString
as )(Chunk b :: StrictByteString
b @(S.BS ForeignPtr Word8
bp Int
bl )ByteString
bs )=caseInt -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compareInt
al Int
bl ofOrdering
LT->StrictByteString
a StrictByteString -> StrictByteString -> Bool
forall a. Eq a => a -> a -> Bool
==ForeignPtr Word8 -> Int -> StrictByteString
S.BS ForeignPtr Word8
bp Int
al Bool -> Bool -> Bool
&&ByteString -> ByteString -> Bool
eq ByteString
as (StrictByteString -> ByteString -> ByteString
Chunk (ForeignPtr Word8 -> Int -> StrictByteString
S.BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
S.plusForeignPtrForeignPtr Word8
bp Int
al )(Int
bl Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
al ))ByteString
bs )Ordering
EQ->StrictByteString
a StrictByteString -> StrictByteString -> Bool
forall a. Eq a => a -> a -> Bool
==StrictByteString
b Bool -> Bool -> Bool
&&ByteString -> ByteString -> Bool
eq ByteString
as ByteString
bs Ordering
GT->ForeignPtr Word8 -> Int -> StrictByteString
S.BS ForeignPtr Word8
ap Int
bl StrictByteString -> StrictByteString -> Bool
forall a. Eq a => a -> a -> Bool
==StrictByteString
b Bool -> Bool -> Bool
&&ByteString -> ByteString -> Bool
eq (StrictByteString -> ByteString -> ByteString
Chunk (ForeignPtr Word8 -> Int -> StrictByteString
S.BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
S.plusForeignPtrForeignPtr Word8
ap Int
bl )(Int
al Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
bl ))ByteString
as )ByteString
bs cmp ::ByteString ->ByteString ->Orderingcmp :: ByteString -> ByteString -> Ordering
cmp ByteString
Empty ByteString
Empty =Ordering
EQcmp ByteString
Empty ByteString
_=Ordering
LTcmp ByteString
_ByteString
Empty =Ordering
GTcmp (Chunk a :: StrictByteString
a @(S.BS ForeignPtr Word8
ap Int
al )ByteString
as )(Chunk b :: StrictByteString
b @(S.BS ForeignPtr Word8
bp Int
bl )ByteString
bs )=caseInt -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compareInt
al Int
bl ofOrdering
LT->caseStrictByteString -> StrictByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
compareStrictByteString
a (ForeignPtr Word8 -> Int -> StrictByteString
S.BS ForeignPtr Word8
bp Int
al )ofOrdering
EQ->ByteString -> ByteString -> Ordering
cmp ByteString
as (StrictByteString -> ByteString -> ByteString
Chunk (ForeignPtr Word8 -> Int -> StrictByteString
S.BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
S.plusForeignPtrForeignPtr Word8
bp Int
al )(Int
bl Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
al ))ByteString
bs )Ordering
result ->Ordering
result Ordering
EQ->caseStrictByteString -> StrictByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
compareStrictByteString
a StrictByteString
b ofOrdering
EQ->ByteString -> ByteString -> Ordering
cmp ByteString
as ByteString
bs Ordering
result ->Ordering
result Ordering
GT->caseStrictByteString -> StrictByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
compare(ForeignPtr Word8 -> Int -> StrictByteString
S.BS ForeignPtr Word8
ap Int
bl )StrictByteString
b ofOrdering
EQ->ByteString -> ByteString -> Ordering
cmp (StrictByteString -> ByteString -> ByteString
Chunk (ForeignPtr Word8 -> Int -> StrictByteString
S.BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
S.plusForeignPtrForeignPtr Word8
ap Int
bl )(Int
al Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
bl ))ByteString
as )ByteString
bs Ordering
result ->Ordering
result append ::ByteString ->ByteString ->ByteString append :: ByteString -> ByteString -> ByteString
append ByteString
xs ByteString
ys =(StrictByteString -> ByteString -> ByteString)
-> ByteString -> ByteString -> ByteString
forall a. (StrictByteString -> a -> a) -> a -> ByteString -> a
foldrChunks StrictByteString -> ByteString -> ByteString
Chunk ByteString
ys ByteString
xs concat ::[ByteString ]->ByteString concat :: [ByteString] -> ByteString
concat =[ByteString] -> ByteString
to wherego :: ByteString -> [ByteString] -> ByteString
go ByteString
Empty [ByteString]
css =[ByteString] -> ByteString
to [ByteString]
css go (Chunk StrictByteString
c ByteString
cs )[ByteString]
css =StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
c (ByteString -> [ByteString] -> ByteString
go ByteString
cs [ByteString]
css )to :: [ByteString] -> ByteString
to []=ByteString
Empty to (ByteString
cs :[ByteString]
css )=ByteString -> [ByteString] -> ByteString
go ByteString
cs [ByteString]
css -- | Repeats the given ByteString n times.times ::Integrala =>a ->ByteString ->ByteString times :: forall b. Integral b => b -> ByteString -> ByteString
times a
0ByteString
_=ByteString
Empty times a
n ByteString
lbs0 |a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<a
0=String -> ByteString
forall a. HasCallStack => String -> a
errorString
"stimes: non-negative multiplier expected"|Bool
otherwise=caseByteString
lbs0 ofByteString
Empty ->ByteString
Empty Chunk StrictByteString
bs ByteString
lbs ->StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
bs (ByteString -> ByteString
go ByteString
lbs )wherego :: ByteString -> ByteString
go ByteString
Empty =a -> ByteString -> ByteString
forall b. Integral b => b -> ByteString -> ByteString
times (a
n a -> a -> a
forall a. Num a => a -> a -> a
-a
1)ByteString
lbs0 go (Chunk StrictByteString
c ByteString
cs )=StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
c (ByteString -> ByteString
go ByteString
cs )-------------------------------------------------------------------------- Conversions-- |/O(1)/ Convert a 'S.StrictByteString' into a 'LazyByteString'.fromStrict ::S.StrictByteString ->LazyByteString fromStrict :: StrictByteString -> ByteString
fromStrict (S.BS ForeignPtr Word8
_Int
0)=ByteString
Empty fromStrict StrictByteString
bs =StrictByteString -> ByteString -> ByteString
Chunk StrictByteString
bs ByteString
Empty -- |/O(n)/ Convert a 'LazyByteString' into a 'S.StrictByteString'.---- Note that this is an /expensive/ operation that forces the whole-- 'LazyByteString' into memory and then copies all the data. If possible, try to-- avoid converting back and forth between strict and lazy bytestrings.--toStrict ::LazyByteString ->S.StrictByteString toStrict :: ByteString -> StrictByteString
toStrict =\ByteString
cs ->ByteString -> ByteString -> StrictByteString
goLen0 ByteString
cs ByteString
cs -- 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 -> StrictByteString
goLen0 ByteString
_ByteString
Empty =ForeignPtr Word8 -> Int -> StrictByteString
S.BS ForeignPtr Word8
S.nullForeignPtr Int
0goLen0 ByteString
cs0 (Chunk StrictByteString
c ByteString
cs )=ByteString -> StrictByteString -> ByteString -> StrictByteString
goLen1 ByteString
cs0 StrictByteString
c ByteString
cs -- It's still possible that the result is a single chunkgoLen1 :: ByteString -> StrictByteString -> ByteString -> StrictByteString
goLen1 ByteString
_StrictByteString
bs ByteString
Empty =StrictByteString
bs goLen1 ByteString
cs0 (S.BS ForeignPtr Word8
_Int
bl )(Chunk (S.BS ForeignPtr Word8
_Int
cl )ByteString
cs )=ByteString -> Int -> ByteString -> StrictByteString
goLen ByteString
cs0 (String -> Int -> Int -> Int
S.checkedAdd String
"Lazy.toStrict"Int
bl Int
cl )ByteString
cs -- General case, just find the total length we'll needgoLen :: ByteString -> Int -> ByteString -> StrictByteString
goLen ByteString
cs0 !Int
total (Chunk (S.BS ForeignPtr Word8
_Int
cl )ByteString
cs )=ByteString -> Int -> ByteString -> StrictByteString
goLen ByteString
cs0 (String -> Int -> Int -> Int
S.checkedAdd String
"Lazy.toStrict"Int
total Int
cl )ByteString
cs goLen ByteString
cs0 Int
total ByteString
Empty =Int -> (ForeignPtr Word8 -> IO ()) -> StrictByteString
S.unsafeCreateFp Int
total ((ForeignPtr Word8 -> IO ()) -> StrictByteString)
-> (ForeignPtr Word8 -> IO ()) -> StrictByteString
forall a b. (a -> b) -> a -> b
$\ForeignPtr Word8
ptr ->ByteString -> ForeignPtr Word8 -> IO ()
goCopy ByteString
cs0 ForeignPtr Word8
ptr -- Copy the datagoCopy :: ByteString -> ForeignPtr Word8 -> IO ()
goCopy ByteString
Empty !ForeignPtr Word8
_=() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return()goCopy (Chunk (S.BS ForeignPtr Word8
fp Int
len )ByteString
cs )!ForeignPtr Word8
ptr =doForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
S.memcpyFp ForeignPtr Word8
ptr ForeignPtr Word8
fp Int
len ByteString -> ForeignPtr Word8 -> IO ()
goCopy ByteString
cs (ForeignPtr Word8
ptr ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`S.plusForeignPtr`Int
len )-- See the comment on Data.ByteString.Internal.concat for some background on-- this implementation.

AltStyle によって変換されたページ (->オリジナル) /