@@ -400,7 +400,7 @@ unSBS (ShortByteString (ByteArray ba#)) = ba#
400400
401401create :: Int -> (forall s . MBA s -> ST s () ) -> ShortByteString
402402create len fill =
403- runST $ do
403+ assert (len >= 0 ) $ runST $ do
404404 mba <- newByteArray len
405405 fill mba
406406 BA # ba# <- unsafeFreezeByteArray mba
@@ -413,59 +413,60 @@ create len fill =
413413-- (<= the maximum size) and the result value. The resulting byte array
414414-- is realloced to this size.
415415createAndTrim :: Int -> (forall s . MBA s -> ST s (Int , a )) -> (ShortByteString , a )
416- createAndTrim l fill =
417- runST $ do
418- mba <- newByteArray l
419- (l' , res) <- fill mba
420- if assert (l' <= l ) $ l' >= l
416+ createAndTrim maxLen fill =
417+ assert (maxLen >= 0 ) $ runST $ do
418+ mba <- newByteArray maxLen
419+ (len , res) <- fill mba
420+ if assert (0 <= len && len <= maxLen ) $ len >= maxLen
421421 then do
422422 BA # ba# <- unsafeFreezeByteArray mba
423423 return (SBS ba# , res)
424424 else do
425- mba2 <- newByteArray l'
426- copyMutableByteArray mba 0 mba2 0 l'
425+ mba2 <- newByteArray len
426+ copyMutableByteArray mba 0 mba2 0 len
427427 BA # ba# <- unsafeFreezeByteArray mba2
428428 return (SBS ba# , res)
429429{-# INLINE createAndTrim #-}
430430
431431createAndTrim' :: Int -> (forall s . MBA s -> ST s Int ) -> ShortByteString
432- createAndTrim' l fill =
433- runST $ do
434- mba <- newByteArray l
435- l' <- fill mba
436- if assert (l' <= l ) $ l' >= l
432+ createAndTrim' maxLen fill =
433+ assert (maxLen >= 0 ) $ runST $ do
434+ mba <- newByteArray maxLen
435+ len <- fill mba
436+ if assert (0 <= len && len <= maxLen ) $ len >= maxLen
437437 then do
438438 BA # ba# <- unsafeFreezeByteArray mba
439439 return (SBS ba# )
440440 else do
441- mba2 <- newByteArray l'
442- copyMutableByteArray mba 0 mba2 0 l'
441+ mba2 <- newByteArray len
442+ copyMutableByteArray mba 0 mba2 0 len
443443 BA # ba# <- unsafeFreezeByteArray mba2
444444 return (SBS ba# )
445445{-# INLINE createAndTrim' #-}
446446
447- createAndTrim'' :: Int -> (forall s . MBA s -> MBA s -> ST s (Int , Int )) -> (ShortByteString , ShortByteString )
448- createAndTrim'' l fill =
447+ -- | Like createAndTrim, but with two buffers at once
448+ createAndTrim2 :: Int -> Int -> (forall s . MBA s -> MBA s -> ST s (Int , Int )) -> (ShortByteString , ShortByteString )
449+ createAndTrim2 maxLen1 maxLen2 fill =
449450 runST $ do
450- mba1 <- newByteArray l
451- mba2 <- newByteArray l
452- (l1, l2 ) <- fill mba1 mba2
453- sbs1 <- freeze' l1 mba1
454- sbs2 <- freeze' l2 mba2
451+ mba1 <- newByteArray maxLen1
452+ mba2 <- newByteArray maxLen2
453+ (len1, len2 ) <- fill mba1 mba2
454+ sbs1 <- freeze' len1 maxLen1 mba1
455+ sbs2 <- freeze' len2 maxLen2 mba2
455456 pure (sbs1, sbs2)
456457 where
457- freeze' :: Int -> MBA s -> ST s ShortByteString
458- freeze' l' mba =
459- if assert (l' <= l ) $ l' >= l
458+ freeze' :: Int -> Int -> MBA s -> ST s ShortByteString
459+ freeze' len maxLen mba =
460+ if assert (0 <= len && len <= maxLen ) $ len >= maxLen
460461 then do
461462 BA # ba# <- unsafeFreezeByteArray mba
462463 return (SBS ba# )
463464 else do
464- mba2 <- newByteArray l'
465- copyMutableByteArray mba 0 mba2 0 l'
465+ mba2 <- newByteArray len
466+ copyMutableByteArray mba 0 mba2 0 len
466467 BA # ba# <- unsafeFreezeByteArray mba2
467468 return (SBS ba# )
468- {-# INLINE createAndTrim'' #-}
469+ {-# INLINE createAndTrim2 #-}
469470
470471isPinned :: ByteArray # -> Bool
471472#if MIN_VERSION_base(4,10,0)
@@ -676,23 +677,23 @@ infixl 5 `snoc`
676677--
677678-- @since 0.11.3.0
678679snoc :: ShortByteString -> Word8 -> ShortByteString
679- snoc = \ sbs c -> let l = length sbs
680- nl = l + 1
681- in create nl $ \ mba -> do
682- copyByteArray (asBA sbs) 0 mba 0 l
683- writeWord8Array mba l c
680+ snoc = \ sbs c -> let len = length sbs
681+ newLen = checkedAdd " Short.snoc " len 1
682+ in create newLen $ \ mba -> do
683+ copyByteArray (asBA sbs) 0 mba 0 len
684+ writeWord8Array mba len c
684685
685686-- | /O(n)/ 'cons' is analogous to (:) for lists.
686687--
687688-- Note: copies the entire byte array
688689--
689690-- @since 0.11.3.0
690691cons :: Word8 -> ShortByteString -> ShortByteString
691- cons c = \ sbs -> let l = length sbs
692- nl = l + 1
693- in create nl $ \ mba -> do
692+ cons c = \ sbs -> let len = length sbs
693+ newLen = checkedAdd " Short.cons " len 1
694+ in create newLen $ \ mba -> do
694695 writeWord8Array mba 0 c
695- copyByteArray (asBA sbs) 0 mba 1 l
696+ copyByteArray (asBA sbs) 0 mba 1 len
696697
697698-- | /O(1)/ Extract the last element of a ShortByteString, which must be finite and non-empty.
698699-- An exception will be thrown in the case of an empty ShortByteString.
@@ -1484,9 +1485,9 @@ find f = \sbs -> case findIndex f sbs of
14841485--
14851486-- @since 0.11.3.0
14861487partition :: (Word8 -> Bool ) -> ShortByteString -> (ShortByteString , ShortByteString )
1487- partition k = \ sbs -> let l = length sbs
1488- in if | l <= 0 -> (sbs, sbs)
1489- | otherwise -> createAndTrim'' l $ \ mba1 mba2 -> go mba1 mba2 (asBA sbs) l
1488+ partition k = \ sbs -> let len = length sbs
1489+ in if | len <= 0 -> (sbs, sbs)
1490+ | otherwise -> createAndTrim2 len len $ \ mba1 mba2 -> go mba1 mba2 (asBA sbs) len
14901491 where
14911492 go :: forall s .
14921493 MBA s -- mutable output bytestring1
@@ -1614,12 +1615,14 @@ indexWord8ArrayAsWord64 (BA# ba#) (I# i#) = W64# (indexWord8ArrayAsWord64# ba# i
16141615#endif
16151616
16161617newByteArray :: Int -> ST s (MBA s )
1617- newByteArray (I # len# ) =
1618+ newByteArray len@ (I # len# ) =
1619+ assert (len >= 0 ) $
16181620 ST $ \ s -> case newByteArray# len# s of
16191621 (# s', mba# # ) -> (# s', MBA # mba# # )
16201622
16211623newPinnedByteArray :: Int -> ST s (MBA s )
1622- newPinnedByteArray (I # len# ) =
1624+ newPinnedByteArray len@ (I # len# ) =
1625+ assert (len >= 0 ) $
16231626 ST $ \ s -> case newPinnedByteArray# len# s of
16241627 (# s', mba# # ) -> (# s', MBA # mba# # )
16251628
0 commit comments