@@ -1,37 +1,42 @@
1{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
1{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
2−{-# LANGUAGE BangPatterns, EmptyDataDecls, FlexibleInstances, MagicHash, UnboxedTuples #-}
2+{-# LANGUAGE BangPatterns, FlexibleInstances, MagicHash, UnboxedTuples #-}
3module Data.Utf8
3module Data.Utf8
5− , Utf8(..)
4+ ( Utf8(..)
11 , contains
8 , contains
13 , startsWith
9 , startsWith
14 , startsWithChar
10 , startsWithChar
15− , endsWithWord
11+ , endsWithWord8
19− , any
15+ , getUnder256
20− , toWord16
16+ , putUnder256
22− -- conversions
18+ , getVeryLong
23− , fromChars
19+ , putVeryLong
25 , toBuilder
22 , toBuilder
27− , fromChunks
26+ , fromSnippet
28− , Chunk(..)
27+ , fromChars
33import Prelude hiding (String, all, any, concat)
38import Prelude hiding (String, all, any, concat)
34−import Data.Binary (Binary(..), Get, getWord8, putWord8)
39+import Data.Binary (Get, get, getWord8, Put, put, putWord8)
35import Data.Binary.Put (putBuilder)
40import Data.Binary.Put (putBuilder)
36import Data.Binary.Get.Internal (readN)
41import Data.Binary.Get.Internal (readN)
37import Data.Bits ((.&.), shiftR)
42import Data.Bits ((.&.), shiftR)
@@ -39,7 +44,6 @@ import qualified Data.ByteString.Internal as B
39import qualified Data.ByteString.Builder.Internal as B
44import qualified Data.ByteString.Builder.Internal as B
40import qualified Data.Char as Char
45import qualified Data.Char as Char
41import qualified Data.List as List
46import qualified Data.List as List
42−import Data.String (IsString(..))
43import Foreign.ForeignPtr (touchForeignPtr)
47import Foreign.ForeignPtr (touchForeignPtr)
44import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
48import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
45import Foreign.Ptr (minusPtr, plusPtr)
49import Foreign.Ptr (minusPtr, plusPtr)
@@ -54,36 +58,35 @@ import GHC.Exts
54 , copyByteArray#
58 , copyByteArray#
55 , copyAddrToByteArray#
59 , copyAddrToByteArray#
56 , copyByteArrayToAddr#
60 , copyByteArrayToAddr#
57− , writeWord8Array#,
61+ , writeWord8Array#
59import GHC.IO
63import GHC.IO
60import GHC.ST (ST(ST), runST)
64import GHC.ST (ST(ST), runST)
61import GHC.Prim
65import GHC.Prim
62import GHC.Word (Word8(W8#), Word16(W16#))
66import GHC.Word (Word8(W8#), Word16(W16#))
68+import qualified Parse.Primitives as P
69−data Utf8 size tipe =
75+data Utf8 tipe =
70 Utf8 ByteArray#
76 Utf8 ByteArray#
73−type String = Utf8 VERY_LONG STRING
74−type VeryLong t = Utf8 VERY_LONG t
75−type Under256 t = Utf8 UNDER_256 t
83−-- IS EMPTY
83+{-# NOINLINE empty #-}
86+ runST (freeze =<< newByteArray 0)
86−isEmpty :: Utf8 l t -> Bool
89+isEmpty :: Utf8 t -> Bool
87isEmpty (Utf8 ba#) =
90isEmpty (Utf8 ba#) =
88 isTrue# (sizeofByteArray# ba# ==# 0#)
91 isTrue# (sizeofByteArray# ba# ==# 0#)
@@ -92,7 +95,7 @@ isEmpty (Utf8 ba#) =
95−size :: Utf8 l t -> Int
98+size :: Utf8 t -> Int
96size (Utf8 ba#) =
99size (Utf8 ba#) =
97 I# (sizeofByteArray# ba#)
100 I# (sizeofByteArray# ba#)
@@ -101,7 +104,7 @@ size (Utf8 ba#) =
101-- CONTAINS
104-- CONTAINS
104−contains :: Word8 -> Utf8 l t -> Bool
107+contains :: Word8 -> Utf8 t -> Bool
105contains (W8# word#) (Utf8 ba#) =
108contains (W8# word#) (Utf8 ba#) =
106 containsHelp word# ba# 0# (sizeofByteArray# ba#)
109 containsHelp word# ba# 0# (sizeofByteArray# ba#)
@@ -117,32 +120,11 @@ containsHelp word# ba# !offset# len# =
123−containsDouble :: Word8 -> Utf8 l t -> Bool
124−containsDouble (W8# word#) (Utf8 ba#) =
125− containsDoubleHelp word# ba# 0# (sizeofByteArray# ba#)
128−containsDoubleHelp :: Word# -> ByteArray# -> Int# -> Int# -> Bool
129−containsDoubleHelp word# ba# !offset# len# =
130− let !offset1# = offset# +# 1# in
131− if isTrue# (offset1# <# len#) then
132− if isTrue# (eqWord# word# (indexWord8Array# ba# offset# ))
133− && isTrue# (eqWord# word# (indexWord8Array# ba# offset1#))
135− else containsDoubleHelp word# ba# (offset# +# 1#) len#
141-- STARTS WITH
123-- STARTS WITH
144{-# INLINE startsWith #-}
126{-# INLINE startsWith #-}
145−startsWith :: Utf8 l t -> Utf8 l t -> Bool
127+startsWith :: Utf8 t -> Utf8 t -> Bool
146startsWith (Utf8 ba1#) (Utf8 ba2#) =
128startsWith (Utf8 ba1#) (Utf8 ba2#) =
148 !len1# = sizeofByteArray# ba1#
130 !len1# = sizeofByteArray# ba1#
@@ -157,9 +139,9 @@ startsWith (Utf8 ba1#) (Utf8 ba2#) =
157-- STARTS WITH CHAR
139-- STARTS WITH CHAR
160−startsWithChar :: (Char -> Bool) -> Utf8 l t -> Bool
142+startsWithChar :: (Char -> Bool) -> Utf8 t -> Bool
161−startsWithChar isGood str@(Utf8 ba#) =
143+startsWithChar isGood bytes@(Utf8 ba#) =
162− if isEmpty str then
144+ if isEmpty bytes then
@@ -177,8 +159,8 @@ startsWithChar isGood str@(Utf8 ba#) =
177-- ENDS WITH WORD
159-- ENDS WITH WORD
180−endsWithWord :: Word8 -> Utf8 l t -> Bool
162+endsWithWord8 :: Word8 -> Utf8 t -> Bool
181−endsWithWord (W8# w#) (Utf8 ba#) =
163+endsWithWord8 (W8# w#) (Utf8 ba#) =
182 let len# = sizeofByteArray# ba# in
164 let len# = sizeofByteArray# ba# in
183 isTrue# (len# ># 0#)
165 isTrue# (len# ># 0#)
@@ -189,12 +171,12 @@ endsWithWord (W8# w#) (Utf8 ba#) =
192−split :: Word8 -> String -> [String]
174+split :: Word8 -> Utf8 t -> [Utf8 t]
193split (W8# divider#) str@(Utf8 ba#) =
175split (W8# divider#) str@(Utf8 ba#) =
194 splitHelp str 0 (findDividers divider# ba# 0# (sizeofByteArray# ba#) [])
176 splitHelp str 0 (findDividers divider# ba# 0# (sizeofByteArray# ba#) [])
197−splitHelp :: String -> Int -> [Int] -> [String]
179+splitHelp :: Utf8 t -> Int -> [Int] -> [Utf8 t]
198splitHelp str start offsets =
180splitHelp str start offsets =
199 case offsets of
181 case offsets of
@@ -215,7 +197,7 @@ findDividers divider# ba# !offset# len# revOffsets =
215 reverse revOffsets
197 reverse revOffsets
218−unsafeSlice :: String -> Int -> Int -> String
200+unsafeSlice :: Utf8 t -> Int -> Int -> Utf8 t
219unsafeSlice str start end =
201unsafeSlice str start end =
220 let !len = end - start in
202 let !len = end - start in
221 if len == 0 then
203 if len == 0 then
@@ -231,7 +213,7 @@ unsafeSlice str start end =
234−join :: Word8 -> [String] -> String
216+join :: Word8 -> [Utf8 t] -> Utf8 t
235join sep strings =
217join sep strings =
236 case strings of
218 case strings of
@@ -245,7 +227,7 @@ join sep strings =
245 freeze mba
227 freeze mba
248−joinHelp :: Word8 -> MBA s -> Int -> String -> [String] -> ST s ()
230+joinHelp :: Word8 -> MBA s -> Int -> Utf8 t -> [Utf8 t] -> ST s ()
249joinHelp sep mba offset str strings =
231joinHelp sep mba offset str strings =
251 !len = size str
233 !len = size str
@@ -263,46 +245,10 @@ joinHelp sep mba offset str strings =
269−all :: (Char -> Bool) -> Utf8 l t -> Bool
271− not (any (not . isGood) utf8)
278−any :: (Char -> Bool) -> Utf8 l t -> Bool
279−any isGood (Utf8 ba#) =
280− anyHelp isGood ba# 0# (sizeofByteArray# ba#)
283−anyHelp :: (Char -> Bool) -> ByteArray# -> Int# -> Int# -> Bool
284−anyHelp isGood ba# offset# len# =
285− if isTrue# (offset# >=# len#) then
289− !w# = indexWord8Array# ba# offset#
291− | isTrue# (ltWord# w# 0xC0##) = (# C# (chr# (word2Int# w#)), 1# #)
292− | isTrue# (ltWord# w# 0xE0##) = (# chr2 ba# offset# w#, 2# #)
293− | isTrue# (ltWord# w# 0xF0##) = (# chr3 ba# offset# w#, 3# #)
294− | True = (# chr4 ba# offset# w#, 4# #)
298− else anyHelp isGood ba# (offset# +# width#) len#
305−instance Eq (Utf8 l t) where
251+instance Eq (Utf8 t) where
306 (==) (Utf8 ba1#) (Utf8 ba2#) =
252 (==) (Utf8 ba1#) (Utf8 ba2#) =
308 !len1# = sizeofByteArray# ba1#
254 !len1# = sizeofByteArray# ba1#
@@ -317,7 +263,7 @@ instance Eq (Utf8 l t) where
317-- COMPARE
263-- COMPARE
320−instance Ord (Utf8 l t) where
266+instance Ord (Utf8 t) where
321 compare (Utf8 ba1#) (Utf8 ba2#) =
267 compare (Utf8 ba1#) (Utf8 ba2#) =
323 !len1# = sizeofByteArray# ba1#
269 !len1# = sizeofByteArray# ba1#
@@ -334,84 +280,20 @@ instance Ord (Utf8 l t) where
340−toWord16 :: String -> Maybe Word16
341−toWord16 (Utf8 ba#) =
342− let !len# = sizeofByteArray# ba# in
343− if isTrue# (len# ==# 0#) then
346− let !w# = indexWord8Array# ba# 0# in
347− if isTrue# (eqWord# w# 0x30##) then
348− if isTrue# (len# ==# 1#) then Just 0 else Nothing
350− toWordHelp ba# 0# len# 0##
353−toWordHelp :: ByteArray# -> Int# -> Int# -> Word# -> Maybe Word16
354−toWordHelp ba# offset# len# number# =
355− if isTrue# (offset# <# len#) then
356− let !w# = indexWord8Array# ba# offset# in
357− if isTrue# (leWord# w# 0x39##) && isTrue# (geWord# w# 0x30##) then
358− let !newNumber# = plusWord# (timesWord# 10## number#) (minusWord# w# 0x30##) in
359− toWordHelp ba# (offset# +# 1#) len# newNumber#
370−fromWord16 :: Word16 -> String
373− do let !size = getWordSize n
374− mba <- newByteArray size
375− writeDigits mba (size - 1) n
379−getWordSize :: Word16 -> Int
383− | True = ceiling (logBase 10 (fromIntegral n + 1) :: Float)
386−writeDigits :: MBA s -> Int -> Word16 -> ST s ()
387−writeDigits !mba !offset !n =
388− do let (q,r) = quotRem n 10
389− writeWord8 mba offset (0x30 + fromIntegral r)
392− else writeDigits mba (offset-1) q
396-- FROM STRING
283-- FROM STRING
399−fromChars :: [Char] -> Utf8 l t
286+fromChars :: [Char] -> Utf8 t
400−fromChars =
287+fromChars chars =
404−instance IsString (Utf8 l t) where
408− do mba <- newByteArray (sum (map getWidth str))
290+ do mba <- newByteArray (sum (map getWidth chars))
409− writeString mba 0 str
291+ writeChars mba 0 chars
413−writeString :: MBA s -> Int -> [Char] -> ST s (Utf8 l t)
295+writeChars :: MBA s -> Int -> [Char] -> ST s (Utf8 t)
414−writeString !mba !offset chars =
296+writeChars !mba !offset chars =
415 case chars of
297 case chars of
417 freeze mba
299 freeze mba
@@ -419,25 +301,25 @@ writeString !mba !offset chars =
419 char : chars
301 char : chars
420 | n < 0x80 ->
302 | n < 0x80 ->
421 do writeWord8 mba (offset ) (fromIntegral n)
303 do writeWord8 mba (offset ) (fromIntegral n)
422− writeString mba (offset + 1) chars
304+ writeChars mba (offset + 1) chars
424 | n < 0x800 ->
306 | n < 0x800 ->
425 do writeWord8 mba (offset ) (fromIntegral ((shiftR n 6 ) + 0xC0))
307 do writeWord8 mba (offset ) (fromIntegral ((shiftR n 6 ) + 0xC0))
426 writeWord8 mba (offset + 1) (fromIntegral (( n .&. 0x3F) + 0x80))
308 writeWord8 mba (offset + 1) (fromIntegral (( n .&. 0x3F) + 0x80))
427− writeString mba (offset + 2) chars
309+ writeChars mba (offset + 2) chars
429 | n < 0x10000 ->
311 | n < 0x10000 ->
430 do writeWord8 mba (offset ) (fromIntegral ((shiftR n 12 ) + 0xE0))
312 do writeWord8 mba (offset ) (fromIntegral ((shiftR n 12 ) + 0xE0))
431 writeWord8 mba (offset + 1) (fromIntegral ((shiftR n 6 .&. 0x3F) + 0x80))
313 writeWord8 mba (offset + 1) (fromIntegral ((shiftR n 6 .&. 0x3F) + 0x80))
432 writeWord8 mba (offset + 2) (fromIntegral (( n .&. 0x3F) + 0x80))
314 writeWord8 mba (offset + 2) (fromIntegral (( n .&. 0x3F) + 0x80))
433− writeString mba (offset + 3) chars
315+ writeChars mba (offset + 3) chars
435 | otherwise ->
317 | otherwise ->
436 do writeWord8 mba (offset ) (fromIntegral ((shiftR n 18 ) + 0xF0))
318 do writeWord8 mba (offset ) (fromIntegral ((shiftR n 18 ) + 0xF0))
437 writeWord8 mba (offset + 1) (fromIntegral ((shiftR n 12 .&. 0x3F) + 0x80))
319 writeWord8 mba (offset + 1) (fromIntegral ((shiftR n 12 .&. 0x3F) + 0x80))
438 writeWord8 mba (offset + 2) (fromIntegral ((shiftR n 6 .&. 0x3F) + 0x80))
320 writeWord8 mba (offset + 2) (fromIntegral ((shiftR n 6 .&. 0x3F) + 0x80))
439 writeWord8 mba (offset + 3) (fromIntegral (( n .&. 0x3F) + 0x80))
321 writeWord8 mba (offset + 3) (fromIntegral (( n .&. 0x3F) + 0x80))
440− writeString mba (offset + 4) chars
322+ writeChars mba (offset + 4) chars
443 n = Char.ord char
325 n = Char.ord char
@@ -455,10 +337,10 @@ getWidth char
458−-- TO STRING
340+-- TO CHARS
461−toChars :: Utf8 l t -> [Char]
343+toChars :: Utf8 t -> [Char]
462toChars (Utf8 ba#) =
344toChars (Utf8 ba#) =
463 toCharsHelp ba# 0# (sizeofByteArray# ba#)
345 toCharsHelp ba# 0# (sizeofByteArray# ba#)
@@ -528,13 +410,13 @@ chr4 ba# offset# firstWord# =
530{-# INLINE toBuilder #-}
412{-# INLINE toBuilder #-}
531−toBuilder :: Utf8 l t -> B.Builder
413+toBuilder :: Utf8 t -> B.Builder
532toBuilder =
414toBuilder =
533 \bytes -> B.builder (toBuilderHelp bytes)
415 \bytes -> B.builder (toBuilderHelp bytes)
536{-# INLINE toBuilderHelp #-}
418{-# INLINE toBuilderHelp #-}
537−toBuilderHelp :: Utf8 l t -> B.BuildStep a -> B.BuildStep a
419+toBuilderHelp :: Utf8 t -> B.BuildStep a -> B.BuildStep a
538toBuilderHelp !bytes@(Utf8 ba#) k =
420toBuilderHelp !bytes@(Utf8 ba#) k =
539 go 0 (I# (sizeofByteArray# ba#))
421 go 0 (I# (sizeofByteArray# ba#))
@@ -554,144 +436,109 @@ toBuilderHelp !bytes@(Utf8 ba#) k =
557−-- FROM PTR
439+-- TO ESCAPED BUILDER
442+{-# INLINE toEscapedBuilder #-}
560−fromPtr :: Ptr Word8 -> Ptr Word8 -> Utf8 l t
443+toEscapedBuilder :: Word8 -> Word8 -> Utf8 t -> B.Builder
561−fromPtr pos end =
444+toEscapedBuilder before after =
562− unsafeDupablePerformIO (stToIO (
445+ \name -> B.builder (toEscapedBuilderHelp before after name)
563− do let !len = minusPtr end pos
564− mba <- newByteArray len
565− copyFromPtr pos mba 0 len
448+{-# INLINE toEscapedBuilderHelp #-}
449+toEscapedBuilderHelp :: Word8 -> Word8 -> Utf8 t -> B.BuildStep a -> B.BuildStep a
450+toEscapedBuilderHelp before after !name@(Utf8 ba#) k =
451+ go 0 (I# (sizeofByteArray# ba#))
453+ go !offset !len !(B.BufferRange bOffset bEnd) =
455+ !bLen = minusPtr bEnd bOffset
458+ do -- TODO test if writing word-by-word is faster
459+ copyToPtr name offset bOffset len
460+ escape before after bOffset name offset len 0
461+ let !newBufferRange = B.BufferRange (plusPtr bOffset len) bEnd
464+ do copyToPtr name offset bOffset bLen
465+ escape before after bOffset name offset bLen 0
466+ let !newOffset = offset + bLen
467+ let !newLength = len - bLen
468+ return $ B.bufferFull 1 bEnd (go newOffset newLength)
471+escape :: Word8 -> Word8 -> Ptr a -> Utf8 t -> Int -> Int -> Int -> IO ()
472+escape before@(W8# before#) after ptr name@(Utf8 ba#) offset@(I# offset#) len@(I# len#) i@(I# i#) =
473+ if isTrue# (i# <# len#) then
474+ if isTrue# (eqWord# before# (indexWord8Array# ba# (offset# +# i#)))
476+ do writeWordToPtr ptr i after
477+ escape before after ptr name offset len (i + 1)
479+ do escape before after ptr name offset len (i + 1)
574−data Chunk
486+-- FROM PTR
575− = Slice (Ptr Word8) Int
580−fromChunks :: [Chunk] -> Utf8 l t
489+fromPtr :: Ptr Word8 -> Ptr Word8 -> Utf8 t
581−fromChunks chunks =
490+fromPtr pos end =
582 unsafeDupablePerformIO (stToIO (
491 unsafeDupablePerformIO (stToIO (
583− do let !len = sum (map chunkToWidth chunks)
492+ do let !len = minusPtr end pos
584 mba <- newByteArray len
493 mba <- newByteArray len
585− writeChunks mba 0 chunks
494+ copyFromPtr pos mba 0 len
586 freeze mba
495 freeze mba
590−chunkToWidth :: Chunk -> Int
600− if code < 0xFFFF then 6 else 12
603−writeChunks :: MBA RealWorld -> Int -> [Chunk] -> ST RealWorld ()
604−writeChunks mba offset chunks =
612− do copyFromPtr ptr mba offset len
613− let !newOffset = offset + len
614− writeChunks mba newOffset chunks
617− do writeWord8 mba offset 0x5C {- \ -}
618− writeWord8 mba (offset + 1) word
619− let !newOffset = offset + 2
620− writeChunks mba newOffset chunks
623− if code < 0xFFFF then
624− do writeCode mba offset code
625− let !newOffset = offset + 6
626− writeChunks mba newOffset chunks
628− do let (hi,lo) = divMod (code - 0x10000) 0x400
629− writeCode mba (offset ) (hi + 0xD800)
630− writeCode mba (offset + 6) (lo + 0xDC00)
631− let !newOffset = offset + 12
632− writeChunks mba newOffset chunks
635−-- TODO see if it is faster to writeWord32 a block of hex-as-ascii
636−writeCode :: MBA RealWorld -> Int -> Int -> ST RealWorld ()
637−writeCode mba offset code =
638− do writeWord8 mba offset 0x5C {- \ -}
639− writeWord8 mba (offset + 1) 0x75 {- u -}
640− writeHex mba (offset + 2) (shiftR code 12)
641− writeHex mba (offset + 3) (shiftR code 8)
642− writeHex mba (offset + 4) (shiftR code 4)
643− writeHex mba (offset + 5) code
646−writeHex :: MBA RealWorld -> Int -> Int -> ST RealWorld ()
647−writeHex mba !offset !bits =
648− do let !n = fromIntegral bits .&. 0x0F
649− writeWord8 mba offset (if n < 10 then 0x30 + n else 0x37 + n)
653−-- UNDER 256 BINARY
503+fromSnippet :: P.Snippet -> Utf8 t
654−
504+fromSnippet (P.Snippet fptr off len _ _) =
655−
505+ unsafeDupablePerformIO (stToIO (
656−instance Binary (Utf8 UNDER_256 t) where
506+ do mba <- newByteArray len
657− put bytes@(Utf8 ba#) =
507+ let !pos = plusPtr (unsafeForeignPtrToPtr fptr) off
658− do putWord8 (W8# (int2Word# (sizeofByteArray# ba#)))
508+ copyFromPtr pos mba 0 len
659− putBuilder (toBuilder bytes)
509+ freeze mba
661− getUnder256 =<< getWord8
664−{-# INLINE getUnder256 #-}
665−getUnder256 :: Word8 -> Get (Utf8 UNDER_256 t)
667− let !n = fromIntegral w in
668− readN n (copyFromByteString n)
672−-- VERY LONG BINARY
517+putUnder256 :: Utf8 t -> Put
519+ do putWord8 (fromIntegral (size bytes))
520+ putBuilder (toBuilder bytes)
675−instance Binary (Utf8 VERY_LONG t) where
523+getUnder256 :: Get (Utf8 t)
676− put str =
524+getUnder256 =
677− do put (size str)
525+ do word <- getWord8
678− putBuilder (toBuilder str)
526+ let !n = fromIntegral word
679− get =
527+ readN n (copyFromByteString n)
683−{-# INLINE getVeryLong #-}
530+putVeryLong :: Utf8 t -> Put
684−getVeryLong :: Int -> Get (Utf8 VERY_LONG t)
531+putVeryLong bytes =
685−getVeryLong n =
532+ do put (size bytes)
686− if n > 0
533+ putBuilder (toBuilder bytes)
687− then readN n (copyFromByteString n)
691−{-# NOINLINE empty #-}
536+getVeryLong :: Get (Utf8 t)
692−empty :: Utf8 l t
537+getVeryLong =
693−empty =
538+ do n <- get
694− runST (freeze =<< newByteArray 0)
539+ if n > 0
540+ then readN n (copyFromByteString n)
@@ -699,7 +546,7 @@ empty =
701{-# INLINE copyFromByteString #-}
548{-# INLINE copyFromByteString #-}
702−copyFromByteString :: Int -> B.ByteString -> Utf8 l t
549+copyFromByteString :: Int -> B.ByteString -> Utf8 t
703copyFromByteString len (B.PS fptr offset _) =
550copyFromByteString len (B.PS fptr offset _) =
704 unsafeDupablePerformIO
551 unsafeDupablePerformIO
@@ -725,14 +572,14 @@ newByteArray (I# len#) =
725 (# s, mba# #) -> (# s, MBA# mba# #)
572 (# s, mba# #) -> (# s, MBA# mba# #)
728−freeze :: MBA s -> ST s (Utf8 l t)
575+freeze :: MBA s -> ST s (Utf8 t)
729freeze (MBA# mba#) =
576freeze (MBA# mba#) =
730 ST $ \s ->
577 ST $ \s ->
731 case unsafeFreezeByteArray# mba# s of
578 case unsafeFreezeByteArray# mba# s of
732 (# s, ba# #) -> (# s, Utf8 ba# #)
579 (# s, ba# #) -> (# s, Utf8 ba# #)
735−copy :: Utf8 l t -> Int -> MBA s -> Int -> Int -> ST s ()
582+copy :: Utf8 t -> Int -> MBA s -> Int -> Int -> ST s ()
736copy (Utf8 ba#) (I# offset#) (MBA# mba#) (I# i#) (I# len#) =
583copy (Utf8 ba#) (I# offset#) (MBA# mba#) (I# i#) (I# len#) =
737 ST $ \s ->
584 ST $ \s ->
738 case copyByteArray# ba# offset# mba# i# len# s of
585 case copyByteArray# ba# offset# mba# i# len# s of
@@ -746,7 +593,7 @@ copyFromPtr (Ptr src#) (MBA# mba#) (I# offset#) (I# len#) =
746 s -> (# s, () #)
593 s -> (# s, () #)
749−copyToPtr :: Utf8 l t -> Int -> Ptr a -> Int -> IO ()
596+copyToPtr :: Utf8 t -> Int -> Ptr a -> Int -> IO ()
750copyToPtr (Utf8 ba#) (I# offset#) (Ptr mba#) (I# len#) =
597copyToPtr (Utf8 ba#) (I# offset#) (Ptr mba#) (I# len#) =
751 IO $ \s ->
598 IO $ \s ->
752 case copyByteArrayToAddr# ba# offset# mba# len# s of
599 case copyByteArrayToAddr# ba# offset# mba# len# s of
@@ -759,3 +606,11 @@ writeWord8 (MBA# mba#) (I# offset#) (W8# w#) =
759 ST $ \s ->
606 ST $ \s ->
760 case writeWord8Array# mba# offset# w# s of
607 case writeWord8Array# mba# offset# w# s of
761 s -> (# s, () #)
608 s -> (# s, () #)
611+{-# INLINE writeWordToPtr #-}
612+writeWordToPtr :: Ptr a -> Int -> Word8 -> IO ()
613+writeWordToPtr (Ptr addr#) (I# offset#) (W8# word#) =
615+ case writeWord8OffAddr# addr# offset# word# s of