1{-# LANGUAGE BangPatterns #-}
3-- Module : Data.Text.Encoding
4-- Copyright : (c) Tom Harper 2008-2009,
5-- (c) Bryan O'Sullivan 2009,
6-- (c) Duncan Coutts 2009
9-- Maintainer : bos@serpentine.com, rtomharper@googlemail.com,
11-- Stability : experimental
12-- Portability : portable
14-- Functions for converting 'Text' values to and from 'ByteString',
15-- using several standard encodings.
17-- To make use of a much larger variety of encodings, use the @text-icu@
20module Data.Text.Encoding
22 -- * Decoding ByteStrings to Text
29 -- ** Controllable error handling
36 -- * Encoding Text to ByteStrings
45import Data.Bits ((.&.))
46import Data.ByteString as B
47import Data.ByteString.Internal as B
48import Data.Text.Encoding.Error (OnDecodeError, strictDecode)
49import Data.Text.Encoding.Utf16 (chr2)
50import Data.Text.Internal (Text(..))
51import Data.Text.UnsafeChar (ord)
52import Data.Text.UnsafeShift (shiftL, shiftR)
53import Data.Word (Word8)
54import Foreign.ForeignPtr (withForeignPtr)
55import Foreign.Ptr (plusPtr)
56import Foreign.Storable (poke)
57import System.IO.Unsafe (unsafePerformIO)
58import qualified Data.Text.Array as A
59import qualified Data.Text.Encoding.Fusion as E
60import qualified Data.Text.Fusion as F
62-- | Decode a 'ByteString' containing 7-bit ASCII encoded text.
63decodeASCII :: ByteString -> Text
64decodeASCII bs = F.unstream (E.streamASCII bs)
65{-# INLINE decodeASCII #-}
67-- | Decode a 'ByteString' containing UTF-8 encoded text.
68decodeUtf8With :: OnDecodeError -> ByteString -> Text
69decodeUtf8With onErr bs = F.unstream (E.streamUtf8 onErr bs)
70{-# INLINE decodeUtf8With #-}
72-- | Decode a 'ByteString' containing UTF-8 encoded text.
73decodeUtf8 :: ByteString -> Text
74decodeUtf8 = decodeUtf8With strictDecode
75{-# INLINE decodeUtf8 #-}
77-- | Encode text using UTF-8 encoding.
78encodeUtf8' :: Text -> ByteString
79encodeUtf8' txt = E.unstream (E.restreamUtf8 (F.stream txt))
80{-# INLINE encodeUtf8' #-}
82-- | Encode text using UTF-8 encoding.
83encodeUtf8 :: Text -> ByteString
84encodeUtf8 (Text arr off len) = unsafePerformIO $ do
86 mallocByteString size0 >>= start size0 off 0
88 start size n0 m0 fp = withForeignPtr fp $ loop n0 m0
90 loop n1 m1 ptr = go n1 m1
93 | n-off == len = return $! PS fp 0 m
94 | size-m < 4 = {-# SCC "encodeUtf8/resize" #-} do
95 let newSize = size `shiftL` 1
96 fp' <- mallocByteString newSize
97 withForeignPtr fp' $ \ptr' -> memcpy ptr' ptr (fromIntegral m)
100 let poke8 k v = poke (ptr `plusPtr` k) (fromIntegral v :: Word8)
101 w = A.unsafeIndex arr n
107 poke8 m $ (w `shiftR` 6) + 0xC0
108 poke8 (m+1) $ (w .&. 0x3f) + 0x80
110 | 0xD800 <= w && w <= 0xDBFF -> do
111 let c = ord $ chr2 w (A.unsafeIndex arr (n+1))
112 poke8 m $ (c `shiftR` 18) + 0xF0
113 poke8 (m+1) $ ((c `shiftR` 12) .&. 0x3F) + 0x80
114 poke8 (m+2) $ ((c `shiftR` 6) .&. 0x3F) + 0x80
115 poke8 (m+3) $ (c .&. 0x3F) + 0x80
118 poke8 m $ (w `shiftR` 12) + 0xE0
119 poke8 (m+1) $ ((w `shiftR` 6) .&. 0x3F) + 0x80
120 poke8 (m+2) $ (w .&. 0x3F) + 0x80
122{- INLINE encodeUtf8 #-}
124-- | Decode text from little endian UTF-16 encoding.
125decodeUtf16LEWith :: OnDecodeError -> ByteString -> Text
126decodeUtf16LEWith onErr bs = F.unstream (E.streamUtf16LE onErr bs)
127{-# INLINE decodeUtf16LEWith #-}
129-- | Decode text from little endian UTF-16 encoding.
130decodeUtf16LE :: ByteString -> Text
131decodeUtf16LE = decodeUtf16LEWith strictDecode
132{-# INLINE decodeUtf16LE #-}
134-- | Decode text from big endian UTF-16 encoding.
135decodeUtf16BEWith :: OnDecodeError -> ByteString -> Text
136decodeUtf16BEWith onErr bs = F.unstream (E.streamUtf16BE onErr bs)
137{-# INLINE decodeUtf16BEWith #-}
139-- | Decode text from big endian UTF-16 encoding.
140decodeUtf16BE :: ByteString -> Text
141decodeUtf16BE = decodeUtf16BEWith strictDecode
142{-# INLINE decodeUtf16BE #-}
144-- | Encode text using little endian UTF-16 encoding.
145encodeUtf16LE :: Text -> ByteString
146encodeUtf16LE txt = E.unstream (E.restreamUtf16LE (F.stream txt))
147{-# INLINE encodeUtf16LE #-}
149-- | Encode text using big endian UTF-16 encoding.
150encodeUtf16BE :: Text -> ByteString
151encodeUtf16BE txt = E.unstream (E.restreamUtf16BE (F.stream txt))
152{-# INLINE encodeUtf16BE #-}
154-- | Decode text from little endian UTF-32 encoding.
155decodeUtf32LEWith :: OnDecodeError -> ByteString -> Text
156decodeUtf32LEWith onErr bs = F.unstream (E.streamUtf32LE onErr bs)
157{-# INLINE decodeUtf32LEWith #-}
159-- | Decode text from little endian UTF-32 encoding.
160decodeUtf32LE :: ByteString -> Text
161decodeUtf32LE = decodeUtf32LEWith strictDecode
162{-# INLINE decodeUtf32LE #-}
164-- | Decode text from big endian UTF-32 encoding.
165decodeUtf32BEWith :: OnDecodeError -> ByteString -> Text
166decodeUtf32BEWith onErr bs = F.unstream (E.streamUtf32BE onErr bs)
167{-# INLINE decodeUtf32BEWith #-}
169-- | Decode text from big endian UTF-32 encoding.
170decodeUtf32BE :: ByteString -> Text
171decodeUtf32BE = decodeUtf32BEWith strictDecode
172{-# INLINE decodeUtf32BE #-}
174-- | Encode text using little endian UTF-32 encoding.
175encodeUtf32LE :: Text -> ByteString
176encodeUtf32LE txt = E.unstream (E.restreamUtf32LE (F.stream txt))
177{-# INLINE encodeUtf32LE #-}
179-- | Encode text using big endian UTF-32 encoding.
180encodeUtf32BE :: Text -> ByteString
181encodeUtf32BE txt = E.unstream (E.restreamUtf32BE (F.stream txt))
182{-# INLINE encodeUtf32BE #-}
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