{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE UnliftedFFITypes #-}
module Z.Data.JSON.Value
(
Value(..)
, parseValue
, parseValue'
, parseValueChunks
, parseValueChunks'
, value
, object
, array
, string
, skipSpaces
) where
import Control.DeepSeq
import Data.Bits ((.&.))
import Data.Functor
import Data.Primitive.PrimArray
import Data.Scientific (Scientific, scientific)
import Data.Typeable
import Data.Word
import GHC.Generics
import qualified Z.Data.Parser as P
import Z.Data.Parser ((<?>))
import qualified Z.Data.Text as T
import Z.Data.Text.Builder (ToText)
import qualified Z.Data.Text.Base as T
import Z.Data.Vector.Base as V
import Z.Data.Vector.Extra as V
import Z.Foreign
import System.IO.Unsafe (unsafeDupablePerformIO)
import Test.QuickCheck.Arbitrary (Arbitrary(..))
import Test.QuickCheck.Gen (Gen(..), listOf)
#define BACKSLASH 92
#define CLOSE_CURLY 125
#define CLOSE_SQUARE 93
#define COMMA 44
#define COLON 58
#define DOUBLE_QUOTE 34
#define OPEN_CURLY 123
#define OPEN_SQUARE 91
#define C_0 48
#define C_9 57
#define C_A 65
#define C_F 70
#define C_a 97
#define C_f 102
#define C_n 110
#define C_t 116
#define MINUS 45
data Value = Object {-# UNPACK #-} !(V.Vector (T.Text, Value))
| Array {-# UNPACK #-} !(V.Vector Value)
| String {-# UNPACK #-} !T.Text
| Number {-# UNPACK #-} !Scientific
| Bool !Bool
| Null
deriving (Value -> Value -> Bool
(Value -> Value -> Bool) -> (Value -> Value -> Bool) -> Eq Value
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Value -> Value -> Bool
$c/= :: Value -> Value -> Bool
== :: Value -> Value -> Bool
$c== :: Value -> Value -> Bool
Eq, Int -> Value -> ShowS
[Value] -> ShowS
Value -> String
(Int -> Value -> ShowS)
-> (Value -> String) -> ([Value] -> ShowS) -> Show Value
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Value] -> ShowS
$cshowList :: [Value] -> ShowS
show :: Value -> String
$cshow :: Value -> String
showsPrec :: Int -> Value -> ShowS
$cshowsPrec :: Int -> Value -> ShowS
Show, Typeable, (forall x. Value -> Rep Value x)
-> (forall x. Rep Value x -> Value) -> Generic Value
forall x. Rep Value x -> Value
forall x. Value -> Rep Value x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Value x -> Value
$cfrom :: forall x. Value -> Rep Value x
Generic, Int -> Value -> TextBuilder ()
(Int -> Value -> TextBuilder ()) -> ToText Value
forall a. (Int -> a -> TextBuilder ()) -> ToText a
toTextBuilder :: Int -> Value -> TextBuilder ()
$ctoTextBuilder :: Int -> Value -> TextBuilder ()
ToText)
instance NFData Value where
{-# INLINE rnf #-}
rnf :: Value -> ()
rnf (Object Vector (Text, Value)
o) = Vector (Text, Value) -> ()
forall a. NFData a => a -> ()
rnf Vector (Text, Value)
o
rnf (Array Vector Value
a) = Vector Value -> ()
forall a. NFData a => a -> ()
rnf Vector Value
a
rnf (String Text
s) = Text -> ()
forall a. NFData a => a -> ()
rnf Text
s
rnf (Number Scientific
n) = Scientific -> ()
forall a. NFData a => a -> ()
rnf Scientific
n
rnf (Bool Bool
b) = Bool -> ()
forall a. NFData a => a -> ()
rnf Bool
b
rnf Value
Null = ()
instance Arbitrary Value where
arbitrary :: Gen Value
arbitrary = Int -> Int -> Gen Value
arbitraryValue Int
0 Int
4
where
arbitraryValue :: Int -> Int -> Gen Value
arbitraryValue :: Int -> Int -> Gen Value
arbitraryValue Int
d Int
s = do
Word
i <- Gen Word
forall a. Arbitrary a => Gen a
arbitrary :: Gen Word
case (Word
i Word -> Word -> Word
forall a. Integral a => a -> a -> a
`mod` Word
6) of
Word
0 -> if Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
s then Vector (Text, Value) -> Value
Object (Vector (Text, Value) -> Value)
-> ([(Text, Value)] -> Vector (Text, Value))
-> [(Text, Value)]
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Text, Value)] -> Vector (Text, Value)
forall (v :: * -> *) a. Vec v a => [a] -> v a
V.pack ([(Text, Value)] -> Value) -> Gen [(Text, Value)] -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Text, Value) -> Gen [(Text, Value)]
forall a. Gen a -> Gen [a]
listOf (Int -> Int -> Gen (Text, Value)
forall a. Arbitrary a => Int -> Int -> Gen (a, Value)
arbitraryKV (Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
s)
else Value -> Gen Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
Null
Word
1 -> if Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
s then Vector Value -> Value
Array (Vector Value -> Value)
-> ([Value] -> Vector Value) -> [Value] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Value] -> Vector Value
forall (v :: * -> *) a. Vec v a => [a] -> v a
V.pack ([Value] -> Value) -> Gen [Value] -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Value -> Gen [Value]
forall a. Gen a -> Gen [a]
listOf (Int -> Int -> Gen Value
arbitraryValue (Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
s)
else Value -> Gen Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
Null
Word
2 -> Text -> Value
String (Text -> Value) -> Gen Text -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Text
forall a. Arbitrary a => Gen a
arbitrary
Word
3 -> do
Integer
c <- Gen Integer
forall a. Arbitrary a => Gen a
arbitrary
Int
e <- Gen Int
forall a. Arbitrary a => Gen a
arbitrary
Value -> Gen Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Value -> Gen Value)
-> (Scientific -> Value) -> Scientific -> Gen Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Value
Number (Scientific -> Gen Value) -> Scientific -> Gen Value
forall a b. (a -> b) -> a -> b
$ Integer -> Int -> Scientific
scientific Integer
c Int
e
Word
4 -> Bool -> Value
Bool (Bool -> Value) -> Gen Bool -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Bool
forall a. Arbitrary a => Gen a
arbitrary
Word
_ -> Value -> Gen Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
Null
arbitraryKV :: Int -> Int -> Gen (a, Value)
arbitraryKV Int
d Int
s = (,) (a -> Value -> (a, Value)) -> Gen a -> Gen (Value -> (a, Value))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
forall a. Arbitrary a => Gen a
arbitrary Gen (Value -> (a, Value)) -> Gen Value -> Gen (a, Value)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Int -> Gen Value
arbitraryValue Int
d Int
s
shrink :: Value -> [Value]
shrink (Object Vector (Text, Value)
kvs) = (Text, Value) -> Value
forall a b. (a, b) -> b
snd ((Text, Value) -> Value) -> [(Text, Value)] -> [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Vector (Text, Value) -> [(Text, Value)]
forall (v :: * -> *) a. Vec v a => v a -> [a]
V.unpack Vector (Text, Value)
kvs)
shrink (Array Vector Value
vs) = Vector Value -> [Value]
forall (v :: * -> *) a. Vec v a => v a -> [a]
V.unpack Vector Value
vs
shrink Value
_ = []
parseValue :: V.Bytes -> (V.Bytes, Either P.ParseError Value)
{-# INLINE parseValue #-}
parseValue :: Bytes -> (Bytes, Either ParseError Value)
parseValue = Parser Value -> Bytes -> (Bytes, Either ParseError Value)
forall a. Parser a -> Bytes -> (Bytes, Either ParseError a)
P.parse Parser Value
value
parseValue' :: V.Bytes -> Either P.ParseError Value
{-# INLINE parseValue' #-}
parseValue' :: Bytes -> Either ParseError Value
parseValue' = Parser Value -> Bytes -> Either ParseError Value
forall a. Parser a -> Bytes -> Either ParseError a
P.parse_ (Parser Value
value Parser Value -> Parser () -> Parser Value
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
skipSpaces Parser Value -> Parser () -> Parser Value
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
P.endOfInput)
parseValueChunks :: Monad m => m V.Bytes -> V.Bytes -> m (V.Bytes, Either P.ParseError Value)
{-# INLINE parseValueChunks #-}
parseValueChunks :: m Bytes -> Bytes -> m (Bytes, Either ParseError Value)
parseValueChunks = Parser Value
-> m Bytes -> Bytes -> m (Bytes, Either ParseError Value)
forall (m :: * -> *) a.
Monad m =>
Parser a -> m Bytes -> Bytes -> m (Bytes, Either ParseError a)
P.parseChunks Parser Value
value
parseValueChunks' :: Monad m => m V.Bytes -> V.Bytes -> m (Either P.ParseError Value)
{-# INLINE parseValueChunks' #-}
parseValueChunks' :: m Bytes -> Bytes -> m (Either ParseError Value)
parseValueChunks' m Bytes
mi Bytes
inp = (Bytes, Either ParseError Value) -> Either ParseError Value
forall a b. (a, b) -> b
snd ((Bytes, Either ParseError Value) -> Either ParseError Value)
-> m (Bytes, Either ParseError Value)
-> m (Either ParseError Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Value
-> m Bytes -> Bytes -> m (Bytes, Either ParseError Value)
forall (m :: * -> *) a.
Monad m =>
Parser a -> m Bytes -> Bytes -> m (Bytes, Either ParseError a)
P.parseChunks (Parser Value
value Parser Value -> Parser () -> Parser Value
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
skipSpaces Parser Value -> Parser () -> Parser Value
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
P.endOfInput) m Bytes
mi Bytes
inp
skipSpaces :: P.Parser ()
{-# INLINE skipSpaces #-}
skipSpaces :: Parser ()
skipSpaces = (Word8 -> Bool) -> Parser ()
P.skipWhile (\ Word8
w -> Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x20 Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x0a Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x0d Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x09)
value :: P.Parser Value
{-# INLINABLE value #-}
value :: Parser Value
value = Text
"Z.Data.JSON.Value.value" Text -> Parser Value -> Parser Value
forall a. Text -> Parser a -> Parser a
<?> do
Parser ()
skipSpaces
Word8
w <- Parser Word8
P.peek
case Word8
w of
DOUBLE_QUOTE -> P.skipWord8 *> (String <$> string_)
OPEN_CURLY -> P.skipWord8 *> (Object <$> object_)
OPEN_SQUARE -> P.skipWord8 *> (Array <$> array_)
Word8
C_f -> Bytes -> Parser ()
P.bytes Bytes
"false" Parser () -> Value -> Parser Value
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> (Bool -> Value
Bool Bool
False)
Word8
C_t -> Bytes -> Parser ()
P.bytes Bytes
"true" Parser () -> Value -> Parser Value
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> (Bool -> Value
Bool Bool
True)
Word8
C_n -> Bytes -> Parser ()
P.bytes Bytes
"null" Parser () -> Value -> Parser Value
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Value
Null
Word8
_ | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
48 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
57 Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== MINUS -> Number <$> P.scientific'
| Bool
otherwise -> String -> Parser Value
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Z.Data.JSON.Value.value: not a valid json value"
array :: P.Parser (V.Vector Value)
{-# INLINE array #-}
array :: Parser (Vector Value)
array = Text
"Z.Data.JSON.Value.array" Text -> Parser (Vector Value) -> Parser (Vector Value)
forall a. Text -> Parser a -> Parser a
<?> Word8 -> Parser ()
P.word8 OPEN_SQUARE *> array_
array_ :: P.Parser (V.Vector Value)
{-# INLINABLE array_ #-}
array_ :: Parser (Vector Value)
array_ = do
Parser ()
skipSpaces
Word8
w <- Parser Word8
P.peek
if Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== CLOSE_SQUARE
then Parser ()
P.skipWord8 Parser () -> Vector Value -> Parser (Vector Value)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Vector Value
forall (v :: * -> *) a. Vec v a => v a
V.empty
else [Value] -> Int -> Parser (Vector Value)
loop [] Int
1
where
loop :: [Value] -> Int -> P.Parser (V.Vector Value)
loop :: [Value] -> Int -> Parser (Vector Value)
loop [Value]
acc !Int
n = do
!Value
v <- Parser Value
value
Parser ()
skipSpaces
let acc' :: [Value]
acc' = Value
vValue -> [Value] -> [Value]
forall a. a -> [a] -> [a]
:[Value]
acc
Word8
ch <- (Word8 -> Bool) -> Parser Word8
P.satisfy ((Word8 -> Bool) -> Parser Word8)
-> (Word8 -> Bool) -> Parser Word8
forall a b. (a -> b) -> a -> b
$ \Word8
w -> Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== COMMA || w Word8
== CLOSE_SQUARE
if Word8
ch Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== COMMA
then Parser ()
skipSpaces Parser () -> Parser (Vector Value) -> Parser (Vector Value)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Value] -> Int -> Parser (Vector Value)
loop [Value]
acc' (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
else Vector Value -> Parser (Vector Value)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Vector Value -> Parser (Vector Value))
-> Vector Value -> Parser (Vector Value)
forall a b. (a -> b) -> a -> b
$! Int -> [Value] -> Vector Value
forall (v :: * -> *) a. Vec v a => Int -> [a] -> v a
V.packRN Int
n [Value]
acc'
object :: P.Parser (V.Vector (T.Text, Value))
{-# INLINE object #-}
object :: Parser (Vector (Text, Value))
object = Text
"Z.Data.JSON.Value.object" Text
-> Parser (Vector (Text, Value)) -> Parser (Vector (Text, Value))
forall a. Text -> Parser a -> Parser a
<?> Word8 -> Parser ()
P.word8 OPEN_CURLY *> object_
object_ :: P.Parser (V.Vector (T.Text, Value))
{-# INLINABLE object_ #-}
object_ :: Parser (Vector (Text, Value))
object_ = do
Parser ()
skipSpaces
Word8
w <- Parser Word8
P.peek
if Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== CLOSE_CURLY
then Parser ()
P.skipWord8 Parser () -> Vector (Text, Value) -> Parser (Vector (Text, Value))
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Vector (Text, Value)
forall (v :: * -> *) a. Vec v a => v a
V.empty
else [(Text, Value)] -> Int -> Parser (Vector (Text, Value))
loop [] Int
1
where
loop :: [(T.Text, Value)] -> Int -> P.Parser (V.Vector (T.Text, Value))
loop :: [(Text, Value)] -> Int -> Parser (Vector (Text, Value))
loop [(Text, Value)]
acc !Int
n = do
!Text
k <- Parser Text
string
Parser ()
skipSpaces
Word8 -> Parser ()
P.word8 COLON
!Value
v <- Parser Value
value
Parser ()
skipSpaces
let acc' :: [(Text, Value)]
acc' = (Text
k, Value
v) (Text, Value) -> [(Text, Value)] -> [(Text, Value)]
forall a. a -> [a] -> [a]
: [(Text, Value)]
acc
Word8
ch <- (Word8 -> Bool) -> Parser Word8
P.satisfy ((Word8 -> Bool) -> Parser Word8)
-> (Word8 -> Bool) -> Parser Word8
forall a b. (a -> b) -> a -> b
$ \Word8
w -> Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== COMMA || w == CLOSE_CURLY
if Word8
ch Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== COMMA
then Parser ()
skipSpaces Parser ()
-> Parser (Vector (Text, Value)) -> Parser (Vector (Text, Value))
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [(Text, Value)] -> Int -> Parser (Vector (Text, Value))
loop [(Text, Value)]
acc' (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
else Vector (Text, Value) -> Parser (Vector (Text, Value))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Vector (Text, Value) -> Parser (Vector (Text, Value)))
-> Vector (Text, Value) -> Parser (Vector (Text, Value))
forall a b. (a -> b) -> a -> b
$! Int -> [(Text, Value)] -> Vector (Text, Value)
forall (v :: * -> *) a. Vec v a => Int -> [a] -> v a
V.packRN Int
n [(Text, Value)]
acc'
string :: P.Parser T.Text
{-# INLINE string #-}
string :: Parser Text
string = Text
"Z.Data.JSON.Value.string" Text -> Parser Text -> Parser Text
forall a. Text -> Parser a -> Parser a
<?> Word8 -> Parser ()
P.word8 DOUBLE_QUOTE *> string_
string_ :: P.Parser T.Text
{-# INLINE string_ #-}
string_ :: Parser Text
string_ = do
(Bytes
bs, Word32
state) <- Word32
-> (Word32 -> Bytes -> Either Word32 (Bytes, Bytes, Word32))
-> Parser (Bytes, Word32)
forall s.
s
-> (s -> Bytes -> Either s (Bytes, Bytes, s)) -> Parser (Bytes, s)
P.scanChunks Word32
0 Word32 -> Bytes -> Either Word32 (Bytes, Bytes, Word32)
go
let mt :: Maybe Text
mt = case Word32
state Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xFF of
Word32
1 -> IO (Maybe Text) -> Maybe Text
forall a. IO a -> a
unsafeDupablePerformIO (do
let !len :: Int
len = Bytes -> Int
forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
bs
!MutablePrimArray RealWorld Word8
mpa <- Int -> IO (MutablePrimArray (PrimState IO) Word8)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
len
!Int
len' <- MutablePrimArray RealWorld Word8
-> (MBA# Word8 -> Int -> IO Int) -> IO Int
forall a b.
Prim a =>
MutablePrimArray RealWorld a -> (MBA# Word8 -> Int -> IO b) -> IO b
withMutablePrimArrayUnsafe MutablePrimArray RealWorld Word8
mpa (\ MBA# Word8
mba# Int
_ ->
Bytes -> (BA# Word8 -> Int -> Int -> IO Int) -> IO Int
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
bs (MBA# Word8 -> BA# Word8 -> Int -> Int -> IO Int
decode_json_string MBA# Word8
mba#))
!PrimArray Word8
pa <- MutablePrimArray (PrimState IO) Word8 -> IO (PrimArray Word8)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld Word8
MutablePrimArray (PrimState IO) Word8
mpa
if Int
len' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then Maybe Text -> IO (Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text
forall a. a -> Maybe a
Just (Bytes -> Text
T.Text (PrimArray Word8 -> Int -> Int -> Bytes
forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
pa Int
0 Int
len')))
else Maybe Text -> IO (Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing)
Word32
3 -> Maybe Text
forall a. Maybe a
Nothing
Word32
_ -> Bytes -> Maybe Text
T.validateMaybe Bytes
bs
case Maybe Text
mt of
Just Text
t -> Parser ()
P.skipWord8 Parser () -> Text -> Parser Text
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Text
t
Maybe Text
_ -> String -> Parser Text
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Z.Data.JSON.Value.string_: utf8 validation or unescaping failed"
where
go :: Word32 -> V.Bytes -> Either Word32 (V.Bytes, V.Bytes, Word32)
go :: Word32 -> Bytes -> Either Word32 (Bytes, Bytes, Word32)
go !Word32
state Bytes
v =
case IO (Word32, Int) -> (Word32, Int)
forall a. IO a -> a
unsafeDupablePerformIO (IO (Word32, Int) -> (Word32, Int))
-> ((MBA# Word8 -> IO Int) -> IO (Word32, Int))
-> (MBA# Word8 -> IO Int)
-> (Word32, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> (MBA# Word8 -> IO Int) -> IO (Word32, Int)
forall a b. Prim a => a -> (MBA# Word8 -> IO b) -> IO (a, b)
withPrimUnsafe Word32
state ((MBA# Word8 -> IO Int) -> (Word32, Int))
-> (MBA# Word8 -> IO Int) -> (Word32, Int)
forall a b. (a -> b) -> a -> b
$ \ MBA# Word8
ps ->
Bytes -> (BA# Word8 -> Int -> Int -> IO Int) -> IO Int
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
v (MBA# Word8 -> BA# Word8 -> Int -> Int -> IO Int
find_json_string_end MBA# Word8
ps)
of (Word32
state', Int
len)
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 ->
let !r :: Bytes
r = Int -> Bytes -> Bytes
forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeTake Int
len Bytes
v
!rest :: Bytes
rest = Int -> Bytes -> Bytes
forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
len Bytes
v
in (Bytes, Bytes, Word32) -> Either Word32 (Bytes, Bytes, Word32)
forall a b. b -> Either a b
Right (Bytes
r, Bytes
rest, Word32
state')
| Bool
otherwise -> Word32 -> Either Word32 (Bytes, Bytes, Word32)
forall a b. a -> Either a b
Left Word32
state'
foreign import ccall unsafe find_json_string_end :: MBA# Word32 -> BA# Word8 -> Int -> Int -> IO Int
foreign import ccall unsafe decode_json_string :: MBA# Word8 -> BA# Word8 -> Int -> Int -> IO Int