@@ -77,7 +77,7 @@ import Data.Word (Word8, Word32)
77import Foreign.C.Types (CSize)
77import Foreign.C.Types (CSize)
78import Foreign.ForeignPtr (withForeignPtr)
78import Foreign.ForeignPtr (withForeignPtr)
79import Foreign.Marshal.Utils (with)
79import Foreign.Marshal.Utils (with)
80−import Foreign.Ptr (Ptr, minusPtr, plusPtr)
80+import Foreign.Ptr (Ptr, minusPtr, nullPtr, plusPtr)
81import Foreign.Storable (Storable, peek, poke)
81import Foreign.Storable (Storable, peek, poke)
82import GHC.Base (MutableByteArray#)
82import GHC.Base (MutableByteArray#)
83import qualified Data.Text.Array as A
83import qualified Data.Text.Array as A
@@ -196,12 +196,14 @@ decodeUtf8With onErr (PS fp off len) = runText $ \done -> do
196-- or continuation where it is encountered.
196-- or continuation where it is encountered.
198-- | A stream oriented decoding result.
198-- | A stream oriented decoding result.
199−data Decoding = Some Text (ByteString -> Decoding)
199+data Decoding = Some Text ByteString (ByteString -> Decoding)
201instance Show Decoding where
201instance Show Decoding where
202− showsPrec d (Some t _) = showParen (d > prec) $
202+ showsPrec d (Some t bs _) = showParen (d > prec) $
203− showString "Some " . showsPrec (prec+1) t
203+ showString "Some " . showsPrec prec' t .
204+ showChar ' ' . showsPrec prec' bs .
204− where prec = 10
206+ where prec = 10; prec' = prec + 1
206newtype CodePoint = CodePoint Word32 deriving (Eq, Show, Num, Storable)
208newtype CodePoint = CodePoint Word32 deriving (Eq, Show, Num, Storable)
207newtype DecoderState = DecoderState Word32 deriving (Eq, Show, Num, Storable)
209newtype DecoderState = DecoderState Word32 deriving (Eq, Show, Num, Storable)
@@ -224,7 +226,7 @@ streamDecodeUtf8With onErr = decodeChunk 0 0
224 -- We create a slightly larger than necessary buffer to accommodate a
226 -- We create a slightly larger than necessary buffer to accommodate a
225 -- potential surrogate pair started in the last buffer
227 -- potential surrogate pair started in the last buffer
226 decodeChunk :: CodePoint -> DecoderState -> ByteString -> Decoding
228 decodeChunk :: CodePoint -> DecoderState -> ByteString -> Decoding
227− decodeChunk codepoint0 state0 (PS fp off len) =
229+ decodeChunk codepoint0 state0 bs@(PS fp off len) =
228 runST $ (unsafeIOToST . decodeChunkToBuffer) =<< A.new (len+1)
230 runST $ (unsafeIOToST . decodeChunkToBuffer) =<< A.new (len+1)
230 decodeChunkToBuffer :: A.MArray s -> IO Decoding
232 decodeChunkToBuffer :: A.MArray s -> IO Decoding
@@ -232,10 +234,12 @@ streamDecodeUtf8With onErr = decodeChunk 0 0
232 with (0::CSize) $ \destOffPtr ->
234 with (0::CSize) $ \destOffPtr ->
233 with codepoint0 $ \codepointPtr ->
235 with codepoint0 $ \codepointPtr ->
234 with state0 $ \statePtr ->
236 with state0 $ \statePtr ->
237+ with nullPtr $ \curPtrPtr ->
235 let end = ptr `plusPtr` (off + len)
238 let end = ptr `plusPtr` (off + len)
236 loop curPtr = do
239 loop curPtr = do
240+ poke curPtrPtr curPtr
237− curPtr' <- c_decode_utf8_with_state (A.maBA dest) destOffPtr curPtr end
241+ curPtr' <- c_decode_utf8_with_state (A.maBA dest) destOffPtr
238− codepointPtr statePtr
242+ curPtrPtr end codepointPtr statePtr
239 state <- peek statePtr
243 state <- peek statePtr
240 case state of
244 case state of
241 UTF8_REJECT -> do
245 UTF8_REJECT -> do
@@ -258,7 +262,10 @@ streamDecodeUtf8With onErr = decodeChunk 0 0
258 chunkText <- unsafeSTToIO $ do
262 chunkText <- unsafeSTToIO $ do
259 arr <- A.unsafeFreeze dest
263 arr <- A.unsafeFreeze dest
260 return $! textP arr 0 (fromIntegral n)
264 return $! textP arr 0 (fromIntegral n)
265+ lastPtr <- peek curPtrPtr
266+ let left = lastPtr `minusPtr` curPtr
267+ return $ Some chunkText (B.drop left bs)
261− return $ Some chunkText (decodeChunk codepoint state)
268+ (decodeChunk codepoint state)
262 in loop (ptr `plusPtr` off)
269 in loop (ptr `plusPtr` off)
263 desc = "Data.Text.Encoding.streamDecodeUtf8With: Invalid UTF-8 stream"
270 desc = "Data.Text.Encoding.streamDecodeUtf8With: Invalid UTF-8 stream"
@@ -421,7 +428,7 @@ foreign import ccall unsafe "_hs_text_decode_utf8" c_decode_utf8
422foreign import ccall unsafe "_hs_text_decode_utf8_state" c_decode_utf8_with_state
429foreign import ccall unsafe "_hs_text_decode_utf8_state" c_decode_utf8_with_state
423 :: MutableByteArray# s -> Ptr CSize
430 :: MutableByteArray# s -> Ptr CSize
424− -> Ptr Word8 -> Ptr Word8
431+ -> Ptr (Ptr Word8) -> Ptr Word8
425 -> Ptr CodePoint -> Ptr DecoderState -> IO (Ptr Word8)
432 -> Ptr CodePoint -> Ptr DecoderState -> IO (Ptr Word8)
427foreign import ccall unsafe "_hs_text_decode_latin1" c_decode_latin1
434foreign import ccall unsafe "_hs_text_decode_latin1" c_decode_latin1