1{-# LANGUAGE CPP, MagicHash, BangPatterns #-}
4-- Module : Data.Text.Encoding.Utf8
5-- Copyright : (c) 2008, 2009 Tom Harper,
6-- (c) 2009, 2010 Bryan O'Sullivan,
7-- (c) 2009 Duncan Coutts
10-- Maintainer : bos@serpentine.com, rtomharper@googlemail.com,
12-- Stability : experimental
15-- Basic UTF-8 validation and character manipulation.
16module Data.Text.Encoding.Utf8
34import Control.Exception (assert)
36import Data.Bits ((.&.))
37import Data.Text.UnsafeChar (ord)
38import Data.Text.UnsafeShift (shiftR)
40import GHC.Word (Word8(..))
44between :: Word8 -- ^ byte to check
45 -> Word8 -- ^ lower bound
46 -> Word8 -- ^ upper bound
48between x y z = x >= y && x <= z
51ord2 :: Char -> (Word8,Word8)
54 assert (n >= 0x80 && n <= 0x07ff)
59 x1 = fromIntegral $ (n `shiftR` 6) + 0xC0
60 x2 = fromIntegral $ (n .&. 0x3F) + 0x80
62ord3 :: Char -> (Word8,Word8,Word8)
65 assert (n >= 0x0800 && n <= 0xffff)
70 x1 = fromIntegral $ (n `shiftR` 12) + 0xE0
71 x2 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
72 x3 = fromIntegral $ (n .&. 0x3F) + 0x80
74ord4 :: Char -> (Word8,Word8,Word8,Word8)
82 x1 = fromIntegral $ (n `shiftR` 18) + 0xF0
83 x2 = fromIntegral $ ((n `shiftR` 12) .&. 0x3F) + 0x80
84 x3 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
85 x4 = fromIntegral $ (n .&. 0x3F) + 0x80
87chr2 :: Word8 -> Word8 -> Char
88chr2 (W8# x1#) (W8# x2#) = C# (chr# (z1# +# z2#))
92 !z1# = uncheckedIShiftL# (y1# -# 0xC0#) 6#
96chr3 :: Word8 -> Word8 -> Word8 -> Char
97chr3 (W8# x1#) (W8# x2#) (W8# x3#) = C# (chr# (z1# +# z2# +# z3#))
102 !z1# = uncheckedIShiftL# (y1# -# 0xE0#) 12#
103 !z2# = uncheckedIShiftL# (y2# -# 0x80#) 6#
107chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char
108chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) =
109 C# (chr# (z1# +# z2# +# z3# +# z4#))
115 !z1# = uncheckedIShiftL# (y1# -# 0xF0#) 18#
116 !z2# = uncheckedIShiftL# (y2# -# 0x80#) 12#
117 !z3# = uncheckedIShiftL# (y3# -# 0x80#) 6#
121validate1 :: Word8 -> Bool
122validate1 x1 = x1 <= 0x7F
123{-# INLINE validate1 #-}
125validate2 :: Word8 -> Word8 -> Bool
126validate2 x1 x2 = between x1 0xC2 0xDF && between x2 0x80 0xBF
127{-# INLINE validate2 #-}
129validate3 :: Word8 -> Word8 -> Word8 -> Bool
130{-# INLINE validate3 #-}
131validate3 x1 x2 x3 = validate3_1 || validate3_2 || validate3_3 || validate3_4
133 validate3_1 = (x1 == 0xE0) &&
134 between x2 0xA0 0xBF &&
136 validate3_2 = between x1 0xE1 0xEC &&
137 between x2 0x80 0xBF &&
139 validate3_3 = x1 == 0xED &&
140 between x2 0x80 0x9F &&
142 validate3_4 = between x1 0xEE 0xEF &&
143 between x2 0x80 0xBF &&
146validate4 :: Word8 -> Word8 -> Word8 -> Word8 -> Bool
147{-# INLINE validate4 #-}
148validate4 x1 x2 x3 x4 = validate4_1 || validate4_2 || validate4_3
150 validate4_1 = x1 == 0xF0 &&
151 between x2 0x90 0xBF &&
152 between x3 0x80 0xBF &&
154 validate4_2 = between x1 0xF1 0xF3 &&
155 between x2 0x80 0xBF &&
156 between x3 0x80 0xBF &&
158 validate4_3 = x1 == 0xF4 &&
159 between x2 0x80 0x8F &&
160 between x3 0x80 0xBF &&
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list