1{-# LANGUAGE CPP, MagicHash, BangPatterns #-}
4-- Module : Data.Text.Internal.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
11-- Stability : experimental
14-- /Warning/: this is an internal module, and does not have a stable
15-- API or name. Functions in this module may not check or enforce
16-- preconditions expected by public modules. Use at your own risk!
18-- Basic UTF-8 validation and character manipulation.
19module Data.Text.Internal.Encoding.Utf8
36#if defined(TEST_SUITE)
41import Control.Exception (assert)
43import Data.Bits ((.&.))
44import Data.Text.Internal.Unsafe.Char (ord)
45import Data.Text.Internal.Unsafe.Shift (shiftR)
47import GHC.Word (Word8(..))
51between :: Word8 -- ^ byte to check
52 -> Word8 -- ^ lower bound
53 -> Word8 -- ^ upper bound
55between x y z = x >= y && x <= z
58ord2 :: Char -> (Word8,Word8)
61 assert (n >= 0x80 && n <= 0x07ff)
66 x1 = fromIntegral $ (n `shiftR` 6) + 0xC0
67 x2 = fromIntegral $ (n .&. 0x3F) + 0x80
69ord3 :: Char -> (Word8,Word8,Word8)
72 assert (n >= 0x0800 && n <= 0xffff)
77 x1 = fromIntegral $ (n `shiftR` 12) + 0xE0
78 x2 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
79 x3 = fromIntegral $ (n .&. 0x3F) + 0x80
81ord4 :: Char -> (Word8,Word8,Word8,Word8)
89 x1 = fromIntegral $ (n `shiftR` 18) + 0xF0
90 x2 = fromIntegral $ ((n `shiftR` 12) .&. 0x3F) + 0x80
91 x3 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
92 x4 = fromIntegral $ (n .&. 0x3F) + 0x80
94chr2 :: Word8 -> Word8 -> Char
95chr2 (W8# x1#) (W8# x2#) = C# (chr# (z1# +# z2#))
99 !z1# = uncheckedIShiftL# (y1# -# 0xC0#) 6#
103chr3 :: Word8 -> Word8 -> Word8 -> Char
104chr3 (W8# x1#) (W8# x2#) (W8# x3#) = C# (chr# (z1# +# z2# +# z3#))
109 !z1# = uncheckedIShiftL# (y1# -# 0xE0#) 12#
110 !z2# = uncheckedIShiftL# (y2# -# 0x80#) 6#
114chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char
115chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) =
116 C# (chr# (z1# +# z2# +# z3# +# z4#))
122 !z1# = uncheckedIShiftL# (y1# -# 0xF0#) 18#
123 !z2# = uncheckedIShiftL# (y2# -# 0x80#) 12#
124 !z3# = uncheckedIShiftL# (y3# -# 0x80#) 6#
128validate1 :: Word8 -> Bool
129validate1 x1 = x1 <= 0x7F
130{-# INLINE validate1 #-}
132validate2 :: Word8 -> Word8 -> Bool
133validate2 x1 x2 = between x1 0xC2 0xDF && between x2 0x80 0xBF
134{-# INLINE validate2 #-}
136validate3 :: Word8 -> Word8 -> Word8 -> Bool
137{-# INLINE validate3 #-}
138validate3 x1 x2 x3 = validate3_1 || validate3_2 || validate3_3 || validate3_4
140 validate3_1 = (x1 == 0xE0) &&
141 between x2 0xA0 0xBF &&
143 validate3_2 = between x1 0xE1 0xEC &&
144 between x2 0x80 0xBF &&
146 validate3_3 = x1 == 0xED &&
147 between x2 0x80 0x9F &&
149 validate3_4 = between x1 0xEE 0xEF &&
150 between x2 0x80 0xBF &&
153validate4 :: Word8 -> Word8 -> Word8 -> Word8 -> Bool
154{-# INLINE validate4 #-}
155validate4 x1 x2 x3 x4 = validate4_1 || validate4_2 || validate4_3
157 validate4_1 = x1 == 0xF0 &&
158 between x2 0x90 0xBF &&
159 between x3 0x80 0xBF &&
161 validate4_2 = between x1 0xF1 0xF3 &&
162 between x2 0x80 0xBF &&
163 between x3 0x80 0xBF &&
165 validate4_3 = x1 == 0xF4 &&
166 between x2 0x80 0x8F &&
167 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