@@ -74,7 +74,7 @@ import Data.ByteString as B
7474import Data.ByteString.Internal as B hiding (c2w)
7575import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
7676import Data.Text.Internal (Text(..), safe, text)
77−-- import Data.Text.Internal.Private (runText)
77+import Data.Text.Internal.Private (runText)
7878import Data.Text.Internal.Unsafe.Char (ord, unsafeWrite)
7979import Data.Text.Internal.Unsafe.Shift (shiftR)
8080-- import Data.Text.Show ()
@@ -95,7 +95,7 @@ import qualified Data.Text.Internal.Encoding.Fusion as E
9595import qualified Data.Text.Internal.Encoding.Utf16 as U16
9696import qualified Data.Text.Internal.Fusion as F
9797
98−import GHC.Exts (ByteArray#, Int(..), Int#, Any)
98+import GHC.Exts (ByteArray#, Int(..), Int#, Any, Addr#, Ptr(..))
9999{-
100100#include "text_cbits.h"
101101-}
@@ -105,6 +105,7 @@ import Data.ByteString (ByteString)
105105import Data.Text.Internal (Text)
106106
107107-------------------------------------
108+import GHC.ForeignPtr
108109import GHCJS.Types
109110import GHCJS.Buffer
110111import Data.JSString (JSString)
@@ -137,55 +138,55 @@ decodeASCII = decodeUtf8
137138-- 'decodeLatin1' is semantically equivalent to
138139-- @Data.Text.pack . Data.ByteString.Char8.unpack@
139140decodeLatin1 :: ByteString -> Text
140−decodeLatin1 = error "decodeLatin1"
141−-- decodeLatin1 (PS fp off len) = text a 0 len
142−-- where
143−-- a = A.run (A.new len >>= unsafeIOToST . go)
144−-- go dest = withForeignPtr fp $ \ptr -> do
145−-- c_decode_latin1 (A.maBA dest) (ptr `plusPtr` off) (ptr `plusPtr` (off+len))
146−-- return dest
141+decodeLatin1 (PS fp off len) = text a 0 len
142+ where
143+ a = A.run (A.new len >>= unsafeIOToST . go)
144+ go dest = withForeignPtr fp $ \ptr -> do
145+ c_decode_latin1 (A.maBA dest) (ptr `plusPtr` off) (ptr `plusPtr` (off+len))
146+ return dest
147147
148148-- foreign import javascript unsafe "h$textToString" js_toString :: JSVal -> Text
149149
150150foreign import javascript unsafe "h$textFromString" js_fromString :: JSString -> (# ByteArray#, Int# #)
151151foreign import javascript unsafe "String['fromCharCode']['apply'](null, $1['u8'])" js_decodeBytes :: JSVal -> JSString
152152foreign import javascript unsafe "h$decodeUtf8z($1, $2)" js_fromByteStringBuffer :: Buffer -> Int -> JSString
153+foreign import javascript unsafe "h$decodeUtf8z($1, $2)" js_fromByteStringBufferz :: Addr# -> Int -> JSString
153154foreign import javascript unsafe "h$encodeUtf8($1)" js_encodeUtf8 :: JSString -> Buffer
155+
156+foreign import javascript unsafe "String['fromCharCode']['apply'](null, $1['u8'])" js_decodeUtf8Hack :: Addr# -> JSString
157+
154158foreign import javascript unsafe "h$encodeUtf8($1)" js_encodeUtf8Mut :: JSString -> MutableBuffer
155159foreign import javascript unsafe "h$encodeUtf16($1)" js_encodeUtf16 :: JSString -> Buffer
156160foreign import javascript unsafe "$1['length']" js_length :: JSString -> Int
157161foreign import javascript unsafe "h$jsstringTake" js_take :: Int -> JSString -> JSString
162+foreign import javascript unsafe "$3.substring($1,$2)" js_substring :: Int# -> Int# -> JSString -> JSString
158163
159164-- | Decode a 'ByteString' containing UTF-8 encoded text.
160165decodeUtf8With :: OnDecodeError -> ByteString -> Text
161−-- decodeUtf8With _ bs@(PS fp off len) = Text $ js_decodeBytes $ unsafeCoerce bs
162− -- decodeUtf8With _ bs = Text $ js_fromByteStringBuffer buf off
163−decodeUtf8With _ bs = Text $ js_take (len) $ js_fromByteStringBuffer buf off
164− where (buf, off, len) = fromByteString bs
165−-- decodeUtf8With onErr (PS fp off len) = runText $ \done -> do
166− -- let go dest = withForeignPtr fp $ \ptr ->
167− -- with (0::CSize) $ \destOffPtr -> do
168− -- let end = ptr `plusPtr` (off + len)
169− -- loop curPtr = do
170− -- curPtr' <- c_decode_utf8 (A.maBA dest) destOffPtr curPtr end
171− -- if curPtr' == end
172− -- then do
173− -- n <- peek destOffPtr
174− -- unsafeSTToIO (done dest (fromIntegral n))
175− -- else do
176− -- x <- peek curPtr'
177− -- case onErr desc (Just x) of
178− -- Nothing -> loop $ curPtr' `plusPtr` 1
179− -- Just c -> do
180− -- destOff <- peek destOffPtr
181− -- w <- unsafeSTToIO $
182− -- unsafeWrite dest (fromIntegral destOff) (safe c)
183− -- poke destOffPtr (destOff + fromIntegral w)
184− -- loop $ curPtr' `plusPtr` 1
185− -- loop (ptr `plusPtr` off)
186− -- (unsafeIOToST . go) =<< A.new len
187− -- where
188− -- desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream"
166+decodeUtf8With onErr (PS fp off len) = runText $ \done -> do
167+ let go dest = withForeignPtr fp $ \ptr ->
168+ with (0::CSize) $ \destOffPtr -> do
169+ let end = ptr `plusPtr` (off + len)
170+ loop curPtr = do
171+ curPtr' <- c_decode_utf8 (A.maBA dest) destOffPtr curPtr end
172+ if curPtr' == end
173+ then do
174+ n <- peek destOffPtr
175+ unsafeSTToIO (done dest (fromIntegral n))
176+ else do
177+ x <- peek curPtr'
178+ case onErr desc (Just x) of
179+ Nothing -> loop $ curPtr' `plusPtr` 1
180+ Just c -> do
181+ destOff <- peek destOffPtr
182+ w <- unsafeSTToIO $
183+ unsafeWrite dest (fromIntegral destOff) (safe c)
184+ poke destOffPtr (destOff + fromIntegral w)
185+ loop $ curPtr' `plusPtr` 1
186+ loop (ptr `plusPtr` off)
187+ (unsafeIOToST . go) =<< A.new len
188+ where
189+ desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream"
189190{- INLINE[0] decodeUtf8With #-}
190191
191192-- $stream
@@ -504,17 +505,17 @@ encodeUtf32BE :: Text -> ByteString
504505encodeUtf32BE txt = E.unstream (E.restreamUtf32BE (F.stream txt))
505506{-# INLINE encodeUtf32BE #-}
506507
507−-- foreign import ccall unsafe "_hs_text_decode_utf8" c_decode_utf8
508−-- :: MutableByteArray# s -> Ptr CSize
509−-- -> Ptr Word8 -> Ptr Word8 -> IO (Ptr Word8)
508+foreign import ccall unsafe "_hs_text_decode_utf8" c_decode_utf8
509+ :: MutableByteArray# s -> Ptr CSize
510+ -> Ptr Word8 -> Ptr Word8 -> IO (Ptr Word8)
510511
511−-- foreign import ccall unsafe "_hs_text_decode_utf8_state" c_decode_utf8_with_state
512−-- :: MutableByteArray# s -> Ptr CSize
513−-- -> Ptr (Ptr Word8) -> Ptr Word8
514−-- -> Ptr CodePoint -> Ptr DecoderState -> IO (Ptr Word8)
512+foreign import ccall unsafe "_hs_text_decode_utf8_state" c_decode_utf8_with_state
513+ :: MutableByteArray# s -> Ptr CSize
514+ -> Ptr (Ptr Word8) -> Ptr Word8
515+ -> Ptr CodePoint -> Ptr DecoderState -> IO (Ptr Word8)
515516
516−-- foreign import ccall unsafe "_hs_text_decode_latin1" c_decode_latin1
517−-- :: MutableByteArray# s -> Ptr Word8 -> Ptr Word8 -> IO ()
517+foreign import ccall unsafe "_hs_text_decode_latin1" c_decode_latin1
518+ :: MutableByteArray# s -> Ptr Word8 -> Ptr Word8 -> IO ()
518519
519−-- foreign import ccall unsafe "_hs_text_encode_utf8" c_encode_utf8
520−-- :: Ptr (Ptr Word8) -> ByteArray# -> CSize -> CSize -> IO ()
520+foreign import ccall unsafe "_hs_text_encode_utf8" c_encode_utf8
521+ :: Ptr (Ptr Word8) -> ByteArray# -> CSize -> CSize -> IO ()