{-# LANGUAGE DeriveDataTypeable #-}
module Text.XML.HXT.DOM.QualifiedName
    ( QName
    , XName(unXN)
    , NsEnv
    , mkQName
    , mkName
    , mkNsName
    , mkSNsName
    , mkPrefixLocalPart
    , equivQName
    , equivUri
    , equalQNameBy
    , namePrefix
    , localPart
    , namespaceUri
    , newXName
    , nullXName
    , isNullXName
    , newQName
    , mkQName'
    , namePrefix'
    , localPart'
    , namespaceUri'
    , setNamePrefix'
    , setLocalPart'
    , setNamespaceUri'
    , qualifiedName
    , qualifiedName'
    , universalName
    , universalUri
    , buildUniversalName
    , normalizeNsUri
    , setNamespace                      
    , isNCName
    , isWellformedQualifiedName
    , isWellformedQName
    , isWellformedNSDecl
    , isWellformedNameSpaceName
    , isNameSpaceName
    , isDeclaredNamespace
    , xmlNamespaceXName
    , xmlXName
    , xmlnsNamespaceXName
    , xmlnsXName
    , xmlnsQN
    , toNsEnv
    )
where
import           Control.Arrow                     ((***))
import           Control.DeepSeq
import           Control.FlatSeq
import           Data.AssocList
import           Data.Binary
import           Data.Char                         (toLower)
import           Data.IORef
import           Data.List                         (isPrefixOf)
import qualified Data.Map                          as M
import           Data.Typeable
import           System.IO.Unsafe                  (unsafePerformIO)
import           Text.XML.HXT.DOM.XmlKeywords      (a_xml, a_xmlns,
                                                    xmlNamespace,
                                                    xmlnsNamespace)
import           Data.Char.Properties.XMLCharProps (isXmlNCNameChar,
                                                    isXmlNCNameStartChar)
data XName                      = XN { XName -> Int
_idXN :: !Int        
                                     ,  XName -> String
unXN ::   String
                                     }
                                  deriving (Typeable)
instance Eq XName where
    (XN Int
id1 String
_) == :: XName -> XName -> Bool
== (XN Int
id2 String
_)    = Int
id1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
id2
instance Ord XName where
    compare :: XName -> XName -> Ordering
compare (XN Int
_ String
n1) (XN Int
_ String
n2) = String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
compare String
n1 String
n2
instance NFData XName where
    rnf :: XName -> ()
rnf (XN Int
_ String
s)                = String -> ()
forall a. NFData a => a -> ()
rnf String
s
instance WNFData XName where
    rwnf :: XName -> ()
rwnf (XN Int
_ String
s)               = String -> ()
forall a. NFData a => a -> ()
rnf String
s
instance Binary XName where
    put :: XName -> Put
put (XN Int
_ String
s)                = String -> Put
forall t. Binary t => t -> Put
put String
s
    get :: Get XName
get                         = do
                                  String
s <- Get String
forall t. Binary t => Get t
get
                                  XName -> Get XName
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (XName -> Get XName) -> XName -> Get XName
forall a b. (a -> b) -> a -> b
$! String -> XName
newXName String
s
type NsEnv              = AssocList XName XName
data QName      = QN { QName -> XName
localPart'    :: !XName
                     , QName -> XName
namePrefix'   :: !XName
                     , QName -> XName
namespaceUri' :: !XName
                     }
             deriving (Typeable)
instance Eq QName where
    (QN XName
lp1 XName
px1 XName
ns1) == :: QName -> QName -> Bool
== (QN XName
lp2 XName
px2 XName
ns2)
        | XName
ns1 XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
/= XName
ns2            = Bool
False                 
        | Bool -> Bool
not (XName -> Bool
isNullXName XName
ns1) = XName
lp1 XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
lp2            
        | Bool
otherwise             = XName
lp1 XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
lp2            
                                  Bool -> Bool -> Bool
&&                    
                                  XName
px1 XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
px2
instance Ord QName where
  compare :: QName -> QName -> Ordering
compare (QN XName
lp1 XName
px1 XName
ns1) (QN XName
lp2 XName
px2 XName
ns2)
      | XName -> Bool
isNullXName XName
ns1 Bool -> Bool -> Bool
&& XName -> Bool
isNullXName XName
ns2              
          = (XName, XName) -> (XName, XName) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (XName
px1, XName
lp1) (XName
px2, XName
lp2)
      | Bool
otherwise                                       
          = (XName, XName) -> (XName, XName) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (XName
lp1, XName
ns1) (XName
lp2, XName
ns2)
instance NFData  QName where
    rnf :: QName -> ()
rnf QName
x = QName -> () -> ()
forall a b. a -> b -> b
seq QName
x ()
instance WNFData QName
instance Show QName where
    show :: QName -> String
show = QName -> String
showQN
instance Binary QName where
    put :: QName -> Put
put (QN XName
lp XName
px XName
ns)   = String -> Put
forall t. Binary t => t -> Put
put (XName -> String
unXN XName
px) Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                          String -> Put
forall t. Binary t => t -> Put
put (XName -> String
unXN XName
lp) Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                          String -> Put
forall t. Binary t => t -> Put
put (XName -> String
unXN XName
ns)
    get :: Get QName
get                 = do
                          String
px <- Get String
forall t. Binary t => Get t
get
                          String
lp <- Get String
forall t. Binary t => Get t
get
                          String
ns <- Get String
forall t. Binary t => Get t
get
                          QName -> Get QName
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (QName -> Get QName) -> QName -> Get QName
forall a b. (a -> b) -> a -> b
$! String -> String -> String -> QName
newNsName String
lp String
px String
ns
                          
                          
                          
isNullXName             :: XName -> Bool
isNullXName :: XName -> Bool
isNullXName             = (XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
nullXName)
{-# INLINE isNullXName #-}
namePrefix              :: QName -> String
namePrefix :: QName -> String
namePrefix              = XName -> String
unXN (XName -> String) -> (QName -> XName) -> QName -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QName -> XName
namePrefix'
{-# INLINE namePrefix #-}
localPart               :: QName -> String
localPart :: QName -> String
localPart               = XName -> String
unXN (XName -> String) -> (QName -> XName) -> QName -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QName -> XName
localPart'
{-# INLINE localPart #-}
namespaceUri            :: QName -> String
namespaceUri :: QName -> String
namespaceUri            = XName -> String
unXN (XName -> String) -> (QName -> XName) -> QName -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QName -> XName
namespaceUri'
{-# INLINE namespaceUri #-}
setNamespaceUri'                        :: XName -> QName -> QName
setNamespaceUri' :: XName -> QName -> QName
setNamespaceUri' XName
ns (QN XName
lp XName
px XName
_ns)      = XName -> XName -> XName -> QName
newQName XName
lp XName
px XName
ns
setLocalPart'                           :: XName -> QName -> QName
setLocalPart' :: XName -> QName -> QName
setLocalPart' XName
lp (QN XName
_lp XName
px XName
ns)         = XName -> XName -> XName -> QName
newQName XName
lp XName
px XName
ns
setNamePrefix'                          :: XName -> QName -> QName
setNamePrefix' :: XName -> QName -> QName
setNamePrefix' XName
px (QN XName
lp XName
_px XName
ns)        = XName -> XName -> XName -> QName
newQName XName
lp XName
px XName
ns
qualifiedName                   :: QName -> String
qualifiedName :: QName -> String
qualifiedName (QN XName
lp XName
px XName
_ns)
    | XName -> Bool
isNullXName XName
px            = XName -> String
unXN XName
lp
    | Bool
otherwise                 = XName -> String
unXN XName
px String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Char
':' Char -> ShowS
forall a. a -> [a] -> [a]
: XName -> String
unXN XName
lp)
qualifiedName'                   :: QName -> String -> String
qualifiedName' :: QName -> ShowS
qualifiedName' (QN XName
lp XName
px XName
_ns)
    | XName -> Bool
isNullXName XName
px            = (XName -> String
unXN XName
lp String -> ShowS
forall a. [a] -> [a] -> [a]
++)
    | Bool
otherwise                 = (XName -> String
unXN XName
px String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char
':' Char -> ShowS
forall a. a -> [a] -> [a]
:) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (XName -> String
unXN XName
lp String -> ShowS
forall a. [a] -> [a] -> [a]
++)
universalName                   :: QName -> String
universalName :: QName -> String
universalName                   = (String -> ShowS) -> QName -> String
buildUniversalName (\ String
ns String
lp -> Char
'{' Char -> ShowS
forall a. a -> [a] -> [a]
: String
ns String -> ShowS
forall a. [a] -> [a] -> [a]
++ Char
'}' Char -> ShowS
forall a. a -> [a] -> [a]
: String
lp)
universalUri                    :: QName -> String
universalUri :: QName -> String
universalUri                    = (String -> ShowS) -> QName -> String
buildUniversalName String -> ShowS
forall a. [a] -> [a] -> [a]
(++)
buildUniversalName              :: (String -> String -> String) -> QName -> String
buildUniversalName :: (String -> ShowS) -> QName -> String
buildUniversalName String -> ShowS
bf n :: QName
n@(QN XName
_lp XName
_px XName
ns)
    | XName -> Bool
isNullXName XName
ns            = QName -> String
localPart QName
n
    | Bool
otherwise                 = XName -> String
unXN XName
ns String -> ShowS
`bf` QName -> String
localPart QName
n
showQN                          :: QName -> String
showQN :: QName -> String
showQN QName
n
    | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
ns                   = ShowS
forall a. Show a => a -> String
show ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ QName -> String
qualifiedName QName
n
    | Bool
otherwise                 = ShowS
forall a. Show a => a -> String
show ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String
"{" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
ns String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"}" String -> ShowS
forall a. [a] -> [a] -> [a]
++ QName -> String
qualifiedName QName
n
    where
    ns :: String
ns = QName -> String
namespaceUri QName
n
mkQName'                        :: XName -> XName -> XName -> QName
mkQName' :: XName -> XName -> XName -> QName
mkQName' XName
px XName
lp XName
ns               = XName -> XName -> XName -> QName
newQName XName
lp XName
px XName
ns
{-# DEPRECATED mkQName' "use newQName instead with lp px ns param seq " #-}
mkPrefixLocalPart               :: String -> String -> QName
mkPrefixLocalPart :: String -> String -> QName
mkPrefixLocalPart String
px String
lp
    | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
px                   = String -> QName
newLpName String
lp
    | Bool
otherwise                 = String -> String -> QName
newPxName String
lp String
px
mkName                          :: String -> QName
mkName :: String -> QName
mkName String
n
    | (Char
':' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
n)
      Bool -> Bool -> Bool
&&
      Bool -> Bool
not (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
px)                     
                                = String -> String -> QName
newPxName String
lp String
px
    | Bool
otherwise                 = String -> QName
newLpName String
n
    where
    (String
px, (Char
_ : String
lp)) = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
':') String
n
mkQName                         :: String -> String -> String -> QName
mkQName :: String -> String -> String -> QName
mkQName String
px String
lp String
ns
    | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
ns                   = String -> String -> QName
mkPrefixLocalPart String
px String
lp
    | Bool
otherwise                 = String -> String -> String -> QName
newNsName String
lp String
px String
ns
mkSNsName                       :: String -> QName
mkSNsName :: String -> QName
mkSNsName                       = String -> QName
mkName
{-# DEPRECATED mkSNsName "use mkName instead" #-}
mkNsName                          :: String -> String -> QName
mkNsName :: String -> String -> QName
mkNsName String
n String
ns
    | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
ns                   = QName
qn
    | Bool
otherwise                 = XName -> QName -> QName
setNamespaceUri' XName
ns' QName
qn
    where
    qn :: QName
qn                          = String -> QName
mkName String
n
    ns' :: XName
ns'                         = String -> XName
newXName String
ns
equivQName                      :: QName -> QName -> Bool
equivQName :: QName -> QName -> Bool
equivQName                      = (String -> String -> Bool) -> QName -> QName -> Bool
equalQNameBy String -> String -> Bool
equivUri
equivUri                        :: String -> String -> Bool
equivUri :: String -> String -> Bool
equivUri String
x String
y                    = ShowS
normalizeNsUri String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== ShowS
normalizeNsUri String
y
equalQNameBy                    :: (String -> String -> Bool) -> QName -> QName -> Bool
equalQNameBy :: (String -> String -> Bool) -> QName -> QName -> Bool
equalQNameBy String -> String -> Bool
equiv QName
q1 QName
q2        = QName -> String
localPart QName
q1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== QName -> String
localPart QName
q2
                                  Bool -> Bool -> Bool
&&
                                  (QName -> String
namespaceUri QName
q1 String -> String -> Bool
`equiv` QName -> String
namespaceUri QName
q2)
normalizeNsUri                  :: String -> String
normalizeNsUri :: ShowS
normalizeNsUri                  = (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
stripSlash
    where
    stripSlash :: ShowS
stripSlash String
""               = String
""
    stripSlash String
s
        | String -> Char
forall a. HasCallStack => [a] -> a
last String
s Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'/'         = ShowS
forall a. HasCallStack => [a] -> [a]
init String
s
        | Bool
otherwise             = String
s
setNamespace                    :: NsEnv -> QName -> QName
setNamespace :: NsEnv -> QName -> QName
setNamespace NsEnv
env n :: QName
n@(QN XName
lp XName
px XName
_ns)
                                = QName -> (XName -> QName) -> Maybe XName -> QName
forall b a. b -> (a -> b) -> Maybe a -> b
maybe QName
n (\ XName
ns -> XName -> XName -> XName -> QName
newQName XName
lp XName
px XName
ns) (Maybe XName -> QName) -> (NsEnv -> Maybe XName) -> NsEnv -> QName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XName -> NsEnv -> Maybe XName
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup XName
px (NsEnv -> QName) -> NsEnv -> QName
forall a b. (a -> b) -> a -> b
$ NsEnv
env
isNCName                        :: String -> Bool
isNCName :: String -> Bool
isNCName []                     = Bool
False
isNCName String
n                      = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ( ((Char -> Bool) -> Char -> Bool)
-> [Char -> Bool] -> String -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Char -> Bool) -> Char -> Bool
forall a b. (a -> b) -> a -> b
($)
                                        (Char -> Bool
isXmlNCNameStartChar (Char -> Bool) -> [Char -> Bool] -> [Char -> Bool]
forall a. a -> [a] -> [a]
: (Char -> Bool) -> [Char -> Bool]
forall a. a -> [a]
repeat Char -> Bool
isXmlNCNameChar)
                                        String
n
                                      )
isWellformedQualifiedName       :: String -> Bool
isWellformedQualifiedName :: String -> Bool
isWellformedQualifiedName String
s
    | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
lp                   = String -> Bool
isNCName String
px
    | Bool
otherwise                 = String -> Bool
isNCName String
px Bool -> Bool -> Bool
&& String -> Bool
isNCName (ShowS
forall a. HasCallStack => [a] -> [a]
tail String
lp)
    where
    (String
px, String
lp)                    = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
':') String
s
isWellformedQName               :: QName -> Bool
isWellformedQName :: QName -> Bool
isWellformedQName (QN XName
lp XName
px XName
_ns)
                                = (String -> Bool
isNCName (String -> Bool) -> (XName -> String) -> XName -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XName -> String
unXN) XName
lp                          
                                  Bool -> Bool -> Bool
&&
                                  ( XName -> Bool
isNullXName XName
px
                                    Bool -> Bool -> Bool
||
                                    (String -> Bool
isNCName (String -> Bool) -> (XName -> String) -> XName -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XName -> String
unXN) XName
px                        
                                  )
isWellformedNSDecl              :: QName -> Bool
isWellformedNSDecl :: QName -> Bool
isWellformedNSDecl QName
n
                                = Bool -> Bool
not (QName -> Bool
isNameSpaceName QName
n)
                                  Bool -> Bool -> Bool
||
                                  QName -> Bool
isWellformedNameSpaceName QName
n
isWellformedNameSpaceName       :: QName -> Bool
isWellformedNameSpaceName :: QName -> Bool
isWellformedNameSpaceName n :: QName
n@(QN XName
lp XName
px XName
_ns)
    | XName -> Bool
isNullXName XName
px            = XName
lp XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
xmlnsXName
    | Bool
otherwise                 = XName
px XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
xmlnsXName
                                  Bool -> Bool -> Bool
&&
                                  Bool -> Bool
not (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
lp')
                                  Bool -> Bool -> Bool
&&
                                  Bool -> Bool
not (String
a_xml String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
lp')
    where
    lp' :: String
lp'                         = QName -> String
localPart QName
n
isNameSpaceName                         :: QName -> Bool
isNameSpaceName :: QName -> Bool
isNameSpaceName (QN XName
lp XName
px XName
_ns)
    | XName -> Bool
isNullXName XName
px                    = XName
lp XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
xmlnsXName
    | Bool
otherwise                         = XName
px XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
xmlnsXName
isDeclaredNamespace                     :: QName -> Bool
isDeclaredNamespace :: QName -> Bool
isDeclaredNamespace (QN XName
_lp XName
px XName
ns)
    | XName -> Bool
isNullXName XName
px                    = Bool
True                          
    | XName
px XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
xmlnsXName                  = XName
ns XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
xmlnsNamespaceXName     
    | XName
px XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
xmlXName                    = XName
ns XName -> XName -> Bool
forall a. Eq a => a -> a -> Bool
== XName
xmlNamespaceXName       
    | Bool
otherwise                         = Bool -> Bool
not (XName -> Bool
isNullXName XName
ns)          
toNsEnv                         :: AssocList String String -> NsEnv
toNsEnv :: AssocList String String -> NsEnv
toNsEnv                         = ((String, String) -> (XName, XName))
-> AssocList String String -> NsEnv
forall a b. (a -> b) -> [a] -> [b]
map (String -> XName
newXName (String -> XName)
-> (String -> XName) -> (String, String) -> (XName, XName)
forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** String -> XName
newXName)
data NameCache          = NC { NameCache -> Int
_newXN   :: !Int                                       
                             , NameCache -> Map String XName
_xnCache :: !(M.Map String XName)
                             , NameCache -> Map (XName, XName, XName) QName
_qnCache :: !(M.Map (XName, XName, XName) QName)       
                             }                                                          
                                                                                        
type ChangeNameCache r  = NameCache -> (NameCache, r)
theNameCache            :: IORef NameCache
theNameCache :: IORef NameCache
theNameCache            = IO (IORef NameCache) -> IORef NameCache
forall a. IO a -> a
unsafePerformIO (NameCache -> IO (IORef NameCache)
forall a. a -> IO (IORef a)
newIORef (NameCache -> IO (IORef NameCache))
-> NameCache -> IO (IORef NameCache)
forall a b. (a -> b) -> a -> b
$ NameCache
initialCache)
{-# NOINLINE theNameCache #-}
initialXNames           :: [XName]
nullXName
 , xmlnsNamespaceXName
 , xmlnsXName
 , xmlNamespaceXName
 , xmlXName             :: XName
initialXNames :: [XName]
initialXNames@[
   XName
nullXName
 , XName
xmlnsNamespaceXName
 , XName
xmlnsXName
 , XName
xmlNamespaceXName
 , XName
xmlXName
 ]                      = (Int -> String -> XName) -> [Int] -> [String] -> [XName]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> String -> XName
XN [Int
0..] ([String] -> [XName]) -> [String] -> [XName]
forall a b. (a -> b) -> a -> b
$
                          [ String
""
                          , String
xmlnsNamespace
                          , String
a_xmlns
                          , String
xmlNamespace
                          , String
a_xml
                          ]
initialQNames           :: [QName]
xmlnsQN                 :: QName
initialQNames :: [QName]
initialQNames@[QName
xmlnsQN] = [XName -> XName -> XName -> QName
QN XName
xmlnsXName XName
nullXName XName
xmlnsNamespaceXName]
initialCache            :: NameCache
initialCache :: NameCache
initialCache            = Int
-> Map String XName -> Map (XName, XName, XName) QName -> NameCache
NC
                          ([XName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [XName]
initialXNames)
                          ([(String, XName)] -> Map String XName
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(String, XName)] -> Map String XName)
-> [(String, XName)] -> Map String XName
forall a b. (a -> b) -> a -> b
$ (XName -> (String, XName)) -> [XName] -> [(String, XName)]
forall a b. (a -> b) -> [a] -> [b]
map (\ XName
xn -> (XName -> String
unXN XName
xn, XName
xn)) [XName]
initialXNames)
                          ([((XName, XName, XName), QName)] -> Map (XName, XName, XName) QName
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([((XName, XName, XName), QName)]
 -> Map (XName, XName, XName) QName)
-> [((XName, XName, XName), QName)]
-> Map (XName, XName, XName) QName
forall a b. (a -> b) -> a -> b
$ (QName -> ((XName, XName, XName), QName))
-> [QName] -> [((XName, XName, XName), QName)]
forall a b. (a -> b) -> [a] -> [b]
map (\ qn :: QName
qn@(QN XName
lp XName
px XName
ns) -> ((XName
lp, XName
px, XName
ns), QName
qn)) [QName]
initialQNames)
changeNameCache         :: NFData r => ChangeNameCache r -> r
changeNameCache :: forall r. NFData r => ChangeNameCache r -> r
changeNameCache ChangeNameCache r
action  = IO r -> r
forall a. IO a -> a
unsafePerformIO IO r
changeNameCache'
    where
    action' :: ChangeNameCache r
action' NameCache
c =
      let r :: (NameCache, r)
r = ChangeNameCache r
action NameCache
c
      in
       (NameCache, r) -> NameCache
forall a b. (a, b) -> a
fst (NameCache, r)
r NameCache -> (NameCache, r) -> (NameCache, r)
forall a b. a -> b -> b
`seq` (NameCache, r)
r    
    changeNameCache' :: IO r
changeNameCache' =
      do
      
      r
res <- IORef NameCache -> ChangeNameCache r -> IO r
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef IORef NameCache
theNameCache ChangeNameCache r
action'
      
      r -> IO r
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return r
res
{-# NOINLINE changeNameCache #-}
newXName'               :: String -> ChangeNameCache XName
newXName' :: String -> ChangeNameCache XName
newXName' String
n c :: NameCache
c@(NC Int
nxn Map String XName
xm Map (XName, XName, XName) QName
qm)
                        = case String -> Map String XName -> Maybe XName
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
n Map String XName
xm of
                          Just XName
xn       -> (NameCache
c, XName
xn)
                          Maybe XName
Nothing       -> let nxn' :: Int
nxn' = Int
nxn Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 in
                                           let xn :: XName
xn   = (Int -> String -> XName
XN Int
nxn String
n) in
                                           let xm' :: Map String XName
xm'  = String -> XName -> Map String XName -> Map String XName
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert String
n XName
xn Map String XName
xm in
                                           
                                           XName -> ()
forall a. NFData a => a -> ()
rnf XName
xn () -> (NameCache, XName) -> (NameCache, XName)
forall a b. a -> b -> b
`seq` (Int
-> Map String XName -> Map (XName, XName, XName) QName -> NameCache
NC Int
nxn' Map String XName
xm' Map (XName, XName, XName) QName
qm, XName
xn)
newQName'               :: XName -> XName -> XName -> ChangeNameCache QName
newQName' :: XName -> XName -> XName -> ChangeNameCache QName
newQName' XName
lp XName
px XName
ns c :: NameCache
c@(NC Int
nxn Map String XName
xm Map (XName, XName, XName) QName
qm)
                        = case (XName, XName, XName)
-> Map (XName, XName, XName) QName -> Maybe QName
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup (XName, XName, XName)
q' Map (XName, XName, XName) QName
qm of
                          Just QName
qn       -> 
                                           (NameCache
c, QName
qn)
                          Maybe QName
Nothing       -> let qm' :: Map (XName, XName, XName) QName
qm'  = (XName, XName, XName)
-> QName
-> Map (XName, XName, XName) QName
-> Map (XName, XName, XName) QName
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (XName, XName, XName)
q' QName
q Map (XName, XName, XName) QName
qm in
                                           
                                           QName
q QName -> (NameCache, QName) -> (NameCache, QName)
forall a b. a -> b -> b
`seq` (Int
-> Map String XName -> Map (XName, XName, XName) QName -> NameCache
NC Int
nxn Map String XName
xm Map (XName, XName, XName) QName
qm', QName
q)
    where
    q' :: (XName, XName, XName)
q'                  = (XName
lp, XName
px, XName
ns)
    q :: QName
q                   = XName -> XName -> XName -> QName
QN XName
lp XName
px XName
ns
andThen                 :: ChangeNameCache r1 ->
                           (r1 -> ChangeNameCache r2) -> ChangeNameCache r2
andThen :: forall r1 r2.
ChangeNameCache r1
-> (r1 -> ChangeNameCache r2) -> ChangeNameCache r2
andThen ChangeNameCache r1
a1 r1 -> ChangeNameCache r2
a2 NameCache
c0        = let (NameCache
c1, r1
r1) = ChangeNameCache r1
a1 NameCache
c0 in
                          (r1 -> ChangeNameCache r2
a2 r1
r1) NameCache
c1
newXName                :: String -> XName
newXName :: String -> XName
newXName String
n              = ChangeNameCache XName -> XName
forall r. NFData r => ChangeNameCache r -> r
changeNameCache (ChangeNameCache XName -> XName) -> ChangeNameCache XName -> XName
forall a b. (a -> b) -> a -> b
$
                          String -> ChangeNameCache XName
newXName' String
n
newQName                :: XName -> XName -> XName -> QName
newQName :: XName -> XName -> XName -> QName
newQName XName
lp XName
px XName
ns       = XName
lp XName -> QName -> QName
forall a b. a -> b -> b
`seq` XName
px XName -> QName -> QName
forall a b. a -> b -> b
`seq` XName
ns XName -> QName -> QName
forall a b. a -> b -> b
`seq`            
                          ( ChangeNameCache QName -> QName
forall r. NFData r => ChangeNameCache r -> r
changeNameCache (ChangeNameCache QName -> QName) -> ChangeNameCache QName -> QName
forall a b. (a -> b) -> a -> b
$
                            XName -> XName -> XName -> ChangeNameCache QName
newQName' XName
lp XName
px XName
ns
                          )
newLpName               :: String -> QName
newLpName :: String -> QName
newLpName String
lp            = ChangeNameCache QName -> QName
forall r. NFData r => ChangeNameCache r -> r
changeNameCache (ChangeNameCache QName -> QName) -> ChangeNameCache QName -> QName
forall a b. (a -> b) -> a -> b
$
                          String -> ChangeNameCache XName
newXName' String
lp ChangeNameCache XName
-> (XName -> ChangeNameCache QName) -> ChangeNameCache QName
forall r1 r2.
ChangeNameCache r1
-> (r1 -> ChangeNameCache r2) -> ChangeNameCache r2
`andThen` \ XName
lp' ->
                          XName -> XName -> XName -> ChangeNameCache QName
newQName' XName
lp' XName
nullXName XName
nullXName
newPxName               :: String -> String -> QName
newPxName :: String -> String -> QName
newPxName String
lp String
px         = ChangeNameCache QName -> QName
forall r. NFData r => ChangeNameCache r -> r
changeNameCache (ChangeNameCache QName -> QName) -> ChangeNameCache QName -> QName
forall a b. (a -> b) -> a -> b
$
                          String -> ChangeNameCache XName
newXName' String
lp ChangeNameCache XName
-> (XName -> ChangeNameCache QName) -> ChangeNameCache QName
forall r1 r2.
ChangeNameCache r1
-> (r1 -> ChangeNameCache r2) -> ChangeNameCache r2
`andThen` \ XName
lp' ->
                          String -> ChangeNameCache XName
newXName' String
px ChangeNameCache XName
-> (XName -> ChangeNameCache QName) -> ChangeNameCache QName
forall r1 r2.
ChangeNameCache r1
-> (r1 -> ChangeNameCache r2) -> ChangeNameCache r2
`andThen` \ XName
px' ->
                          XName -> XName -> XName -> ChangeNameCache QName
newQName' XName
lp' XName
px' XName
nullXName
newNsName               :: String -> String -> String -> QName
newNsName :: String -> String -> String -> QName
newNsName String
lp String
px String
ns      = ChangeNameCache QName -> QName
forall r. NFData r => ChangeNameCache r -> r
changeNameCache (ChangeNameCache QName -> QName) -> ChangeNameCache QName -> QName
forall a b. (a -> b) -> a -> b
$
                          String -> ChangeNameCache XName
newXName' String
lp ChangeNameCache XName
-> (XName -> ChangeNameCache QName) -> ChangeNameCache QName
forall r1 r2.
ChangeNameCache r1
-> (r1 -> ChangeNameCache r2) -> ChangeNameCache r2
`andThen` \ XName
lp' ->
                          String -> ChangeNameCache XName
newXName' String
px ChangeNameCache XName
-> (XName -> ChangeNameCache QName) -> ChangeNameCache QName
forall r1 r2.
ChangeNameCache r1
-> (r1 -> ChangeNameCache r2) -> ChangeNameCache r2
`andThen` \ XName
px' ->
                          String -> ChangeNameCache XName
newXName' String
ns ChangeNameCache XName
-> (XName -> ChangeNameCache QName) -> ChangeNameCache QName
forall r1 r2.
ChangeNameCache r1
-> (r1 -> ChangeNameCache r2) -> ChangeNameCache r2
`andThen` \ XName
ns' ->
                          XName -> XName -> XName -> ChangeNameCache QName
newQName' XName
lp' XName
px' XName
ns'