content: {-
  
  API matches that of
  
  -- Package     : bytestring-0.12.2.0
  --
  -- Module      : Data.ByteString.Short.Internal
  -- Copyright   : (c) Duncan Coutts 2012-2013, Julian Ospald 2022
  -- License     : BSD-style
  --
  -- Maintainer  : hasufell@posteo.de
  -- Stability   : stable
  -- Portability : ghc only
  
  but with the representation of ShortByteString hidden
  (it is different from GHC).
  
  types and documentation below are copied from bytestring-0.12.2.0
  though the implementations differ (except where stated)
  
  -}
  module Data.ByteString.Short.Internal(
      -- * The @ShortByteString@ type and representation
      ShortByteString,
  
      -- * Introducing and eliminating 'ShortByteString's
      empty,
      singleton,
      pack,
      unpack,
      fromShort,
      toShort,
  
      -- * Basic interface
      snoc,
      cons,
      append,
      last,
      tail,
      uncons,
      head,
      init,
      unsnoc,
      null,
      length,
  
      -- * Transforming ShortByteStrings
      map,
      reverse,
      intercalate,
  
      -- * Reducing 'ShortByteString's (folds)
      foldl,
      foldl',
      foldl1,
      foldl1',
  
      foldr,
      foldr',
      foldr1,
      foldr1',
  
      -- ** Special folds
      all,
      any,
      concat,
  
      -- ** Generating and unfolding ShortByteStrings
      replicate,
      unfoldr,
      unfoldrN,
  
      -- * Substrings
  
      -- ** Breaking strings
      take,
      takeEnd,
      takeWhileEnd,
      takeWhile,
      drop,
      dropEnd,
      dropWhile,
      dropWhileEnd,
      breakEnd,
      break,
      span,
      spanEnd,
      splitAt,
      split,
      splitWith,
      stripSuffix,
      stripPrefix,
  
      -- * Predicates
      isInfixOf,
      isPrefixOf,
      isSuffixOf,
  
      -- ** Search for arbitrary substrings
      breakSubstring,
  
      -- * Searching ShortByteStrings
  
      -- ** Searching by equality
      elem,
  
      -- ** Searching with a predicate
      find,
      filter,
      partition,
  
      -- * Indexing ShortByteStrings
      index,
      indexMaybe,
      (!?),
      elemIndex,
      elemIndices,
      count,
      findIndex,
      findIndices,
      unsafeIndex,
  
  {-
      -- * Low level operations -- XXX
      createFromPtr,
      copyToPtr,
  -}
  
      -- ** Encoding validation
      isValidUtf8,
  
      -- * Low level conversions
      -- ** Packing 'Foreign.C.String.CString's and pointers
      packCString,
      packCStringLen,
  
      -- ** Using ShortByteStrings as 'Foreign.C.String.CString's
      useAsCString,
      useAsCStringLen
    ) where
  
  import Prelude hiding
    ( empty, singleton, pack, unpack, fromShort, toShort,
      snoc, cons, append, unsnoc, last, tail, uncons, head, init,
      null, length, map, reverse, intercalate,
      foldl, foldl', foldl1, foldl1', foldr, foldr', foldr1, foldr1',
      all, any, concat, replicate, unfoldr, unfoldrN,
      take, takeEnd, takeWhileEnd, takeWhile,
      drop, dropEnd, dropWhileEnd, dropWhile,
      break, breakEnd, span, spanEnd, splitAt, split, splitWith,
      stripSuffix, stripPrefix, isInfixOf, isPrefixOf, isSuffixOf,
      breakSubstring, elem, find, filter, partition,
      index, indexMaybe, (!?), elemIndex, elemIndices, count,
      findIndex, findIndices, unsafeIndex,
  --  createFromPtr, copyToPtr, -- XXX
      isValidUtf8,
      packCString, packCStringLen, useAsCString, useAsCStringLen,
    )
  import Control.DeepSeq.Class
  import Foreign (Ptr)
  import Foreign.C.String (CString, CStringLen)
  
  import Data.Coerce ( coerce )
  import Data.Data ( Data(..) )
  import Data.Typeable ( Typeable(..) )
  import GHC.Generics ( Generic(..) )
  import Data.Monoid ( Monoid(..) )
  import Data.Semigroup ( Semigroup(..), stimesMonoid )
  import Data.List.NonEmpty ( NonEmpty(..) )
  import Data.String ( IsString(..) )
  -- import qualified GHC.Exts -- XXX OverloadedLists
  import GHC.Stack ( HasCallStack )
  import Data.ByteString as BS
  import Data.ByteString.Unsafe as BS.Unsafe
  
  import Data.Word (Word8)
  
  newtype ShortByteString = S ByteString
  --  deriving (Eq, Ord, Data, Typeable, Generic)
    deriving (Eq, Ord, Typeable, NFData)
  
  fromShort :: ShortByteString -> ByteString
  fromShort (S b) = b
  
  toShort :: ByteString -> ShortByteString
  toShort b = S b
  
  -- copied from bytestring-0.12.2.0
  instance Semigroup ShortByteString where
    (<>)    = append
    sconcat (b:|bs) = concat (b:bs)
    stimes  = stimesMonoid
  
  -- copied from bytestring-0.12.2.0
  instance Monoid ShortByteString where
    mempty  = empty
    mappend = (<>)
    mconcat = concat
  
  -- copied from bytestring-0.12.2.0
  instance Show ShortByteString where
    showsPrec p ps r = showsPrec p (unpackChars ps) r
  
  -- copied from bytestring-0.12.2.0
  instance Read ShortByteString where
    readsPrec p str = [ (packChars x, y) | (x, y) <- readsPrec p str ]
  
  -- copied from bytestring-0.12.2.0
  instance IsString ShortByteString where
    fromString = packChars
  
  {-
  instance GHC.Exts.IsList ShortByteString where -- XXX OverloadedLists
    type Item ShortByteString = Word8
    fromList  = toShort . GHC.Exts.fromList
    fromListN = (toShort .) . GHC.Exts.fromListN
    toList    = GHC.Exts.toList . fromShort
  -}
  
  empty :: ShortByteString
  empty = coerce BS.empty
  
  singleton :: Word8 -> ShortByteString
  singleton = coerce BS.singleton
  
  pack :: [Word8] -> ShortByteString
  pack = coerce BS.pack
  
  unpack :: ShortByteString -> [Word8]
  unpack = coerce BS.unpack
  
  snoc :: ShortByteString -> Word8 -> ShortByteString
  snoc = coerce BS.snoc
  
  cons :: Word8 -> ShortByteString -> ShortByteString
  cons = coerce BS.cons
  
  append :: ShortByteString -> ShortByteString -> ShortByteString
  append = coerce BS.append
  
  last :: HasCallStack => ShortByteString -> Word8
  last = coerce BS.last
  
  tail :: HasCallStack => ShortByteString -> ShortByteString
  tail = coerce BS.tail
  
  uncons :: ShortByteString -> Maybe (Word8, ShortByteString)
  uncons = coerce BS.uncons
  
  head :: HasCallStack => ShortByteString -> Word8
  head = coerce BS.head
  
  init :: HasCallStack => ShortByteString -> ShortByteString
  init = coerce BS.init
  
  unsnoc :: ShortByteString -> Maybe (ShortByteString, Word8)
  unsnoc = coerce BS.unsnoc
  
  null :: ShortByteString -> Bool
  null = coerce BS.null
  
  length :: ShortByteString -> Int
  length = coerce BS.length
  
  map :: (Word8 -> Word8) -> ShortByteString -> ShortByteString
  map = coerce BS.map
  
  reverse :: ShortByteString -> ShortByteString
  reverse = coerce BS.reverse
  
  intercalate :: ShortByteString -> [ShortByteString] -> ShortByteString
  intercalate = coerce BS.intercalate
  
  foldl :: (a -> Word8 -> a) -> a -> ShortByteString -> a
  foldl f e = BS.foldl f e . coerce
  
  foldl' :: (a -> Word8 -> a) -> a -> ShortByteString -> a
  foldl' f e = BS.foldl' f e . coerce
  
  foldl1 :: HasCallStack => (Word8 -> Word8 -> Word8) -> ShortByteString -> Word8
  foldl1 = coerce BS.foldl1
  
  foldl1' :: HasCallStack => (Word8 -> Word8 -> Word8) -> ShortByteString -> Word8
  foldl1' = coerce BS.foldl1'
  
  foldr :: (Word8 -> a -> a) -> a -> ShortByteString -> a
  foldr f e = BS.foldr f e . coerce
  
  foldr' :: (Word8 -> a -> a) -> a -> ShortByteString -> a
  foldr' f e = BS.foldr' f e . coerce
  
  foldr1 :: HasCallStack => (Word8 -> Word8 -> Word8) -> ShortByteString -> Word8
  foldr1 = coerce BS.foldr1
  
  foldr1' :: HasCallStack => (Word8 -> Word8 -> Word8) -> ShortByteString -> Word8
  foldr1' = coerce BS.foldr1'
  
  all :: (Word8 -> Bool) -> ShortByteString -> Bool
  all = coerce BS.all
  
  any :: (Word8 -> Bool) -> ShortByteString -> Bool
  any = coerce BS.any
  
  concat :: [ShortByteString] -> ShortByteString
  concat = coerce BS.concat
  
  replicate :: Int -> Word8 -> ShortByteString
  replicate = coerce BS.replicate
  
  unfoldr :: (a -> Maybe (Word8, a)) -> a -> ShortByteString
  unfoldr f = coerce . BS.unfoldr f
  
  unfoldrN :: Int -> (a -> Maybe (Word8, a)) -> a -> (ShortByteString, Maybe a)
  unfoldrN n f = coerce . BS.unfoldrN n f
  
  take :: Int -> ShortByteString -> ShortByteString
  take = coerce BS.take
  
  takeEnd :: Int -> ShortByteString -> ShortByteString
  takeEnd = coerce BS.takeEnd
  
  takeWhileEnd :: (Word8 -> Bool) -> ShortByteString -> ShortByteString
  takeWhileEnd = coerce BS.takeWhileEnd
  
  takeWhile :: (Word8 -> Bool) -> ShortByteString -> ShortByteString
  takeWhile = coerce BS.takeWhile
  
  drop :: Int -> ShortByteString -> ShortByteString
  drop = coerce BS.drop
  
  dropEnd :: Int -> ShortByteString -> ShortByteString
  dropEnd = coerce BS.dropEnd
  
  dropWhile :: (Word8 -> Bool) -> ShortByteString -> ShortByteString
  dropWhile = coerce BS.dropWhile
  
  dropWhileEnd :: (Word8 -> Bool) -> ShortByteString -> ShortByteString
  dropWhileEnd = coerce BS.dropWhileEnd
  
  breakEnd :: (Word8 -> Bool) -> ShortByteString -> (ShortByteString, ShortByteString)
  breakEnd = coerce BS.breakEnd
  
  break :: (Word8 -> Bool) -> ShortByteString -> (ShortByteString, ShortByteString)
  break = coerce BS.break
  
  span :: (Word8 -> Bool) -> ShortByteString -> (ShortByteString, ShortByteString)
  span = coerce BS.span
  
  spanEnd :: (Word8 -> Bool) -> ShortByteString -> (ShortByteString, ShortByteString)
  spanEnd = coerce BS.spanEnd
  
  splitAt :: Int -> ShortByteString -> (ShortByteString, ShortByteString)
  splitAt = coerce BS.splitAt
  
  split :: Word8 -> ShortByteString -> [ShortByteString]
  split = coerce BS.split
  
  splitWith :: (Word8 -> Bool) -> ShortByteString -> [ShortByteString]
  splitWith = coerce BS.splitWith
  
  stripSuffix :: ShortByteString -> ShortByteString -> Maybe ShortByteString
  stripSuffix = coerce BS.stripSuffix
  
  stripPrefix :: ShortByteString -> ShortByteString -> Maybe ShortByteString
  stripPrefix = coerce BS.stripPrefix
  
  isInfixOf :: ShortByteString -> ShortByteString -> Bool
  isInfixOf = coerce BS.isInfixOf
  
  isPrefixOf :: ShortByteString -> ShortByteString -> Bool
  isPrefixOf = coerce BS.isPrefixOf
  
  isSuffixOf :: ShortByteString -> ShortByteString -> Bool
  isSuffixOf = coerce BS.isSuffixOf
  
  breakSubstring :: ShortByteString -> ShortByteString -> (ShortByteString, ShortByteString)
  breakSubstring = coerce BS.breakSubstring
  
  elem :: Word8 -> ShortByteString -> Bool
  elem = coerce BS.elem
  
  find :: (Word8 -> Bool) -> ShortByteString -> Maybe Word8
  find = coerce BS.find
  
  filter :: (Word8 -> Bool) -> ShortByteString -> ShortByteString
  filter = coerce BS.filter
  
  partition :: (Word8 -> Bool) -> ShortByteString -> (ShortByteString, ShortByteString)
  partition = coerce BS.partition
  
  index :: HasCallStack => ShortByteString -> Int -> Word8
  index = coerce BS.index
  
  indexMaybe :: ShortByteString -> Int -> Maybe Word8
  indexMaybe = coerce BS.indexMaybe
  
  (!?) :: ShortByteString -> Int -> Maybe Word8
  (!?) = coerce (BS.!?)
  
  elemIndex :: Word8 -> ShortByteString -> Maybe Int
  elemIndex = coerce BS.elemIndex
  
  elemIndices :: Word8 -> ShortByteString -> [Int]
  elemIndices = coerce BS.elemIndices
  
  count :: Word8 -> ShortByteString -> Int
  count = coerce BS.count
  
  findIndex :: (Word8 -> Bool) -> ShortByteString -> Maybe Int
  findIndex = coerce BS.findIndex
  
  findIndices :: (Word8 -> Bool) -> ShortByteString -> [Int]
  findIndices = coerce BS.findIndices
  
  unsafeIndex :: ShortByteString -> Int -> Word8
  unsafeIndex = coerce BS.Unsafe.unsafeIndex
  
  {- XXX
  createFromPtr :: Ptr a -> Int -> IO ShortByteString
  createFromPtr p = coerce . BS.createFromPtr p
  
  copyToPtr :: ShortByteString -> Int -> Ptr a -> Int -> IO ()
  copyToPtr = BS.copyToPtr . coerce
  -}
  
  isValidUtf8 :: ShortByteString -> Bool
  isValidUtf8 = coerce BS.isValidUtf8
  
  packCString :: CString -> IO ShortByteString
  packCString = coerce BS.packCString
  
  packCStringLen :: CStringLen -> IO ShortByteString
  packCStringLen = coerce BS.packCStringLen
  
  useAsCString :: ShortByteString -> (CString -> IO a) -> IO a
  useAsCString = BS.useAsCString . coerce
  
  useAsCStringLen :: ShortByteString -> (CStringLen -> IO a) -> IO a
  useAsCStringLen = BS.useAsCStringLen . coerce
  
  -- private
  
  -- truncates wide characters
  packChars :: [Char] -> ShortByteString
  packChars = toShort . BS.pack . fmap (toEnum . fromEnum)
  
  unpackChars :: ShortByteString -> [Char]
  unpackChars = fmap  (toEnum . fromEnum) . BS.unpack . fromShort
  