@@ -77,7 +77,7 @@ import Data.Word (Word8, Word32)
7777import Foreign.C.Types (CSize)
7878import Foreign.ForeignPtr (withForeignPtr)
7979import Foreign.Marshal.Utils (with)
80−import Foreign.Ptr (Ptr, minusPtr, plusPtr)
80+import Foreign.Ptr (Ptr, minusPtr, nullPtr, plusPtr)
8181import Foreign.Storable (Storable, peek, poke)
8282import GHC.Base (MutableByteArray#)
8383import qualified Data.Text.Array as A
@@ -196,12 +196,14 @@ decodeUtf8With onErr (PS fp off len) = runText $ \done -> do
196196-- or continuation where it is encountered.
197197
198198-- | A stream oriented decoding result.
199−data Decoding = Some Text (ByteString -> Decoding)
199+data Decoding = Some Text ByteString (ByteString -> Decoding)
200200
201201instance Show Decoding where
202− showsPrec d (Some t _) = showParen (d > prec) $
203− showString "Some " . showsPrec (prec+1) t
204− where prec = 10
202+ showsPrec d (Some t bs _) = showParen (d > prec) $
203+ showString "Some " . showsPrec prec' t .
204+ showChar ' ' . showsPrec prec' bs .
205+ showString " _"
206+ where prec = 10; prec' = prec + 1
205207
206208newtype CodePoint = CodePoint Word32 deriving (Eq, Show, Num, Storable)
207209newtype DecoderState = DecoderState Word32 deriving (Eq, Show, Num, Storable)
@@ -224,7 +226,7 @@ streamDecodeUtf8With onErr = decodeChunk 0 0
224226 -- We create a slightly larger than necessary buffer to accommodate a
225227 -- potential surrogate pair started in the last buffer
226228 decodeChunk :: CodePoint -> DecoderState -> ByteString -> Decoding
227− decodeChunk codepoint0 state0 (PS fp off len) =
229+ decodeChunk codepoint0 state0 bs@(PS fp off len) =
228230 runST $ (unsafeIOToST . decodeChunkToBuffer) =<< A.new (len+1)
229231 where
230232 decodeChunkToBuffer :: A.MArray s -> IO Decoding
@@ -232,10 +234,12 @@ streamDecodeUtf8With onErr = decodeChunk 0 0
232234 with (0::CSize) $ \destOffPtr ->
233235 with codepoint0 $ \codepointPtr ->
234236 with state0 $ \statePtr ->
237+ with nullPtr $ \curPtrPtr ->
235238 let end = ptr `plusPtr` (off + len)
236239 loop curPtr = do
237− curPtr' <- c_decode_utf8_with_state (A.maBA dest) destOffPtr curPtr end
238− codepointPtr statePtr
240+ poke curPtrPtr curPtr
241+ curPtr' <- c_decode_utf8_with_state (A.maBA dest) destOffPtr
242+ curPtrPtr end codepointPtr statePtr
239243 state <- peek statePtr
240244 case state of
241245 UTF8_REJECT -> do
@@ -258,7 +262,10 @@ streamDecodeUtf8With onErr = decodeChunk 0 0
258262 chunkText <- unsafeSTToIO $ do
259263 arr <- A.unsafeFreeze dest
260264 return $! textP arr 0 (fromIntegral n)
261− return $ Some chunkText (decodeChunk codepoint state)
265+ lastPtr <- peek curPtrPtr
266+ let left = lastPtr `minusPtr` curPtr
267+ return $ Some chunkText (B.drop left bs)
268+ (decodeChunk codepoint state)
262269 in loop (ptr `plusPtr` off)
263270 desc = "Data.Text.Encoding.streamDecodeUtf8With: Invalid UTF-8 stream"
264271
@@ -421,7 +428,7 @@ foreign import ccall unsafe "_hs_text_decode_utf8" c_decode_utf8
421428
422429foreign import ccall unsafe "_hs_text_decode_utf8_state" c_decode_utf8_with_state
423430 :: MutableByteArray# s -> Ptr CSize
424− -> Ptr Word8 -> Ptr Word8
431+ -> Ptr (Ptr Word8) -> Ptr Word8
425432 -> Ptr CodePoint -> Ptr DecoderState -> IO (Ptr Word8)
426433
427434foreign import ccall unsafe "_hs_text_decode_latin1" c_decode_latin1