on master help sign in
Add Utf8.toString
f368d89Evan Czaplicki
compiler/src/Data/Utf8.hs+78−5
@@ -1,7 +1,8 @@
1{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
1{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
2{-# LANGUAGE BangPatterns, MagicHash, UnboxedTuples #-}
2{-# LANGUAGE BangPatterns, MagicHash, UnboxedTuples #-}
3module Data.Utf8
3module Data.Utf8
4− ( Utf8
4+ ( Utf8(..)
5+ , toString
5 , toBuilder
6 , toBuilder
6 , fromChunks
7 , fromChunks
7 , Chunk(..)
8 , Chunk(..)
@@ -19,7 +20,7 @@ import Foreign.ForeignPtr (ForeignPtr, touchForeignPtr)
19import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
20import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
20import Foreign.Ptr (minusPtr, plusPtr)
21import Foreign.Ptr (minusPtr, plusPtr)
21import GHC.Exts
22import GHC.Exts
22− ( Int(I#), Ptr(Ptr)
23+ ( Int(I#), Ptr(Ptr), Char(C#)
23 , RealWorld
24 , RealWorld
24 , ByteArray#, MutableByteArray#
25 , ByteArray#, MutableByteArray#
25 , isTrue#
26 , isTrue#
@@ -92,14 +93,14 @@ instance Binary Utf8 where
92getUtf8 :: Int -> Get Utf8
93getUtf8 :: Int -> Get Utf8
93getUtf8 n =
94getUtf8 n =
94 if n > 0 then
95 if n > 0 then
95− readN n (fromByteString n)
96+ readN n (copyFromByteString n)
96 else
97 else
97 return empty
98 return empty
98
99
99
100
100-- TODO add inline?
101-- TODO add inline?
101−fromByteString :: Int -> B.ByteString -> Utf8
102+copyFromByteString :: Int -> B.ByteString -> Utf8
102−fromByteString len (B.PS fptr offset _) =
103+copyFromByteString len (B.PS fptr offset _) =
103 unsafeDupablePerformIO
104 unsafeDupablePerformIO
104 (
105 (
105 do mba <- stToIO (newByteArray len)
106 do mba <- stToIO (newByteArray len)
@@ -228,6 +229,78 @@ toBuilderHelp !utf8@(Utf8 ba#) k =
228
229
229
230
230
231
232+-- TO STRING
233+
234+
235+toString :: Utf8 -> String
236+toString (Utf8 ba#) =
237+ let
238+ !len# = sizeofByteArray# ba#
239+ in
240+ toStringHelp ba# 0# len#
241+
242+
243+toStringHelp :: ByteArray# -> Int# -> Int# -> String
244+toStringHelp ba# offset# len# =
245+ if isTrue# (offset# >=# len#) then
246+ []
247+ else
248+ let
249+ !w# = indexWord8Array# ba# offset#
250+ !(# char, width# #)
251+ | isTrue# (ltWord# w# 0xC0##) = (# C# (chr# (word2Int# w#)), 1# #)
252+ | isTrue# (ltWord# w# 0xE0##) = (# chr2 ba# offset# w#, 2# #)
253+ | isTrue# (ltWord# w# 0xF0##) = (# chr3 ba# offset# w#, 3# #)
254+ | True = (# chr4 ba# offset# w#, 4# #)
255+
256+ !newOffset# = offset# +# width#
257+ in
258+ char : toStringHelp ba# newOffset# len#
259+
260+
261+{-# INLINE chr2 #-}
262+chr2 :: ByteArray# -> Int# -> Word# -> Char
263+chr2 ba# offset# firstWord# =
264+ let
265+ !i1# = word2Int# firstWord#
266+ !i2# = word2Int# (indexWord8Array# ba# (offset# +# 1#))
267+ !c1# = uncheckedIShiftL# (i1# -# 0xC0#) 6#
268+ !c2# = i2# -# 0x80#
269+ in
270+ C# (chr# (c1# +# c2#))
271+
272+
273+{-# INLINE chr3 #-}
274+chr3 :: ByteArray# -> Int# -> Word# -> Char
275+chr3 ba# offset# firstWord# =
276+ let
277+ !i1# = word2Int# firstWord#
278+ !i2# = word2Int# (indexWord8Array# ba# (offset# +# 1#))
279+ !i3# = word2Int# (indexWord8Array# ba# (offset# +# 2#))
280+ !c1# = uncheckedIShiftL# (i1# -# 0xE0#) 12#
281+ !c2# = uncheckedIShiftL# (i2# -# 0x80#) 6#
282+ !c3# = i3# -# 0x80#
283+ in
284+ C# (chr# (c1# +# c2# +# c3#))
285+
286+
287+{-# INLINE chr4 #-}
288+chr4 :: ByteArray# -> Int# -> Word# -> Char
289+chr4 ba# offset# firstWord# =
290+ let
291+ !i1# = word2Int# firstWord#
292+ !i2# = word2Int# (indexWord8Array# ba# (offset# +# 1#))
293+ !i3# = word2Int# (indexWord8Array# ba# (offset# +# 2#))
294+ !i4# = word2Int# (indexWord8Array# ba# (offset# +# 3#))
295+ !c1# = uncheckedIShiftL# (i1# -# 0xF0#) 18#
296+ !c2# = uncheckedIShiftL# (i2# -# 0x80#) 12#
297+ !c3# = uncheckedIShiftL# (i3# -# 0x80#) 6#
298+ !c4# = i4# -# 0x80#
299+ in
300+ C# (chr# (c1# +# c2# +# c3# +# c4#))
301+
302+
303+
231-- PRIMITIVES
304-- PRIMITIVES
232
305
233
306