1{-# LANGUAGE CPP, DeriveDataTypeable, UnboxedTuples #-}
2{-# OPTIONS_HADDOCK not-home #-}
5-- Module : Data.Text.Internal
6-- Copyright : (c) 2008, 2009 Tom Harper,
7-- (c) 2009, 2010 Bryan O'Sullivan,
8-- (c) 2009 Duncan Coutts
11-- Maintainer : bos@serpentine.com
12-- Stability : experimental
15-- A module containing private 'Text' internals. This exposes the
16-- 'Text' representation and low level construction functions.
17-- Modules which extend the 'Text' system may need to use this module.
19-- You should not use this module unless you are determined to monkey
20-- with the internals, as the functions here do just about nothing to
21-- preserve data invariants. You have been warned!
23#if defined(__GLASGOW_HASKELL__) && !defined(__HADDOCK__)
27module Data.Text.Internal
37 -- * Code that must be here for accessibility
42 -- * Checked multiplication
51import Control.Exception (assert)
54import Data.Int (Int32, Int64)
55import Data.Text.Internal.Unsafe.Char (ord)
56import Data.Typeable (Typeable)
57import qualified Data.Text.Array as A
59-- | A space efficient, packed, unboxed Unicode text type.
61 {-# UNPACK #-} !A.Array -- payload (Word16 elements)
62 {-# UNPACK #-} !Int -- offset (units of Word16, not Char)
63 {-# UNPACK #-} !Int -- length (units of Word16, not Char)
66-- | Smart constructor.
67text_ :: A.Array -> Int -> Int -> Text
70 let c = A.unsafeIndex arr off
72 in assert (len >= 0) .
74 assert (alen == 0 || len == 0 || off < alen) .
75 assert (len == 0 || c < 0xDC00 || c > 0xDFFF) $
80-- | /O(1)/ The empty 'Text'.
82empty = Text A.empty 0 0
83{-# INLINE [1] empty #-}
85-- | A non-inlined version of 'empty'.
87empty_ = Text A.empty 0 0
88{-# NOINLINE empty_ #-}
90-- | Construct a 'Text' without invisibly pinning its byte array in
91-- memory if its length has dwindled to zero.
92text :: A.Array -> Int -> Int -> Text
93text arr off len | len == 0 = empty
94 | otherwise = text_ arr off len
97textP :: A.Array -> Int -> Int -> Text
98{-# DEPRECATED textP "Use text instead" #-}
101-- | A useful 'show'-like function for debugging purposes.
102showText :: Text -> String
103showText (Text arr off len) =
104 "Text " ++ show (A.toList arr off len) ++ ' ' :
105 show off ++ ' ' : show len
107-- | Map a 'Char' to a 'Text'-safe value.
109-- UTF-16 surrogate code points are not included in the set of Unicode
110-- scalar values, but are unfortunately admitted as valid 'Char'
111-- values by Haskell. They cannot be represented in a 'Text'. This
112-- function remaps those code points to the Unicode replacement
113-- character (U+FFFD, \'�\'), and leaves other code points
117 | ord c .&. 0x1ff800 /= 0xd800 = c
118 | otherwise = '\xfffd'
119{-# INLINE [0] safe #-}
121-- | Apply a function to the first element of an optional pair.
122firstf :: (a -> c) -> Maybe (a,b) -> Maybe (c,b)
123firstf f (Just (a, b)) = Just (f a, b)
124firstf _ Nothing = Nothing
126-- | Checked multiplication. Calls 'error' if the result would
128mul :: Int -> Int -> Int
129#if WORD_SIZE_IN_BITS == 64
130mul a b = fromIntegral $ fromIntegral a `mul64` fromIntegral b
132mul a b = fromIntegral $ fromIntegral a `mul32` fromIntegral b
137-- | Checked multiplication. Calls 'error' if the result would
139mul64 :: Int64 -> Int64 -> Int64
141 | a >= 0 && b >= 0 = mul64_ a b
142 | a >= 0 = -mul64_ a (-b)
143 | b >= 0 = -mul64_ (-a) b
144 | otherwise = mul64_ (-a) (-b)
148mul64_ :: Int64 -> Int64 -> Int64
150 | ahi > 0 && bhi > 0 = error "overflow"
151 | top > 0x7fffffff = error "overflow"
152 | total < 0 = error "overflow"
154 where (# ahi, alo #) = (# a `shiftR` 32, a .&. 0xffffffff #)
155 (# bhi, blo #) = (# b `shiftR` 32, b .&. 0xffffffff #)
156 top = ahi * blo + alo * bhi
157 total = (top `shiftL` 32) + alo * blo
160-- | Checked multiplication. Calls 'error' if the result would
162mul32 :: Int32 -> Int32 -> Int32
163mul32 a b = case fromIntegral a * fromIntegral b of
164 ab | ab < min32 || ab > max32 -> error "overflow"
165 | otherwise -> fromIntegral ab
166 where min32 = -0x80000000 :: Int64
173-- Internally, the 'Text' type is represented as an array of 'Word16'
174-- UTF-16 code units. The offset and length fields in the constructor
175-- are in these units, /not/ units of 'Char'.
177-- Invariants that all functions must maintain:
179-- * Since the 'Text' type uses UTF-16 internally, it cannot represent
180-- characters in the reserved surrogate code point range U+D800 to
181-- U+DFFF. To maintain this invariant, the 'safe' function maps
182-- 'Char' values in this range to the replacement character (U+FFFD,
185-- * A leading (or \"high\") surrogate code unit (0xD800–0xDBFF) must
186-- always be followed by a trailing (or \"low\") surrogate code unit
187-- (0xDC00-0xDFFF). A trailing surrogate code unit must always be
188-- preceded by a leading surrogate code unit.
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