{-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE CPP #-} module Data.GenValidity.ByteString where import Data.GenValidity import Data.Validity.ByteString () import Test.QuickCheck #if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<*>), pure) import Data.Functor ((<$>)) #endif import qualified Data.ByteString as SB import qualified Data.ByteString.Internal as SB import qualified Data.ByteString.Lazy as LB import qualified Data.ByteString.Lazy.Internal as LB instance GenUnchecked SB.ByteString where genUnchecked = error $ unlines [ "Data.GenValidity.ByteString.genUnchecked :: Strict.ByteString" , "You probably do not want to use this." , "You probably want to use 'genValid' instead." , "See https://github.com/NorfairKing/validity/blob/master/docs/BYTESTRING.md" ] shrinkUnchecked = error $ unlines [ "Data.GenValidity.ByteString.shrinkUnchecked :: Strict.ByteString -> [Strict.ByteString]" , "You probably do not want to use this." , "You probably want to use 'shrinkValid' instead." , "See https://github.com/NorfairKing/validity/blob/master/docs/BYTESTRING.md" ] -- | -- -- > genValid = SB.pack <$> genValid -- > shrinkValid = fmap SB.pack . shrinkValid . SB.unpack instance GenValid SB.ByteString where genValid = SB.pack <$> genValid shrinkValid = fmap SB.pack . shrinkValid . SB.unpack -- | WARNING: Unchecked ByteStrings are __seriously__ broken. -- -- The pointer may still point to something which is fine, but -- the offset and length will most likely be complete nonsense. -- This will most-likely lead to segfaults. -- -- This means that 'genUnchecked' will generate seriously broken 'ByteString' values. -- This is __intended__. If you need valid 'ByteString' values, use 'GenValid' instead. -- -- Make sure to not use any test suite combinators or property combinators that involve -- 'GenInvalid' (like 'genValiditySpec') on types that contain 'ByteString' values. genTrulyUncheckedStrictByteString :: Gen SB.ByteString genTrulyUncheckedStrictByteString = do ws <- genUnchecked -- TODO what do we do about the foreign pointer? let SB.PS p _ _ = SB.pack ws SB.PS p <$> genUnchecked <*> genUnchecked shrinkTrulyUncheckedStrictByteString :: SB.ByteString -> [SB.ByteString] shrinkTrulyUncheckedStrictByteString (SB.PS p o l) = [SB.PS p o' l' | (o', l') <- shrinkUnchecked (o, l)] instance GenUnchecked LB.ByteString where genUnchecked = sized $ \n -> case n of 0 -> pure LB.Empty _ -> do (a, b) <- genSplit n sb <- resize a genUnchecked lb <- resize b genUnchecked pure $ LB.Chunk sb lb shrinkUnchecked lb_ = case lb_ of LB.Empty -> [] (LB.Chunk sb lb) -> LB.Empty : [LB.Chunk sb' lb' | (sb', lb') <- shrinkUnchecked (sb, lb)] instance GenValid LB.ByteString where genValid = LB.pack <$> genValid shrinkValid = fmap LB.pack . shrinkValid . LB.unpack