{- 
    Copyright 2013-2019 Mario Blazevic

    License: BSD3 (see BSD3-LICENSE.txt file)
-}

-- | This module defines the 'ByteStringUTF8' newtype wrapper around 'ByteString', together with its 'TextualMonoid'
-- instance. The 'FactorialMonoid' instance of a wrapped 'ByteStringUTF8' value differs from the original 'ByteString':
-- the prime 'factors' of the original value are its bytes, and for the wrapped value the prime 'factors' are its valid
-- UTF8 byte sequences. The following example session demonstrates the relationship:
-- 
-- >> let utf8@(ByteStringUTF8 bs) = fromString "E=mc\xb2"
-- >> bs
-- >"E=mc\194\178"
-- >> factors bs
-- >["E","=","m","c","\194","\178"]
-- >> utf8
-- >"E=mc²"
-- >> factors utf8
-- >["E","=","m","c","²"]
--
-- The 'TextualMonoid' instance follows the same logic, but it also decodes all valid UTF8 sequences into
-- characters. Any invalid UTF8 byte sequence from the original 'ByteString' is preserved as a single prime factor:
--
-- >> let utf8'@(ByteStringUTF8 bs') = ByteStringUTF8 (Data.ByteString.map pred bs)
-- >> bs'
-- >"D<lb\193\177"
-- >> factors bs'
-- >["D","<","l","b","\193","\177"]
-- >> utf8'
-- >"D<lb\[193,177]"
-- >> factors utf8'
-- >["D","<","l","b","\[193,177]"]

{-# LANGUAGE Haskell2010 #-}

module Data.Monoid.Instances.ByteString.UTF8 (
   ByteStringUTF8(..), decode
   )
where

import Control.Exception (assert)
import Data.Bits ((.&.), (.|.), shiftL, shiftR)
import Data.Char (chr, ord, isDigit, isPrint)
import qualified Data.Foldable as Foldable
import qualified Data.List as List
import Data.Maybe (fromMaybe, isJust, isNothing)
import Data.String (IsString(fromString))
import Data.Word (Word8)
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Char8 as ByteString.Char8
import Data.ByteString.Internal (w2c)
import Data.ByteString.Unsafe (unsafeDrop, unsafeHead, unsafeTail, unsafeTake, unsafeIndex)

import Data.Semigroup (Semigroup(..))
import Data.Monoid (Monoid(..))
import Data.Semigroup.Cancellative (LeftReductive(..), LeftCancellative)
import Data.Semigroup.Factorial (Factorial(..))
import Data.Monoid.GCD (LeftGCDMonoid(..))
import Data.Monoid.Null (MonoidNull(..), PositiveMonoid)
import Data.Monoid.Factorial (FactorialMonoid(..))
import Data.Monoid.Textual (TextualMonoid(..))
import qualified Data.Monoid.Factorial as Factorial (FactorialMonoid(..))
import qualified Data.Monoid.Textual as Textual (TextualMonoid(..))

import Prelude hiding (any, drop, dropWhile, foldl, foldl1, foldr, foldr1, scanl, scanr, scanl1, scanr1,
                       map, concatMap, break, span)

newtype ByteStringUTF8 = ByteStringUTF8 ByteString deriving (ByteStringUTF8 -> ByteStringUTF8 -> Bool
(ByteStringUTF8 -> ByteStringUTF8 -> Bool)
-> (ByteStringUTF8 -> ByteStringUTF8 -> Bool) -> Eq ByteStringUTF8
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
$c/= :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
== :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
$c== :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
Eq, Eq ByteStringUTF8
Eq ByteStringUTF8 =>
(ByteStringUTF8 -> ByteStringUTF8 -> Ordering)
-> (ByteStringUTF8 -> ByteStringUTF8 -> Bool)
-> (ByteStringUTF8 -> ByteStringUTF8 -> Bool)
-> (ByteStringUTF8 -> ByteStringUTF8 -> Bool)
-> (ByteStringUTF8 -> ByteStringUTF8 -> Bool)
-> (ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8)
-> (ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8)
-> Ord ByteStringUTF8
ByteStringUTF8 -> ByteStringUTF8 -> Bool
ByteStringUTF8 -> ByteStringUTF8 -> Ordering
ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8
$cmin :: ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8
max :: ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8
$cmax :: ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8
>= :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
$c>= :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
> :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
$c> :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
<= :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
$c<= :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
< :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
$c< :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
compare :: ByteStringUTF8 -> ByteStringUTF8 -> Ordering
$ccompare :: ByteStringUTF8 -> ByteStringUTF8 -> Ordering
$cp1Ord :: Eq ByteStringUTF8
Ord)

-- | Takes a raw 'ByteString' chunk and returns a pair of 'ByteStringUTF8' decoding the prefix of the chunk and the
-- remaining suffix that is either null or contains the incomplete last character of the chunk.
decode :: ByteString -> (ByteStringUTF8, ByteString)
decode :: ByteString -> (ByteStringUTF8, ByteString)
decode bs :: ByteString
bs
   | ByteString -> Bool
ByteString.null ByteString
bs Bool -> Bool -> Bool
|| Word8
l Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs, ByteString
forall a. Monoid a => a
mempty)
   | Word8
l Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= 0xC0 = (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteString
ByteString.init ByteString
bs), Word8 -> ByteString
ByteString.singleton Word8
l)
   | ByteString -> Bool
ByteString.null ByteString
prefix = (ByteStringUTF8
forall a. Monoid a => a
mempty, ByteString
bs)
   | Bool
otherwise =
      case Word8 -> ByteString -> Maybe (Char, ByteStringUTF8)
toChar (ByteString -> Word8
ByteString.last ByteString
prefix) ByteString
suffix
      of Nothing -> (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteString
ByteString.init ByteString
prefix), Int -> ByteString -> ByteString
forall m. FactorialMonoid m => Int -> m -> m
drop (ByteString -> Int
ByteString.length ByteString
prefix Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) ByteString
bs)
         Just{} -> (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs, ByteString
forall a. Monoid a => a
mempty)
   where (prefix :: ByteString
prefix, suffix :: ByteString
suffix) = (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
ByteString.breakEnd Word8 -> Bool
byteStartsCharacter ByteString
bs
         l :: Word8
l = ByteString -> Word8
ByteString.last ByteString
bs

-- | O(n)
instance Semigroup ByteStringUTF8 where
   ByteStringUTF8 a :: ByteString
a <> :: ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8
<> ByteStringUTF8 b :: ByteString
b = ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString
a ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
b)
   {-# INLINE (<>) #-}

-- | O(n)
instance Monoid ByteStringUTF8 where
   mempty :: ByteStringUTF8
mempty = ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
ByteString.empty
   {-# INLINE mempty #-}
   ByteStringUTF8 a :: ByteString
a mappend :: ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8
`mappend` ByteStringUTF8 b :: ByteString
b = ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString
a ByteString -> ByteString -> ByteString
forall a. Monoid a => a -> a -> a
`mappend` ByteString
b)
   {-# INLINE mappend #-}

-- | O(1)
instance MonoidNull ByteStringUTF8 where
   null :: ByteStringUTF8 -> Bool
null (ByteStringUTF8 b :: ByteString
b) = ByteString -> Bool
ByteString.null ByteString
b
   {-# INLINE null #-}

-- | O(n)
instance LeftReductive ByteStringUTF8 where
   stripPrefix :: ByteStringUTF8 -> ByteStringUTF8 -> Maybe ByteStringUTF8
stripPrefix (ByteStringUTF8 a :: ByteString
a) (ByteStringUTF8 b :: ByteString
b) = (ByteString -> ByteStringUTF8)
-> Maybe ByteString -> Maybe ByteStringUTF8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteString -> Maybe ByteString
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix ByteString
a ByteString
b)
   {-# INLINE stripPrefix #-}
   ByteStringUTF8 a :: ByteString
a isPrefixOf :: ByteStringUTF8 -> ByteStringUTF8 -> Bool
`isPrefixOf` ByteStringUTF8 b :: ByteString
b = ByteString
a ByteString -> ByteString -> Bool
forall m. LeftReductive m => m -> m -> Bool
`isPrefixOf` ByteString
b
   {-# INLINE isPrefixOf #-}

instance LeftCancellative ByteStringUTF8

-- | O(prefixLength)
instance LeftGCDMonoid ByteStringUTF8 where
   commonPrefix :: ByteStringUTF8 -> ByteStringUTF8 -> ByteStringUTF8
commonPrefix (ByteStringUTF8 a :: ByteString
a) (ByteStringUTF8 b :: ByteString
b) = ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteString -> ByteString
forall m. LeftGCDMonoid m => m -> m -> m
commonPrefix ByteString
a ByteString
b)
   {-# INLINE commonPrefix #-}
   stripCommonPrefix :: ByteStringUTF8
-> ByteStringUTF8
-> (ByteStringUTF8, ByteStringUTF8, ByteStringUTF8)
stripCommonPrefix (ByteStringUTF8 a :: ByteString
a) (ByteStringUTF8 b :: ByteString
b) = (ByteString, ByteString, ByteString)
-> (ByteStringUTF8, ByteStringUTF8, ByteStringUTF8)
wrapTriple (ByteString -> ByteString -> (ByteString, ByteString, ByteString)
forall m. LeftGCDMonoid m => m -> m -> (m, m, m)
stripCommonPrefix ByteString
a ByteString
b)
   {-# INLINE stripCommonPrefix #-}

instance Show ByteStringUTF8 where
   showsPrec :: Int -> ByteStringUTF8 -> ShowS
showsPrec _ bs :: ByteStringUTF8
bs s0 :: String
s0 = '"' Char -> ShowS
forall a. a -> [a] -> [a]
: (ByteStringUTF8 -> ShowS)
-> (Char -> ShowS) -> String -> ByteStringUTF8 -> String
forall t a.
TextualMonoid t =>
(t -> a -> a) -> (Char -> a -> a) -> a -> t -> a
Textual.foldr ByteStringUTF8 -> ShowS
showsBytes Char -> ShowS
showsChar ('"' Char -> ShowS
forall a. a -> [a] -> [a]
: String
s0) ByteStringUTF8
bs
      where showsBytes :: ByteStringUTF8 -> ShowS
showsBytes (ByteStringUTF8 b :: ByteString
b) s :: String
s = '\\' Char -> ShowS
forall a. a -> [a] -> [a]
: [Word8] -> ShowS
forall a. Show a => a -> ShowS
shows (ByteString -> [Word8]
ByteString.unpack ByteString
b) String
s
            showsChar :: Char -> ShowS
showsChar c :: Char
c s :: String
s
              | Char -> Bool
isPrint Char
c = Char
c Char -> ShowS
forall a. a -> [a] -> [a]
: String
s
              | h :: Char
h:_ <- String
s, Char -> Bool
isDigit Char
h = "\\" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Char -> Int
ord Char
c) String -> ShowS
forall a. [a] -> [a] -> [a]
++ "\\&" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s
              | Bool
otherwise = "\\" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Char -> Int
ord Char
c) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s

instance IsString ByteStringUTF8 where
   fromString :: String -> ByteStringUTF8
fromString = ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8)
-> (String -> ByteString) -> String -> ByteStringUTF8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> ByteString) -> String -> ByteString
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
Foldable.foldMap Char -> ByteString
fromChar
   {-# INLINE fromString #-}

instance PositiveMonoid ByteStringUTF8

instance Factorial ByteStringUTF8 where
   primePrefix :: ByteStringUTF8 -> ByteStringUTF8
primePrefix utf8 :: ByteStringUTF8
utf8@(ByteStringUTF8 bs :: ByteString
bs)
      | ByteString -> Bool
ByteString.null ByteString
bs = ByteStringUTF8
utf8
      | ByteString -> Word8
unsafeHead ByteString
bs Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = ByteString -> ByteStringUTF8
ByteStringUTF8 (Int -> ByteString -> ByteString
ByteString.take 1 ByteString
bs)
      | Bool
otherwise = case (Word8 -> Bool) -> ByteString -> Maybe Int
ByteString.findIndex Word8 -> Bool
byteStartsCharacter (ByteString -> ByteString
unsafeTail ByteString
bs)
                    of Just i :: Int
i -> ByteString -> ByteStringUTF8
ByteStringUTF8 (Int -> ByteString -> ByteString
ByteString.take (Int -> Int
forall a. Enum a => a -> a
succ Int
i) ByteString
bs)
                       Nothing -> ByteStringUTF8
utf8
   {-# INLINABLE primePrefix #-}
   factors :: ByteStringUTF8 -> [ByteStringUTF8]
factors (ByteStringUTF8 bs :: ByteString
bs) = (ByteString -> ByteStringUTF8) -> [ByteString] -> [ByteStringUTF8]
forall a b. (a -> b) -> [a] -> [b]
List.map ByteString -> ByteStringUTF8
ByteStringUTF8 ([ByteString] -> [ByteStringUTF8])
-> [ByteString] -> [ByteStringUTF8]
forall a b. (a -> b) -> a -> b
$ (Word8 -> Word8 -> Bool) -> ByteString -> [ByteString]
ByteString.groupBy Word8 -> Word8 -> Bool
forall a a. (Ord a, Ord a, Num a, Num a) => a -> a -> Bool
continued ByteString
bs
      where continued :: a -> a -> Bool
continued a :: a
a b :: a
b = a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= 0x80 Bool -> Bool -> Bool
&& a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= 0x80 Bool -> Bool -> Bool
&& a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0
   {-# INLINABLE factors #-}
   length :: ByteStringUTF8 -> Int
length (ByteStringUTF8 bs :: ByteString
bs) = (Int, Bool) -> Int
forall a b. (a, b) -> a
fst (((Int, Bool) -> Word8 -> (Int, Bool))
-> (Int, Bool) -> ByteString -> (Int, Bool)
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
ByteString.foldl' (Int, Bool) -> Word8 -> (Int, Bool)
forall a a. (Ord a, Num a, Enum a) => (a, Bool) -> a -> (a, Bool)
count (0, Bool
False) ByteString
bs)
      where count :: (a, Bool) -> a -> (a, Bool)
count (n :: a
n, high :: Bool
high) byte :: a
byte | a
byte a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (a -> a
forall a. Enum a => a -> a
succ a
n, Bool
False)
                                 | a
byte a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0 = (if Bool
high then a
n else a -> a
forall a. Enum a => a -> a
succ a
n, Bool
True)
                                 | Bool
otherwise = (a -> a
forall a. Enum a => a -> a
succ a
n, Bool
True)
   {-# INLINABLE length #-}
   foldl :: (a -> ByteStringUTF8 -> a) -> a -> ByteStringUTF8 -> a
foldl f :: a -> ByteStringUTF8 -> a
f a0 :: a
a0 (ByteStringUTF8 bs :: ByteString
bs) = (a -> ByteString -> a) -> a -> [ByteString] -> a
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl a -> ByteString -> a
f' a
a0 (ByteString -> [ByteString]
groupASCII ByteString
bs)
      where f' :: a -> ByteString -> a
f' a :: a
a b :: ByteString
b | ByteString -> Word8
unsafeHead ByteString
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (a -> Word8 -> a) -> a -> ByteString -> a
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
ByteString.foldl a -> Word8 -> a
f'' a
a ByteString
b
                   | Bool
otherwise = a -> ByteStringUTF8 -> a
f a
a (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
b)
            f'' :: a -> Word8 -> a
f'' a :: a
a w :: Word8
w = a -> ByteStringUTF8 -> a
f a
a (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString
ByteString.singleton Word8
w)
   {-# INLINABLE foldl #-}
   foldl' :: (a -> ByteStringUTF8 -> a) -> a -> ByteStringUTF8 -> a
foldl' f :: a -> ByteStringUTF8 -> a
f a0 :: a
a0 (ByteStringUTF8 bs :: ByteString
bs) = (a -> ByteString -> a) -> a -> [ByteString] -> a
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' a -> ByteString -> a
f' a
a0 (ByteString -> [ByteString]
groupASCII ByteString
bs)
      where f' :: a -> ByteString -> a
f' a :: a
a b :: ByteString
b | ByteString -> Word8
unsafeHead ByteString
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (a -> Word8 -> a) -> a -> ByteString -> a
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
ByteString.foldl' a -> Word8 -> a
f'' a
a ByteString
b
                   | Bool
otherwise = a -> ByteStringUTF8 -> a
f a
a (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
b)
            f'' :: a -> Word8 -> a
f'' a :: a
a w :: Word8
w = a -> ByteStringUTF8 -> a
f a
a (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString
ByteString.singleton Word8
w)
   {-# INLINABLE foldl' #-}
   foldr :: (ByteStringUTF8 -> a -> a) -> a -> ByteStringUTF8 -> a
foldr f :: ByteStringUTF8 -> a -> a
f a0 :: a
a0 (ByteStringUTF8 bs :: ByteString
bs) = (ByteString -> a -> a) -> a -> [ByteString] -> a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr ByteString -> a -> a
f' a
a0 (ByteString -> [ByteString]
groupASCII ByteString
bs)
      where f' :: ByteString -> a -> a
f' b :: ByteString
b a :: a
a | ByteString -> Word8
unsafeHead ByteString
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (Word8 -> a -> a) -> a -> ByteString -> a
forall a. (Word8 -> a -> a) -> a -> ByteString -> a
ByteString.foldr Word8 -> a -> a
f'' a
a ByteString
b
                   | Bool
otherwise = ByteStringUTF8 -> a -> a
f (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
b) a
a
            f'' :: Word8 -> a -> a
f'' w :: Word8
w a :: a
a = ByteStringUTF8 -> a -> a
f (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString
ByteString.singleton Word8
w) a
a
   {-# INLINABLE foldr #-}
   reverse :: ByteStringUTF8 -> ByteStringUTF8
reverse (ByteStringUTF8 bs :: ByteString
bs) =
      ByteString -> ByteStringUTF8
ByteStringUTF8 ([ByteString] -> ByteString
ByteString.concat ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> [ByteString]
forall a. [a] -> [a]
List.reverse ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> a -> b
$ (ByteString -> ByteString) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
List.map ByteString -> ByteString
reverseASCII ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
groupASCII ByteString
bs)
      where reverseASCII :: ByteString -> ByteString
reverseASCII b :: ByteString
b | ByteString -> Word8
unsafeHead ByteString
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = ByteString -> ByteString
ByteString.reverse ByteString
b
                           | Bool
otherwise = ByteString
b
   {-# INLINABLE reverse #-}

instance FactorialMonoid ByteStringUTF8 where
   splitPrimePrefix :: ByteStringUTF8 -> Maybe (ByteStringUTF8, ByteStringUTF8)
splitPrimePrefix utf8 :: ByteStringUTF8
utf8@(ByteStringUTF8 bs :: ByteString
bs)
      | ByteString -> Bool
ByteString.null ByteString
bs = Maybe (ByteStringUTF8, ByteStringUTF8)
forall a. Maybe a
Nothing
      | ByteString -> Word8
unsafeHead ByteString
bs Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (ByteStringUTF8, ByteStringUTF8)
-> Maybe (ByteStringUTF8, ByteStringUTF8)
forall a. a -> Maybe a
Just ((ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
wrapPair ((ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8))
-> (ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> (ByteString, ByteString)
ByteString.splitAt 1 ByteString
bs)
      | Bool
otherwise = case (Word8 -> Bool) -> ByteString -> Maybe Int
ByteString.findIndex Word8 -> Bool
byteStartsCharacter (ByteString -> ByteString
unsafeTail ByteString
bs)
                    of Just i :: Int
i -> (ByteStringUTF8, ByteStringUTF8)
-> Maybe (ByteStringUTF8, ByteStringUTF8)
forall a. a -> Maybe a
Just ((ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
wrapPair ((ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8))
-> (ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> (ByteString, ByteString)
ByteString.splitAt (Int -> Int
forall a. Enum a => a -> a
succ Int
i) ByteString
bs)
                       Nothing -> (ByteStringUTF8, ByteStringUTF8)
-> Maybe (ByteStringUTF8, ByteStringUTF8)
forall a. a -> Maybe a
Just (ByteStringUTF8
utf8, ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ ByteString
ByteString.empty)
   {-# INLINABLE splitPrimePrefix #-}
   splitPrimeSuffix :: ByteStringUTF8 -> Maybe (ByteStringUTF8, ByteStringUTF8)
splitPrimeSuffix (ByteStringUTF8 bs :: ByteString
bs)
      | ByteString -> Bool
ByteString.null ByteString
bs = Maybe (ByteStringUTF8, ByteStringUTF8)
forall a. Maybe a
Nothing
      | ByteString -> Bool
ByteString.null ByteString
prefix = (ByteStringUTF8, ByteStringUTF8)
-> Maybe (ByteStringUTF8, ByteStringUTF8)
forall a. a -> Maybe a
Just ((ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
wrapPair (ByteString, ByteString)
splitBS)
      | Bool -> Bool
not (ByteString -> Bool
ByteString.null ByteString
suffix) Bool -> Bool -> Bool
&& ByteString -> Word8
ByteString.last ByteString
prefix Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (ByteStringUTF8, ByteStringUTF8)
-> Maybe (ByteStringUTF8, ByteStringUTF8)
forall a. a -> Maybe a
Just ((ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
wrapPair (ByteString, ByteString)
splitBS)
      | Bool
otherwise = (ByteStringUTF8, ByteStringUTF8)
-> Maybe (ByteStringUTF8, ByteStringUTF8)
forall a. a -> Maybe a
Just ((ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
wrapPair ((ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8))
-> (ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> (ByteString, ByteString)
ByteString.splitAt (Int -> Int
forall a. Enum a => a -> a
pred (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
ByteString.length ByteString
prefix) ByteString
bs)
      where splitBS :: (ByteString, ByteString)
splitBS@(prefix :: ByteString
prefix, suffix :: ByteString
suffix) = (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
ByteString.breakEnd Word8 -> Bool
byteStartsCharacter ByteString
bs
   {-# INLINABLE splitPrimeSuffix #-}
   splitAt :: Int -> ByteStringUTF8 -> (ByteStringUTF8, ByteStringUTF8)
splitAt n :: Int
n (ByteStringUTF8 bs :: ByteString
bs) = (ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
wrapPair (Int -> ByteString -> (ByteString, ByteString)
ByteString.splitAt (Int -> ByteString -> Int
charStartIndex Int
n ByteString
bs) ByteString
bs)
   {-# INLINE splitAt #-}
   take :: Int -> ByteStringUTF8 -> ByteStringUTF8
take n :: Int
n (ByteStringUTF8 bs :: ByteString
bs) = ByteString -> ByteStringUTF8
ByteStringUTF8 (Int -> ByteString -> ByteString
ByteString.take (Int -> ByteString -> Int
charStartIndex Int
n ByteString
bs) ByteString
bs)
   {-# INLINE take #-}
   drop :: Int -> ByteStringUTF8 -> ByteStringUTF8
drop n :: Int
n (ByteStringUTF8 bs :: ByteString
bs) = ByteString -> ByteStringUTF8
ByteStringUTF8 (Int -> ByteString -> ByteString
ByteString.drop (Int -> ByteString -> Int
charStartIndex Int
n ByteString
bs) ByteString
bs)
   {-# INLINE drop #-}
   dropWhile :: (ByteStringUTF8 -> Bool) -> ByteStringUTF8 -> ByteStringUTF8
dropWhile p :: ByteStringUTF8 -> Bool
p (ByteStringUTF8 bs0 :: ByteString
bs0) = ByteString -> ByteStringUTF8
dropASCII ByteString
bs0
      where dropASCII :: ByteString -> ByteStringUTF8
dropASCII bs :: ByteString
bs =
               let suffix :: ByteString
suffix = (Word8 -> Bool) -> ByteString -> ByteString
ByteString.dropWhile (\w :: Word8
w-> Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 Bool -> Bool -> Bool
&& ByteStringUTF8 -> Bool
p (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString
ByteString.singleton Word8
w)) ByteString
bs
               in if ByteString -> Bool
ByteString.null ByteString
suffix Bool -> Bool -> Bool
|| ByteString -> Word8
unsafeHead ByteString
suffix Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80
                  then ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
suffix
                  else ByteString -> ByteStringUTF8
dropMultiByte ByteString
suffix
            dropMultiByte :: ByteString -> ByteStringUTF8
dropMultiByte bs :: ByteString
bs =
               let utf8 :: ByteStringUTF8
utf8 = ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs
               in case (Word8 -> Bool) -> ByteString -> Maybe Int
ByteString.findIndex Word8 -> Bool
byteStartsCharacter (ByteString -> ByteString
unsafeTail ByteString
bs)
                  of Nothing -> if ByteStringUTF8 -> Bool
p ByteStringUTF8
utf8 then ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
ByteString.empty else ByteStringUTF8
utf8
                     Just i :: Int
i -> let (hd :: ByteString
hd, tl :: ByteString
tl) = Int -> ByteString -> (ByteString, ByteString)
ByteString.splitAt (Int -> Int
forall a. Enum a => a -> a
succ Int
i) ByteString
bs
                               in if ByteStringUTF8 -> Bool
p (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
hd)
                                  then ByteString -> ByteStringUTF8
dropASCII ByteString
tl
                                  else ByteStringUTF8
utf8
   {-# INLINE dropWhile #-}
   takeWhile :: (ByteStringUTF8 -> Bool) -> ByteStringUTF8 -> ByteStringUTF8
takeWhile p :: ByteStringUTF8 -> Bool
p utf8 :: ByteStringUTF8
utf8@(ByteStringUTF8 bs :: ByteString
bs) =
      ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
ByteString.take (ByteString -> Int
ByteString.length ByteString
bs Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
s) ByteString
bs
      where (ByteStringUTF8 s :: ByteString
s) = (ByteStringUTF8 -> Bool) -> ByteStringUTF8 -> ByteStringUTF8
forall m. FactorialMonoid m => (m -> Bool) -> m -> m
Factorial.dropWhile ByteStringUTF8 -> Bool
p ByteStringUTF8
utf8
   {-# INLINE takeWhile #-}
   span :: (ByteStringUTF8 -> Bool)
-> ByteStringUTF8 -> (ByteStringUTF8, ByteStringUTF8)
span p :: ByteStringUTF8 -> Bool
p utf8 :: ByteStringUTF8
utf8@(ByteStringUTF8 bs :: ByteString
bs) =
      (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
ByteString.take (ByteString -> Int
ByteString.length ByteString
bs Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
s) ByteString
bs, ByteStringUTF8
suffix)
      where suffix :: ByteStringUTF8
suffix@(ByteStringUTF8 s :: ByteString
s) = (ByteStringUTF8 -> Bool) -> ByteStringUTF8 -> ByteStringUTF8
forall m. FactorialMonoid m => (m -> Bool) -> m -> m
Factorial.dropWhile ByteStringUTF8 -> Bool
p ByteStringUTF8
utf8
   {-# INLINE span #-}
   break :: (ByteStringUTF8 -> Bool)
-> ByteStringUTF8 -> (ByteStringUTF8, ByteStringUTF8)
break p :: ByteStringUTF8 -> Bool
p = (ByteStringUTF8 -> Bool)
-> ByteStringUTF8 -> (ByteStringUTF8, ByteStringUTF8)
forall m. FactorialMonoid m => (m -> Bool) -> m -> (m, m)
Factorial.span (Bool -> Bool
not (Bool -> Bool)
-> (ByteStringUTF8 -> Bool) -> ByteStringUTF8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStringUTF8 -> Bool
p)
   {-# INLINE break #-}
   spanMaybe :: s
-> (s -> ByteStringUTF8 -> Maybe s)
-> ByteStringUTF8
-> (ByteStringUTF8, ByteStringUTF8, s)
spanMaybe s0 :: s
s0 f :: s -> ByteStringUTF8 -> Maybe s
f (ByteStringUTF8 bs0 :: ByteString
bs0) = (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
ByteString.take (ByteString -> Int
ByteString.length ByteString
bs0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
dropped) ByteString
bs0,
                                          ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
dropped,
                                          s
s')
      where (dropped :: ByteString
dropped, s' :: s
s') = s -> ByteString -> (ByteString, s)
dropASCII s
s0 ByteString
bs0
            dropASCII :: s -> ByteString -> (ByteString, s)
dropASCII s :: s
s bs :: ByteString
bs =
               let suffix :: ByteString
suffix = Int -> ByteString -> ByteString
ByteString.drop Int
index ByteString
bs
                   (index :: Int
index, s1 :: s
s1) = (Word8 -> ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s))
-> ((Int, s) -> (Int, s)) -> ByteString -> (Int, s) -> (Int, s)
forall a. (Word8 -> a -> a) -> a -> ByteString -> a
ByteString.foldr Word8 -> ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s)
f8 (Int, s) -> (Int, s)
forall a. a -> a
id ByteString
bs (0, s
s)
                   f8 :: Word8 -> ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s)
f8 w :: Word8
w cont :: (Int, s) -> (Int, s)
cont (i :: Int
i, s2 :: s
s2)
                     | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80, Just s3 :: s
s3 <- s -> ByteStringUTF8 -> Maybe s
f s
s2 (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString
ByteString.singleton Word8
w) =
                         let i' :: Int
i' = Int -> Int
forall a. Enum a => a -> a
succ Int
i :: Int in Int -> (Int, s) -> (Int, s)
forall a b. a -> b -> b
seq Int
i' ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s)
forall a b. (a -> b) -> a -> b
$ (Int, s) -> (Int, s)
cont (Int
i', s
s3)
                     | Bool
otherwise = (Int
i, s
s2)
               in if ByteString -> Bool
ByteString.null ByteString
suffix Bool -> Bool -> Bool
|| ByteString -> Word8
unsafeHead ByteString
suffix Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80
                  then (ByteString
suffix, s
s1)
                  else s -> ByteString -> (ByteString, s)
dropMultiByte s
s1 ByteString
suffix
            dropMultiByte :: s -> ByteString -> (ByteString, s)
dropMultiByte s :: s
s bs :: ByteString
bs =
               case (Word8 -> Bool) -> ByteString -> Maybe Int
ByteString.findIndex Word8 -> Bool
byteStartsCharacter (ByteString -> ByteString
unsafeTail ByteString
bs)
               of Nothing -> case s -> ByteStringUTF8 -> Maybe s
f s
s (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs)
                             of Just s1 :: s
s1 -> (ByteString
ByteString.empty, s
s1)
                                Nothing -> (ByteString
bs, s
s)
                  Just i :: Int
i -> let (hd :: ByteString
hd, tl :: ByteString
tl) = Int -> ByteString -> (ByteString, ByteString)
ByteString.splitAt (Int -> Int
forall a. Enum a => a -> a
succ Int
i) ByteString
bs
                            in case s -> ByteStringUTF8 -> Maybe s
f s
s (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
hd)
                               of Just s1 :: s
s1 -> s -> ByteString -> (ByteString, s)
dropASCII s
s1 ByteString
tl
                                  Nothing -> (ByteString
bs, s
s)
   {-# INLINE spanMaybe #-}
   spanMaybe' :: s
-> (s -> ByteStringUTF8 -> Maybe s)
-> ByteStringUTF8
-> (ByteStringUTF8, ByteStringUTF8, s)
spanMaybe' s0 :: s
s0 f :: s -> ByteStringUTF8 -> Maybe s
f (ByteStringUTF8 bs0 :: ByteString
bs0) = (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$
                                           Int -> ByteString -> ByteString
ByteString.take (ByteString -> Int
ByteString.length ByteString
bs0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
dropped) ByteString
bs0,
                                           ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
dropped,
                                           s
s')
      where (dropped :: ByteString
dropped, s' :: s
s') = s -> ByteString -> (ByteString, s)
dropASCII s
s0 ByteString
bs0
            dropASCII :: s -> ByteString -> (ByteString, s)
dropASCII s :: s
s bs :: ByteString
bs =
               let suffix :: ByteString
suffix = Int -> ByteString -> ByteString
ByteString.drop Int
index ByteString
bs
                   (index :: Int
index, s1 :: s
s1) = (Word8 -> ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s))
-> ((Int, s) -> (Int, s)) -> ByteString -> (Int, s) -> (Int, s)
forall a. (Word8 -> a -> a) -> a -> ByteString -> a
ByteString.foldr Word8 -> ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s)
f8 (Int, s) -> (Int, s)
forall a. a -> a
id ByteString
bs (0, s
s)
                   f8 :: Word8 -> ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s)
f8 w :: Word8
w cont :: (Int, s) -> (Int, s)
cont (i :: Int
i, s2 :: s
s2)
                     | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80, Just s3 :: s
s3 <- s -> ByteStringUTF8 -> Maybe s
f s
s2 (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString
ByteString.singleton Word8
w) =
                         let i' :: Int
i' = Int -> Int
forall a. Enum a => a -> a
succ Int
i :: Int in Int -> (Int, s) -> (Int, s)
forall a b. a -> b -> b
seq Int
i' ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s)
forall a b. (a -> b) -> a -> b
$ s -> (Int, s) -> (Int, s)
forall a b. a -> b -> b
seq s
s3 ((Int, s) -> (Int, s)) -> (Int, s) -> (Int, s)
forall a b. (a -> b) -> a -> b
$ (Int, s) -> (Int, s)
cont (Int
i', s
s3)
                     | Bool
otherwise = (Int
i, s
s)
               in if ByteString -> Bool
ByteString.null ByteString
suffix Bool -> Bool -> Bool
|| ByteString -> Word8
unsafeHead ByteString
suffix Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80
                  then (ByteString
suffix, s
s1)
                  else s -> ByteString -> (ByteString, s)
dropMultiByte s
s1 ByteString
suffix
            dropMultiByte :: s -> ByteString -> (ByteString, s)
dropMultiByte s :: s
s bs :: ByteString
bs =
               case (Word8 -> Bool) -> ByteString -> Maybe Int
ByteString.findIndex Word8 -> Bool
byteStartsCharacter (ByteString -> ByteString
unsafeTail ByteString
bs)
               of Nothing -> case s -> ByteStringUTF8 -> Maybe s
f s
s (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs)
                             of Just s1 :: s
s1 -> s -> (ByteString, s) -> (ByteString, s)
forall a b. a -> b -> b
seq s
s1 (ByteString
ByteString.empty, s
s1)
                                Nothing -> (ByteString
bs, s
s)
                  Just i :: Int
i -> let (hd :: ByteString
hd, tl :: ByteString
tl) = Int -> ByteString -> (ByteString, ByteString)
ByteString.splitAt (Int -> Int
forall a. Enum a => a -> a
succ Int
i) ByteString
bs
                            in case s -> ByteStringUTF8 -> Maybe s
f s
s (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
hd)
                               of Just s1 :: s
s1 -> s -> (ByteString, s) -> (ByteString, s)
forall a b. a -> b -> b
seq s
s1 (s -> ByteString -> (ByteString, s)
dropASCII s
s1 ByteString
tl)
                                  Nothing -> (ByteString
bs, s
s)
   {-# INLINE spanMaybe' #-}

instance TextualMonoid ByteStringUTF8 where
   singleton :: Char -> ByteStringUTF8
singleton = ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8)
-> (Char -> ByteString) -> Char -> ByteStringUTF8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ByteString
fromChar
   {-# INLINE singleton #-}
   splitCharacterPrefix :: ByteStringUTF8 -> Maybe (Char, ByteStringUTF8)
splitCharacterPrefix (ByteStringUTF8 bs :: ByteString
bs) = ByteString -> Maybe (Word8, ByteString)
ByteString.uncons ByteString
bs Maybe (Word8, ByteString)
-> ((Word8, ByteString) -> Maybe (Char, ByteStringUTF8))
-> Maybe (Char, ByteStringUTF8)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Word8 -> ByteString -> Maybe (Char, ByteStringUTF8))
-> (Word8, ByteString) -> Maybe (Char, ByteStringUTF8)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Word8 -> ByteString -> Maybe (Char, ByteStringUTF8)
toChar
   {-# INLINE splitCharacterPrefix #-}
   foldl :: (a -> ByteStringUTF8 -> a)
-> (a -> Char -> a) -> a -> ByteStringUTF8 -> a
foldl ft :: a -> ByteStringUTF8 -> a
ft fc :: a -> Char -> a
fc a0 :: a
a0 (ByteStringUTF8 bs :: ByteString
bs) = case ((a, [Word8]) -> Char -> (a, [Word8]))
-> (a, [Word8]) -> ByteString -> (a, [Word8])
forall a. (a -> Char -> a) -> a -> ByteString -> a
ByteString.Char8.foldl (a, [Word8]) -> Char -> (a, [Word8])
f (a
a0, []) ByteString
bs
                                        of (a :: a
a, []) -> a
a
                                           (a :: a
a, acc :: [Word8]
acc) -> a -> [Word8] -> a
multiByte a
a [Word8]
acc
      where f :: (a, [Word8]) -> Char -> (a, [Word8])
f (a :: a
a, []) c :: Char
c | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x80' = (a -> Char -> a
fc a
a Char
c, [])
                        | Bool
otherwise = (a
a, [Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
c])
            f (a :: a
a, acc :: [Word8]
acc) c :: Char
c | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x80' = (a -> Char -> a
fc (a -> [Word8] -> a
multiByte a
a [Word8]
acc) Char
c, [])
                         | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\xC0' = (a
a, Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c) Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: [Word8]
acc)
                         | Bool
otherwise = (a -> [Word8] -> a
multiByte a
a [Word8]
acc, [Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
c])
            multiByte :: a -> [Word8] -> a
multiByte a :: a
a acc :: [Word8]
acc = (ByteString -> a) -> (Char -> a) -> [Word8] -> a
forall a. (ByteString -> a) -> (Char -> a) -> [Word8] -> a
reverseBytesToChar (a -> ByteStringUTF8 -> a
ft a
a (ByteStringUTF8 -> a)
-> (ByteString -> ByteStringUTF8) -> ByteString -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteStringUTF8
ByteStringUTF8) (a -> Char -> a
fc a
a) [Word8]
acc
   {-# INLINE foldl #-}
   foldl' :: (a -> ByteStringUTF8 -> a)
-> (a -> Char -> a) -> a -> ByteStringUTF8 -> a
foldl' ft :: a -> ByteStringUTF8 -> a
ft fc :: a -> Char -> a
fc a0 :: a
a0 (ByteStringUTF8 bs :: ByteString
bs) = case ((a, [Word8]) -> Char -> (a, [Word8]))
-> (a, [Word8]) -> ByteString -> (a, [Word8])
forall a. (a -> Char -> a) -> a -> ByteString -> a
ByteString.Char8.foldl' (a, [Word8]) -> Char -> (a, [Word8])
f (a
a0, []) ByteString
bs
                                         of (a :: a
a, []) -> a
a
                                            (a :: a
a, acc :: [Word8]
acc) -> a -> [Word8] -> a
multiByte a
a [Word8]
acc
      where f :: (a, [Word8]) -> Char -> (a, [Word8])
f (a :: a
a, []) c :: Char
c | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x80' = (a -> Char -> a
fc a
a Char
c, [])
                        | Bool
otherwise = a -> (a, [Word8]) -> (a, [Word8])
forall a b. a -> b -> b
seq a
a (a
a, [Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
c])
            f (a :: a
a, acc :: [Word8]
acc) c :: Char
c | a -> Char -> Char
forall a b. a -> b -> b
seq a
a Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x80' = let a' :: a
a' = a -> [Word8] -> a
multiByte a
a [Word8]
acc in a -> (a, [Word8]) -> (a, [Word8])
forall a b. a -> b -> b
seq a
a' (a -> Char -> a
fc a
a' Char
c, [])
                         | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\xC0' = (a
a, Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c) Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: [Word8]
acc)
                         | Bool
otherwise = let a' :: a
a' = a -> [Word8] -> a
multiByte a
a [Word8]
acc in a -> (a, [Word8]) -> (a, [Word8])
forall a b. a -> b -> b
seq a
a' (a
a', [Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
c])
            multiByte :: a -> [Word8] -> a
multiByte a :: a
a acc :: [Word8]
acc = (ByteString -> a) -> (Char -> a) -> [Word8] -> a
forall a. (ByteString -> a) -> (Char -> a) -> [Word8] -> a
reverseBytesToChar (a -> ByteStringUTF8 -> a
ft a
a (ByteStringUTF8 -> a)
-> (ByteString -> ByteStringUTF8) -> ByteString -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteStringUTF8
ByteStringUTF8) (a -> Char -> a
fc a
a) [Word8]
acc
   {-# INLINE foldl' #-}
   foldr :: (ByteStringUTF8 -> a -> a)
-> (Char -> a -> a) -> a -> ByteStringUTF8 -> a
foldr ft :: ByteStringUTF8 -> a -> a
ft fc :: Char -> a -> a
fc a0 :: a
a0 (ByteStringUTF8 bs :: ByteString
bs) = case (Char -> (a, [Word8]) -> (a, [Word8]))
-> (a, [Word8]) -> ByteString -> (a, [Word8])
forall a. (Char -> a -> a) -> a -> ByteString -> a
ByteString.Char8.foldr Char -> (a, [Word8]) -> (a, [Word8])
f (a
a0, []) ByteString
bs
                                        of (a :: a
a, []) -> a
a
                                           (a :: a
a, acc :: [Word8]
acc) -> a -> [Word8] -> a
multiByte a
a [Word8]
acc
      where f :: Char -> (a, [Word8]) -> (a, [Word8])
f c :: Char
c (a :: a
a, []) | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x80' = (Char -> a -> a
fc Char
c a
a, [])
                        | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\xC0' = (a
a, [Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
c])
                        | Bool
otherwise = (ByteStringUTF8 -> a -> a
ft (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Char -> ByteString
ByteString.Char8.singleton Char
c) a
a, [])
            f c :: Char
c (a :: a
a, acc :: [Word8]
acc) | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x80' = (Char -> a -> a
fc Char
c (ByteStringUTF8 -> a -> a
ft (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ [Word8] -> ByteString
ByteString.pack [Word8]
acc) a
a), [])
                         | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\xC0' = (a
a, Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c) Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: [Word8]
acc)
                         | Bool
otherwise = (a -> [Word8] -> a
multiByte a
a (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c) Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: [Word8]
acc), [])
            multiByte :: a -> [Word8] -> a
multiByte a :: a
a acc :: [Word8]
acc = (ByteString -> a) -> (Char -> a) -> [Word8] -> a
forall a. (ByteString -> a) -> (Char -> a) -> [Word8] -> a
bytesToChar ((ByteStringUTF8 -> a -> a
`ft` a
a) (ByteStringUTF8 -> a)
-> (ByteString -> ByteStringUTF8) -> ByteString -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteStringUTF8
ByteStringUTF8) (Char -> a -> a
`fc` a
a) [Word8]
acc
   {-# INLINE foldr #-}
   dropWhile :: (ByteStringUTF8 -> Bool)
-> (Char -> Bool) -> ByteStringUTF8 -> ByteStringUTF8
dropWhile pb :: ByteStringUTF8 -> Bool
pb pc :: Char -> Bool
pc (ByteStringUTF8 bs :: ByteString
bs) = ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
dropASCII ByteString
bs
      where dropASCII :: ByteString -> ByteString
dropASCII rest :: ByteString
rest = case (Char -> Bool) -> ByteString -> Maybe Int
ByteString.Char8.findIndex (\c :: Char
c-> Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
> '\x7f' Bool -> Bool -> Bool
|| Bool -> Bool
not (Char -> Bool
pc Char
c)) ByteString
rest
                             of Nothing -> ByteString
ByteString.empty
                                Just j :: Int
j -> let rest' :: ByteString
rest' = Int -> ByteString -> ByteString
unsafeDrop Int
j ByteString
rest
                                          in if ByteString -> Word8
unsafeHead ByteString
rest' Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
> 0x7f
                                             then ByteString -> ByteString
dropMultiByte ByteString
rest'
                                             else ByteString
rest'
            dropMultiByte :: ByteString -> ByteString
dropMultiByte rest :: ByteString
rest = case ByteStringUTF8 -> Maybe (Char, ByteStringUTF8)
forall t. TextualMonoid t => t -> Maybe (Char, t)
splitCharacterPrefix (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
rest)
                                 of Just (c :: Char
c, ByteStringUTF8 rest' :: ByteString
rest') | Char -> Bool
pc Char
c -> ByteString -> ByteString
dropASCII ByteString
rest'
                                    Nothing -> let j :: Int
j = Int -> Int
forall a. Enum a => a -> a
succ (ByteString -> Int
headIndex (ByteString -> Int) -> ByteString -> Int
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
forall m. FactorialMonoid m => Int -> m -> m
drop 1 ByteString
rest)
                                               in if ByteStringUTF8 -> Bool
pb (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
ByteString.take Int
j ByteString
rest)
                                                  then ByteString -> ByteString
dropASCII (Int -> ByteString -> ByteString
unsafeDrop Int
j ByteString
rest)
                                                  else ByteString
rest
                                    _ -> ByteString
rest
   {-# INLINE dropWhile #-}
   takeWhile :: (ByteStringUTF8 -> Bool)
-> (Char -> Bool) -> ByteStringUTF8 -> ByteStringUTF8
takeWhile pb :: ByteStringUTF8 -> Bool
pb pc :: Char -> Bool
pc utf8 :: ByteStringUTF8
utf8@(ByteStringUTF8 bs :: ByteString
bs) =
      ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeTake (ByteString -> Int
ByteString.length ByteString
bs Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
suffix) ByteString
bs
      where ByteStringUTF8 suffix :: ByteString
suffix = (ByteStringUTF8 -> Bool)
-> (Char -> Bool) -> ByteStringUTF8 -> ByteStringUTF8
forall t.
TextualMonoid t =>
(t -> Bool) -> (Char -> Bool) -> t -> t
Textual.dropWhile ByteStringUTF8 -> Bool
pb Char -> Bool
pc ByteStringUTF8
utf8
   {-# INLINE takeWhile #-}
   span :: (ByteStringUTF8 -> Bool)
-> (Char -> Bool)
-> ByteStringUTF8
-> (ByteStringUTF8, ByteStringUTF8)
span pb :: ByteStringUTF8 -> Bool
pb pc :: Char -> Bool
pc utf8 :: ByteStringUTF8
utf8@(ByteStringUTF8 bs :: ByteString
bs) = (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeTake (ByteString -> Int
ByteString.length ByteString
bs Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
suffix') ByteString
bs, ByteStringUTF8
suffix)
      where suffix :: ByteStringUTF8
suffix@(ByteStringUTF8 suffix' :: ByteString
suffix') = (ByteStringUTF8 -> Bool)
-> (Char -> Bool) -> ByteStringUTF8 -> ByteStringUTF8
forall t.
TextualMonoid t =>
(t -> Bool) -> (Char -> Bool) -> t -> t
Textual.dropWhile ByteStringUTF8 -> Bool
pb Char -> Bool
pc ByteStringUTF8
utf8
   {-# INLINE span #-}
   break :: (ByteStringUTF8 -> Bool)
-> (Char -> Bool)
-> ByteStringUTF8
-> (ByteStringUTF8, ByteStringUTF8)
break pb :: ByteStringUTF8 -> Bool
pb pc :: Char -> Bool
pc = (ByteStringUTF8 -> Bool)
-> (Char -> Bool)
-> ByteStringUTF8
-> (ByteStringUTF8, ByteStringUTF8)
forall t.
TextualMonoid t =>
(t -> Bool) -> (Char -> Bool) -> t -> (t, t)
Textual.span (Bool -> Bool
not (Bool -> Bool)
-> (ByteStringUTF8 -> Bool) -> ByteStringUTF8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStringUTF8 -> Bool
pb) (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
pc)
   {-# INLINE break #-}
   spanMaybe :: s
-> (s -> ByteStringUTF8 -> Maybe s)
-> (s -> Char -> Maybe s)
-> ByteStringUTF8
-> (ByteStringUTF8, ByteStringUTF8, s)
spanMaybe s0 :: s
s0 ft :: s -> ByteStringUTF8 -> Maybe s
ft fc :: s -> Char -> Maybe s
fc (ByteStringUTF8 bs :: ByteString
bs)  =
      let inner :: Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner i :: Int
i s :: s
s
            | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len =
                let w :: Word8
w = ByteString -> Int -> Word8
unsafeIndex ByteString
bs Int
i
                in if Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80
                   then case s -> Char -> Maybe s
fc s
s (Word8 -> Char
w2c Word8
w)
                        of Just s' :: s
s' -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) s
s'
                           Nothing -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
forall c. Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done Int
i s
s
                   else case ByteStringUTF8 -> Maybe (Char, ByteStringUTF8)
forall t. TextualMonoid t => t -> Maybe (Char, t)
splitCharacterPrefix (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeDrop Int
i ByteString
bs)
                        of Just (c :: Char
c, ByteStringUTF8 rest :: ByteString
rest) | Just s' :: s
s' <- s -> Char -> Maybe s
fc s
s Char
c -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
rest) s
s'
                           Nothing -> let j :: Int
j = Int -> Int
forall a. Enum a => a -> a
succ (ByteString -> Int
headIndex (ByteString -> Int) -> ByteString -> Int
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
forall m. FactorialMonoid m => Int -> m -> m
drop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) ByteString
bs)
                                      in case s -> ByteStringUTF8 -> Maybe s
ft s
s (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
ByteString.take Int
j (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeDrop Int
i ByteString
bs)
                                         of Just s' :: s
s' -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
j) s
s'
                                            Nothing -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
forall c. Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done Int
i s
s
                           _ -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
forall c. Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done Int
i s
s
            | Bool
otherwise = Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
forall c. Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done Int
i s
s
          done :: Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done i :: Int
i s :: c
s = Int
i Int
-> (ByteStringUTF8, ByteStringUTF8, c)
-> (ByteStringUTF8, ByteStringUTF8, c)
forall a b. a -> b -> b
`seq` c
s c
-> (ByteStringUTF8, ByteStringUTF8, c)
-> (ByteStringUTF8, ByteStringUTF8, c)
forall a b. a -> b -> b
`seq` (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeTake Int
i ByteString
bs, ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeDrop Int
i ByteString
bs, c
s)
          len :: Int
len = ByteString -> Int
ByteString.length ByteString
bs
      in Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner 0 s
s0
   {-# INLINE spanMaybe #-}
   spanMaybe' :: s
-> (s -> ByteStringUTF8 -> Maybe s)
-> (s -> Char -> Maybe s)
-> ByteStringUTF8
-> (ByteStringUTF8, ByteStringUTF8, s)
spanMaybe' s0 :: s
s0 ft :: s -> ByteStringUTF8 -> Maybe s
ft fc :: s -> Char -> Maybe s
fc (ByteStringUTF8 bs :: ByteString
bs)  =
      let inner :: Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner i :: Int
i s :: s
s
            | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len =
                s
s s
-> (ByteStringUTF8, ByteStringUTF8, s)
-> (ByteStringUTF8, ByteStringUTF8, s)
forall a b. a -> b -> b
`seq`
                let w :: Word8
w = ByteString -> Int -> Word8
unsafeIndex ByteString
bs Int
i
                in if Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80
                   then case s -> Char -> Maybe s
fc s
s (Word8 -> Char
w2c Word8
w)
                        of Just s' :: s
s' -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) s
s'
                           Nothing -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
forall c. Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done Int
i s
s
                   else case ByteStringUTF8 -> Maybe (Char, ByteStringUTF8)
forall t. TextualMonoid t => t -> Maybe (Char, t)
splitCharacterPrefix (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeDrop Int
i ByteString
bs)
                        of Just (c :: Char
c, ByteStringUTF8 rest :: ByteString
rest) | Just s' :: s
s' <- s -> Char -> Maybe s
fc s
s Char
c -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
rest) s
s'
                           Nothing -> let j :: Int
j = Int -> Int
forall a. Enum a => a -> a
succ (ByteString -> Int
headIndex (ByteString -> Int) -> ByteString -> Int
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
forall m. FactorialMonoid m => Int -> m -> m
drop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) ByteString
bs)
                                      in case s -> ByteStringUTF8 -> Maybe s
ft s
s (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
ByteString.take Int
j (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeDrop Int
i ByteString
bs)
                                         of Just s' :: s
s' -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
j) s
s'
                                            Nothing -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
forall c. Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done Int
i s
s
                           _ -> Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
forall c. Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done Int
i s
s
            | Bool
otherwise = Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
forall c. Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done Int
i s
s
          done :: Int -> c -> (ByteStringUTF8, ByteStringUTF8, c)
done i :: Int
i s :: c
s = Int
i Int
-> (ByteStringUTF8, ByteStringUTF8, c)
-> (ByteStringUTF8, ByteStringUTF8, c)
forall a b. a -> b -> b
`seq` c
s c
-> (ByteStringUTF8, ByteStringUTF8, c)
-> (ByteStringUTF8, ByteStringUTF8, c)
forall a b. a -> b -> b
`seq` (ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeTake Int
i ByteString
bs, ByteString -> ByteStringUTF8
ByteStringUTF8 (ByteString -> ByteStringUTF8) -> ByteString -> ByteStringUTF8
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
unsafeDrop Int
i ByteString
bs, c
s)
          len :: Int
len = ByteString -> Int
ByteString.length ByteString
bs
      in Int -> s -> (ByteStringUTF8, ByteStringUTF8, s)
inner 0 s
s0
   {-# INLINE spanMaybe' #-}
   find :: (Char -> Bool) -> ByteStringUTF8 -> Maybe Char
find p :: Char -> Bool
p (ByteStringUTF8 bs0 :: ByteString
bs0) = ByteString -> Maybe Char
loop ByteString
bs0
      where loop :: ByteString -> Maybe Char
loop bs :: ByteString
bs = case (Char -> Bool) -> ByteString -> Maybe Int
ByteString.Char8.findIndex (\c :: Char
c-> Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= '\x80' Bool -> Bool -> Bool
|| Char -> Bool
p Char
c) ByteString
bs
                      of Nothing -> Maybe Char
forall a. Maybe a
Nothing
                         Just i :: Int
i -> let x :: Word8
x = ByteString -> Int -> Word8
unsafeIndex ByteString
bs Int
i
                                       bs' :: ByteString
bs' = Int -> ByteString -> ByteString
unsafeDrop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) ByteString
bs
                                   in if Word8
x Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80
                                      then Char -> Maybe Char
forall a. a -> Maybe a
Just (Word8 -> Char
w2c Word8
x)
                                      else case Word8 -> ByteString -> Maybe (Char, ByteStringUTF8)
toChar Word8
x ByteString
bs'
                                           of Just (c :: Char
c, ByteStringUTF8 rest :: ByteString
rest) | Char -> Bool
p Char
c -> Char -> Maybe Char
forall a. a -> Maybe a
Just Char
c
                                                                            | Bool
otherwise -> ByteString -> Maybe Char
loop ByteString
rest
                                              Nothing -> ByteString -> Maybe Char
loop ((Word8 -> Bool) -> ByteString -> ByteString
ByteString.dropWhile (Bool -> Bool
not (Bool -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Bool
byteStartsCharacter) ByteString
bs')
   {-# INLINE find #-}
   any :: (Char -> Bool) -> ByteStringUTF8 -> Bool
any p :: Char -> Bool
p utf8 :: ByteStringUTF8
utf8 = Maybe Char -> Bool
forall a. Maybe a -> Bool
isJust ((Char -> Bool) -> ByteStringUTF8 -> Maybe Char
forall t. TextualMonoid t => (Char -> Bool) -> t -> Maybe Char
find Char -> Bool
p ByteStringUTF8
utf8)
   {-# INLINE any #-}
   all :: (Char -> Bool) -> ByteStringUTF8 -> Bool
all p :: Char -> Bool
p utf8 :: ByteStringUTF8
utf8 = Maybe Char -> Bool
forall a. Maybe a -> Bool
isNothing ((Char -> Bool) -> ByteStringUTF8 -> Maybe Char
forall t. TextualMonoid t => (Char -> Bool) -> t -> Maybe Char
find (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
p) ByteStringUTF8
utf8)
   {-# INLINE all #-}
   elem :: Char -> ByteStringUTF8 -> Bool
elem c :: Char
c utf8 :: ByteStringUTF8
utf8@(ByteStringUTF8 bs :: ByteString
bs)
     | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x80' = Char -> ByteString -> Bool
ByteString.Char8.elem Char
c ByteString
bs
     | Bool
otherwise = (Char -> Bool) -> ByteStringUTF8 -> Bool
forall t. TextualMonoid t => (Char -> Bool) -> t -> Bool
any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
c) ByteStringUTF8
utf8
   {-# INLINE elem #-}

reverseBytesToChar :: (ByteString -> a) -> (Char -> a) -> [Word8] -> a
reverseBytesToChar :: (ByteString -> a) -> (Char -> a) -> [Word8] -> a
reverseBytesToChar ft :: ByteString -> a
ft fc :: Char -> a
fc [w :: Word8
w] = if Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 then Char -> a
fc (Word8 -> Char
w2c Word8
w) else ByteString -> a
ft (Word8 -> ByteString
ByteString.singleton Word8
w)
reverseBytesToChar ft :: ByteString -> a
ft fc :: Char -> a
fc [b0 :: Word8
b0, b1 :: Word8
b1] =
  Bool -> a -> a
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b0 Bool -> Bool -> Bool
&& Word8
b0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0) (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$
  if 0xC2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b1 Bool -> Bool -> Bool
&& Word8
b1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xE0
  then Char -> a
fc (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x1F) 6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F))
  else ByteString -> a
ft ([Word8] -> ByteString
ByteString.pack [Word8
b1, Word8
b0])
reverseBytesToChar ft :: ByteString -> a
ft fc :: Char -> a
fc [b0 :: Word8
b0, b1 :: Word8
b1, b2 :: Word8
b2] =
  Bool -> a -> a
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b0 Bool -> Bool -> Bool
&& Word8
b0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0 Bool -> Bool -> Bool
&& 0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b1 Bool -> Bool -> Bool
&& Word8
b1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0) (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$
  if (0xE0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
b2 Bool -> Bool -> Bool
|| 0xE0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
b2 Bool -> Bool -> Bool
&& 0xA0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b1) Bool -> Bool -> Bool
&& Word8
b2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF0
  then Char -> a
fc (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b2 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0xF) 12
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 6
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F))
  else ByteString -> a
ft ([Word8] -> ByteString
ByteString.pack [Word8
b2, Word8
b1, Word8
b0])
reverseBytesToChar ft :: ByteString -> a
ft fc :: Char -> a
fc [b0 :: Word8
b0, b1 :: Word8
b1, b2 :: Word8
b2, b3 :: Word8
b3] =
  Bool -> a -> a
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b0 Bool -> Bool -> Bool
&& Word8
b0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0 Bool -> Bool -> Bool
&& 0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b1 Bool -> Bool -> Bool
&& Word8
b1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0 Bool -> Bool -> Bool
&& 0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b2 Bool -> Bool -> Bool
&& Word8
b2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0) (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$
  if (0xF0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
b3 Bool -> Bool -> Bool
|| 0xF0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
b3 Bool -> Bool -> Bool
&& 0x90 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b2) Bool -> Bool -> Bool
&& Word8
b3 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF5 Bool -> Bool -> Bool
&& (Word8
b3 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF4 Bool -> Bool -> Bool
|| Word8
b2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x90)
  then Char -> a
fc (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b3 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x7) 18
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b2 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 12
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 6
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F))
  else ByteString -> a
ft ([Word8] -> ByteString
ByteString.pack [Word8
b3, Word8
b2, Word8
b1, Word8
b0])
reverseBytesToChar ft :: ByteString -> a
ft _fc :: Char -> a
_fc bytes :: [Word8]
bytes = ByteString -> a
ft (ByteString -> ByteString
ByteString.reverse (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ [Word8] -> ByteString
ByteString.pack [Word8]
bytes)

bytesToChar :: (ByteString -> a) -> (Char -> a) -> [Word8] -> a
bytesToChar :: (ByteString -> a) -> (Char -> a) -> [Word8] -> a
bytesToChar ft :: ByteString -> a
ft fc :: Char -> a
fc [w :: Word8
w] = if Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 then Char -> a
fc (Word8 -> Char
w2c Word8
w) else ByteString -> a
ft (Word8 -> ByteString
ByteString.singleton Word8
w)
bytesToChar ft :: ByteString -> a
ft fc :: Char -> a
fc bytes :: [Word8]
bytes@[b1 :: Word8
b1, b0 :: Word8
b0] =
  Bool -> a -> a
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b0 Bool -> Bool -> Bool
&& Word8
b0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0) (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$
  if 0xC2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b1 Bool -> Bool -> Bool
&& Word8
b1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xE0
  then Char -> a
fc (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x1F) 6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F))
  else ByteString -> a
ft ([Word8] -> ByteString
ByteString.pack [Word8]
bytes)
bytesToChar ft :: ByteString -> a
ft fc :: Char -> a
fc bytes :: [Word8]
bytes@[b2 :: Word8
b2, b1 :: Word8
b1, b0 :: Word8
b0] =
  Bool -> a -> a
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b0 Bool -> Bool -> Bool
&& Word8
b0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0 Bool -> Bool -> Bool
&& 0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b1 Bool -> Bool -> Bool
&& Word8
b1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0) (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$
  if (0xE0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
b2 Bool -> Bool -> Bool
|| 0xE0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
b2 Bool -> Bool -> Bool
&& 0xA0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b1) Bool -> Bool -> Bool
&& Word8
b2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF0
  then Char -> a
fc (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b2 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0xF) 12
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 6
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F))
  else ByteString -> a
ft ([Word8] -> ByteString
ByteString.pack [Word8]
bytes)
bytesToChar ft :: ByteString -> a
ft fc :: Char -> a
fc bytes :: [Word8]
bytes@[b3 :: Word8
b3, b2 :: Word8
b2, b1 :: Word8
b1, b0 :: Word8
b0] =
  Bool -> a -> a
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b0 Bool -> Bool -> Bool
&& Word8
b0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0 Bool -> Bool -> Bool
&& 0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b1 Bool -> Bool -> Bool
&& Word8
b1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0 Bool -> Bool -> Bool
&& 0x80 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b2 Bool -> Bool -> Bool
&& Word8
b2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0) (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$
  if (0xF0 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
b3 Bool -> Bool -> Bool
|| 0xF0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
b3 Bool -> Bool -> Bool
&& 0x90 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
b2) Bool -> Bool -> Bool
&& Word8
b3 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF5 Bool -> Bool -> Bool
&& (Word8
b3 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF4 Bool -> Bool -> Bool
|| Word8
b2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x90)
  then Char -> a
fc (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b3 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x7) 18
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b2 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 12
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 6
                Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F))
  else ByteString -> a
ft ([Word8] -> ByteString
ByteString.pack [Word8]
bytes)
bytesToChar ft :: ByteString -> a
ft _fc :: Char -> a
_fc bytes :: [Word8]
bytes = ByteString -> a
ft ([Word8] -> ByteString
ByteString.pack [Word8]
bytes)

wrapPair :: (ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
wrapPair :: (ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8)
wrapPair (bs1 :: ByteString
bs1, bs2 :: ByteString
bs2) = (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs1, ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs2)
{-# INLINE wrapPair #-}

wrapTriple :: (ByteString, ByteString, ByteString) -> (ByteStringUTF8, ByteStringUTF8, ByteStringUTF8)
wrapTriple :: (ByteString, ByteString, ByteString)
-> (ByteStringUTF8, ByteStringUTF8, ByteStringUTF8)
wrapTriple (bs1 :: ByteString
bs1, bs2 :: ByteString
bs2, bs3 :: ByteString
bs3) = (ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs1, ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs2, ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
bs3)
{-# INLINE wrapTriple #-}

fromChar :: Char -> ByteString
fromChar :: Char -> ByteString
fromChar c :: Char
c | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x80'    = Char -> ByteString
ByteString.Char8.singleton Char
c
           | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x800'   = [Word8] -> ByteString
ByteString.pack [0xC0 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftR Int
n 6),
                                              0x80 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F)]
           | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< '\x10000' = [Word8] -> ByteString
ByteString.pack [0xE0 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftR Int
n 12),
                                              0x80 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftR Int
n 6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F),
                                              0x80 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F)]
           | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0x200000  = [Word8] -> ByteString
ByteString.pack [0xF0 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftR Int
n 18),
                                              0x80 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftR Int
n 12 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F),
                                              0x80 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftR Int
n 6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F),
                                              0x80 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F)]
           | Bool
otherwise  = String -> ByteString
forall a. (?callStack::CallStack) => String -> a
error ("Data.Char.ord '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Char
c Char -> ShowS
forall a. a -> [a] -> [a]
: "' >=0x200000"))
   where n :: Int
n = Char -> Int
ord Char
c

toChar :: Word8 -> ByteString -> Maybe (Char, ByteStringUTF8)
toChar :: Word8 -> ByteString -> Maybe (Char, ByteStringUTF8)
toChar hd :: Word8
hd tl :: ByteString
tl | Word8
hd Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (Char, ByteStringUTF8) -> Maybe (Char, ByteStringUTF8)
forall a. a -> Maybe a
Just (Word8 -> Char
w2c Word8
hd, ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
tl)
             | Word8
hd Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC2 = Maybe (Char, ByteStringUTF8)
forall a. Maybe a
Nothing
             | Word8
hd Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xE0 = do (b0 :: Word8
b0, t0 :: ByteString
t0) <- ByteString -> Maybe (Word8, ByteString)
ByteString.uncons ByteString
tl
                              if ByteString -> Int
headIndex ByteString
tl Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1
                                 then (Char, ByteStringUTF8) -> Maybe (Char, ByteStringUTF8)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
hd Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x1F) 6
                                                   Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F),
                                              ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
t0)
                                 else Maybe (Char, ByteStringUTF8)
forall a. Maybe a
Nothing
             | Word8
hd Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF0 = do (b1 :: Word8
b1, t1 :: ByteString
t1) <- ByteString -> Maybe (Word8, ByteString)
ByteString.uncons ByteString
tl
                              (b0 :: Word8
b0, t0 :: ByteString
t0) <- ByteString -> Maybe (Word8, ByteString)
ByteString.uncons ByteString
t1
                              if (Word8
hd Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
> 0xE0 Bool -> Bool -> Bool
|| Word8
b1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= 0xA0) Bool -> Bool -> Bool
&& ByteString -> Int
headIndex ByteString
tl Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 2
                                 then (Char, ByteStringUTF8) -> Maybe (Char, ByteStringUTF8)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
hd Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0xF) 12
                                                   Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 6
                                                   Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F),
                                              ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
t0)
                                 else Maybe (Char, ByteStringUTF8)
forall a. Maybe a
Nothing
             | Word8
hd Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF5 = do (b2 :: Word8
b2, t2 :: ByteString
t2) <- ByteString -> Maybe (Word8, ByteString)
ByteString.uncons ByteString
tl
                              (b1 :: Word8
b1, t1 :: ByteString
t1) <- ByteString -> Maybe (Word8, ByteString)
ByteString.uncons ByteString
t2
                              (b0 :: Word8
b0, t0 :: ByteString
t0) <- ByteString -> Maybe (Word8, ByteString)
ByteString.uncons ByteString
t1
                              if (Word8
hd Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
> 0xF0 Bool -> Bool -> Bool
|| Word8
b2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= 0x90) Bool -> Bool -> Bool
&& (Word8
hd Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0xF4 Bool -> Bool -> Bool
|| Word8
b2 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x90) Bool -> Bool -> Bool
&& ByteString -> Int
headIndex ByteString
tl Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 3
                                 then (Char, ByteStringUTF8) -> Maybe (Char, ByteStringUTF8)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
hd Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x7) 18
                                                   Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b2 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 12
                                                   Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F) 6
                                                   Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 0x3F),
                                              ByteString -> ByteStringUTF8
ByteStringUTF8 ByteString
t0)
                                 else Maybe (Char, ByteStringUTF8)
forall a. Maybe a
Nothing
             | Bool
otherwise = Maybe (Char, ByteStringUTF8)
forall a. Maybe a
Nothing

groupASCII :: ByteString -> [ByteString]
groupASCII :: ByteString -> [ByteString]
groupASCII = (Word8 -> Word8 -> Bool) -> ByteString -> [ByteString]
ByteString.groupBy Word8 -> Word8 -> Bool
forall a a. (Ord a, Ord a, Num a, Num a) => a -> a -> Bool
continued
   where continued :: a -> a -> Bool
continued a :: a
a b :: a
b = (a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80) Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== (a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80) Bool -> Bool -> Bool
&& a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0
{-# INLINE groupASCII #-}

headIndex :: ByteString -> Int
headIndex :: ByteString -> Int
headIndex bs :: ByteString
bs = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (ByteString -> Int
ByteString.length ByteString
bs) (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ (Word8 -> Bool) -> ByteString -> Maybe Int
ByteString.findIndex Word8 -> Bool
byteStartsCharacter ByteString
bs
{-# INLINE headIndex #-}

byteStartsCharacter :: Word8 -> Bool
byteStartsCharacter :: Word8 -> Bool
byteStartsCharacter b :: Word8
b = Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= 0xC0
{-# INLINE byteStartsCharacter #-}

charStartIndex :: Int -> ByteString -> Int
charStartIndex :: Int -> ByteString -> Int
charStartIndex n :: Int
n _ | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0 = 0
charStartIndex n0 :: Int
n0 bs :: ByteString
bs = (Word8 -> ((Int, Bool, Int) -> Int) -> (Int, Bool, Int) -> Int)
-> ((Int, Bool, Int) -> Int)
-> ByteString
-> (Int, Bool, Int)
-> Int
forall a. (Word8 -> a -> a) -> a -> ByteString -> a
ByteString.foldr Word8 -> ((Int, Bool, Int) -> Int) -> (Int, Bool, Int) -> Int
forall a a a.
(Ord a, Num a, Num a, Enum a, Enum a, Eq a) =>
a -> ((a, Bool, a) -> a) -> (a, Bool, a) -> a
count (Int -> (Int, Bool, Int) -> Int
forall a b. a -> b -> a
const (Int -> (Int, Bool, Int) -> Int) -> Int -> (Int, Bool, Int) -> Int
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
ByteString.length ByteString
bs) ByteString
bs (Int
n0, Bool
False, 0)
      where count :: a -> ((a, Bool, a) -> a) -> (a, Bool, a) -> a
count byte :: a
byte _    (0, high :: Bool
high, i :: a
i) | a
byte a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 Bool -> Bool -> Bool
|| a
byte a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= 0xC0 Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
high = a
i
            count byte :: a
byte cont :: (a, Bool, a) -> a
cont (n :: a
n, high :: Bool
high, i :: a
i) | a
byte a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0x80 = (a, Bool, a) -> a
cont (a -> a
forall a. Enum a => a -> a
pred a
n, Bool
False, a -> a
forall a. Enum a => a -> a
succ a
i)
                                         | a
byte a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0xC0 = (a, Bool, a) -> a
cont (if Bool
high then a
n else a -> a
forall a. Enum a => a -> a
pred a
n, Bool
True, a -> a
forall a. Enum a => a -> a
succ a
i)
                                         | Bool
otherwise = (a, Bool, a) -> a
cont (a -> a
forall a. Enum a => a -> a
pred a
n, Bool
True, a -> a
forall a. Enum a => a -> a
succ a
i)
{-# INLINE charStartIndex #-}