richter     00/12/18 04:43:29

  Modified:    .        Tag: Embperl2c DOM.xs Embperl.pm epcomp.c epdom.c
                        epmain.c
  Log:
  Embperl 2
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.6   +25 -25    embperl/DOM.xs
  
  Index: DOM.xs
  ===================================================================
  RCS file: /home/cvs/embperl/DOM.xs,v
  retrieving revision 1.1.2.5
  retrieving revision 1.1.2.6
  diff -u -r1.1.2.5 -r1.1.2.6
  --- DOM.xs    2000/12/18 11:38:07     1.1.2.5
  +++ DOM.xs    2000/12/18 12:43:21     1.1.2.6
  @@ -86,24 +86,24 @@
       XSRETURN(1) ;
   
   
  -SV *
  -embperl_Node_iReplaceChildWithCDATA (xOldChild,sText)
  -    int xOldChild
  -    SV * sText
  -PREINIT:
  -    STRLEN l ;
  -    char * s  ;
  -PPCODE:
  -    s = SV2String (sText, l) ;
  -    Node_replaceChildWithCDATA (DomTree_self(pCurrReq -> xCurrDomTree), -1, 
xOldChild, s, l, (pCurrReq -> nCurrEscMode & 3)== 3?1 + (pCurrReq -> nCurrEscMode & 
4):pCurrReq -> nCurrEscMode, nflgModified | nflgReturn) ;
  -    pCurrReq -> nCurrEscMode = pCurrReq -> nEscMode ;
  -    pCurrReq -> bEscModeSet = -1 ;
  -    /*SvREFCNT_inc (sText) ;*/
  -    ST(0) = sText ;
  -    XSRETURN(1) ;
  -
  -
  +SV *
  +embperl_Node_iReplaceChildWithCDATA (xOldChild,sText)
  +    int xOldChild
  +    SV * sText
  +PREINIT:
  +    STRLEN l ;
  +    char * s  ;
  +PPCODE:
  +    s = SV2String (sText, l) ;
  +    Node_replaceChildWithCDATA (DomTree_self(pCurrReq -> xCurrDomTree), -1, 
xOldChild, s, l, (pCurrReq -> nCurrEscMode & 3)== 3?1 + (pCurrReq -> nCurrEscMode & 
4):pCurrReq -> nCurrEscMode, nflgModified | nflgReturn) ;
  +    pCurrReq -> nCurrEscMode = pCurrReq -> nEscMode ;
  +    pCurrReq -> bEscModeSet = -1 ;
  +    /*SvREFCNT_inc (sText) ;*/
  +    ST(0) = sText ;
  +    XSRETURN(1) ;
   
  +
  +
   SV *
   embperl_Node_replaceChildWithUrlDATA (pDomNode,sText)
       tDomNode * pDomNode
  @@ -190,15 +190,15 @@
       pCurrReq -> nCurrEscMode = pCurrReq -> nEscMode ;
       pCurrReq -> bEscModeSet = -1 ;
       DomTree_checkpoint (xDomTree, xChild) ;
  +
  +void
  +embperl_DomTree_iCheckpoint (xChild)
  +    int xChild
  +CODE:
  +    pCurrReq -> nCurrEscMode = pCurrReq -> nEscMode ;
  +    pCurrReq -> bEscModeSet = -1 ;
  +    DomTree_checkpoint (pCurrReq -> xCurrDomTree, xChild) ;
   
  -void
  -embperl_DomTree_iCheckpoint (xChild)
  -    int xChild
  -CODE:
  -    pCurrReq -> nCurrEscMode = pCurrReq -> nEscMode ;
  -    pCurrReq -> bEscModeSet = -1 ;
  -    DomTree_checkpoint (pCurrReq -> xCurrDomTree, xChild) ;
  -
   void
   embperl_DomTree_iDiscardAfterCheckpoint (xDomTree, xNode)
       int xDomTree
  
  
  
  1.118.4.19 +3 -3      embperl/Embperl.pm
  
  Index: Embperl.pm
  ===================================================================
  RCS file: /home/cvs/embperl/Embperl.pm,v
  retrieving revision 1.118.4.18
  retrieving revision 1.118.4.19
  diff -u -r1.118.4.18 -r1.118.4.19
  --- Embperl.pm        2000/12/18 11:38:10     1.118.4.18
  +++ Embperl.pm        2000/12/18 12:43:22     1.118.4.19
  @@ -10,7 +10,7 @@
   #   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
   #   WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   #
  -#   $Id: Embperl.pm,v 1.118.4.18 2000/12/18 11:38:10 richter Exp $
  +#   $Id: Embperl.pm,v 1.118.4.19 2000/12/18 12:43:22 richter Exp $
   #
   ###################################################################################
   
  @@ -1829,8 +1829,8 @@
           *{"$package\:\:http_headers_out"} = \%HTML::Embperl::http_headers_out ;
        *{"$package\:\:req_rec"} = \$HTML::Embperl::req_rec ; # if defined 
($HTML::Embperl::req_rec) ;
           ##ep2##
  -        *{"$package\:\:_ep_node"} = \$HTML::Embperl::_ep_node ;
  -        #*{"$package\:\:_ep_cp"} = \$HTML::Embperl::_ep_cp ;
  +        *{"$package\:\:_ep_node"} = \$HTML::Embperl::_ep_node ;
  +        #*{"$package\:\:_ep_cp"} = \$HTML::Embperl::_ep_cp ;
           #*{"$package\:\:_ep_rp"} = \$HTML::Embperl::_ep_ep ;
           ##/ep2##
   
  
  
  
  1.4.2.28  +10 -10    embperl/Attic/epcomp.c
  
  Index: epcomp.c
  ===================================================================
  RCS file: /home/cvs/embperl/Attic/epcomp.c,v
  retrieving revision 1.4.2.27
  retrieving revision 1.4.2.28
  diff -u -r1.4.2.27 -r1.4.2.28
  --- epcomp.c  2000/12/18 11:38:11     1.4.2.27
  +++ epcomp.c  2000/12/18 12:43:23     1.4.2.28
  @@ -711,12 +711,12 @@
                        {
                        StringAdd (ppCode, "$_ep_DomTree", 0) ; 
                        }
  -                 else if (*p == 'x')
  -                     {
  -                     char s [20] ;
  -                     int  l = sprintf (s, "%u", pNode -> xNdx) ;
  -                     StringAdd (ppCode, s, l) ; 
  -                     }
  +                 else if (*p == 'x')
  +                     {
  +                     char s [20] ;
  +                     int  l = sprintf (s, "%u", pNode -> xNdx) ;
  +                     StringAdd (ppCode, s, l) ; 
  +                     }
                    else if (*p == 'l')
                        {
                        char s [20] ;
  @@ -938,9 +938,9 @@
   
        pNode -> bFlags |= nflgCheckpoint ;
        //l = sprintf (buf, " _ep_cp($_ep_DomTree,%d) ;\n", 
*bCheckpointPending<0?pNode -> xNdx:*bCheckpointPending) ;
  -     //l = sprintf (buf, " _ep_cp($_ep_DomTree,%d) ;\n", pNode -> xNdx) ;
  +     //l = sprintf (buf, " _ep_cp($_ep_DomTree,%d) ;\n", pNode -> xNdx) ;
        l = sprintf (buf, " _ep_cp(%d) ;\n", pNode -> xNdx) ;
  -     //l = sprintf (buf, " $_ep_cp=%d;\n", pNode -> xNdx) ;
  +     //l = sprintf (buf, " $_ep_cp=%d;\n", pNode -> xNdx) ;
        nCheckpointCodeOffset = StringAdd (r -> pProg, buf,     l) ;
        *bCheckpointPending = 0 ;
   
  @@ -1138,9 +1138,9 @@
        
        pNode -> bFlags |= nflgCheckpoint ;
        //l = sprintf (buf, " _ep_cp($_ep_DomTree,%d) ;\n", 
*bCheckpointPending<0?pNode -> xNdx:*bCheckpointPending) ;
  -     //l = sprintf (buf, " _ep_cp($_ep_DomTree,%d) ;\n", pNode -> xNdx) ;
  +     //l = sprintf (buf, " _ep_cp($_ep_DomTree,%d) ;\n", pNode -> xNdx) ;
        l = sprintf (buf, " _ep_cp(%d) ;\n", pNode -> xNdx) ;
  -     //l = sprintf (buf, " $_ep_cp=%d;\n", pNode -> xNdx) ;
  +     //l = sprintf (buf, " $_ep_cp=%d;\n", pNode -> xNdx) ;
        nCheckpointCodeOffset = StringAdd (r -> pProg, buf,  l) ; 
        *bCheckpointPending = 0 ;
   
  
  
  
  1.4.2.21  +2608 -2608embperl/Attic/epdom.c
  
  Index: epdom.c
  ===================================================================
  RCS file: /home/cvs/embperl/Attic/epdom.c,v
  retrieving revision 1.4.2.20
  retrieving revision 1.4.2.21
  diff -u -r1.4.2.20 -r1.4.2.21
  --- epdom.c   2000/12/18 11:38:12     1.4.2.20
  +++ epdom.c   2000/12/18 12:43:23     1.4.2.21
  @@ -1,2608 +1,2608 @@
  
-/*###################################################################################
  -#
  -#   Embperl - Copyright (c) 1997-2000 Gerald Richter / ECOS
  -#
  -#   You may distribute under the terms of either the GNU General Public
  -#   License or the Artistic License, as specified in the Perl README file.
  -#
  -#   THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  -#   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  -#   WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  -#
  
-###################################################################################*/
  -
  -
  -#include "ep.h"
  -#include "epmacro.h"
  -
  -HV * pStringTableHash ;          /* Hash to translate strings to index number */
  -HE * * pStringTableArray  ;   /* Array with pointers to strings */
  -tStringIndex  * pFreeStringsNdx  ;   /* List of freed string indexes */
  -
  -
  -tDomTree * pDomTrees ;
  -tIndex *   pFreeDomTrees ;
  -
  -int nInitialNodePadSize = 196 ;
  -
  -int nMemUsage = 0 ;
  -int numNodes  = 0 ;
  -int numAttr   = 0 ;
  -int numStr    = 0 ;
  -int numPads   = 0 ;
  -int numReplace   = 0 ;
  -
  -tIndex xNoName  = 0 ;
  -tIndex xDomTreeAttr = 0 ;
  -tIndex xDocument ;
  -tIndex xDocumentFraq ;
  -tIndex xOrderIndexAttr ;
  -
  -int nCheckpointCache = 0 ;
  -int nCheckpointCacheMask = 0x1ff ;
  -tIndex xCheckpointCache[512] ;
  -
  -
  -tUInt8 * MemFree[256] ;
  -tUInt8 * pMemLast = NULL ;
  -tUInt8 * pMemEnd = NULL ;
  -
  -struct tPad
  -    {
  -    tNodeData Nodes [1024] ;
  -    } ;
  -
  -typedef struct tPad tPad ;
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* mydie                                                                    */
  -/*                                                                          */
  -/* Fatal Error                                                              */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -int mydie (char *  msg)
  -    {
  -    strncpy (pCurrReq -> errdat1, msg, sizeof (pCurrReq -> errdat1)) ;
  -    LogError (pCurrReq, 9999) ;
  -    puts (msg) ;
  -    exit (1) ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node memory management                                                   */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tNodeData * dom_malloc (size_t  nSize)
  -    {
  -    int          nFree = (nSize+15)>>4 ;
  -    void *  pNew ;
  -    
  -    if (nFree > sizeof (MemFree) / sizeof (void *))
  -     mydie ("Node to huge for dom_malloc") ;
  -
  -    if (pNew = MemFree[nFree])
  -     { /* --- take one entry off the free list --- */
  -     MemFree[nFree] = *((tUInt8 * *)pNew) ;
  -     return pNew ;
  -     }
  -    
  -    nSize = nFree * 16 ; /* --- make dividable by 16 --- */
  -    if (pMemLast + nSize < pMemEnd)
  -     { /* --- take space at the end of the pad --- */
  -     pNew = pMemLast ;
  -     pMemLast += nSize ;
  -     return pNew ;
  -     }
  -    
  -    /* --- Pad full -> alloc new one --- */
  -    
  -    pMemLast = malloc(sizeof (tPad)) ;
  -
  -    nMemUsage += sizeof (tPad) ;
  -
  -    pMemEnd = pMemLast + sizeof (tPad) ;
  -    pNew = pMemLast ;
  -    pMemLast += nSize ;
  -    return pNew ;
  -    }
  -
  -
  -void dom_free (tNodeData * pNode)
  -    {
  -    int          nSize = sizeof (tNodeData) + pNode -> numAttr * sizeof (tAttrData) 
;
  -    int          nFree = (nSize+15)>>4 ;
  -    void *  pFree ;
  -    
  -    if (nFree > sizeof (MemFree) / sizeof (void *))
  -     mydie ("Node to huge for dom_malloc") ;
  -
  -    /* --- add to the free list --- */
  -    pFree = MemFree[nFree] ;
  -    MemFree[nFree] = (tUInt8 *)pNode ;
  -    *((tUInt8 * *)pNode) = pFree ;
  -    return ;
  -    }
  -
  -
  -
  -tNodeData *  dom_realloc (tNodeData * pNode, size_t  nSize)
  -    {
  -    int          nOldSize = sizeof (tNodeData) + pNode -> numAttr * sizeof 
(tAttrData) ;
  -    tNodeData * pNew ;
  -    
  -    if (((tUInt8 *)pNode) + nOldSize == pMemLast)
  -     { /* --- expand --- */
  -     if (((tUInt8 *)pNode) + nSize < pMemEnd)
  -         { /* --- take space at the end of the pad --- */
  -         pMemLast = ((tUInt8 *)pNode) + nSize ;
  -         return pNode ;
  -         }
  -     }
  -    
  -    pNew = dom_malloc (nSize) ;
  -    memcpy (pNew, pNode, nOldSize) ;
  -    dom_free (pNode) ;
  -    return pNew ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* general memory management                                                */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -void * str_malloc (size_t  n)
  -    {
  -    void * m = malloc(n + sizeof (size_t)) ;
  -    if (m)
  -     {
  -     nMemUsage += n ;
  -     *((size_t *)m)++ = n ;
  -     }
  -
  -    return m ;
  -    }
  -
  -
  -
  -void * str_realloc (void * s, size_t  n)
  -    {
  -    void * m = ((size_t *)s) - 1 ;
  -    nMemUsage -= *((size_t *)m) ;
  -    if (m = realloc (m, n + sizeof (size_t)))
  -     {
  -     nMemUsage += n ;
  -     *((size_t *)m)++ = n ;
  -     }
  -    return m ;
  -    }
  -
  -//#define dom_free(s)    (free(s))
  -
  -void str_free (void * s)
  -    {
  -    void * m = ((size_t *)s) - 1 ;
  -    nMemUsage -= *((size_t *)m) ;
  -    free (m) ;
  -    }
  -
  -
  -
  -
  -
  -
  -/* forward */
  -static int DomTree_free (SV * pSV, MAGIC * mg) ;
  -
  -
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* ArrayNew                                                                 */
  -/*                                                                          */
  -/* Create a new dynamic array                                               */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -int ArrayNew (/*in*/ const tArray * pArray,
  -           /*in*/ int        nAdd,
  -           /*in*/ int        nElementSize)
  -
  -
  -    {
  -    struct tArrayCtrl * pNew ;
  -    
  -    if ((pNew = str_malloc (nAdd * nElementSize + sizeof (struct tArrayCtrl))) == 
NULL)
  -     return 0 ;
  -    
  -    memset (pNew, 0, nAdd * nElementSize + sizeof (struct tArrayCtrl)) ; 
  -    *(void * *)pArray = (struct tArray *)(pNew + 1) ;
  -    pNew -> nMax = nAdd ;
  -    pNew -> nAdd = nAdd ;
  -    pNew -> nFill = 0  ;
  -    pNew -> nElementSize = nElementSize  ;
  -
  -    return ok ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* ArrayFree                                                                */
  -/*                                                                          */
  -/* Create a new dynamic array                                               */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -int ArrayFree (/*in*/ const tArray * pArray)
  -
  -
  -    {
  -    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  -
  -    if (pCtrl)
  -        str_free (pCtrl) ;
  -
  -    (*(void * *)pArray) = NULL ;
  -
  -    return ok ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* ArrayClone                                                               */
  -/*                                                                          */
  -/* Create a new dynamic array as exact copy of old one                      */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -int ArrayClone (/*in*/  const tArray * pOrgArray,
  -             /*out*/ const tArray * pNewArray)
  -
  -
  -    {
  -    struct tArrayCtrl * pNew ;
  -    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pOrgArray)) - 1 ;
  -    int    size = pCtrl -> nFill * pCtrl -> nElementSize + sizeof (struct 
tArrayCtrl) ;
  -    
  -    if ((pNew = str_malloc (size)) == NULL)
  -     return 0 ;
  -    
  -    memcpy (pNew, pCtrl, size) ; 
  -    *(void * *)pNewArray = (struct tArray *)(pNew + 1) ;
  -    pNew -> nMax = pCtrl -> nFill ;
  -
  -    return ok ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* ArrayAdd                                                                 */
  -/*                                                                          */
  -/* Make space for numElements in Array and return index of first one        */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -int ArrayAdd (/*in*/ const tArray * pArray,
  -           /*in*/ int        numElements)
  -
  -    {
  -    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  -    int               nNdx ;
  -
  -
  -    if (pCtrl -> nFill + numElements > pCtrl -> nMax)
  -     {
  -     struct tArrayCtrl * pNew ;
  -     int                 nNewMax = pCtrl -> nFill + numElements + pCtrl -> nAdd ;
  -     
  -     if ((pNew = str_realloc (pCtrl, nNewMax * pCtrl -> nElementSize + sizeof 
(struct tArrayCtrl))) == NULL)
  -         return 0 ;
  -     
  -     *(void * *)pArray = (struct tArray *)(pNew + 1) ;
  -     pNew -> nMax = nNewMax ;
  -     pCtrl = pNew ;
  -     }
  -
  -    nNdx = pCtrl -> nFill ;
  -    pCtrl -> nFill += numElements ;
  -    return nNdx ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* ArraySub                                                              */
  -/*                                                                          */
  -/* Remove numElemenets from the end of the array. Does not reallocate memory*/
  -/* Returns -1 if less then numElemenets are avialable                            */
  -/*                                                                       */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -int ArraySub (/*in*/ const tArray * pArray,
  -           /*in*/ int        numElements)
  -
  -    {
  -    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  -    int               nNdx ;
  -
  -
  -    if (pCtrl -> nFill < numElements)
  -     return -1 ;
  -    else
  -     pCtrl -> nFill -= numElements ;
  -
  -    return pCtrl -> nFill ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* ArraySet                                                                 */
  -/*                                                                          */
  -/* Make space that at least numElements in the Array                        */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -int ArraySet (/*in*/ const tArray * pArray,
  -           /*in*/ int        numElements)
  -
  -    {
  -    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  -    int               nNdx ;
  -    char *       p ;
  -
  -    if (numElements > pCtrl -> nMax)
  -     {
  -     struct tArrayCtrl * pNew ;
  -     int                 nNewMax = pCtrl -> nFill + pCtrl -> nAdd ;
  -
  -     if (nNewMax < numElements)
  -         nNewMax = numElements + pCtrl -> nAdd ;
  -     
  -     if ((pNew = str_realloc (pCtrl, nNewMax * pCtrl -> nElementSize + sizeof 
(struct tArrayCtrl))) == NULL)
  -         return 0 ;
  -     
  -     p = (char *)(pNew + 1) ;
  -     *(void * *)pArray = (struct tArray *)p ;
  -     memset (p + pNew -> nMax * pNew -> nElementSize, 0, (nNewMax - pNew -> nMax) * 
pNew -> nElementSize) ; 
  -     pNew -> nMax = nNewMax ;
  -     pCtrl = pNew ;
  -     }
  -
  -    return numElements ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* ArraySetSize                                                             */
  -/*                                                                          */
  -/* Make space for exact numElements in the Array                         */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -int ArraySetSize (/*in*/ const tArray * pArray,
  -               /*in*/ int    numElements)
  -
  -    {
  -    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  -    int               nNdx ;
  -    char *       p ;
  -
  -    
  -    if (numElements > pCtrl -> nMax)
  -     ArraySet (pArray, numElements) ;
  -    
  -    pCtrl -> nFill = numElements ;
  -
  -    return numElements ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* ArrayGetSize                                                             */
  -/*                                                                          */
  -/* Get size of Array                                                     */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -int ArrayGetSize (/*in*/ const tArray * pArray)
  -
  -    {
  -    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(pArray)) - 1 ;
  -    
  -    return pCtrl -> nFill  ;
  -    }
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* StringNew                                                                */
  -/*                                                                          */
  -/* create a new string                                                      */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -void StringNew (/*in*/ char * * pArray,
  -           /*in*/ int        nAdd)
  -
  -    {              
  -    if ((*(void * *)pArray) == NULL)
  -     ArrayNew (pArray, nAdd, sizeof (char)) ;
  -    else
  -     ArraySetSize (pArray, 0);
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* StringFree                                                               */
  -/*                                                                          */
  -/* Free String memory                                                       */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -void StringFree (/*in*/ char * * pArray)
  -              
  -
  -    {              
  -    if ((*(void * *)pArray) != NULL)
  -     ArrayFree (pArray) ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* StringAdd                                                                */
  -/*                                                                          */
  -/* append to string                                                         */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -int StringAdd (/*in*/ char * *          pArray,
  -            /*in*/ const char * sAdd,
  -            /*in*/ int          nLen)
  -
  -    {              
  -    int nIndex ;
  -    
  -    if (nLen == 0)
  -     nLen = strlen (sAdd) ;
  -
  -    nIndex = ArrayAdd (pArray, nLen) ;
  -
  -    memcpy ((*pArray)+nIndex, sAdd, nLen) ;
  -    
  -    return nIndex ;
  -    }
  -
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* String2Ndx                                                               */
  -/*                                                                          */
  -/* Convert String to an unique index                                        */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tStringIndex String2NdxInc (/*in*/ const char *          sText,
  -                         /*in*/ int              nLen,
  -                         /*in*/ int              bInc) 
  -
  -    {
  -    SV * *  ppSV ;
  -    SV *    pSVKey ;
  -    SV *    pSVNdx ;
  -    HE *    pHEKey ;
  -    int          nNdx ;
  -    
  -
  -    if (sText == NULL)
  -     return 0 ;
  -
  -    if ((ppSV = hv_fetch (pStringTableHash, (char *)sText, nLen, 0)) != NULL)
  -     {
  -
  -     /*lprintf (pCurrReq, "String2Ndx type=%d  iok=%d flg=%x\n", 
*ppSV?SvTYPE(*ppSV):-1, SvIOK (*ppSV), SvFLAGS(*ppSV)) ;*/
  -
  -     if (*ppSV != NULL && SvIOKp (*ppSV)) /* use SvIOKp to avoid problems with 
tainting */
  -         {
  -         if (bInc)
  -             SvREFCNT_inc (*ppSV) ;
  -         nNdx = SvIVX (*ppSV) ;
  -         if (nNdx < 6 || nNdx == 92)
  -             lprintf (pCurrReq, "old string %s (#%d) refcnt=%d\n", Ndx2String 
(nNdx), nNdx, SvREFCNT(*ppSV)) ;
  -         return nNdx ;
  -         }
  -     }
  -
  -
  -    /* new string */
  -     
  -    nNdx = ArraySub (&pFreeStringsNdx, 1) ;
  -    if (nNdx != (tIndex)(-1))
  -     nNdx = pFreeStringsNdx[nNdx] ;
  -    else
  -     nNdx = ArrayAdd (&pStringTableArray, 1) ;
  -    
  -    pSVNdx = newSViv (nNdx) ;
  -    SvTAINTED_off (pSVNdx) ;
  -
  -    if (bInc)
  -     SvREFCNT_inc (pSVNdx) ;  
  -    pSVKey = newSVpv (nLen?(char *)sText:"", nLen) ;
  -    pHEKey = hv_store_ent (pStringTableHash, pSVKey, pSVNdx, 0) ;
  -    SvREFCNT_dec (pSVKey) ;
  -
  -    pStringTableArray[nNdx] = pHEKey ;
  -
  -    numStr++ ;
  -
  -    if (nNdx < 6 || nNdx == 92)
  -     lprintf (pCurrReq, "new string %s (#%d) refcnt=%d\n", Ndx2String (nNdx), nNdx, 
SvREFCNT(pSVNdx)) ;
  -    
  -    return nNdx ;    
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* NdxStringFree                                                            */
  -/*                                                                          */
  -/* Free one reference to a string                                           */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -void NdxStringFree (/*in*/ tStringIndex                  nNdx)
  -
  -    {
  -    HE *    pHE = pStringTableArray[nNdx] ;
  -    SV *    pSVNdx = HeVAL (pHE) ;
  -    
  -    SvREFCNT_dec (pSVNdx) ;
  -
  -    if (nNdx < 6 || nNdx == 92)
  -     lprintf (pCurrReq, "free string %s (#%d) refcnt=%d\n", Ndx2String (nNdx), 
nNdx, SvREFCNT(pSVNdx)) ;
  -    
  -    if (SvREFCNT(pSVNdx) == 1)
  -     {
  -     int n ;
  -     
  -     /* lprintf (pCurrReq, "delete string %s (#%d)\n", Ndx2String (nNdx), nNdx) ; 
*/
  -     hv_delete (pStringTableHash, HeKEY (pHE), HeKLEN(pHE), 0) ;
  -     pStringTableArray[nNdx] = NULL ;
  -     n = ArrayAdd (&pFreeStringsNdx, 1) ;
  -     pFreeStringsNdx[n] = nNdx ;
  -
  -     numStr-- ;
  -     }
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomInit                                                                  */
  -/*                                                                          */
  -/*                                                                          */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -int DomInit (void)
  -
  -    {
  -    SV *    pSVKey ;
  -    SV *    pSVNdx ;
  -    HE *    pHEKey ;
  -    
  -    pStringTableHash = newHV () ;
  -
  -    ArrayNew (&pStringTableArray, 256, sizeof (HE *)) ; 
  -    ArrayNew (&pFreeStringsNdx, 256, sizeof (tStringIndex *)) ; 
  -
  -    ArrayAdd (&pStringTableArray, 2) ;
  -    /* NULL */
  -    pSVNdx = newSViv (0) ;
  -    SvREFCNT_inc (pSVNdx) ;  
  -    pSVKey = newSVpv ("", 0) ;
  -    pHEKey = hv_store_ent (pStringTableHash, pSVKey, pSVNdx, 0) ;
  -    pStringTableArray[0] = pHEKey ;
  -
  -    /* "" */
  -    pSVNdx = newSViv (1) ;
  -    SvREFCNT_inc (pSVNdx) ;  
  -    pSVKey = newSVpv ("", 0) ;
  -    pHEKey = hv_store_ent (pStringTableHash, pSVKey, pSVNdx, 0) ;
  -    pStringTableArray[1] = pHEKey ;
  -
  -    numStr+=2 ;
  -
  -    xNoName       = String2Ndx ("<noname>", 8) ;
  -    xDomTreeAttr  = String2Ndx ("<domtree>", 9) ;
  -    xDocument     = String2Ndx ("Document", 8) ;
  -    xDocumentFraq = String2Ndx ("DocumentFraq", 12) ;
  -    xOrderIndexAttr   = String2Ndx ("<orderindex>", 10) ;
  -
  -    ArrayNew (&pDomTrees, 64, sizeof (tDomTree)) ; 
  -    ArrayAdd (&pDomTrees, 1) ;
  -    memset (&pDomTrees[0], 0, sizeof (tDomTree)) ;
  -    ArrayNew (&pFreeDomTrees, 64, sizeof (tIndex)) ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomStats                                                                 */
  -/*                                                                          */
  -/* print statistics                                                         */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -void DomStats (void)
  -
  -    {
  -    lprintf (pCurrReq, "[%d]PERF: DOMSTAT: MemUsage = %d Bytes  numNodes = %d  
numStr = %d  numReplace = %d  \n", pCurrReq -> nPid, nMemUsage, numNodes,  numStr, 
numReplace) ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_alloc                                                         */
  -/*                                                                          */
  -/* Alloc storage for a new DomTree and associate it with a SV. deleteing    */
  -/* the SV will delete the DomTree  also                                  */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -MGVTBL DomTree_mvtTab = { NULL, NULL, NULL, NULL, DomTree_free } ;
  -
  -
  -tDomTree * DomTree_alloc (void)
  -
  -    {
  -    tDomTree * pDomTree ;
  -    tIndex     n ;
  -    SV *       pSV ;
  -    struct magic * pMagic ;
  -
  -
  -    n = ArraySub (&pFreeDomTrees, 1) ;
  -    if (n != (tIndex)(-1))
  -     n = pFreeDomTrees[n] ;
  -    else
  -     n = ArrayAdd (&pDomTrees, 1) ;
  -    pDomTree = DomTree_self (n) ;
  -
  -    memset (pDomTree, 0, sizeof (*pDomTree)) ;
  -    
  -    pSV = newSViv (n) ;
  -    sv_magic (pSV, pSV, 0, NULL, n) ;
  -    pMagic = mg_find (pSV, 0) ;
  -
  -    if (pMagic)
  -     pMagic -> mg_virtual = &DomTree_mvtTab ;
  -    else
  -        {
  -        LogError (pCurrReq, rcMagicError) ;
  -        }
  -
  -    pDomTree -> pDomTreeSV = pSV ;
  -    pDomTree -> xNdx = n ;
  -
  -
  -    return pDomTree ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_new                                                              */
  -/*                                                                          */
  -/*                                                                          */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -int DomTree_new (tDomTree * * pNewLookup)
  -
  -    {
  -    tDomTree * pDomTree ;
  -    pDomTree = DomTree_alloc () ;
  -
  -    ArrayNew (&pDomTree -> pLookup, 256, sizeof (struct tNodeData *)) ; 
  -    ArrayAdd (&pDomTree -> pLookup, 1) ;
  -
  -    ArrayNew (&pDomTree -> pOrder, 256, sizeof (tDomTreeOrder)) ; 
  -
  -    *pNewLookup = pDomTree  ;
  -
  -    return pDomTree -> xNdx ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_dodelete                                                        */
  -/*                                                                          */
  -/* Frees all memory allocated by this DomTree                                    */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -static int DomTree_dodelete (tDomTree * pDomTree)
  -
  -    {
  -    tNodeData * * pLookup = (tNodeData * *)pDomTree -> pLookup ;
  -    int        numLookup  ;
  -    tIndex     xDomTree  = pDomTree -> xNdx ;
  -    tIndex     xNdx ;
  -
  -    if (pCurrReq -> bDebug & dbgParse)
  -     lprintf (pCurrReq, "[%d]Delete: DomTree = %d SVs=%d\n", pCurrReq -> nPid, 
pDomTree -> xNdx, sv_count) ; 
  -
  -    if (!xDomTree)
  -     {
  -     if (pCurrReq -> bDebug & dbgParse)
  -         lprintf (pCurrReq, "[%d]Delete: Already deleted DomTree = %d SVs=%d\n", 
pCurrReq -> nPid, pDomTree -> xNdx, sv_count) ; 
  -     return ok ;
  -     }
  -    
  -    numLookup = ArrayGetSize (pLookup) ;
  -    pLookup += numLookup - 1 ;
  -    while (numLookup-- > 0)
  -     {
  -     tNodeData * pNode = *pLookup ;
  -     
  -     if (pNode && pNode -> nType != (tNodeType)ntypAttr && xDomTree == pNode -> 
xDomTree)
  -         {
  -         int         nOffset ;
  -
  -         /* lprintf (pCurrReq, "delete typ=%d  Pad  xNdx=%d\n", pPad -> nType, pPad 
-> xNdx) ; */
  -
  -         int n = pNode -> numAttr ;
  -         tAttrData * pAttr = Node_selfFirstAttr(pNode) ;
  -
  -         while (n--)
  -             {
  -             //pDomTree -> pLookup[pAttr -> xNdx] = NULL ;
  -             if (pAttr -> bFlags)
  -                 {
  -                 if (pAttr -> xName)
  -                     NdxStringFree (pAttr -> xName) ;
  -                 if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  -                     NdxStringFree (pAttr -> xValue) ;
  -                 }
  -             pAttr++ ;
  -             }
  -         /* lprintf (pCurrReq, "delete typ=%d  Node xNdx=%d\n", pNode -> nType, 
pNode -> xNdx) ; */
  -         //pDomTree -> pLookup[pNode -> xNdx] = NULL ;
  -         if (pNode -> nText)
  -             NdxStringFree (pNode -> nText) ;
  -         
  -         dom_free (pNode) ;
  -         numNodes-- ;
  -         }
  -
  -     pLookup-- ;
  -     }
  -
  -
  -    ArrayFree (&pDomTree -> pLookup) ;
  -    ArrayFree (&pDomTree -> pOrder) ;
  -    
  -    if (pDomTree -> pSV)
  -     SvREFCNT_dec (pDomTree -> pSV) ;
  -
  -
  -    xNdx = ArrayAdd (&pFreeDomTrees, 1) ;
  -    pDomTree -> xNdx = 0 ;
  -    pFreeDomTrees[xNdx] = xDomTree ;
  -
  -    return ok ;    
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_free                                                          */
  -/*                                                                          */
  -/* Frees all memory allocated by this DomTree                                    */
  -/* Do not call directly. Is called by Perl when RefCnt goes to zero      */
  -/*                                                                          */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -static int DomTree_free (SV * pSV, MAGIC * mg)
  -
  -    {
  -    return DomTree_dodelete (DomTree_self (mg -> mg_len)) ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_delete                                                        */
  -/*                                                                          */
  -/* Frees all memory allocated by this DomTree                                    */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -int DomTree_delete (tDomTree * pDomTree)
  -
  -    {
  -    SvREFCNT_dec (pDomTree -> pDomTreeSV) ;
  -    return ok ;
  -    }
  -
  -    
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_clone                                                            */
  -/*                                                                          */
  -/*                                                                          */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -int DomTree_clone (/*in*/ tDomTree * pOrgDomTree,
  -                /*out*/tDomTree * *  pNewDomTree,
  -                /*in*/ int           bForceDocFraq)
  -
  -    {
  -    tDomTree * pDomTree ;
  -    tNodeData * pDocument ;
  -    tIndex      xOrgDomTree = pOrgDomTree -> xNdx ; 
  -    
  -     
  -    pDomTree = DomTree_alloc () ;
  -    pOrgDomTree = DomTree_self (xOrgDomTree) ; /* relookup in case it has moved */
  -    
  -    pDomTree -> xDocument = pOrgDomTree -> xDocument ;
  -    pDomTree -> xFilename = pOrgDomTree -> xFilename ;
  -
  -    ArrayClone (pOrgDomTree, &pDomTree -> pLookup) ; 
  -    ArrayNew (&pDomTree -> pOrder, 128, sizeof (tDomTreeOrder)) ; 
  -
  -    if (pDomTree -> pSV = pOrgDomTree -> pSV)
  -        SvREFCNT_inc (pDomTree -> pSV) ;
  -
  -    pDocument = Node_self (pDomTree, pDomTree -> xDocument) ;
  -    
  -    if (bForceDocFraq || pDocument -> nType == ntypDocumentFraq)
  -     {
  -     tAttrData * pAttr; 
  -     pDocument = Node_selfCloneNode (pDomTree, pDocument, 1) ;
  -     pAttr = Element_selfSetAttribut (pDomTree, pDocument, NULL, xDomTreeAttr, 
NULL, pDomTree -> xNdx, 0) ;
  -     pAttr -> bFlags = aflgOK ; /* reset string value flag */
  -     pDomTree -> xDocument = pDocument -> xNdx ;
  -     pDocument -> nType = ntypDocumentFraq ;
  -     if (pDocument -> nText != xDocumentFraq)
  -         {
  -         NdxStringFree (pDocument -> nText) ;
  -         pDocument -> nText = xDocumentFraq ;
  -         NdxStringRefcntInc (xDocumentFraq) ;
  -         }
  -     }
  -    
  -
  -    *pNewDomTree = pDomTree  ;
  -
  -    return pDomTree -> xNdx ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_checkpoint                                                       */
  -/*                                                                          */
  -/* Add a new checkpoint to sync the programm execution with the DOM tree    */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -void DomTree_checkpoint (tIndex xDomTree, tNode xChild)
  -
  -
  -    {
  -    if (pCurrReq -> nPhase == phRun || pCurrReq -> nPhase == phTerm)
  -     {
  -     tDomTree * pDomTree = DomTree_self (xDomTree) ;
  -     int n = ArrayAdd (&pDomTree -> pOrder, 1) ;
  -     (pDomTree -> pOrder)[n].xFromNode = xChild ;
  -     (pDomTree -> pOrder)[n].xToNode   = 0 ;
  -     if (pCurrReq -> bDebug & dbgParse)
  -         lprintf (pCurrReq, "[%d]Checkpoint: DomTree=%d Node=%d OrderIndex %d 
SVs=%d\n", pCurrReq -> nPid, xDomTree, xChild, n, sv_count) ; 
  -     }
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_selfCheckpoint                                                   */
  -/*                                                                          */
  -/* Add a new checkpoint to sync the programm execution with the DOM tree    */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -void DomTree_selfCheckpoint (tDomTree * pDomTree, tNode xFromNode, tNode xToNode)
  -
  -
  -    {
  -    if (pCurrReq -> nPhase == phRun || pCurrReq -> nPhase == phTerm)
  -     {
  -     int n = ArrayAdd (&pDomTree -> pOrder, 1) ;
  -     (pDomTree -> pOrder)[n].xFromNode = xFromNode ;
  -     (pDomTree -> pOrder)[n].xToNode   = xToNode ;
  -     if (pCurrReq -> bDebug & dbgParse)
  -         lprintf (pCurrReq, "[%d]Checkpoint: DomTree=%d Node=%d -> %d OrderIndex %d 
SVs=%d\n", pCurrReq -> nPid, pDomTree -> xNdx, xFromNode, xToNode, n, sv_count) ; 
  -     }
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* DomTree_discardAfterCheckpoint                                           */
  -/*                                                                          */
  -/* Search for the next checkpoint after xNode and discard all checkpoints   */
  -/* set after and including that one                                      */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -int DomTree_selfDiscardAfterCheckpoint (/*in*/ tDomTree *        pDomTree, 
  -                                      /*in*/ tNodeData *     pNode,
  -                                      /*in*/ tNodeData *     pArgNode)
  -
  -
  -    {
  -    tNode    xNode ;
  -    tNodeData * pChild ;    
  -    tDomTreeOrder *  pOrder ;
  -    int         n ;
  -    int         o ;
  -
  -
  -    if (!pArgNode)
  -     {
  -     pArgNode = pNode ;
  -     pNode = Node_selfFirstChild (pDomTree, pNode) ;
  -     if (!pNode)
  -         pNode = Node_selfNextSibling (pDomTree, pNode) ;
  -     }
  -    
  -    while (pNode && (pNode -> bFlags & nflgCheckpoint) == 0) 
  -     {
  -     pChild = Node_selfFirstChild (pDomTree, pNode) ;
  -     if (pChild)
  -         if (DomTree_selfDiscardAfterCheckpoint (pDomTree, pChild, pArgNode))
  -             return 1 ;
  -                                 
  -     pNode = Node_selfNextSibling (pDomTree, pNode) ;
  -     }
  -
  -    if (pNode == NULL)
  -     return 0 ;
  -
  -    xNode = pNode -> xNdx ;
  -
  -    pOrder = pDomTree -> pOrder ;
  -    o = n = ArrayGetSize (pOrder) ;
  -    while (--n >= 0)
  -     {
  -     if (pOrder[n].xFromNode == xNode)
  -         break ;
  -     }
  -    ArraySetSize (&pDomTree -> pOrder, n) ;
  -
  -    if (pCurrReq -> bDebug & dbgParse)
  -     lprintf (pCurrReq, "[%d]Checkpoint Discard: Node=%d Checkpoint=%d  OrderIndex 
%d -> %d\n", pCurrReq -> nPid, pArgNode -> xNdx, xNode, o, n) ; 
  -    
  -    return 1 ;
  -    }
  -
  -
  -
  -int DomTree_discardAfterCheckpoint (/*in*/ tIndex  xDomTree, 
  -                                  /*in*/ tNode   xNode)
  -
  -
  -    {
  -    tDomTree * pDomTree = DomTree_self (xDomTree) ;
  -    tNodeData * pNode   = Node_self (pDomTree, xNode) ;
  -    
  -    return DomTree_selfDiscardAfterCheckpoint (pDomTree, pNode, NULL) ;
  -    }
  -
  -/* ------------------------------------------------------------------------ 
  -
  -interface Node {
  -  // NodeType
  -  const unsigned short      ELEMENT_NODE                   = 1;
  -  const unsigned short      ATTRIBUTE_NODE                 = 2;
  -  const unsigned short      TEXT_NODE                      = 3;
  -  const unsigned short      CDATA_SECTION_NODE             = 4;
  -  const unsigned short      ENTITY_REFERENCE_NODE          = 5;
  -  const unsigned short      ENTITY_NODE                    = 6;
  -  const unsigned short      PROCESSING_INSTRUCTION_NODE    = 7;
  -  const unsigned short      COMMENT_NODE                   = 8;
  -  const unsigned short      DOCUMENT_NODE                  = 9;
  -  const unsigned short      DOCUMENT_TYPE_NODE             = 10;
  -  const unsigned short      DOCUMENT_FRAGMENT_NODE         = 11;
  -  const unsigned short      NOTATION_NODE                  = 12;
  -
  -  readonly attribute DOMString        nodeName;
  -           attribute DOMString        nodeValue;
  -                                        // raises(DOMException) on setting
  -                                        // raises(DOMException) on retrieval
  -
  -  readonly attribute unsigned short   nodeType;
  -  readonly attribute Node             parentNode;
  -  readonly attribute NodeList         childNodes;
  -  readonly attribute Node             firstChild;
  -  readonly attribute Node             lastChild;
  -  readonly attribute Node             previousSibling;
  -  readonly attribute Node             nextSibling;
  -  readonly attribute NamedNodeMap     attributes;
  -  // Modified in DOM Level 2:
  -  readonly attribute Document         ownerDocument;
  -  Node               insertBefore(in Node newChild, 
  -                                  in Node refChild)
  -                                        raises(DOMException);
  -  Node               replaceChild(in Node newChild, 
  -                                  in Node oldChild)
  -                                        raises(DOMException);
  -  Node               removeChild(in Node oldChild)
  -                                        raises(DOMException);
  -  Node               appendChild(in Node newChild)
  -                                        raises(DOMException);
  -  boolean            hasChildNodes();
  -  Node               cloneNode(in boolean deep);
  -  // Introduced in DOM Level 2:
  -  void               normalize();
  -  // Introduced in DOM Level 2:
  -  boolean            supports(in DOMString feature, 
  -                              in DOMString version);
  -  // Introduced in DOM Level 2:
  -  readonly attribute DOMString        namespaceURI;
  -  // Introduced in DOM Level 2:
  -           attribute DOMString        prefix;
  -                                        // raises(DOMException) on setting
  -
  -  // Introduced in DOM Level 2:
  -  readonly attribute DOMString        localName;
  -};
  -
  -
  -
  -*/
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_newAndAppend                                                        */
  -/*                                                                          */
  -/* Create new node and append it to parent                                  */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tNodeData * Node_newAndAppend (/*in*/  tDomTree *     pDomTree,
  -                               /*in*/  tIndex            xParent,
  -                               /*in*/  tIndex *          pxChilds,
  -                               /*in*/  tSInt32           nLinenumber,
  -                               /*in*/  tSInt32           nSize) 
  -
  -    {
  -    tIndex xChilds        = pxChilds?*pxChilds:0 ;
  -    tNodeData * pNewChild  ;
  -    tIndex      xNdx      = ArrayAdd (&pDomTree -> pLookup, 1) ;
  -
  -    if (nSize == 0)
  -        nSize = sizeof (tNodeData) ;
  -
  -    if ((pDomTree -> pLookup[xNdx] = pNewChild = dom_malloc (nSize)) == NULL)
  -     return NULL ;
  -
  -    memset (pNewChild, 0, nSize) ;
  -    pNewChild -> xParent = xParent ;
  -    pNewChild -> xNdx    = xNdx ;
  -    pNewChild -> nLinenumber = nLinenumber ;
  -    pNewChild -> bFlags = nflgOK ;
  -    pNewChild -> xDomTree = pDomTree -> xNdx ;
  -
  -    if (xChilds)
  -        { /* --- attribute has already childs, get the first and last one --- */
  -     tNodeData * pFirstChild = Node_self (pDomTree, xChilds) ;
  -        tNodeData * pLastChild  = Node_self (pDomTree, pFirstChild -> xPrev) ;
  -
  -        pNewChild -> xNext      = pFirstChild -> xNdx ;    
  -        pNewChild -> xPrev      = pLastChild -> xNdx ;    
  -        pFirstChild -> xPrev    = xNdx ;    
  -        pLastChild -> xNext     = xNdx ;    
  -        }
  -    else
  -        /* --- attribute has no childs, get a new one --- */
  -        {
  -        pNewChild -> xPrev   = xNdx ;
  -        pNewChild -> xNext   = xNdx ;
  -        if (pxChilds)
  -            *pxChilds = xNdx ;
  -        }
  -
  -    numNodes++ ;
  -    
  -    return pNewChild ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_selfExpand                                                          */
  -/*                                                                          */
  -/* Expand a node to hold more attributes                                    */
  -/*                                                                          */
  -/*  pNode    Node to expand                                              */
  -/*  numOldAttr       number of Attributes in the old node that must be relocated */
  -/*              (-1 to take form pNode)                                     */
  -/*  numNewAttr  new number of attributes                                    */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tNodeData * Node_selfExpand   (/*in*/  tDomTree *     pDomTree,
  -                               /*in*/  tNodeData *       pNode,
  -                               /*in*/  tUInt16           numOldAttr, 
  -                               /*in*/  tUInt16           numNewAttr) 
  -
  -    {
  -    tNodeData * pNewChild  ;
  -    tNode       xNdx = pNode -> xNdx ;
  -    int              nSize = sizeof (tNodeData) + numNewAttr  * sizeof (tAttrData) 
;
  -
  -    if ((pNewChild = dom_realloc (pNode, nSize)) == NULL)
  -     return NULL ;
  -
  -    if (pNewChild != pNode)
  -     {
  -     tAttrData * pAttr = ((struct tAttrData * )(pNewChild + 1))  ;
  -     void * * pLookup = pDomTree -> pLookup ;
  -
  -     if (numOldAttr == (tUInt16) -1)
  -         numOldAttr = pNewChild -> numAttr ;
  -
  -     pLookup[xNdx] = pNewChild ;
  -
  -     while (numOldAttr--)
  -         {
  -         pLookup[pAttr -> xNdx] = pAttr ;
  -         pAttr++ ; 
  -         }
  -     }
  -   
  -    return pNewChild ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_appendChild                                                         */
  -/*                                                                          */
  -/* Append a child node to a parent node                                     */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tNode Node_appendChild (/*in*/  tDomTree *    pDomTree,
  -                     /*in*/  tNodeType        nType,
  -                     /*in*/  int              bForceAttrValue,
  -                     /*in*/  const char *     sText,
  -                     /*in*/  int              nTextLen,
  -                     /*in*/  tNode            xParent,
  -                     /*in*/  int              nLevel,
  -                     /*in*/  int              nLinenumber)
  -
  -    {
  -    tNodeData *      pParent;
  -    tIndex   xText ;
  -
  -    pParent = Node_self (pDomTree, xParent) ;
  -    
  -    if (nType == ntypAttr)
  -     { /* add new attribute to node */           
  -     struct tAttrData *  pNew  ;
  -     tIndex              xNdx ;
  -
  -     pParent = Node_selfExpand (pDomTree, pParent, -1, pParent -> numAttr + 1) ;
  -
  -     pNew = ((struct tAttrData * )(pParent + 1)) + pParent -> numAttr ;
  -
  -        xNdx = ArrayAdd (&pDomTree -> pLookup, 1) ;
  -     pDomTree -> pLookup[xNdx] = (struct tNodeData *)pNew ;
  -
  -     pNew -> xName       = sText?String2NdxNoInc (sText, nTextLen):nTextLen ;
  -     NdxStringRefcntInc (pNew -> xName) ;
  -     pNew -> xValue      = 0 ;
  -     pNew -> bFlags      = aflgOK ;
  -     pNew -> nType       = nType ;
  -     pNew -> xNdx        = xNdx ;
  -     pNew -> nNodeOffset = ((tUInt8 *)pNew) - ((tUInt8 *)pParent) ;
  -        pParent -> numAttr++ ;
  -     numAttr++ ;
  -
  -     if (pCurrReq -> bDebug & dbgParse)
  -         lprintf (pCurrReq, "[%d]PARSE: AddNode: +%02d %*s Attribut parent=%d 
node=%d type=%d text=%*.*s (#%d)\n", 
  -                                  pCurrReq -> nPid, nLevel, nLevel * 2, "", 
xParent, xNdx, nType, nTextLen, nTextLen, sText?sText:Ndx2String (nTextLen), 
sText?String2NdxNoInc (sText, nTextLen):nTextLen) ; 
  -
  -     return xNdx ;
  -     }
  -    
  -    if ((bForceAttrValue || nType == ntypAttrValue) && 
  -     (pParent -> nType != ntypAttr || (pParent -> bFlags & aflgAttrChilds) == 0))
  -     { 
  -     /* --- add value of attribute, to non attribute parent node                 */
  -     /*     first add dummy attribute to parent with xNoName as name index       */
  -     /*     if this attribute already exist, append the new value as new _child_ */
  -     /*     to that attribute. This means, that an attribute can have multiple   */
  -     /*     child(values), in which case we set the aflgAttrChilds flag          */
  -
  -     struct tAttrData * pNew = (struct tAttrData * )pParent ; 
  -        int bAddChild = 0 ;
  -     
  -     if (pNew -> nType != ntypAttr)
  -            { /* --- parent is not a attribute --- */   
  -         if (nType == ntypAttrValue)
  -             {
  -             int i ;
  -
  -             for (i = 0; i < nTextLen; i++)
  -                 {
  -                 if (!isspace (sText[i]))
  -                     break ;
  -                 }
  -             
  -             if (i == nTextLen)
  -                 return 1 ; /* do not add only spaces as cdata inside a tag */
  -             }
  -
  -         pNew = ((tAttrData *)(pParent + 1)) + pParent -> numAttr - 1 ; /* get last 
attribute of node */
  -         if (pParent -> numAttr == 0 || pNew -> xName != xNoName || bForceAttrValue 
> 1)
  -             { /* --- add dummy attribute --- */
  -             if (!(xParent = Node_appendChild (pDomTree, ntypAttr, 0, NULL, 
xNoName, xParent, nLevel, nLinenumber)))
  -                 return 0 ;
  -             nLevel++ ;
  -             pNew = (struct tAttrData * )pDomTree -> pLookup[xParent] ;  
  -                }
  -         else
  -             { /* --- dummy attribute already exist, reuse it --- */
  -             xParent = pNew -> xNdx ;
  -             bAddChild = 1 ;
  -             nLevel++ ;
  -             }
  -         }
  -        
  -        
  -        if (!bAddChild && !bForceAttrValue)
  -         { /* we have an simple attribute, now put the value into it */
  -         pNew -> xValue  = sText?String2NdxNoInc (sText, nTextLen):nTextLen ;
  -         NdxStringRefcntInc (pNew -> xValue) ;
  -         if (pCurrReq -> bDebug & dbgParse)
  -             lprintf (pCurrReq, "[%d]PARSE: AddNode: +%02d %*s AttributValue 
parent=%d node=%d type=%d text=%*.*s (#%d)\n", pCurrReq -> nPid, nLevel, nLevel * 2, 
"", xParent, pNew -> xNdx, nType, nTextLen, nTextLen, 
  -                                        sText?sText:"<null>", sText?String2NdxNoInc 
(sText, nTextLen):-1) ; 
  -         pNew -> bFlags |= aflgAttrValue ;
  -
  -         return xParent ;
  -         }
  -        else
  -         /* --- we have to add a new child to the attribute, so set the attribute 
as parent --- */
  -         pParent = (tNodeData *)pNew ;
  -
  -        }
  -
  -    /* --- if we come we here we have add a new child node --- */
  -
  -     {
  -     struct tNodeData *  pChilds ;
  -     struct tNodeData *  pNew    ;
  -     tIndex              xNdx ;
  -     tIndex xOldValue = 0 ;
  -
  -     if (pParent && pParent -> nType == ntypAttr)
  -         { /* --- we add a new child to an attribute --- */
  -            if (((tAttrData *)pParent) -> bFlags & aflgAttrValue)
  -                {
  -                xOldValue = ((tAttrData *)pParent) -> xValue ;
  -                ((tAttrData *)pParent) -> xValue = 0 ;
  -                
  -                pNew = Node_newAndAppend (pDomTree, xParent, &(((tAttrData 
*)pParent) -> xValue), nLinenumber, 0) ;
  -                pNew -> nType = ntypAttrValue ;
  -                pNew -> nText = xOldValue ;
  -                }
  -
  -            ((tAttrData *)pParent) -> bFlags &= ~aflgAttrValue ;
  -            ((tAttrData *)pParent) -> bFlags |= aflgAttrChilds ;
  -            pNew = Node_newAndAppend (pDomTree, xParent, &(((tAttrData *)pParent) 
-> xValue), nLinenumber, 0) ;
  -            
  -            }
  -        else
  -            {
  -            pNew = Node_newAndAppend (pDomTree, xParent, pParent?&(pParent -> 
xChilds):NULL, nLinenumber, 0) ;
  -            }
  -        
  -       
  -     if (sText)
  -         xText = String2Ndx (sText, nTextLen) ;
  -     else
  -         {
  -         NdxStringRefcntInc(nTextLen) ;
  -         xText = nTextLen ;
  -         }
  -     pNew -> nType = nType ;
  -        pNew -> nText = xText ;
  -     
  -     if (pCurrReq -> bDebug & dbgParse)
  -         lprintf (pCurrReq, "[%d]PARSE: AddNode: +%02d %*s Element parent=%d 
node=%d type=%d text=%*.*s (#%d)\n", pCurrReq -> nPid, nLevel, nLevel * 2, "", 
xParent, pNew -> xNdx, nType, nTextLen, nTextLen, sText?sText:"<null>", 
  -                                                                             
sText?String2NdxNoInc (sText, nTextLen):-1) ; 
  -
  -     return pNew -> xNdx ;
  -     }
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_removeChild                                                         */
  -/*                                                                          */
  -/* Remove a child node                                                      */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tNodeData * Node_selfRemoveChild (/*in*/ tDomTree *   pDomTree,
  -                     /*in*/ tNode            xParent,
  -                     /*in*/ tNodeData *      pChild)
  -
  -    {
  -    struct tNodeData *       pParent = Node_self (pDomTree, pChild -> xParent) ;
  -    
  -    if (pChild -> xNext == pChild -> xNdx)
  -        { /* --- the only child --- */
  -        pParent -> xChilds = 0 ;
  -        }
  -    else 
  -        {
  -        tNodeData * pPrev = Node_self (pDomTree, pChild -> xPrev) ;
  -        tNodeData * pNext = Node_self (pDomTree, pChild -> xNext) ;
  -
  -        if (pParent -> xChilds == pChild -> xNdx)
  -            { /* --- the first child --- */
  -            pParent -> xChilds = pChild -> xNext ;
  -            }
  -
  -        pPrev -> xNext = pNext -> xNdx ;
  -        pNext -> xPrev = pPrev -> xNdx ;
  -        }
  -
  -    
  -    pDomTree -> pLookup[pChild -> xNdx] = NULL ;
  -    dom_free (pChild) ;
  -    numNodes-- ;
  -
  -    return NULL ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_removeChild                                                         */
  -/*                                                                          */
  -/* Remove a child node                                                      */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tNode Node_removeChild (/*in*/ tDomTree *       pDomTree,
  -                     /*in*/ tNode            xParent,
  -                     /*in*/ tNode            xChild)
  -
  -    {
  -    Node_selfRemoveChild (pDomTree, xParent, Node_self (pDomTree, xChild)) ;
  -    return 0 ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_cloneNode                                                           */
  -/*                                                                          */
  -/* clone a node                                                             */
  -/* bDeep = 1 clone childs also                                              */
  -/* bDeep = 0 clone no childs                                                */
  -/* bDeep = -1 clone no attributes and no childs                             */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tNodeData * Node_selfCloneNode (/*in*/ tDomTree *      pDomTree,
  -                             /*in*/ tNodeData *     pNode,
  -                             /*in*/  int            bDeep)
  -
  -    {
  -    int              len  = sizeof (tNodeData) + (bDeep == -1?0:pNode -> numAttr * 
sizeof (tAttrData)) ; 
  -    tNode       xNewNode ;
  -    tNodeData * pNew ;
  -
  -    if ((pNew = dom_malloc (len)) == NULL)
  -     return NULL ;
  -
  -    numNodes++ ;
  -    
  -    memcpy (pNew, pNode, len) ;
  -    xNewNode         = ArrayAdd (&pDomTree -> pLookup, 1) ;
  -    pDomTree -> pLookup[xNewNode]    = pNew ;
  -    pNew -> xNdx     = xNewNode ;
  -    pNew -> bFlags      &= ~nflgModified ;
  -    pNew -> xDomTree    = pDomTree -> xNdx ;
  -
  -    if (pNew -> nText)
  -     NdxStringRefcntInc (pNew -> nText) ;
  -    
  -    if (bDeep == -1)
  -     pNew -> numAttr = 0 ;
  -    else
  -     {
  -     tAttrData * pAttr = (tAttrData * )(pNew + 1) ;
  -     int         n     = pNew -> numAttr ;
  -
  -     while (n)
  -         {
  -         xNewNode = ArrayAdd (&pDomTree -> pLookup, 1) ;
  -         pDomTree -> pLookup[xNewNode] = pAttr ;
  -         pAttr -> xNdx = xNewNode ;
  -         if (pAttr -> xName)
  -             NdxStringRefcntInc (pAttr -> xName) ;
  -         if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  -             NdxStringRefcntInc (pAttr -> xValue) ;
  -         n-- ;
  -         pAttr++ ;
  -         }
  -     }
  -    if (bDeep < 1)
  -     pNew -> xChilds = 0 ;
  -
  -    return pNew ;
  -    }
  -                                
  -
  -
  -
  -tNode Node_cloneNode (/*in*/ tDomTree *      pDomTree,
  -                 /*in*/ tNode            xNode,
  -                 /*in*/  int             bDeep)
  -
  -    {
  -    tNodeData * pNew = Node_selfCloneNode (pDomTree, Node_self (pDomTree, xNode), 
bDeep) ;
  -
  -    if (pNew)
  -     return pNew -> xNdx ;
  -
  -    return 0 ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_selfCondCloneNode                                                   */
  -/*                                                                          */
  -/* clone a node if it's part of a different DomTree in preparation for      */
  -/* a change                                                                 */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tNodeData * Node_selfCondCloneNode (/*in*/ tDomTree *      pDomTree,
  -                                 /*in*/ tNodeData *     pNode)
  -
  -    {
  -    int              len  ;
  -    tNodeData * pNew ;
  -    tAttrData * pAttr ;
  -    int         n ;
  -    void * *    pLookup  ;
  -    tNode    xNdx ;
  -    
  -    if (pNode -> xDomTree == pDomTree -> xNdx)
  -        return pNode ;
  -
  -    pLookup = pDomTree -> pLookup ;
  -    len          = sizeof (tNodeData) + pNode -> numAttr * sizeof (tAttrData) ; 
  -    xNdx    = pNode -> xNdx ;
  -
  -    if ((pLookup[xNdx] = pNew = dom_malloc (len)) == NULL)
  -     return NULL ;
  -
  -    numNodes++ ;
  -    
  -    memcpy (pNew, pNode, len) ;
  -
  -    pNew -> bFlags      &= ~nflgModified ;
  -    pNew -> xDomTree    = pDomTree -> xNdx ;
  -
  -    if (pNew -> nText)
  -     NdxStringRefcntInc (pNew -> nText) ;
  -    
  -    pAttr = (tAttrData * )(pNew + 1) ;
  -    n     = pNew -> numAttr ;
  -
  -    while (n)
  -     {
  -     pLookup[pAttr -> xNdx] = pAttr ;
  -     if (pAttr -> xName)
  -         NdxStringRefcntInc (pAttr -> xName) ;
  -     if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  -         NdxStringRefcntInc (pAttr -> xValue) ;
  -     n-- ;
  -     pAttr++ ;
  -     }
  -
  -    return pNew ;
  -    }
  -
  -                                
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_replaceChild                                                        */
  -/*                                                                          */
  -/* Replaces the node pointed by pOldChildDomTree/xOldChild, with the node   */
  -/* pointed by pDomTree/xNode                                                */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tNode Node_replaceChildWithNode (/*in*/ tDomTree *      pDomTree,
  -                              /*in*/ tNode           xNode,
  -                                 /*in*/ tDomTree *      pOldChildDomTree,
  -                              /*in*/ tNode           xOldChild)
  -
  -    {
  -    int              bFlags = nflgModified | nflgReturn ;
  -    tNode    xOrgChild  = xOldChild ;
  -    tNodeData *      pNode      = Node_self (pDomTree, xNode) ;
  -    tNodeData *      pOldChild  ;
  -    
  -    pOldChild  = Node_selfCondCloneNode (pOldChildDomTree, Node_self 
(pOldChildDomTree, xOldChild)) ; 
  -
  -    if (pOldChild -> bFlags & nflgModified) 
  -     {
  -     pOldChild -> bFlags |= bFlags ;
  -     pOldChild = Node_selfCloneNode (pOldChildDomTree, pNode, 1) ;
  -     xOldChild = pOldChild -> xNdx ;
  -     }
  -    else
  -     {
  -     int         len  = sizeof (tNodeData) + pNode -> numAttr * sizeof (tAttrData) 
; 
  -     int         numAttr = pOldChild -> numAttr ;
  -     int         nOffset ;
  -     tAttrData * pAttr  ;
  -     int         n      ;
  -     void * * pLookup  ;
  -
  -     
  -        pOldChild  = Node_selfExpand (pOldChildDomTree, pOldChild, 0, pNode -> 
numAttr) ;
  -        
  -     if (pOldChild -> nText)
  -         NdxStringFree (pOldChild -> nText) ;
  -
  -     pAttr = ((struct tAttrData * )(pOldChild + 1))  ;
  -     n     = pOldChild -> numAttr ;
  -
  -     while (n > 0)
  -         {
  -         if (pAttr -> xName)
  -             NdxStringFree (pAttr -> xName) ;
  -         if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  -             NdxStringFree  (pAttr -> xValue) ;
  -         n-- ;
  -         pAttr++ ;
  -         }
  -
  -     memcpy (pOldChild, pNode, len) ;
  -
  -     if (pOldChild -> nText)
  -         NdxStringRefcntInc (pOldChild -> nText) ;
  -     
  -
  -     pOldChild -> xDomTree = pDomTree -> xNdx ;
  -     pOldChild -> xNdx       = xOldChild ;
  -     pOldChild -> bFlags |= bFlags ;
  -
  -     pAttr = ((struct tAttrData * )(pOldChild + 1))  ;
  -     n     = pNode -> numAttr ;
  -     pLookup = pDomTree -> pLookup ;
  -
  -
  -     while (n > 0)
  -         {
  -         if (pAttr -> xName)
  -             NdxStringRefcntInc (pAttr -> xName) ;
  -         if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  -             NdxStringRefcntInc  (pAttr -> xValue) ;
  -         pLookup[pAttr -> xNdx] = pAttr ;
  -         n-- ;
  -         pAttr++ ;
  -         }
  -     
  -     pAttr = ((struct tAttrData * )(pOldChild + 1)) + pOldChild -> numAttr ;
  -     n     = numAttr - pNode -> numAttr ;
  -
  -     while (n > 0)
  -         {
  -         pAttr -> bFlags = nflgDeleted ;
  -         if (pAttr -> xName)
  -             NdxStringFree (pAttr -> xName) ;
  -         if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  -             NdxStringFree (pAttr -> xValue) ;
  -         n-- ;
  -         pAttr++ ;
  -         }
  -     }
  -
  -    if (pOldChild -> nType == ntypDocumentFraq)
  -     {
  -     tAttrData * pAttr = Element_selfSetAttribut (pOldChildDomTree, pOldChild, 
NULL, xDomTreeAttr, NULL, pDomTree -> xNdx, 0) ;
  -     pAttr -> bFlags = aflgOK ; /* reset string value flag */
  -     }
  -     
  -    DomTree_selfCheckpoint (pOldChildDomTree, xOrgChild, xOldChild) ;
  -    
  -    return xOldChild ;
  -    }
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_insertBefore                                                        */
  -/*                                                                          */
  -/* Inserts a child node before another node                                 */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_insertAfter                                                         */
  -/*                                                                          */
  -/* Inserts a child node after another node                                  */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -tNode Node_insertAfter          (/*in*/ tDomTree *      pNewNodeDomTree,
  -                              /*in*/ tNode           xNewNode,
  -                                 /*in*/ tDomTree *      pRefNodeDomTree,
  -                              /*in*/ tNode           xRefNode)
  -
  -    {
  -    int              bFlags = nflgModified | nflgReturn ;
  -    tNodeData *      pNewNode      = Node_self (pNewNodeDomTree, xNewNode) ;
  -    tNodeData *      pRefNode      = Node_self (pRefNodeDomTree, xRefNode) ;
  -    tNodeData *      pNxtNode      = Node_selfNextSibling (pRefNodeDomTree, 
pRefNode) ;
  -    tNode    xOrgNode ;
  -
  -
  -    if (pNewNodeDomTree != pRefNodeDomTree)
  -        {
  -        tNodeData * pNew = Node_newAndAppend (pRefNodeDomTree, pRefNode -> xParent, 
NULL, pNewNode -> nLinenumber, sizeof (tNodeData) + pNewNode -> numAttr * sizeof 
(tAttrData)) ;        
  -
  -        pNew -> nText   = pNewNode -> nText ;
  -        pNew -> xChilds = pNewNode -> xChilds ;
  -        pNew -> nType   = pNewNode -> nType ;
  -        pNew -> bFlags  = pNewNode -> bFlags | nflgModified | nflgReturn ;
  -        
  -        if (pNew -> nText)
  -         NdxStringRefcntInc (pNew -> nText) ;
  -        pNewNode = pNew ;
  -        }    
  -    
  -    pRefNode  = Node_selfCondCloneNode (pRefNodeDomTree, pRefNode) ; 
  -    if (pNxtNode)
  -        pNxtNode  = Node_selfCondCloneNode (pRefNodeDomTree, pNxtNode) ; 
  -    else
  -        pNxtNode = pRefNode ;
  -
  -    if ((pNxtNode -> bFlags & nflgModified) == 0)
  -     {
  -     xOrgNode = pNewNode -> xNdx ;
  -     pNxtNode -> xPrev = pNewNode -> xNdx ;
  -     pRefNode -> xNext = pNewNode -> xNdx ;
  -     pNewNode -> xPrev = pRefNode -> xNdx ;
  -     pNewNode -> xNext = pNxtNode -> xNdx ;
  -     }
  -    else
  -     xOrgNode = pNxtNode -> xNdx ;
  -
  -    DomTree_selfCheckpoint (pRefNodeDomTree, xOrgNode, pNewNode -> xNdx) ;
  -
  -    if (pNewNode -> nType == ntypDocumentFraq)
  -     {
  -     tAttrData * pAttr = Element_selfSetAttribut (pRefNodeDomTree, pNewNode, NULL, 
xDomTreeAttr, NULL, pNewNodeDomTree -> xNdx, 0) ;
  -     pAttr -> bFlags = aflgOK ; /* reset string value flag */
  -     }
  -
  -    return pNewNode -> xNdx ;
  -    }
  -
  -
  -
  -    
  -    
  -
  -
  -
  -
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_replaceChild                                                        */
  -/*                                                                          */
  -/* Replace child node                                                       */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -tNode Node_replaceChildWithCDATA (/*in*/ tDomTree *   pDomTree,
  -                               /*in*/ tNode           xNode,
  -                               /*in*/ tNode           xOldChild,
  -                               /*in*/ const char *    sText,
  -                               /*in*/ int             nTextLen,
  -                               /*in*/ int             nEscMode,
  -                               /*in*/ int             bFlags)
  -
  -    {
  -    tNodeData *      pOldChild  ;
  -    tNode    xOrgChild  = xOldChild ;
  -    tStringIndex n ;
  -    
  -    numReplace++ ;
  -
  -    /* *** lprintf (pCurrReq, "rp1--> SVs=%d  %s  DomTree Old=%d\n", sv_count, 
sText?sText:"<null>", Node_selfDomTree (Node_self (pDomTree, xOldChild))) ; */
  -
  -    pOldChild  = Node_selfCondCloneNode (pDomTree, Node_self (pDomTree, xOldChild)) 
; 
  -
  -    xCheckpointCache[nCheckpointCache++] = xOldChild ;
  -
  -    if (pOldChild -> bFlags & nflgModified) 
  -     {
  -     pOldChild -> bFlags |= bFlags ;
  -     pOldChild = Node_selfCloneNode (pDomTree, pOldChild, 0) ;
  -     xOldChild = pOldChild -> xNdx ;
  -     }
  -    /* *** lprintf (pCurrReq, "rp2--> DomTree New=%d\n", Node_selfDomTree 
(pOldChild)) ; */
  -    
  -    DomTree_selfCheckpoint (pDomTree, xOrgChild, xOldChild) ;
  -    
  -    xCheckpointCache[nCheckpointCache++] = xOldChild ;
  -    nCheckpointCache &= nCheckpointCacheMask ;
  -    xCheckpointCache[nCheckpointCache] = 0 ;
  -
  -   
  -    if (nEscMode != -1)
  -     {
  -     pOldChild -> nType  = (nEscMode & 3)?ntypText:ntypCDATA ;
  -     pOldChild -> bFlags &= ~(nflgEscUrl + nflgEscChar) ;
  -     pOldChild -> bFlags |= (nEscMode ^ nflgEscChar) & (nflgEscUrl + nflgEscChar) ;
  -     }
  -    else
  -     pOldChild -> nType  = ntypCDATA ;
  -
  -    n = pOldChild -> nText ;
  -    pOldChild -> nText = String2Ndx(sText, nTextLen) ;
  -    pOldChild -> xChilds = 0 ;
  -    pOldChild -> bFlags |= bFlags ;
  -    if (n)
  -     NdxStringFree (n) ;
  -
  -    /* *** lprintf (pCurrReq, "rp<-- nText=%d sText=>%*.*s< nTextLen = %d  
SVs=%d\n", pOldChild -> nText, nTextLen,nTextLen, sText?sText:"<null>",  nTextLen, 
sv_count) ; */
  -    return xOldChild ;
  -    }
  -
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_selfLastChild                                                       */
  -/*                                                                          */
  -/* Get last child node                                                           */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tNodeData * Node_selfLastChild   (/*in*/  tDomTree *   pDomTree,
  -                               /*in*/  tNodeData *  pNode) 
  -
  -    {
  -    if (pNode -> xChilds)
  -        return Node_self (pDomTree, Node_selfFirstChild (pDomTree, pNode) -> xPrev) 
;
  -    
  -    return 0 ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_selfNthChild (pNode, nChildNo) ;                                    */
  -/*                                                                          */
  -/* Get nth child node                                                            */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -struct tNodeData * Node_selfNthChild (/*in*/  tDomTree *    pDomTree,
  -                                   /*in*/ struct tNodeData * pNode,
  -                                   /*in*/ int                nChildNo) 
  -
  -    {
  -    if (pNode -> xChilds)
  -        {
  -        tNodeData * pChild  ;
  -        tNodeData * pFirstChild = Node_selfFirstChild (pDomTree, pNode) ;
  -
  -        if (nChildNo == 0)
  -            return pFirstChild ;
  -        
  -        
  -        pChild = pFirstChild ;
  -
  -        do
  -            {
  -            pChild = Node_self (pDomTree, pChild -> xNext) ;
  -            if (nChildNo-- < 2)
  -                return pChild ;
  -            }
  -        while (nChildNo > 1 && pChild != pFirstChild) ;
  -        }
  -
  -    return 0 ;
  -    }
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_nextSibling (xNode) ;                                               */
  -/*                                                                          */
  -/* Get next sibling node                                                 */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tNodeData * Node_selfNextSibling (/*in*/ tDomTree *  pDomTree,
  -                               /*in*/ tNodeData * pNode) 
  -
  -    {
  -    tNodeData * pParent  ;
  -
  -    if (pNode -> xNext == pNode -> xNdx)
  -        return NULL ;
  -    
  -    pParent = Node_self (pDomTree, pNode -> xParent) ;
  -    if (pParent -> xChilds == pNode -> xNext)
  -        return NULL ;
  -    
  -    return Node_self (pDomTree, pNode -> xNext) ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_nextSibling (xNode) ;                                               */
  -/*                                                                          */
  -/* Get next sibling node                                                 */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tNode Node_nextSibling (/*in*/ tDomTree *  pDomTree,
  -                     /*in*/ tNode       xNode) 
  -
  -
  -    {
  -    tNodeData * pNode = Node_self (pDomTree, xNode) ;
  -    tNodeData * pParent  ;
  -
  -    if (pNode -> xNext == pNode -> xNdx)
  -        return 0 ;
  -    
  -    pParent = Node_self (pDomTree, pNode -> xParent) ;
  -    if (pParent -> xChilds == pNode -> xNext)
  -        return 0 ;
  -    
  -    return pNode -> xNext ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_previousSibling (xNode) ;                                           */
  -/*                                                                          */
  -/* Get previous sibling node                                             */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tNodeData * Node_selfPreviousSibling (/*in*/ tDomTree *  pDomTree,
  -                               /*in*/ tNodeData * pNode) 
  -
  -    {
  -    tNodeData * pParent  ;
  -
  -    if (pNode -> xPrev == pNode -> xNdx)
  -        return 0 ;
  -    
  -    pParent = Node_self (pDomTree, pNode -> xParent) ;
  -    if (pParent -> xChilds == pNode -> xPrev)
  -        return 0 ;
  -    
  -    return Node_self (pDomTree, pNode -> xPrev) ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_previousSibling (xNode) ;                                           */
  -/*                                                                          */
  -/* Get previous sibling node                                             */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -tNode Node_previousSibling (/*in*/ tDomTree *  pDomTree,
  -                     /*in*/ tNode       xNode) 
  -
  -
  -    {
  -    tNodeData * pNode = Node_self (pDomTree, xNode) ;
  -    tNodeData * pParent  ;
  -
  -    if (pNode -> xPrev == pNode -> xNdx)
  -        return 0 ;
  -    
  -    pParent = Node_self (pDomTree, pNode -> xParent) ;
  -    if (pParent -> xChilds == pNode -> xPrev)
  -        return 0 ;
  -    
  -    return pNode -> xPrev ;
  -    }
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Node_toString                                                            */
  -/*                                                                          */
  -/*                                                                          */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tNodeData * Node_toString2 (/*in*/  tDomTree *     pDomTree,
  -                 /*i/o*/ register req *  r,
  -                 /*in*/  tNode           xNode,
  -                    /*in*/  int *           pOrderNdx)
  -
  -
  -    {
  -    tNode xFirstNode = xNode ;
  -    tNode xNextNode ;
  -    int   nOrderNdx = *pOrderNdx ;
  -    int   nOrderIndexNode = -1 ;
  -    int   bCheckpointFound = 0  ;
  -    tNodeData * pNextNode ;
  -    tNodeData * pSavedNode = NULL ;
  -    tNodeData * pSavedNodeFrom = NULL ;
  -    tNodeData * pLastStartTag = NULL ;
  -    tNodeData * pNode = Node_self (pDomTree, xNode) ;
  -    tNodeData * pFirstNode = pNode ;
  -    
  -    
  -    
  -    if (pNode -> nType == ntypDocumentFraq)
  -     {
  -     tAttrData * pOrderIndex = Element_selfGetAttribut (pDomTree, pNode, NULL, 
xOrderIndexAttr) ;
  -     pDomTree = DomTree_self (Element_selfGetAttribut (pDomTree, pNode, NULL, 
xDomTreeAttr) -> xValue) ;
  -     if (pOrderIndex)
  -         nOrderNdx = pOrderIndex -> xValue ;
  -     }
  -    
  -
  -    pNode = Node_selfFirstChild (pDomTree, pNode) ;
  -
  -    while (pNode)
  -     {
  -     if (pNode -> bFlags & nflgCheckpoint)
  -         { /* see how the control flow contiounes */
  -         if ((xNextNode = pDomTree -> pOrder[nOrderNdx].xFromNode) != pNode -> xNdx 
&& xNextNode)    
  -             {
  -             tNodeData * pNewNode ;
  -                tNodeData * pNewParent ;
  -                tNodeData * pParent ;
  -                
  -                if (pCurrReq -> bDebug & dbgParse)
  -                 lprintf (r, "[%d]toString: ** Skip Node=%d to Node=%d (OrderIndex 
%d)\n", r -> nPid, pNode -> xNdx, xNextNode, nOrderNdx) ; 
  -             
  -             if (xNextNode == -1)
  -                 return NULL ; /* end of flow */
  -             
  -             bCheckpointFound = 1 ;
  -                pSavedNode = NULL ;
  -             pNewNode      = Node_self (pDomTree, xNextNode) ;
  -             pNewParent    = Node_selfParentNode (pDomTree, pNewNode) ;
  -             if (pParent       = pLastStartTag)
  -                 {
  -                 while (pNewParent != pParent)
  -                     {
  -                     if (pParent)
  -                         {
  -                         oputs (r, "</") ;
  -                         oputs (r, Node_selfNodeName (pParent)) ;
  -                         oputc (r, '>') ;
  -                         }
  -                     else
  -                         {
  -                         lprintf (r, "[%d]WARN: unstructured jump\n", r -> nPid) ;
  -                         break ;
  -                         }
  -                     pParent = Node_selfParentNode (pDomTree, pParent) ;
  -                     }
  -                 }
  -             pLastStartTag = NULL ;
  -             pNode = pNewNode ;
  -             }
  -         nOrderNdx++ ;
  -         }
  -
  -     if (pNode -> bFlags & nflgReturn)
  -         { /* we should use another node to replace this one */
  -         tDomTreeOrder * pOrder = pDomTree -> pOrder ;
  -         int             n      = ArrayGetSize (pOrder) ;
  -         int             i      = nOrderNdx ;
  -
  -         while (pOrder[i].xFromNode != pNode -> xNdx && i < n)  
  -             i++ ;
  -         
  -         if (i < n)
  -             {                   
  -             if ((xNextNode = pOrder[i].xToNode) != pNode -> xNdx && xNextNode)     
 
  -                 {
  -                 if (pCurrReq -> bDebug & dbgParse)
  -                     lprintf (r, "[%d]toString: ** Replace Node=%d with Node=%d 
(OrderIndex %d, initial %d)\n", r -> nPid, pNode -> xNdx, xNextNode, i, nOrderNdx) ; 
  -                 pSavedNode = pNode ;    
  -                 pNode  = Node_self (pDomTree, xNextNode) ;
  -                 pSavedNodeFrom = pNode ;    
  -                 }
  -             if (i == nOrderNdx)
  -                 nOrderNdx++, nOrderIndexNode = -1 ;
  -             else
  -                 nOrderIndexNode = i ;
  -             }
  -         else
  -             {
  -             mydie ("Internal Error: Orderindex out of range") ;
  -             }
  -         }
  -
  -
  -     if (pCurrReq -> bDebug & dbgParse)
  -         lprintf (r, "[%d]toString: Node=%d type=%d flags=%x text=>%s<= (#%d) 
SVs=%d\n", r -> nPid, pNode -> xNdx, pNode -> nType,  pNode -> bFlags, Ndx2String 
(pNode -> nText), pNode -> nText, sv_count) ; 
  -
  -     if (pNode -> bFlags & nflgIgnore)
  -            ;
  -     else if (pNode -> nType == ntypDocumentFraq)
  -         {
  -         Node_toString (pDomTree, r, pNode -> xNdx) ; 
  -         oputs (r, "\r\n") ;
  -         }
  -        else if (pNode -> nType == ntypTag || pNode -> nType == ntypStartTag)
  -         {
  -         int n = pNode -> numAttr ;
  -         struct tAttrData * pAttr = (struct tAttrData *)(pNode + 1) ;
  -
  -         if (pNode -> nType == ntypStartTag)
  -             pLastStartTag = pNode ;
  -
  -         oputc (r, '<') ;
  -         oputs (r, Node_selfNodeName (pNode)) ;
  -         
  -         while (n--)
  -             {
  -             if (pAttr -> bFlags)
  -                 {
  -                 char * s ;
  -                 int    l ;
  -                 oputc (r, ' ') ;
  -                 if (pAttr -> xName != xNoName)
  -                     {
  -                     Ndx2StringLen (pAttr -> xName,s,l) ;
  -                     owrite (r, s, l);
  -                     }
  -
  -                 if (pAttr -> xValue)
  -                     {
  -                     if (pAttr -> xName != xNoName)
  -                         oputs (r, "=\"") ;
  -
  -                     if (pAttr -> bFlags & aflgAttrChilds)
  -                         {
  -                         tAttrData * pAttrNode = (tAttrData * )Node_toString2 
(pDomTree, r, pAttr -> xNdx, &nOrderNdx) ;
  -                            if (pAttrNode && pAttrNode != pAttr)
  -                                {
  -                                pAttr = pAttrNode ;
  -                                pNode = Attr_selfNode(pAttr) ;
  -                                n = pNode -> numAttr - Attr_selfAttrNum (pAttr) - 1 
;
  -                                if (n < 0)
  -                                    n = 0 ;
  -                                }
  -                         }
  -                     else
  -                         {
  -                         Ndx2StringLen (pAttr -> xValue, s, l) ;
  -                         while (isspace (*s) && l > 0)
  -                             s++, l-- ;
  -                         owrite (r, s, l) ;
  -                         }
  -                     if (pAttr -> xName != xNoName)
  -                         oputc (r, '"') ;
  -                     }
  -                 }
  -             pAttr++ ;
  -             }
  -         oputc (r, '>') ;
  -         }
  -     else if (pNode -> nType == ntypText)
  -         {
  -         char * s ;
  -         int    l ;
  -         Ndx2StringLen (pNode -> nText,s,l) ;
  -         OutputEscape (r, s, l, (pNode -> bFlags & nflgEscUrl)?Char2Url:Char2Html, 
(pNode -> bFlags & nflgEscChar)?'\\':0) ;
  -         }
  -     else 
  -         {
  -         char * s ;
  -         int    l ;
  -         Ndx2StringLen (pNode -> nText,s,l) ;
  -         owrite (r, s, l);
  -         }
  -
  -     if (nOrderNdx == nOrderIndexNode)
  -         nOrderNdx++ ;
  -
  -     if (pNode -> nType == ntypDocumentFraq)
  -         pNextNode = NULL ;
  -     else
  -         pNextNode = Node_selfFirstChild (pDomTree, pNode) ;
  -     if (pNextNode == NULL)
  -         {
  -         if (pSavedNode && pSavedNodeFrom == pNode)
  -             {
  -             pNode = pSavedNode ;
  -             pSavedNode = NULL ;
  -             }
  -
  -     
  -         pNextNode  = Node_selfNextSibling (pDomTree, pNode) ;
  -         while (pNextNode == NULL)
  -             {
  -             pNextNode = Node_selfParentNode (pDomTree, pNode) ;
  -             if (pNextNode == NULL || pNextNode  == pFirstNode || pNextNode -> 
nType == ntypAttr)
  -                    {
  -                    *pOrderNdx = nOrderNdx ;
  -                    return bCheckpointFound?pNextNode:NULL ;
  -                    }
  -                 
  -             if (pSavedNode && pSavedNodeFrom == pNextNode)
  -                 {
  -                 pNextNode = pSavedNode ;
  -                 pSavedNode = NULL ;
  -                 }
  -             pNode = pNextNode ;
  -             pNextNode  = Node_selfNextSibling (pDomTree, pNextNode) ;
  -             if (pNode -> nType == ntypStartTag && (pNode -> bFlags & nflgIgnore) 
== 0 &&
  -                 (pNextNode == NULL || (pNextNode -> bFlags & nflgCheckpoint) == 0 
|| pDomTree -> pOrder[nOrderNdx].xFromNode == pNextNode -> xNdx))
  -                 {
  -                 oputs (r, "</") ;
  -                 oputs (r, Node_selfNodeName (pNode)) ;
  -                 oputc (r, '>') ;
  -                 pLastStartTag = Node_selfParentNode (pDomTree, 
pNextNode?pNextNode:pNode) ;
  -                 }
  -             }
  -         }
  -     pNode = pNextNode ;
  -     }
  -
  -    *pOrderNdx = nOrderNdx ;
  -
  -    return NULL ;    
  -    }
  -
  -void Node_toString (/*in*/  tDomTree *   pDomTree,
  -                 /*i/o*/ register req * r,
  -                 /*in*/  tNode           xNode)
  -
  -
  -    {
  -    int   nOrderNdx = 0 ;
  -
  -    Node_toString2 (pDomTree, r, xNode, &nOrderNdx) ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* NodeList_toString                                                            */
  -/*                                                                          */
  -/*                                                                          */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -void NodeList_toString (/*in*/  tDomTree *   pDomTree,
  -                     /*in*/ tNode        xNode)
  -
  -
  -    {
  -    xNode = Node_firstChild (pDomTree, xNode) ;
  -
  -    
  -
  -    }
  -
  -    
  -/* ------------------------------------------------------------------------
  -
  -interface Element : Node {
  -  readonly attribute DOMString        tagName;
  -  DOMString          getAttribute(in DOMString name);
  -  void               setAttribute(in DOMString name, 
  -                                  in DOMString value)
  -                                        raises(DOMException);
  -  void               removeAttribute(in DOMString name)
  -                                        raises(DOMException);
  -  Attr               getAttributeNode(in DOMString name);
  -  Attr               setAttributeNode(in Attr newAttr)
  -                                        raises(DOMException);
  -  Attr               removeAttributeNode(in Attr oldAttr)
  -                                        raises(DOMException);
  -  NodeList           getElementsByTagName(in DOMString name);
  -  // Introduced in DOM Level 2:
  -  DOMString          getAttributeNS(in DOMString namespaceURI, 
  -                                    in DOMString localName);
  -  // Introduced in DOM Level 2:
  -  void               setAttributeNS(in DOMString namespaceURI, 
  -                                    in DOMString qualifiedName, 
  -                                    in DOMString value)
  -                                        raises(DOMException);
  -  // Introduced in DOM Level 2:
  -  void               removeAttributeNS(in DOMString namespaceURI, 
  -                                       in DOMString localName)
  -                                        raises(DOMException);
  -  // Introduced in DOM Level 2:
  -  Attr               getAttributeNodeNS(in DOMString namespaceURI, 
  -                                        in DOMString localName);
  -  // Introduced in DOM Level 2:
  -  Attr               setAttributeNodeNS(in Attr newAttr)
  -                                        raises(DOMException);
  -  // Introduced in DOM Level 2:
  -  NodeList           getElementsByTagNameNS(in DOMString namespaceURI, 
  -                                            in DOMString localName);
  -  // Introduced in DOM Level 2:
  -  boolean            hasAttribute(in DOMString name);
  -  // Introduced in DOM Level 2:
  -  boolean            hasAttributeNS(in DOMString namespaceURI, 
  -                                    in DOMString localName);
  -};
  -
  -
  -------------------------------------------------------------------------- */
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Element_selfGetAttribut                                                  */
  -/*                                                                          */
  -/* Get attribute value of Element by name                                   */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tAttrData *  Element_selfGetAttribut (/*in*/ tDomTree *              pDomTree,
  -                                   /*in*/ struct tNodeData * pNode,
  -                                   /*in*/ const char *       sAttrName,
  -                                   /*in*/ int                nAttrNameLen) 
  -
  -    {
  -    int nAttrName = sAttrName?String2NdxNoInc (sAttrName, 
nAttrNameLen):nAttrNameLen ;
  -    struct tAttrData * pAttr = (struct tAttrData * )(pNode + 1) ;
  -    int  n = pNode -> numAttr ;
  -
  -    while (n > 0 && (nAttrName != pAttr -> xName || !pAttr -> bFlags))
  -     {
  -     n-- ;
  -     pAttr++ ;
  -     }
  -
  -    if (n)
  -     return pAttr ;
  -
  -    return NULL ;
  -    }
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Element_selfGetNthAttribut                                               */
  -/*                                                                          */
  -/* Get attribute value of Element by index                                  */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tAttrData *  Element_selfGetNthAttribut (/*in*/ tDomTree *      pDomTree,
  -                                      /*in*/ struct tNodeData * pNode,
  -                                      /*in*/ int                n)
  -
  -    {
  -    struct tAttrData * pAttr = (struct tAttrData * )(pNode + 1) ;
  -    int  num = pNode -> numAttr ;
  -
  -    if (n < 0 || n >= num)
  -        return NULL ;
  -
  -    return pAttr + n ;
  -    }
  -
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Element_selfSetAttribut                                                  */
  -/*                                                                          */
  -/* Set attribute value of Element by name                                   */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tAttrData *  Element_selfSetAttribut (/*in*/ tDomTree *              pDomTree,
  -                                   /*in*/ struct tNodeData * pNode,
  -                                   /*in*/ const char *       sAttrName,
  -                                   /*in*/ int                nAttrNameLen,
  -                                   /*in*/ const char *       sNewValue, 
  -                                   /*in*/ int                nNewValueLen,
  -                                   /*in*/ int                bClone)
  -
  -    {
  -    tAttrData * pAttr ;
  -    tNode xAttr ;
  -    tNodeData * pNewNode ;
  -
  -    pNode = Node_selfCondCloneNode (pDomTree, pNode) ;
  -    pAttr = Element_selfGetAttribut (pDomTree, pNode, sAttrName, nAttrNameLen) ;
  -
  -    if (pAttr)
  -     {
  -     tIndex xValue = sNewValue?String2NdxNoInc (sNewValue, 
nNewValueLen):nNewValueLen ;
  -     NdxStringRefcntInc (xValue) ;
  -
  -     if (bClone)
  -         {
  -         if (pAttr -> xValue != xValue && (pNode -> bFlags & nflgModified))
  -             {
  -             pNewNode = Node_selfCloneNode (pDomTree, pNode, 1) ;
  -             pAttr = Element_selfGetAttribut (pDomTree, pNewNode, sAttrName, 
nAttrNameLen) ;
  -             
  -             DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNewNode -> xNdx) ;
  -             }
  -         else
  -             DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNode -> xNdx) ;
  -
  -         pNode -> bFlags |= nflgReturn | nflgModified ;
  -         }
  -
  -     if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  -         NdxStringFree (pAttr -> xValue) ;
  -
  -     pAttr -> xValue = xValue ;
  -     return pAttr ;
  -     }
  -
  -    if (pNode -> bFlags & nflgModified && bClone)
  -     pNewNode = Node_selfCloneNode (pDomTree, pNode, 1) ;
  -    else
  -     pNewNode = pNode ;
  -
  -    if (bClone)
  -     {
  -     pNode -> bFlags |= nflgReturn | nflgModified ;
  -     DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNewNode -> xNdx) ;
  -     }
  -    
  -    xAttr = Node_appendChild (pDomTree, ntypAttr, 0, sAttrName, nAttrNameLen, 
pNewNode -> xNdx, 0, pNewNode -> nLinenumber) ;
  -    Node_appendChild (pDomTree, ntypAttrValue, 0, sNewValue, nNewValueLen, xAttr, 
0, pNewNode -> nLinenumber) ;
  -    return (tAttrData *)Node_self(pDomTree, xAttr) ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Element_selfRemoveAttribut                                               */
  -/*                                                                          */
  -/* Remove attribute of Element by name                                      */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -tAttrData *  Element_selfRemoveAttribut (/*in*/ tDomTree *           pDomTree,
  -                                   /*in*/ struct tNodeData * pNode,
  -                                   /*in*/ const char *       sAttrName,
  -                                   /*in*/ int                nAttrNameLen,
  -                                   /*in*/ int                bClone)
  -
  -    {
  -    tAttrData * pAttr ;
  -    tNodeData * pNewNode ;
  -    
  -    Node_selfCondCloneNode (pDomTree, pNode) ;
  -    pNode = Node_self (pDomTree, pNode -> xNdx) ;
  -
  -    pAttr = Element_selfGetAttribut (pDomTree, pNode, sAttrName, nAttrNameLen) ;
  -    if (bClone)
  -     {
  -     if (pAttr != NULL && (pNode -> bFlags & nflgModified))
  -         {
  -         pNode -> bFlags |= nflgReturn | nflgModified ;
  -
  -         pNewNode = Node_selfCloneNode (pDomTree, pNode, 1) ;
  -         pAttr = Element_selfGetAttribut (pDomTree, pNewNode, sAttrName, 
nAttrNameLen) ;
  -    
  -         DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNewNode -> xNdx) ;
  -         }
  -     else
  -         {
  -         pNode -> bFlags |= nflgReturn | nflgModified ;
  -
  -         DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNode -> xNdx) ;
  -         }
  -     }
  -
  -    if (pAttr)
  -     {
  -     pAttr -> bFlags = 0 ;
  -     if (pAttr -> xName)
  -         NdxStringFree (pAttr -> xName) ;
  -     if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  -         NdxStringFree (pAttr -> xValue) ;
  -     }
  -
  -    /*
  -    int    nCopyAttr ;
  -
  -    if (pAttr)
  -     {
  -     nAttr = pAttr - ((struct tAttrData * )(pNode + 1)) ;
  -     pNode -> numAttr-- ;
  -     nCopyAttr = pNode -> numAttr - nAttr  ;
  -     if (nCopyAttr)
  -         {
  -         memcpy (pAttr, pAttr + 1, nCopyAttr * sizeof (tAttrData)) ;
  -         while (nCopyAttr--)
  -             {
  -             pDomTree -> pLookup[pAttr -> xNdx] = pAttr ;
  -             pAttr++ ;
  -             }
  -         }
  -     }
  -    */
  -
  -    return pAttr ;
  -    }
  -
  -
  -/* ------------------------------------------------------------------------
  -
  -
  -interface Attr : Node {
  -  readonly attribute DOMString        name;
  -  readonly attribute boolean          specified;
  -           attribute DOMString        value;
  -                                        // raises(DOMException) on setting
  -
  -  // Introduced in DOM Level 2:
  -  readonly attribute Element          ownerElement;
  -};
  -
  ------------------------------------------------------------------------- */
  -
  -
  -
  -/* ------------------------------------------------------------------------ */
  -/*                                                                          */
  -/* Attr_selfValue                                                        */
  -/*                                                                          */
  -/*                                                                          */
  -/*                                                                          */
  -/* ------------------------------------------------------------------------ */
  -
  -
  -
  -char *       Attr_selfValue (/*in*/ tDomTree *               pDomTree,
  -                          /*in*/ struct tAttrData * pAttr,
  -                         /*out*/ char * *    ppAttr) 
  -
  -    {
  -    struct tNodeData * pNode ;
  -    
  -    if (!pAttr)
  -     return NULL ;
  -
  -    if (!(pAttr -> bFlags & aflgAttrChilds))
  -     return Ndx2String (pAttr -> xValue) ;
  -
  -    pNode = Node_self (pDomTree, pAttr -> xValue) ;
  -    
  -    StringNew (ppAttr, 512) ;
  -
  -    while (pNode)
  -     {
  -     char * s ;
  -     int    l ;
  -
  -     if (pNode -> bFlags & nflgReturn)
  -         {
  -         tIndex xNdx = pNode -> xNdx ;
  -         tNodeData * pUseNode ;
  -         int i = nCheckpointCache - 2 ;
  -     
  -         i &= nCheckpointCacheMask ;
  -         
  -         while (xCheckpointCache[i] && xCheckpointCache[i] != xNdx)
  -             {
  -             i -= 2 ;
  -             i &= nCheckpointCacheMask ;
  -             }
  -
  -         if (xCheckpointCache[i])
  -             xNdx = xCheckpointCache[i+1] ;
  -
  -         pUseNode = Node_self (pDomTree, xNdx) ;
  -         Ndx2StringLen (pUseNode -> nText,s,l) ;
  -         }
  -     else    
  -         Ndx2StringLen (pNode -> nText,s,l) ;
  -     StringAdd (ppAttr, s, l) ;
  -     pNode = Node_selfNextSibling (pDomTree, pNode) ;
  -     }
  -
  -    return *ppAttr ;
  -    }
  
+/*###################################################################################
  +#
  +#   Embperl - Copyright (c) 1997-2000 Gerald Richter / ECOS
  +#
  +#   You may distribute under the terms of either the GNU General Public
  +#   License or the Artistic License, as specified in the Perl README file.
  +#
  +#   THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  +#   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  +#   WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  +#
  
+###################################################################################*/
  +
  +
  +#include "ep.h"
  +#include "epmacro.h"
  +
  +HV * pStringTableHash ;          /* Hash to translate strings to index number */
  +HE * * pStringTableArray  ;   /* Array with pointers to strings */
  +tStringIndex  * pFreeStringsNdx  ;   /* List of freed string indexes */
  +
  +
  +tDomTree * pDomTrees ;
  +tIndex *   pFreeDomTrees ;
  +
  +int nInitialNodePadSize = 196 ;
  +
  +int nMemUsage = 0 ;
  +int numNodes  = 0 ;
  +int numAttr   = 0 ;
  +int numStr    = 0 ;
  +int numPads   = 0 ;
  +int numReplace   = 0 ;
  +
  +tIndex xNoName  = 0 ;
  +tIndex xDomTreeAttr = 0 ;
  +tIndex xDocument ;
  +tIndex xDocumentFraq ;
  +tIndex xOrderIndexAttr ;
  +
  +int nCheckpointCache = 0 ;
  +int nCheckpointCacheMask = 0x1ff ;
  +tIndex xCheckpointCache[512] ;
  +
  +
  +tUInt8 * MemFree[256] ;
  +tUInt8 * pMemLast = NULL ;
  +tUInt8 * pMemEnd = NULL ;
  +
  +struct tPad
  +    {
  +    tNodeData Nodes [1024] ;
  +    } ;
  +
  +typedef struct tPad tPad ;
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* mydie                                                                    */
  +/*                                                                          */
  +/* Fatal Error                                                              */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +int mydie (char *  msg)
  +    {
  +    strncpy (pCurrReq -> errdat1, msg, sizeof (pCurrReq -> errdat1)) ;
  +    LogError (pCurrReq, 9999) ;
  +    puts (msg) ;
  +    exit (1) ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node memory management                                                   */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tNodeData * dom_malloc (size_t  nSize)
  +    {
  +    int          nFree = (nSize+15)>>4 ;
  +    void *  pNew ;
  +    
  +    if (nFree > sizeof (MemFree) / sizeof (void *))
  +     mydie ("Node to huge for dom_malloc") ;
  +
  +    if (pNew = MemFree[nFree])
  +     { /* --- take one entry off the free list --- */
  +     MemFree[nFree] = *((tUInt8 * *)pNew) ;
  +     return pNew ;
  +     }
  +    
  +    nSize = nFree * 16 ; /* --- make dividable by 16 --- */
  +    if (pMemLast + nSize < pMemEnd)
  +     { /* --- take space at the end of the pad --- */
  +     pNew = pMemLast ;
  +     pMemLast += nSize ;
  +     return pNew ;
  +     }
  +    
  +    /* --- Pad full -> alloc new one --- */
  +    
  +    pMemLast = malloc(sizeof (tPad)) ;
  +
  +    nMemUsage += sizeof (tPad) ;
  +
  +    pMemEnd = pMemLast + sizeof (tPad) ;
  +    pNew = pMemLast ;
  +    pMemLast += nSize ;
  +    return pNew ;
  +    }
  +
  +
  +void dom_free (tNodeData * pNode)
  +    {
  +    int          nSize = sizeof (tNodeData) + pNode -> numAttr * sizeof (tAttrData) 
;
  +    int          nFree = (nSize+15)>>4 ;
  +    void *  pFree ;
  +    
  +    if (nFree > sizeof (MemFree) / sizeof (void *))
  +     mydie ("Node to huge for dom_malloc") ;
  +
  +    /* --- add to the free list --- */
  +    pFree = MemFree[nFree] ;
  +    MemFree[nFree] = (tUInt8 *)pNode ;
  +    *((tUInt8 * *)pNode) = pFree ;
  +    return ;
  +    }
  +
  +
  +
  +tNodeData *  dom_realloc (tNodeData * pNode, size_t  nSize)
  +    {
  +    int          nOldSize = sizeof (tNodeData) + pNode -> numAttr * sizeof 
(tAttrData) ;
  +    tNodeData * pNew ;
  +    
  +    if (((tUInt8 *)pNode) + nOldSize == pMemLast)
  +     { /* --- expand --- */
  +     if (((tUInt8 *)pNode) + nSize < pMemEnd)
  +         { /* --- take space at the end of the pad --- */
  +         pMemLast = ((tUInt8 *)pNode) + nSize ;
  +         return pNode ;
  +         }
  +     }
  +    
  +    pNew = dom_malloc (nSize) ;
  +    memcpy (pNew, pNode, nOldSize) ;
  +    dom_free (pNode) ;
  +    return pNew ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* general memory management                                                */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +void * str_malloc (size_t  n)
  +    {
  +    void * m = malloc(n + sizeof (size_t)) ;
  +    if (m)
  +     {
  +     nMemUsage += n ;
  +     *((size_t *)m)++ = n ;
  +     }
  +
  +    return m ;
  +    }
  +
  +
  +
  +void * str_realloc (void * s, size_t  n)
  +    {
  +    void * m = ((size_t *)s) - 1 ;
  +    nMemUsage -= *((size_t *)m) ;
  +    if (m = realloc (m, n + sizeof (size_t)))
  +     {
  +     nMemUsage += n ;
  +     *((size_t *)m)++ = n ;
  +     }
  +    return m ;
  +    }
  +
  +//#define dom_free(s)    (free(s))
  +
  +void str_free (void * s)
  +    {
  +    void * m = ((size_t *)s) - 1 ;
  +    nMemUsage -= *((size_t *)m) ;
  +    free (m) ;
  +    }
  +
  +
  +
  +
  +
  +
  +/* forward */
  +static int DomTree_free (SV * pSV, MAGIC * mg) ;
  +
  +
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* ArrayNew                                                                 */
  +/*                                                                          */
  +/* Create a new dynamic array                                               */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +int ArrayNew (/*in*/ const tArray * pArray,
  +           /*in*/ int        nAdd,
  +           /*in*/ int        nElementSize)
  +
  +
  +    {
  +    struct tArrayCtrl * pNew ;
  +    
  +    if ((pNew = str_malloc (nAdd * nElementSize + sizeof (struct tArrayCtrl))) == 
NULL)
  +     return 0 ;
  +    
  +    memset (pNew, 0, nAdd * nElementSize + sizeof (struct tArrayCtrl)) ; 
  +    *(void * *)pArray = (struct tArray *)(pNew + 1) ;
  +    pNew -> nMax = nAdd ;
  +    pNew -> nAdd = nAdd ;
  +    pNew -> nFill = 0  ;
  +    pNew -> nElementSize = nElementSize  ;
  +
  +    return ok ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* ArrayFree                                                                */
  +/*                                                                          */
  +/* Create a new dynamic array                                               */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +int ArrayFree (/*in*/ const tArray * pArray)
  +
  +
  +    {
  +    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  +
  +    if (pCtrl)
  +        str_free (pCtrl) ;
  +
  +    (*(void * *)pArray) = NULL ;
  +
  +    return ok ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* ArrayClone                                                               */
  +/*                                                                          */
  +/* Create a new dynamic array as exact copy of old one                      */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +int ArrayClone (/*in*/  const tArray * pOrgArray,
  +             /*out*/ const tArray * pNewArray)
  +
  +
  +    {
  +    struct tArrayCtrl * pNew ;
  +    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pOrgArray)) - 1 ;
  +    int    size = pCtrl -> nFill * pCtrl -> nElementSize + sizeof (struct 
tArrayCtrl) ;
  +    
  +    if ((pNew = str_malloc (size)) == NULL)
  +     return 0 ;
  +    
  +    memcpy (pNew, pCtrl, size) ; 
  +    *(void * *)pNewArray = (struct tArray *)(pNew + 1) ;
  +    pNew -> nMax = pCtrl -> nFill ;
  +
  +    return ok ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* ArrayAdd                                                                 */
  +/*                                                                          */
  +/* Make space for numElements in Array and return index of first one        */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +int ArrayAdd (/*in*/ const tArray * pArray,
  +           /*in*/ int        numElements)
  +
  +    {
  +    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  +    int               nNdx ;
  +
  +
  +    if (pCtrl -> nFill + numElements > pCtrl -> nMax)
  +     {
  +     struct tArrayCtrl * pNew ;
  +     int                 nNewMax = pCtrl -> nFill + numElements + pCtrl -> nAdd ;
  +     
  +     if ((pNew = str_realloc (pCtrl, nNewMax * pCtrl -> nElementSize + sizeof 
(struct tArrayCtrl))) == NULL)
  +         return 0 ;
  +     
  +     *(void * *)pArray = (struct tArray *)(pNew + 1) ;
  +     pNew -> nMax = nNewMax ;
  +     pCtrl = pNew ;
  +     }
  +
  +    nNdx = pCtrl -> nFill ;
  +    pCtrl -> nFill += numElements ;
  +    return nNdx ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* ArraySub                                                              */
  +/*                                                                          */
  +/* Remove numElemenets from the end of the array. Does not reallocate memory*/
  +/* Returns -1 if less then numElemenets are avialable                            */
  +/*                                                                       */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +int ArraySub (/*in*/ const tArray * pArray,
  +           /*in*/ int        numElements)
  +
  +    {
  +    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  +    int               nNdx ;
  +
  +
  +    if (pCtrl -> nFill < numElements)
  +     return -1 ;
  +    else
  +     pCtrl -> nFill -= numElements ;
  +
  +    return pCtrl -> nFill ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* ArraySet                                                                 */
  +/*                                                                          */
  +/* Make space that at least numElements in the Array                        */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +int ArraySet (/*in*/ const tArray * pArray,
  +           /*in*/ int        numElements)
  +
  +    {
  +    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  +    int               nNdx ;
  +    char *       p ;
  +
  +    if (numElements > pCtrl -> nMax)
  +     {
  +     struct tArrayCtrl * pNew ;
  +     int                 nNewMax = pCtrl -> nFill + pCtrl -> nAdd ;
  +
  +     if (nNewMax < numElements)
  +         nNewMax = numElements + pCtrl -> nAdd ;
  +     
  +     if ((pNew = str_realloc (pCtrl, nNewMax * pCtrl -> nElementSize + sizeof 
(struct tArrayCtrl))) == NULL)
  +         return 0 ;
  +     
  +     p = (char *)(pNew + 1) ;
  +     *(void * *)pArray = (struct tArray *)p ;
  +     memset (p + pNew -> nMax * pNew -> nElementSize, 0, (nNewMax - pNew -> nMax) * 
pNew -> nElementSize) ; 
  +     pNew -> nMax = nNewMax ;
  +     pCtrl = pNew ;
  +     }
  +
  +    return numElements ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* ArraySetSize                                                             */
  +/*                                                                          */
  +/* Make space for exact numElements in the Array                         */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +int ArraySetSize (/*in*/ const tArray * pArray,
  +               /*in*/ int    numElements)
  +
  +    {
  +    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(*(void * *)pArray)) - 1 ;
  +    int               nNdx ;
  +    char *       p ;
  +
  +    
  +    if (numElements > pCtrl -> nMax)
  +     ArraySet (pArray, numElements) ;
  +    
  +    pCtrl -> nFill = numElements ;
  +
  +    return numElements ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* ArrayGetSize                                                             */
  +/*                                                                          */
  +/* Get size of Array                                                     */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +int ArrayGetSize (/*in*/ const tArray * pArray)
  +
  +    {
  +    struct tArrayCtrl * pCtrl = ((struct tArrayCtrl *)(pArray)) - 1 ;
  +    
  +    return pCtrl -> nFill  ;
  +    }
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* StringNew                                                                */
  +/*                                                                          */
  +/* create a new string                                                      */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +void StringNew (/*in*/ char * * pArray,
  +           /*in*/ int        nAdd)
  +
  +    {              
  +    if ((*(void * *)pArray) == NULL)
  +     ArrayNew (pArray, nAdd, sizeof (char)) ;
  +    else
  +     ArraySetSize (pArray, 0);
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* StringFree                                                               */
  +/*                                                                          */
  +/* Free String memory                                                       */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +void StringFree (/*in*/ char * * pArray)
  +              
  +
  +    {              
  +    if ((*(void * *)pArray) != NULL)
  +     ArrayFree (pArray) ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* StringAdd                                                                */
  +/*                                                                          */
  +/* append to string                                                         */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +int StringAdd (/*in*/ char * *          pArray,
  +            /*in*/ const char * sAdd,
  +            /*in*/ int          nLen)
  +
  +    {              
  +    int nIndex ;
  +    
  +    if (nLen == 0)
  +     nLen = strlen (sAdd) ;
  +
  +    nIndex = ArrayAdd (pArray, nLen) ;
  +
  +    memcpy ((*pArray)+nIndex, sAdd, nLen) ;
  +    
  +    return nIndex ;
  +    }
  +
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* String2Ndx                                                               */
  +/*                                                                          */
  +/* Convert String to an unique index                                        */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tStringIndex String2NdxInc (/*in*/ const char *          sText,
  +                         /*in*/ int              nLen,
  +                         /*in*/ int              bInc) 
  +
  +    {
  +    SV * *  ppSV ;
  +    SV *    pSVKey ;
  +    SV *    pSVNdx ;
  +    HE *    pHEKey ;
  +    int          nNdx ;
  +    
  +
  +    if (sText == NULL)
  +     return 0 ;
  +
  +    if ((ppSV = hv_fetch (pStringTableHash, (char *)sText, nLen, 0)) != NULL)
  +     {
  +
  +     /*lprintf (pCurrReq, "String2Ndx type=%d  iok=%d flg=%x\n", 
*ppSV?SvTYPE(*ppSV):-1, SvIOK (*ppSV), SvFLAGS(*ppSV)) ;*/
  +
  +     if (*ppSV != NULL && SvIOKp (*ppSV)) /* use SvIOKp to avoid problems with 
tainting */
  +         {
  +         if (bInc)
  +             SvREFCNT_inc (*ppSV) ;
  +         nNdx = SvIVX (*ppSV) ;
  +         if (nNdx < 6 || nNdx == 92)
  +             lprintf (pCurrReq, "old string %s (#%d) refcnt=%d\n", Ndx2String 
(nNdx), nNdx, SvREFCNT(*ppSV)) ;
  +         return nNdx ;
  +         }
  +     }
  +
  +
  +    /* new string */
  +     
  +    nNdx = ArraySub (&pFreeStringsNdx, 1) ;
  +    if (nNdx != (tIndex)(-1))
  +     nNdx = pFreeStringsNdx[nNdx] ;
  +    else
  +     nNdx = ArrayAdd (&pStringTableArray, 1) ;
  +    
  +    pSVNdx = newSViv (nNdx) ;
  +    SvTAINTED_off (pSVNdx) ;
  +
  +    if (bInc)
  +     SvREFCNT_inc (pSVNdx) ;  
  +    pSVKey = newSVpv (nLen?(char *)sText:"", nLen) ;
  +    pHEKey = hv_store_ent (pStringTableHash, pSVKey, pSVNdx, 0) ;
  +    SvREFCNT_dec (pSVKey) ;
  +
  +    pStringTableArray[nNdx] = pHEKey ;
  +
  +    numStr++ ;
  +
  +    if (nNdx < 6 || nNdx == 92)
  +     lprintf (pCurrReq, "new string %s (#%d) refcnt=%d\n", Ndx2String (nNdx), nNdx, 
SvREFCNT(pSVNdx)) ;
  +    
  +    return nNdx ;    
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* NdxStringFree                                                            */
  +/*                                                                          */
  +/* Free one reference to a string                                           */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +void NdxStringFree (/*in*/ tStringIndex                  nNdx)
  +
  +    {
  +    HE *    pHE = pStringTableArray[nNdx] ;
  +    SV *    pSVNdx = HeVAL (pHE) ;
  +    
  +    SvREFCNT_dec (pSVNdx) ;
  +
  +    if (nNdx < 6 || nNdx == 92)
  +     lprintf (pCurrReq, "free string %s (#%d) refcnt=%d\n", Ndx2String (nNdx), 
nNdx, SvREFCNT(pSVNdx)) ;
  +    
  +    if (SvREFCNT(pSVNdx) == 1)
  +     {
  +     int n ;
  +     
  +     /* lprintf (pCurrReq, "delete string %s (#%d)\n", Ndx2String (nNdx), nNdx) ; */
  +     hv_delete (pStringTableHash, HeKEY (pHE), HeKLEN(pHE), 0) ;
  +     pStringTableArray[nNdx] = NULL ;
  +     n = ArrayAdd (&pFreeStringsNdx, 1) ;
  +     pFreeStringsNdx[n] = nNdx ;
  +
  +     numStr-- ;
  +     }
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomInit                                                                  */
  +/*                                                                          */
  +/*                                                                          */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +int DomInit (void)
  +
  +    {
  +    SV *    pSVKey ;
  +    SV *    pSVNdx ;
  +    HE *    pHEKey ;
  +    
  +    pStringTableHash = newHV () ;
  +
  +    ArrayNew (&pStringTableArray, 256, sizeof (HE *)) ; 
  +    ArrayNew (&pFreeStringsNdx, 256, sizeof (tStringIndex *)) ; 
  +
  +    ArrayAdd (&pStringTableArray, 2) ;
  +    /* NULL */
  +    pSVNdx = newSViv (0) ;
  +    SvREFCNT_inc (pSVNdx) ;  
  +    pSVKey = newSVpv ("", 0) ;
  +    pHEKey = hv_store_ent (pStringTableHash, pSVKey, pSVNdx, 0) ;
  +    pStringTableArray[0] = pHEKey ;
  +
  +    /* "" */
  +    pSVNdx = newSViv (1) ;
  +    SvREFCNT_inc (pSVNdx) ;  
  +    pSVKey = newSVpv ("", 0) ;
  +    pHEKey = hv_store_ent (pStringTableHash, pSVKey, pSVNdx, 0) ;
  +    pStringTableArray[1] = pHEKey ;
  +
  +    numStr+=2 ;
  +
  +    xNoName       = String2Ndx ("<noname>", 8) ;
  +    xDomTreeAttr  = String2Ndx ("<domtree>", 9) ;
  +    xDocument     = String2Ndx ("Document", 8) ;
  +    xDocumentFraq = String2Ndx ("DocumentFraq", 12) ;
  +    xOrderIndexAttr   = String2Ndx ("<orderindex>", 10) ;
  +
  +    ArrayNew (&pDomTrees, 64, sizeof (tDomTree)) ; 
  +    ArrayAdd (&pDomTrees, 1) ;
  +    memset (&pDomTrees[0], 0, sizeof (tDomTree)) ;
  +    ArrayNew (&pFreeDomTrees, 64, sizeof (tIndex)) ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomStats                                                                 */
  +/*                                                                          */
  +/* print statistics                                                         */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +void DomStats (void)
  +
  +    {
  +    lprintf (pCurrReq, "[%d]PERF: DOMSTAT: MemUsage = %d Bytes  numNodes = %d  
numStr = %d  numReplace = %d  \n", pCurrReq -> nPid, nMemUsage, numNodes,  numStr, 
numReplace) ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_alloc                                                         */
  +/*                                                                          */
  +/* Alloc storage for a new DomTree and associate it with a SV. deleteing    */
  +/* the SV will delete the DomTree  also                                  */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +MGVTBL DomTree_mvtTab = { NULL, NULL, NULL, NULL, DomTree_free } ;
  +
  +
  +tDomTree * DomTree_alloc (void)
  +
  +    {
  +    tDomTree * pDomTree ;
  +    tIndex     n ;
  +    SV *       pSV ;
  +    struct magic * pMagic ;
  +
  +
  +    n = ArraySub (&pFreeDomTrees, 1) ;
  +    if (n != (tIndex)(-1))
  +     n = pFreeDomTrees[n] ;
  +    else
  +     n = ArrayAdd (&pDomTrees, 1) ;
  +    pDomTree = DomTree_self (n) ;
  +
  +    memset (pDomTree, 0, sizeof (*pDomTree)) ;
  +    
  +    pSV = newSViv (n) ;
  +    sv_magic (pSV, pSV, 0, NULL, n) ;
  +    pMagic = mg_find (pSV, 0) ;
  +
  +    if (pMagic)
  +     pMagic -> mg_virtual = &DomTree_mvtTab ;
  +    else
  +        {
  +        LogError (pCurrReq, rcMagicError) ;
  +        }
  +
  +    pDomTree -> pDomTreeSV = pSV ;
  +    pDomTree -> xNdx = n ;
  +
  +
  +    return pDomTree ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_new                                                              */
  +/*                                                                          */
  +/*                                                                          */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +int DomTree_new (tDomTree * * pNewLookup)
  +
  +    {
  +    tDomTree * pDomTree ;
  +    pDomTree = DomTree_alloc () ;
  +
  +    ArrayNew (&pDomTree -> pLookup, 256, sizeof (struct tNodeData *)) ; 
  +    ArrayAdd (&pDomTree -> pLookup, 1) ;
  +
  +    ArrayNew (&pDomTree -> pOrder, 256, sizeof (tDomTreeOrder)) ; 
  +
  +    *pNewLookup = pDomTree  ;
  +
  +    return pDomTree -> xNdx ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_dodelete                                                        */
  +/*                                                                          */
  +/* Frees all memory allocated by this DomTree                                    */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +static int DomTree_dodelete (tDomTree * pDomTree)
  +
  +    {
  +    tNodeData * * pLookup = (tNodeData * *)pDomTree -> pLookup ;
  +    int        numLookup  ;
  +    tIndex     xDomTree  = pDomTree -> xNdx ;
  +    tIndex     xNdx ;
  +
  +    if (pCurrReq -> bDebug & dbgParse)
  +     lprintf (pCurrReq, "[%d]Delete: DomTree = %d SVs=%d\n", pCurrReq -> nPid, 
pDomTree -> xNdx, sv_count) ; 
  +
  +    if (!xDomTree)
  +     {
  +     if (pCurrReq -> bDebug & dbgParse)
  +         lprintf (pCurrReq, "[%d]Delete: Already deleted DomTree = %d SVs=%d\n", 
pCurrReq -> nPid, pDomTree -> xNdx, sv_count) ; 
  +     return ok ;
  +     }
  +    
  +    numLookup = ArrayGetSize (pLookup) ;
  +    pLookup += numLookup - 1 ;
  +    while (numLookup-- > 0)
  +     {
  +     tNodeData * pNode = *pLookup ;
  +     
  +     if (pNode && pNode -> nType != (tNodeType)ntypAttr && xDomTree == pNode -> 
xDomTree)
  +         {
  +         int         nOffset ;
  +
  +         /* lprintf (pCurrReq, "delete typ=%d  Pad  xNdx=%d\n", pPad -> nType, pPad 
-> xNdx) ; */
  +
  +         int n = pNode -> numAttr ;
  +         tAttrData * pAttr = Node_selfFirstAttr(pNode) ;
  +
  +         while (n--)
  +             {
  +             //pDomTree -> pLookup[pAttr -> xNdx] = NULL ;
  +             if (pAttr -> bFlags)
  +                 {
  +                 if (pAttr -> xName)
  +                     NdxStringFree (pAttr -> xName) ;
  +                 if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  +                     NdxStringFree (pAttr -> xValue) ;
  +                 }
  +             pAttr++ ;
  +             }
  +         /* lprintf (pCurrReq, "delete typ=%d  Node xNdx=%d\n", pNode -> nType, 
pNode -> xNdx) ; */
  +         //pDomTree -> pLookup[pNode -> xNdx] = NULL ;
  +         if (pNode -> nText)
  +             NdxStringFree (pNode -> nText) ;
  +         
  +         dom_free (pNode) ;
  +         numNodes-- ;
  +         }
  +
  +     pLookup-- ;
  +     }
  +
  +
  +    ArrayFree (&pDomTree -> pLookup) ;
  +    ArrayFree (&pDomTree -> pOrder) ;
  +    
  +    if (pDomTree -> pSV)
  +     SvREFCNT_dec (pDomTree -> pSV) ;
  +
  +
  +    xNdx = ArrayAdd (&pFreeDomTrees, 1) ;
  +    pDomTree -> xNdx = 0 ;
  +    pFreeDomTrees[xNdx] = xDomTree ;
  +
  +    return ok ;    
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_free                                                          */
  +/*                                                                          */
  +/* Frees all memory allocated by this DomTree                                    */
  +/* Do not call directly. Is called by Perl when RefCnt goes to zero      */
  +/*                                                                          */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +static int DomTree_free (SV * pSV, MAGIC * mg)
  +
  +    {
  +    return DomTree_dodelete (DomTree_self (mg -> mg_len)) ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_delete                                                        */
  +/*                                                                          */
  +/* Frees all memory allocated by this DomTree                                    */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +int DomTree_delete (tDomTree * pDomTree)
  +
  +    {
  +    SvREFCNT_dec (pDomTree -> pDomTreeSV) ;
  +    return ok ;
  +    }
  +
  +    
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_clone                                                            */
  +/*                                                                          */
  +/*                                                                          */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +int DomTree_clone (/*in*/ tDomTree * pOrgDomTree,
  +                /*out*/tDomTree * *  pNewDomTree,
  +                /*in*/ int           bForceDocFraq)
  +
  +    {
  +    tDomTree * pDomTree ;
  +    tNodeData * pDocument ;
  +    tIndex      xOrgDomTree = pOrgDomTree -> xNdx ; 
  +    
  +     
  +    pDomTree = DomTree_alloc () ;
  +    pOrgDomTree = DomTree_self (xOrgDomTree) ; /* relookup in case it has moved */
  +    
  +    pDomTree -> xDocument = pOrgDomTree -> xDocument ;
  +    pDomTree -> xFilename = pOrgDomTree -> xFilename ;
  +
  +    ArrayClone (pOrgDomTree, &pDomTree -> pLookup) ; 
  +    ArrayNew (&pDomTree -> pOrder, 128, sizeof (tDomTreeOrder)) ; 
  +
  +    if (pDomTree -> pSV = pOrgDomTree -> pSV)
  +        SvREFCNT_inc (pDomTree -> pSV) ;
  +
  +    pDocument = Node_self (pDomTree, pDomTree -> xDocument) ;
  +    
  +    if (bForceDocFraq || pDocument -> nType == ntypDocumentFraq)
  +     {
  +     tAttrData * pAttr; 
  +     pDocument = Node_selfCloneNode (pDomTree, pDocument, 1) ;
  +     pAttr = Element_selfSetAttribut (pDomTree, pDocument, NULL, xDomTreeAttr, 
NULL, pDomTree -> xNdx, 0) ;
  +     pAttr -> bFlags = aflgOK ; /* reset string value flag */
  +     pDomTree -> xDocument = pDocument -> xNdx ;
  +     pDocument -> nType = ntypDocumentFraq ;
  +     if (pDocument -> nText != xDocumentFraq)
  +         {
  +         NdxStringFree (pDocument -> nText) ;
  +         pDocument -> nText = xDocumentFraq ;
  +         NdxStringRefcntInc (xDocumentFraq) ;
  +         }
  +     }
  +    
  +
  +    *pNewDomTree = pDomTree  ;
  +
  +    return pDomTree -> xNdx ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_checkpoint                                                       */
  +/*                                                                          */
  +/* Add a new checkpoint to sync the programm execution with the DOM tree    */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +void DomTree_checkpoint (tIndex xDomTree, tNode xChild)
  +
  +
  +    {
  +    if (pCurrReq -> nPhase == phRun || pCurrReq -> nPhase == phTerm)
  +     {
  +     tDomTree * pDomTree = DomTree_self (xDomTree) ;
  +     int n = ArrayAdd (&pDomTree -> pOrder, 1) ;
  +     (pDomTree -> pOrder)[n].xFromNode = xChild ;
  +     (pDomTree -> pOrder)[n].xToNode   = 0 ;
  +     if (pCurrReq -> bDebug & dbgParse)
  +         lprintf (pCurrReq, "[%d]Checkpoint: DomTree=%d Node=%d OrderIndex %d 
SVs=%d\n", pCurrReq -> nPid, xDomTree, xChild, n, sv_count) ; 
  +     }
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_selfCheckpoint                                                   */
  +/*                                                                          */
  +/* Add a new checkpoint to sync the programm execution with the DOM tree    */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +void DomTree_selfCheckpoint (tDomTree * pDomTree, tNode xFromNode, tNode xToNode)
  +
  +
  +    {
  +    if (pCurrReq -> nPhase == phRun || pCurrReq -> nPhase == phTerm)
  +     {
  +     int n = ArrayAdd (&pDomTree -> pOrder, 1) ;
  +     (pDomTree -> pOrder)[n].xFromNode = xFromNode ;
  +     (pDomTree -> pOrder)[n].xToNode   = xToNode ;
  +     if (pCurrReq -> bDebug & dbgParse)
  +         lprintf (pCurrReq, "[%d]Checkpoint: DomTree=%d Node=%d -> %d OrderIndex %d 
SVs=%d\n", pCurrReq -> nPid, pDomTree -> xNdx, xFromNode, xToNode, n, sv_count) ; 
  +     }
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* DomTree_discardAfterCheckpoint                                           */
  +/*                                                                          */
  +/* Search for the next checkpoint after xNode and discard all checkpoints   */
  +/* set after and including that one                                      */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +int DomTree_selfDiscardAfterCheckpoint (/*in*/ tDomTree *        pDomTree, 
  +                                      /*in*/ tNodeData *     pNode,
  +                                      /*in*/ tNodeData *     pArgNode)
  +
  +
  +    {
  +    tNode    xNode ;
  +    tNodeData * pChild ;    
  +    tDomTreeOrder *  pOrder ;
  +    int         n ;
  +    int         o ;
  +
  +
  +    if (!pArgNode)
  +     {
  +     pArgNode = pNode ;
  +     pNode = Node_selfFirstChild (pDomTree, pNode) ;
  +     if (!pNode)
  +         pNode = Node_selfNextSibling (pDomTree, pNode) ;
  +     }
  +    
  +    while (pNode && (pNode -> bFlags & nflgCheckpoint) == 0) 
  +     {
  +     pChild = Node_selfFirstChild (pDomTree, pNode) ;
  +     if (pChild)
  +         if (DomTree_selfDiscardAfterCheckpoint (pDomTree, pChild, pArgNode))
  +             return 1 ;
  +                                 
  +     pNode = Node_selfNextSibling (pDomTree, pNode) ;
  +     }
  +
  +    if (pNode == NULL)
  +     return 0 ;
  +
  +    xNode = pNode -> xNdx ;
  +
  +    pOrder = pDomTree -> pOrder ;
  +    o = n = ArrayGetSize (pOrder) ;
  +    while (--n >= 0)
  +     {
  +     if (pOrder[n].xFromNode == xNode)
  +         break ;
  +     }
  +    ArraySetSize (&pDomTree -> pOrder, n) ;
  +
  +    if (pCurrReq -> bDebug & dbgParse)
  +     lprintf (pCurrReq, "[%d]Checkpoint Discard: Node=%d Checkpoint=%d  OrderIndex 
%d -> %d\n", pCurrReq -> nPid, pArgNode -> xNdx, xNode, o, n) ; 
  +    
  +    return 1 ;
  +    }
  +
  +
  +
  +int DomTree_discardAfterCheckpoint (/*in*/ tIndex  xDomTree, 
  +                                  /*in*/ tNode   xNode)
  +
  +
  +    {
  +    tDomTree * pDomTree = DomTree_self (xDomTree) ;
  +    tNodeData * pNode   = Node_self (pDomTree, xNode) ;
  +    
  +    return DomTree_selfDiscardAfterCheckpoint (pDomTree, pNode, NULL) ;
  +    }
  +
  +/* ------------------------------------------------------------------------ 
  +
  +interface Node {
  +  // NodeType
  +  const unsigned short      ELEMENT_NODE                   = 1;
  +  const unsigned short      ATTRIBUTE_NODE                 = 2;
  +  const unsigned short      TEXT_NODE                      = 3;
  +  const unsigned short      CDATA_SECTION_NODE             = 4;
  +  const unsigned short      ENTITY_REFERENCE_NODE          = 5;
  +  const unsigned short      ENTITY_NODE                    = 6;
  +  const unsigned short      PROCESSING_INSTRUCTION_NODE    = 7;
  +  const unsigned short      COMMENT_NODE                   = 8;
  +  const unsigned short      DOCUMENT_NODE                  = 9;
  +  const unsigned short      DOCUMENT_TYPE_NODE             = 10;
  +  const unsigned short      DOCUMENT_FRAGMENT_NODE         = 11;
  +  const unsigned short      NOTATION_NODE                  = 12;
  +
  +  readonly attribute DOMString        nodeName;
  +           attribute DOMString        nodeValue;
  +                                        // raises(DOMException) on setting
  +                                        // raises(DOMException) on retrieval
  +
  +  readonly attribute unsigned short   nodeType;
  +  readonly attribute Node             parentNode;
  +  readonly attribute NodeList         childNodes;
  +  readonly attribute Node             firstChild;
  +  readonly attribute Node             lastChild;
  +  readonly attribute Node             previousSibling;
  +  readonly attribute Node             nextSibling;
  +  readonly attribute NamedNodeMap     attributes;
  +  // Modified in DOM Level 2:
  +  readonly attribute Document         ownerDocument;
  +  Node               insertBefore(in Node newChild, 
  +                                  in Node refChild)
  +                                        raises(DOMException);
  +  Node               replaceChild(in Node newChild, 
  +                                  in Node oldChild)
  +                                        raises(DOMException);
  +  Node               removeChild(in Node oldChild)
  +                                        raises(DOMException);
  +  Node               appendChild(in Node newChild)
  +                                        raises(DOMException);
  +  boolean            hasChildNodes();
  +  Node               cloneNode(in boolean deep);
  +  // Introduced in DOM Level 2:
  +  void               normalize();
  +  // Introduced in DOM Level 2:
  +  boolean            supports(in DOMString feature, 
  +                              in DOMString version);
  +  // Introduced in DOM Level 2:
  +  readonly attribute DOMString        namespaceURI;
  +  // Introduced in DOM Level 2:
  +           attribute DOMString        prefix;
  +                                        // raises(DOMException) on setting
  +
  +  // Introduced in DOM Level 2:
  +  readonly attribute DOMString        localName;
  +};
  +
  +
  +
  +*/
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_newAndAppend                                                        */
  +/*                                                                          */
  +/* Create new node and append it to parent                                  */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tNodeData * Node_newAndAppend (/*in*/  tDomTree *     pDomTree,
  +                               /*in*/  tIndex            xParent,
  +                               /*in*/  tIndex *          pxChilds,
  +                               /*in*/  tSInt32           nLinenumber,
  +                               /*in*/  tSInt32           nSize) 
  +
  +    {
  +    tIndex xChilds        = pxChilds?*pxChilds:0 ;
  +    tNodeData * pNewChild  ;
  +    tIndex      xNdx      = ArrayAdd (&pDomTree -> pLookup, 1) ;
  +
  +    if (nSize == 0)
  +        nSize = sizeof (tNodeData) ;
  +
  +    if ((pDomTree -> pLookup[xNdx] = pNewChild = dom_malloc (nSize)) == NULL)
  +     return NULL ;
  +
  +    memset (pNewChild, 0, nSize) ;
  +    pNewChild -> xParent = xParent ;
  +    pNewChild -> xNdx    = xNdx ;
  +    pNewChild -> nLinenumber = nLinenumber ;
  +    pNewChild -> bFlags = nflgOK ;
  +    pNewChild -> xDomTree = pDomTree -> xNdx ;
  +
  +    if (xChilds)
  +        { /* --- attribute has already childs, get the first and last one --- */
  +     tNodeData * pFirstChild = Node_self (pDomTree, xChilds) ;
  +        tNodeData * pLastChild  = Node_self (pDomTree, pFirstChild -> xPrev) ;
  +
  +        pNewChild -> xNext      = pFirstChild -> xNdx ;    
  +        pNewChild -> xPrev      = pLastChild -> xNdx ;    
  +        pFirstChild -> xPrev    = xNdx ;    
  +        pLastChild -> xNext     = xNdx ;    
  +        }
  +    else
  +        /* --- attribute has no childs, get a new one --- */
  +        {
  +        pNewChild -> xPrev   = xNdx ;
  +        pNewChild -> xNext   = xNdx ;
  +        if (pxChilds)
  +            *pxChilds = xNdx ;
  +        }
  +
  +    numNodes++ ;
  +    
  +    return pNewChild ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_selfExpand                                                          */
  +/*                                                                          */
  +/* Expand a node to hold more attributes                                    */
  +/*                                                                          */
  +/*  pNode    Node to expand                                              */
  +/*  numOldAttr       number of Attributes in the old node that must be relocated */
  +/*              (-1 to take form pNode)                                     */
  +/*  numNewAttr  new number of attributes                                    */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tNodeData * Node_selfExpand   (/*in*/  tDomTree *     pDomTree,
  +                               /*in*/  tNodeData *       pNode,
  +                               /*in*/  tUInt16           numOldAttr, 
  +                               /*in*/  tUInt16           numNewAttr) 
  +
  +    {
  +    tNodeData * pNewChild  ;
  +    tNode       xNdx = pNode -> xNdx ;
  +    int              nSize = sizeof (tNodeData) + numNewAttr  * sizeof (tAttrData) ;
  +
  +    if ((pNewChild = dom_realloc (pNode, nSize)) == NULL)
  +     return NULL ;
  +
  +    if (pNewChild != pNode)
  +     {
  +     tAttrData * pAttr = ((struct tAttrData * )(pNewChild + 1))  ;
  +     void * * pLookup = pDomTree -> pLookup ;
  +
  +     if (numOldAttr == (tUInt16) -1)
  +         numOldAttr = pNewChild -> numAttr ;
  +
  +     pLookup[xNdx] = pNewChild ;
  +
  +     while (numOldAttr--)
  +         {
  +         pLookup[pAttr -> xNdx] = pAttr ;
  +         pAttr++ ; 
  +         }
  +     }
  +   
  +    return pNewChild ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_appendChild                                                         */
  +/*                                                                          */
  +/* Append a child node to a parent node                                     */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tNode Node_appendChild (/*in*/  tDomTree *    pDomTree,
  +                     /*in*/  tNodeType        nType,
  +                     /*in*/  int              bForceAttrValue,
  +                     /*in*/  const char *     sText,
  +                     /*in*/  int              nTextLen,
  +                     /*in*/  tNode            xParent,
  +                     /*in*/  int              nLevel,
  +                     /*in*/  int              nLinenumber)
  +
  +    {
  +    tNodeData *      pParent;
  +    tIndex   xText ;
  +
  +    pParent = Node_self (pDomTree, xParent) ;
  +    
  +    if (nType == ntypAttr)
  +     { /* add new attribute to node */           
  +     struct tAttrData *  pNew  ;
  +     tIndex              xNdx ;
  +
  +     pParent = Node_selfExpand (pDomTree, pParent, -1, pParent -> numAttr + 1) ;
  +
  +     pNew = ((struct tAttrData * )(pParent + 1)) + pParent -> numAttr ;
  +
  +        xNdx = ArrayAdd (&pDomTree -> pLookup, 1) ;
  +     pDomTree -> pLookup[xNdx] = (struct tNodeData *)pNew ;
  +
  +     pNew -> xName       = sText?String2NdxNoInc (sText, nTextLen):nTextLen ;
  +     NdxStringRefcntInc (pNew -> xName) ;
  +     pNew -> xValue      = 0 ;
  +     pNew -> bFlags      = aflgOK ;
  +     pNew -> nType       = nType ;
  +     pNew -> xNdx        = xNdx ;
  +     pNew -> nNodeOffset = ((tUInt8 *)pNew) - ((tUInt8 *)pParent) ;
  +        pParent -> numAttr++ ;
  +     numAttr++ ;
  +
  +     if (pCurrReq -> bDebug & dbgParse)
  +         lprintf (pCurrReq, "[%d]PARSE: AddNode: +%02d %*s Attribut parent=%d 
node=%d type=%d text=%*.*s (#%d)\n", 
  +                                  pCurrReq -> nPid, nLevel, nLevel * 2, "", 
xParent, xNdx, nType, nTextLen, nTextLen, sText?sText:Ndx2String (nTextLen), 
sText?String2NdxNoInc (sText, nTextLen):nTextLen) ; 
  +
  +     return xNdx ;
  +     }
  +    
  +    if ((bForceAttrValue || nType == ntypAttrValue) && 
  +     (pParent -> nType != ntypAttr || (pParent -> bFlags & aflgAttrChilds) == 0))
  +     { 
  +     /* --- add value of attribute, to non attribute parent node                 */
  +     /*     first add dummy attribute to parent with xNoName as name index       */
  +     /*     if this attribute already exist, append the new value as new _child_ */
  +     /*     to that attribute. This means, that an attribute can have multiple   */
  +     /*     child(values), in which case we set the aflgAttrChilds flag          */
  +
  +     struct tAttrData * pNew = (struct tAttrData * )pParent ; 
  +        int bAddChild = 0 ;
  +     
  +     if (pNew -> nType != ntypAttr)
  +            { /* --- parent is not a attribute --- */   
  +         if (nType == ntypAttrValue)
  +             {
  +             int i ;
  +
  +             for (i = 0; i < nTextLen; i++)
  +                 {
  +                 if (!isspace (sText[i]))
  +                     break ;
  +                 }
  +             
  +             if (i == nTextLen)
  +                 return 1 ; /* do not add only spaces as cdata inside a tag */
  +             }
  +
  +         pNew = ((tAttrData *)(pParent + 1)) + pParent -> numAttr - 1 ; /* get last 
attribute of node */
  +         if (pParent -> numAttr == 0 || pNew -> xName != xNoName || bForceAttrValue 
> 1)
  +             { /* --- add dummy attribute --- */
  +             if (!(xParent = Node_appendChild (pDomTree, ntypAttr, 0, NULL, 
xNoName, xParent, nLevel, nLinenumber)))
  +                 return 0 ;
  +             nLevel++ ;
  +             pNew = (struct tAttrData * )pDomTree -> pLookup[xParent] ;  
  +                }
  +         else
  +             { /* --- dummy attribute already exist, reuse it --- */
  +             xParent = pNew -> xNdx ;
  +             bAddChild = 1 ;
  +             nLevel++ ;
  +             }
  +         }
  +        
  +        
  +        if (!bAddChild && !bForceAttrValue)
  +         { /* we have an simple attribute, now put the value into it */
  +         pNew -> xValue  = sText?String2NdxNoInc (sText, nTextLen):nTextLen ;
  +         NdxStringRefcntInc (pNew -> xValue) ;
  +         if (pCurrReq -> bDebug & dbgParse)
  +             lprintf (pCurrReq, "[%d]PARSE: AddNode: +%02d %*s AttributValue 
parent=%d node=%d type=%d text=%*.*s (#%d)\n", pCurrReq -> nPid, nLevel, nLevel * 2, 
"", xParent, pNew -> xNdx, nType, nTextLen, nTextLen, 
  +                                        sText?sText:"<null>", sText?String2NdxNoInc 
(sText, nTextLen):-1) ; 
  +         pNew -> bFlags |= aflgAttrValue ;
  +
  +         return xParent ;
  +         }
  +        else
  +         /* --- we have to add a new child to the attribute, so set the attribute 
as parent --- */
  +         pParent = (tNodeData *)pNew ;
  +
  +        }
  +
  +    /* --- if we come we here we have add a new child node --- */
  +
  +     {
  +     struct tNodeData *  pChilds ;
  +     struct tNodeData *  pNew    ;
  +     tIndex              xNdx ;
  +     tIndex xOldValue = 0 ;
  +
  +     if (pParent && pParent -> nType == ntypAttr)
  +         { /* --- we add a new child to an attribute --- */
  +            if (((tAttrData *)pParent) -> bFlags & aflgAttrValue)
  +                {
  +                xOldValue = ((tAttrData *)pParent) -> xValue ;
  +                ((tAttrData *)pParent) -> xValue = 0 ;
  +                
  +                pNew = Node_newAndAppend (pDomTree, xParent, &(((tAttrData 
*)pParent) -> xValue), nLinenumber, 0) ;
  +                pNew -> nType = ntypAttrValue ;
  +                pNew -> nText = xOldValue ;
  +                }
  +
  +            ((tAttrData *)pParent) -> bFlags &= ~aflgAttrValue ;
  +            ((tAttrData *)pParent) -> bFlags |= aflgAttrChilds ;
  +            pNew = Node_newAndAppend (pDomTree, xParent, &(((tAttrData *)pParent) 
-> xValue), nLinenumber, 0) ;
  +            
  +            }
  +        else
  +            {
  +            pNew = Node_newAndAppend (pDomTree, xParent, pParent?&(pParent -> 
xChilds):NULL, nLinenumber, 0) ;
  +            }
  +        
  +       
  +     if (sText)
  +         xText = String2Ndx (sText, nTextLen) ;
  +     else
  +         {
  +         NdxStringRefcntInc(nTextLen) ;
  +         xText = nTextLen ;
  +         }
  +     pNew -> nType = nType ;
  +        pNew -> nText = xText ;
  +     
  +     if (pCurrReq -> bDebug & dbgParse)
  +         lprintf (pCurrReq, "[%d]PARSE: AddNode: +%02d %*s Element parent=%d 
node=%d type=%d text=%*.*s (#%d)\n", pCurrReq -> nPid, nLevel, nLevel * 2, "", 
xParent, pNew -> xNdx, nType, nTextLen, nTextLen, sText?sText:"<null>", 
  +                                                                             
sText?String2NdxNoInc (sText, nTextLen):-1) ; 
  +
  +     return pNew -> xNdx ;
  +     }
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_removeChild                                                         */
  +/*                                                                          */
  +/* Remove a child node                                                      */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tNodeData * Node_selfRemoveChild (/*in*/ tDomTree *   pDomTree,
  +                     /*in*/ tNode            xParent,
  +                     /*in*/ tNodeData *      pChild)
  +
  +    {
  +    struct tNodeData *       pParent = Node_self (pDomTree, pChild -> xParent) ;
  +    
  +    if (pChild -> xNext == pChild -> xNdx)
  +        { /* --- the only child --- */
  +        pParent -> xChilds = 0 ;
  +        }
  +    else 
  +        {
  +        tNodeData * pPrev = Node_self (pDomTree, pChild -> xPrev) ;
  +        tNodeData * pNext = Node_self (pDomTree, pChild -> xNext) ;
  +
  +        if (pParent -> xChilds == pChild -> xNdx)
  +            { /* --- the first child --- */
  +            pParent -> xChilds = pChild -> xNext ;
  +            }
  +
  +        pPrev -> xNext = pNext -> xNdx ;
  +        pNext -> xPrev = pPrev -> xNdx ;
  +        }
  +
  +    
  +    pDomTree -> pLookup[pChild -> xNdx] = NULL ;
  +    dom_free (pChild) ;
  +    numNodes-- ;
  +
  +    return NULL ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_removeChild                                                         */
  +/*                                                                          */
  +/* Remove a child node                                                      */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tNode Node_removeChild (/*in*/ tDomTree *       pDomTree,
  +                     /*in*/ tNode            xParent,
  +                     /*in*/ tNode            xChild)
  +
  +    {
  +    Node_selfRemoveChild (pDomTree, xParent, Node_self (pDomTree, xChild)) ;
  +    return 0 ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_cloneNode                                                           */
  +/*                                                                          */
  +/* clone a node                                                             */
  +/* bDeep = 1 clone childs also                                              */
  +/* bDeep = 0 clone no childs                                                */
  +/* bDeep = -1 clone no attributes and no childs                             */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tNodeData * Node_selfCloneNode (/*in*/ tDomTree *      pDomTree,
  +                             /*in*/ tNodeData *     pNode,
  +                             /*in*/  int            bDeep)
  +
  +    {
  +    int              len  = sizeof (tNodeData) + (bDeep == -1?0:pNode -> numAttr * 
sizeof (tAttrData)) ; 
  +    tNode       xNewNode ;
  +    tNodeData * pNew ;
  +
  +    if ((pNew = dom_malloc (len)) == NULL)
  +     return NULL ;
  +
  +    numNodes++ ;
  +    
  +    memcpy (pNew, pNode, len) ;
  +    xNewNode         = ArrayAdd (&pDomTree -> pLookup, 1) ;
  +    pDomTree -> pLookup[xNewNode]    = pNew ;
  +    pNew -> xNdx     = xNewNode ;
  +    pNew -> bFlags      &= ~nflgModified ;
  +    pNew -> xDomTree    = pDomTree -> xNdx ;
  +
  +    if (pNew -> nText)
  +     NdxStringRefcntInc (pNew -> nText) ;
  +    
  +    if (bDeep == -1)
  +     pNew -> numAttr = 0 ;
  +    else
  +     {
  +     tAttrData * pAttr = (tAttrData * )(pNew + 1) ;
  +     int         n     = pNew -> numAttr ;
  +
  +     while (n)
  +         {
  +         xNewNode = ArrayAdd (&pDomTree -> pLookup, 1) ;
  +         pDomTree -> pLookup[xNewNode] = pAttr ;
  +         pAttr -> xNdx = xNewNode ;
  +         if (pAttr -> xName)
  +             NdxStringRefcntInc (pAttr -> xName) ;
  +         if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  +             NdxStringRefcntInc (pAttr -> xValue) ;
  +         n-- ;
  +         pAttr++ ;
  +         }
  +     }
  +    if (bDeep < 1)
  +     pNew -> xChilds = 0 ;
  +
  +    return pNew ;
  +    }
  +                                
  +
  +
  +
  +tNode Node_cloneNode (/*in*/ tDomTree *      pDomTree,
  +                 /*in*/ tNode            xNode,
  +                 /*in*/  int             bDeep)
  +
  +    {
  +    tNodeData * pNew = Node_selfCloneNode (pDomTree, Node_self (pDomTree, xNode), 
bDeep) ;
  +
  +    if (pNew)
  +     return pNew -> xNdx ;
  +
  +    return 0 ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_selfCondCloneNode                                                   */
  +/*                                                                          */
  +/* clone a node if it's part of a different DomTree in preparation for      */
  +/* a change                                                                 */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tNodeData * Node_selfCondCloneNode (/*in*/ tDomTree *      pDomTree,
  +                                 /*in*/ tNodeData *     pNode)
  +
  +    {
  +    int              len  ;
  +    tNodeData * pNew ;
  +    tAttrData * pAttr ;
  +    int         n ;
  +    void * *    pLookup  ;
  +    tNode    xNdx ;
  +    
  +    if (pNode -> xDomTree == pDomTree -> xNdx)
  +        return pNode ;
  +
  +    pLookup = pDomTree -> pLookup ;
  +    len          = sizeof (tNodeData) + pNode -> numAttr * sizeof (tAttrData) ; 
  +    xNdx    = pNode -> xNdx ;
  +
  +    if ((pLookup[xNdx] = pNew = dom_malloc (len)) == NULL)
  +     return NULL ;
  +
  +    numNodes++ ;
  +    
  +    memcpy (pNew, pNode, len) ;
  +
  +    pNew -> bFlags      &= ~nflgModified ;
  +    pNew -> xDomTree    = pDomTree -> xNdx ;
  +
  +    if (pNew -> nText)
  +     NdxStringRefcntInc (pNew -> nText) ;
  +    
  +    pAttr = (tAttrData * )(pNew + 1) ;
  +    n     = pNew -> numAttr ;
  +
  +    while (n)
  +     {
  +     pLookup[pAttr -> xNdx] = pAttr ;
  +     if (pAttr -> xName)
  +         NdxStringRefcntInc (pAttr -> xName) ;
  +     if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  +         NdxStringRefcntInc (pAttr -> xValue) ;
  +     n-- ;
  +     pAttr++ ;
  +     }
  +
  +    return pNew ;
  +    }
  +
  +                                
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_replaceChild                                                        */
  +/*                                                                          */
  +/* Replaces the node pointed by pOldChildDomTree/xOldChild, with the node   */
  +/* pointed by pDomTree/xNode                                                */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tNode Node_replaceChildWithNode (/*in*/ tDomTree *      pDomTree,
  +                              /*in*/ tNode           xNode,
  +                                 /*in*/ tDomTree *      pOldChildDomTree,
  +                              /*in*/ tNode           xOldChild)
  +
  +    {
  +    int              bFlags = nflgModified | nflgReturn ;
  +    tNode    xOrgChild  = xOldChild ;
  +    tNodeData *      pNode      = Node_self (pDomTree, xNode) ;
  +    tNodeData *      pOldChild  ;
  +    
  +    pOldChild  = Node_selfCondCloneNode (pOldChildDomTree, Node_self 
(pOldChildDomTree, xOldChild)) ; 
  +
  +    if (pOldChild -> bFlags & nflgModified) 
  +     {
  +     pOldChild -> bFlags |= bFlags ;
  +     pOldChild = Node_selfCloneNode (pOldChildDomTree, pNode, 1) ;
  +     xOldChild = pOldChild -> xNdx ;
  +     }
  +    else
  +     {
  +     int         len  = sizeof (tNodeData) + pNode -> numAttr * sizeof (tAttrData) 
; 
  +     int         numAttr = pOldChild -> numAttr ;
  +     int         nOffset ;
  +     tAttrData * pAttr  ;
  +     int         n      ;
  +     void * * pLookup  ;
  +
  +     
  +        pOldChild  = Node_selfExpand (pOldChildDomTree, pOldChild, 0, pNode -> 
numAttr) ;
  +        
  +     if (pOldChild -> nText)
  +         NdxStringFree (pOldChild -> nText) ;
  +
  +     pAttr = ((struct tAttrData * )(pOldChild + 1))  ;
  +     n     = pOldChild -> numAttr ;
  +
  +     while (n > 0)
  +         {
  +         if (pAttr -> xName)
  +             NdxStringFree (pAttr -> xName) ;
  +         if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  +             NdxStringFree  (pAttr -> xValue) ;
  +         n-- ;
  +         pAttr++ ;
  +         }
  +
  +     memcpy (pOldChild, pNode, len) ;
  +
  +     if (pOldChild -> nText)
  +         NdxStringRefcntInc (pOldChild -> nText) ;
  +     
  +
  +     pOldChild -> xDomTree = pDomTree -> xNdx ;
  +     pOldChild -> xNdx       = xOldChild ;
  +     pOldChild -> bFlags |= bFlags ;
  +
  +     pAttr = ((struct tAttrData * )(pOldChild + 1))  ;
  +     n     = pNode -> numAttr ;
  +     pLookup = pDomTree -> pLookup ;
  +
  +
  +     while (n > 0)
  +         {
  +         if (pAttr -> xName)
  +             NdxStringRefcntInc (pAttr -> xName) ;
  +         if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  +             NdxStringRefcntInc  (pAttr -> xValue) ;
  +         pLookup[pAttr -> xNdx] = pAttr ;
  +         n-- ;
  +         pAttr++ ;
  +         }
  +     
  +     pAttr = ((struct tAttrData * )(pOldChild + 1)) + pOldChild -> numAttr ;
  +     n     = numAttr - pNode -> numAttr ;
  +
  +     while (n > 0)
  +         {
  +         pAttr -> bFlags = nflgDeleted ;
  +         if (pAttr -> xName)
  +             NdxStringFree (pAttr -> xName) ;
  +         if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  +             NdxStringFree (pAttr -> xValue) ;
  +         n-- ;
  +         pAttr++ ;
  +         }
  +     }
  +
  +    if (pOldChild -> nType == ntypDocumentFraq)
  +     {
  +     tAttrData * pAttr = Element_selfSetAttribut (pOldChildDomTree, pOldChild, 
NULL, xDomTreeAttr, NULL, pDomTree -> xNdx, 0) ;
  +     pAttr -> bFlags = aflgOK ; /* reset string value flag */
  +     }
  +     
  +    DomTree_selfCheckpoint (pOldChildDomTree, xOrgChild, xOldChild) ;
  +    
  +    return xOldChild ;
  +    }
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_insertBefore                                                        */
  +/*                                                                          */
  +/* Inserts a child node before another node                                 */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_insertAfter                                                         */
  +/*                                                                          */
  +/* Inserts a child node after another node                                  */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +tNode Node_insertAfter          (/*in*/ tDomTree *      pNewNodeDomTree,
  +                              /*in*/ tNode           xNewNode,
  +                                 /*in*/ tDomTree *      pRefNodeDomTree,
  +                              /*in*/ tNode           xRefNode)
  +
  +    {
  +    int              bFlags = nflgModified | nflgReturn ;
  +    tNodeData *      pNewNode      = Node_self (pNewNodeDomTree, xNewNode) ;
  +    tNodeData *      pRefNode      = Node_self (pRefNodeDomTree, xRefNode) ;
  +    tNodeData *      pNxtNode      = Node_selfNextSibling (pRefNodeDomTree, 
pRefNode) ;
  +    tNode    xOrgNode ;
  +
  +
  +    if (pNewNodeDomTree != pRefNodeDomTree)
  +        {
  +        tNodeData * pNew = Node_newAndAppend (pRefNodeDomTree, pRefNode -> xParent, 
NULL, pNewNode -> nLinenumber, sizeof (tNodeData) + pNewNode -> numAttr * sizeof 
(tAttrData)) ;        
  +
  +        pNew -> nText   = pNewNode -> nText ;
  +        pNew -> xChilds = pNewNode -> xChilds ;
  +        pNew -> nType   = pNewNode -> nType ;
  +        pNew -> bFlags  = pNewNode -> bFlags | nflgModified | nflgReturn ;
  +        
  +        if (pNew -> nText)
  +         NdxStringRefcntInc (pNew -> nText) ;
  +        pNewNode = pNew ;
  +        }    
  +    
  +    pRefNode  = Node_selfCondCloneNode (pRefNodeDomTree, pRefNode) ; 
  +    if (pNxtNode)
  +        pNxtNode  = Node_selfCondCloneNode (pRefNodeDomTree, pNxtNode) ; 
  +    else
  +        pNxtNode = pRefNode ;
  +
  +    if ((pNxtNode -> bFlags & nflgModified) == 0)
  +     {
  +     xOrgNode = pNewNode -> xNdx ;
  +     pNxtNode -> xPrev = pNewNode -> xNdx ;
  +     pRefNode -> xNext = pNewNode -> xNdx ;
  +     pNewNode -> xPrev = pRefNode -> xNdx ;
  +     pNewNode -> xNext = pNxtNode -> xNdx ;
  +     }
  +    else
  +     xOrgNode = pNxtNode -> xNdx ;
  +
  +    DomTree_selfCheckpoint (pRefNodeDomTree, xOrgNode, pNewNode -> xNdx) ;
  +
  +    if (pNewNode -> nType == ntypDocumentFraq)
  +     {
  +     tAttrData * pAttr = Element_selfSetAttribut (pRefNodeDomTree, pNewNode, NULL, 
xDomTreeAttr, NULL, pNewNodeDomTree -> xNdx, 0) ;
  +     pAttr -> bFlags = aflgOK ; /* reset string value flag */
  +     }
  +
  +    return pNewNode -> xNdx ;
  +    }
  +
  +
  +
  +    
  +    
  +
  +
  +
  +
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_replaceChild                                                        */
  +/*                                                                          */
  +/* Replace child node                                                       */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +tNode Node_replaceChildWithCDATA (/*in*/ tDomTree *   pDomTree,
  +                               /*in*/ tNode           xNode,
  +                               /*in*/ tNode           xOldChild,
  +                               /*in*/ const char *    sText,
  +                               /*in*/ int             nTextLen,
  +                               /*in*/ int             nEscMode,
  +                               /*in*/ int             bFlags)
  +
  +    {
  +    tNodeData *      pOldChild  ;
  +    tNode    xOrgChild  = xOldChild ;
  +    tStringIndex n ;
  +    
  +    numReplace++ ;
  +
  +    /* *** lprintf (pCurrReq, "rp1--> SVs=%d  %s  DomTree Old=%d\n", sv_count, 
sText?sText:"<null>", Node_selfDomTree (Node_self (pDomTree, xOldChild))) ; */
  +
  +    pOldChild  = Node_selfCondCloneNode (pDomTree, Node_self (pDomTree, xOldChild)) 
; 
  +
  +    xCheckpointCache[nCheckpointCache++] = xOldChild ;
  +
  +    if (pOldChild -> bFlags & nflgModified) 
  +     {
  +     pOldChild -> bFlags |= bFlags ;
  +     pOldChild = Node_selfCloneNode (pDomTree, pOldChild, 0) ;
  +     xOldChild = pOldChild -> xNdx ;
  +     }
  +    /* *** lprintf (pCurrReq, "rp2--> DomTree New=%d\n", Node_selfDomTree 
(pOldChild)) ; */
  +    
  +    DomTree_selfCheckpoint (pDomTree, xOrgChild, xOldChild) ;
  +    
  +    xCheckpointCache[nCheckpointCache++] = xOldChild ;
  +    nCheckpointCache &= nCheckpointCacheMask ;
  +    xCheckpointCache[nCheckpointCache] = 0 ;
  +
  +   
  +    if (nEscMode != -1)
  +     {
  +     pOldChild -> nType  = (nEscMode & 3)?ntypText:ntypCDATA ;
  +     pOldChild -> bFlags &= ~(nflgEscUrl + nflgEscChar) ;
  +     pOldChild -> bFlags |= (nEscMode ^ nflgEscChar) & (nflgEscUrl + nflgEscChar) ;
  +     }
  +    else
  +     pOldChild -> nType  = ntypCDATA ;
  +
  +    n = pOldChild -> nText ;
  +    pOldChild -> nText = String2Ndx(sText, nTextLen) ;
  +    pOldChild -> xChilds = 0 ;
  +    pOldChild -> bFlags |= bFlags ;
  +    if (n)
  +     NdxStringFree (n) ;
  +
  +    /* *** lprintf (pCurrReq, "rp<-- nText=%d sText=>%*.*s< nTextLen = %d  
SVs=%d\n", pOldChild -> nText, nTextLen,nTextLen, sText?sText:"<null>",  nTextLen, 
sv_count) ; */
  +    return xOldChild ;
  +    }
  +
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_selfLastChild                                                       */
  +/*                                                                          */
  +/* Get last child node                                                           */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tNodeData * Node_selfLastChild   (/*in*/  tDomTree *   pDomTree,
  +                               /*in*/  tNodeData *  pNode) 
  +
  +    {
  +    if (pNode -> xChilds)
  +        return Node_self (pDomTree, Node_selfFirstChild (pDomTree, pNode) -> xPrev) 
;
  +    
  +    return 0 ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_selfNthChild (pNode, nChildNo) ;                                    */
  +/*                                                                          */
  +/* Get nth child node                                                            */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +struct tNodeData * Node_selfNthChild (/*in*/  tDomTree *    pDomTree,
  +                                   /*in*/ struct tNodeData * pNode,
  +                                   /*in*/ int                nChildNo) 
  +
  +    {
  +    if (pNode -> xChilds)
  +        {
  +        tNodeData * pChild  ;
  +        tNodeData * pFirstChild = Node_selfFirstChild (pDomTree, pNode) ;
  +
  +        if (nChildNo == 0)
  +            return pFirstChild ;
  +        
  +        
  +        pChild = pFirstChild ;
  +
  +        do
  +            {
  +            pChild = Node_self (pDomTree, pChild -> xNext) ;
  +            if (nChildNo-- < 2)
  +                return pChild ;
  +            }
  +        while (nChildNo > 1 && pChild != pFirstChild) ;
  +        }
  +
  +    return 0 ;
  +    }
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_nextSibling (xNode) ;                                               */
  +/*                                                                          */
  +/* Get next sibling node                                                 */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tNodeData * Node_selfNextSibling (/*in*/ tDomTree *  pDomTree,
  +                               /*in*/ tNodeData * pNode) 
  +
  +    {
  +    tNodeData * pParent  ;
  +
  +    if (pNode -> xNext == pNode -> xNdx)
  +        return NULL ;
  +    
  +    pParent = Node_self (pDomTree, pNode -> xParent) ;
  +    if (pParent -> xChilds == pNode -> xNext)
  +        return NULL ;
  +    
  +    return Node_self (pDomTree, pNode -> xNext) ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_nextSibling (xNode) ;                                               */
  +/*                                                                          */
  +/* Get next sibling node                                                 */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tNode Node_nextSibling (/*in*/ tDomTree *  pDomTree,
  +                     /*in*/ tNode       xNode) 
  +
  +
  +    {
  +    tNodeData * pNode = Node_self (pDomTree, xNode) ;
  +    tNodeData * pParent  ;
  +
  +    if (pNode -> xNext == pNode -> xNdx)
  +        return 0 ;
  +    
  +    pParent = Node_self (pDomTree, pNode -> xParent) ;
  +    if (pParent -> xChilds == pNode -> xNext)
  +        return 0 ;
  +    
  +    return pNode -> xNext ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_previousSibling (xNode) ;                                           */
  +/*                                                                          */
  +/* Get previous sibling node                                             */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tNodeData * Node_selfPreviousSibling (/*in*/ tDomTree *  pDomTree,
  +                               /*in*/ tNodeData * pNode) 
  +
  +    {
  +    tNodeData * pParent  ;
  +
  +    if (pNode -> xPrev == pNode -> xNdx)
  +        return 0 ;
  +    
  +    pParent = Node_self (pDomTree, pNode -> xParent) ;
  +    if (pParent -> xChilds == pNode -> xPrev)
  +        return 0 ;
  +    
  +    return Node_self (pDomTree, pNode -> xPrev) ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_previousSibling (xNode) ;                                           */
  +/*                                                                          */
  +/* Get previous sibling node                                             */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +tNode Node_previousSibling (/*in*/ tDomTree *  pDomTree,
  +                     /*in*/ tNode       xNode) 
  +
  +
  +    {
  +    tNodeData * pNode = Node_self (pDomTree, xNode) ;
  +    tNodeData * pParent  ;
  +
  +    if (pNode -> xPrev == pNode -> xNdx)
  +        return 0 ;
  +    
  +    pParent = Node_self (pDomTree, pNode -> xParent) ;
  +    if (pParent -> xChilds == pNode -> xPrev)
  +        return 0 ;
  +    
  +    return pNode -> xPrev ;
  +    }
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Node_toString                                                            */
  +/*                                                                          */
  +/*                                                                          */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tNodeData * Node_toString2 (/*in*/  tDomTree *     pDomTree,
  +                 /*i/o*/ register req *  r,
  +                 /*in*/  tNode           xNode,
  +                    /*in*/  int *           pOrderNdx)
  +
  +
  +    {
  +    tNode xFirstNode = xNode ;
  +    tNode xNextNode ;
  +    int   nOrderNdx = *pOrderNdx ;
  +    int   nOrderIndexNode = -1 ;
  +    int   bCheckpointFound = 0  ;
  +    tNodeData * pNextNode ;
  +    tNodeData * pSavedNode = NULL ;
  +    tNodeData * pSavedNodeFrom = NULL ;
  +    tNodeData * pLastStartTag = NULL ;
  +    tNodeData * pNode = Node_self (pDomTree, xNode) ;
  +    tNodeData * pFirstNode = pNode ;
  +    
  +    
  +    
  +    if (pNode -> nType == ntypDocumentFraq)
  +     {
  +     tAttrData * pOrderIndex = Element_selfGetAttribut (pDomTree, pNode, NULL, 
xOrderIndexAttr) ;
  +     pDomTree = DomTree_self (Element_selfGetAttribut (pDomTree, pNode, NULL, 
xDomTreeAttr) -> xValue) ;
  +     if (pOrderIndex)
  +         nOrderNdx = pOrderIndex -> xValue ;
  +     }
  +    
  +
  +    pNode = Node_selfFirstChild (pDomTree, pNode) ;
  +
  +    while (pNode)
  +     {
  +     if (pNode -> bFlags & nflgCheckpoint)
  +         { /* see how the control flow contiounes */
  +         if ((xNextNode = pDomTree -> pOrder[nOrderNdx].xFromNode) != pNode -> xNdx 
&& xNextNode)    
  +             {
  +             tNodeData * pNewNode ;
  +                tNodeData * pNewParent ;
  +                tNodeData * pParent ;
  +                
  +                if (pCurrReq -> bDebug & dbgParse)
  +                 lprintf (r, "[%d]toString: ** Skip Node=%d to Node=%d (OrderIndex 
%d)\n", r -> nPid, pNode -> xNdx, xNextNode, nOrderNdx) ; 
  +             
  +             if (xNextNode == -1)
  +                 return NULL ; /* end of flow */
  +             
  +             bCheckpointFound = 1 ;
  +                pSavedNode = NULL ;
  +             pNewNode      = Node_self (pDomTree, xNextNode) ;
  +             pNewParent    = Node_selfParentNode (pDomTree, pNewNode) ;
  +             if (pParent       = pLastStartTag)
  +                 {
  +                 while (pNewParent != pParent)
  +                     {
  +                     if (pParent)
  +                         {
  +                         oputs (r, "</") ;
  +                         oputs (r, Node_selfNodeName (pParent)) ;
  +                         oputc (r, '>') ;
  +                         }
  +                     else
  +                         {
  +                         lprintf (r, "[%d]WARN: unstructured jump\n", r -> nPid) ;
  +                         break ;
  +                         }
  +                     pParent = Node_selfParentNode (pDomTree, pParent) ;
  +                     }
  +                 }
  +             pLastStartTag = NULL ;
  +             pNode = pNewNode ;
  +             }
  +         nOrderNdx++ ;
  +         }
  +
  +     if (pNode -> bFlags & nflgReturn)
  +         { /* we should use another node to replace this one */
  +         tDomTreeOrder * pOrder = pDomTree -> pOrder ;
  +         int             n      = ArrayGetSize (pOrder) ;
  +         int             i      = nOrderNdx ;
  +
  +         while (pOrder[i].xFromNode != pNode -> xNdx && i < n)  
  +             i++ ;
  +         
  +         if (i < n)
  +             {                   
  +             if ((xNextNode = pOrder[i].xToNode) != pNode -> xNdx && xNextNode)     
 
  +                 {
  +                 if (pCurrReq -> bDebug & dbgParse)
  +                     lprintf (r, "[%d]toString: ** Replace Node=%d with Node=%d 
(OrderIndex %d, initial %d)\n", r -> nPid, pNode -> xNdx, xNextNode, i, nOrderNdx) ; 
  +                 pSavedNode = pNode ;    
  +                 pNode  = Node_self (pDomTree, xNextNode) ;
  +                 pSavedNodeFrom = pNode ;    
  +                 }
  +             if (i == nOrderNdx)
  +                 nOrderNdx++, nOrderIndexNode = -1 ;
  +             else
  +                 nOrderIndexNode = i ;
  +             }
  +         else
  +             {
  +             mydie ("Internal Error: Orderindex out of range") ;
  +             }
  +         }
  +
  +
  +     if (pCurrReq -> bDebug & dbgParse)
  +         lprintf (r, "[%d]toString: Node=%d type=%d flags=%x text=>%s<= (#%d) 
SVs=%d\n", r -> nPid, pNode -> xNdx, pNode -> nType,  pNode -> bFlags, Ndx2String 
(pNode -> nText), pNode -> nText, sv_count) ; 
  +
  +     if (pNode -> bFlags & nflgIgnore)
  +            ;
  +     else if (pNode -> nType == ntypDocumentFraq)
  +         {
  +         Node_toString (pDomTree, r, pNode -> xNdx) ; 
  +         oputs (r, "\r\n") ;
  +         }
  +        else if (pNode -> nType == ntypTag || pNode -> nType == ntypStartTag)
  +         {
  +         int n = pNode -> numAttr ;
  +         struct tAttrData * pAttr = (struct tAttrData *)(pNode + 1) ;
  +
  +         if (pNode -> nType == ntypStartTag)
  +             pLastStartTag = pNode ;
  +
  +         oputc (r, '<') ;
  +         oputs (r, Node_selfNodeName (pNode)) ;
  +         
  +         while (n--)
  +             {
  +             if (pAttr -> bFlags)
  +                 {
  +                 char * s ;
  +                 int    l ;
  +                 oputc (r, ' ') ;
  +                 if (pAttr -> xName != xNoName)
  +                     {
  +                     Ndx2StringLen (pAttr -> xName,s,l) ;
  +                     owrite (r, s, l);
  +                     }
  +
  +                 if (pAttr -> xValue)
  +                     {
  +                     if (pAttr -> xName != xNoName)
  +                         oputs (r, "=\"") ;
  +
  +                     if (pAttr -> bFlags & aflgAttrChilds)
  +                         {
  +                         tAttrData * pAttrNode = (tAttrData * )Node_toString2 
(pDomTree, r, pAttr -> xNdx, &nOrderNdx) ;
  +                            if (pAttrNode && pAttrNode != pAttr)
  +                                {
  +                                pAttr = pAttrNode ;
  +                                pNode = Attr_selfNode(pAttr) ;
  +                                n = pNode -> numAttr - Attr_selfAttrNum (pAttr) - 1 
;
  +                                if (n < 0)
  +                                    n = 0 ;
  +                                }
  +                         }
  +                     else
  +                         {
  +                         Ndx2StringLen (pAttr -> xValue, s, l) ;
  +                         while (isspace (*s) && l > 0)
  +                             s++, l-- ;
  +                         owrite (r, s, l) ;
  +                         }
  +                     if (pAttr -> xName != xNoName)
  +                         oputc (r, '"') ;
  +                     }
  +                 }
  +             pAttr++ ;
  +             }
  +         oputc (r, '>') ;
  +         }
  +     else if (pNode -> nType == ntypText)
  +         {
  +         char * s ;
  +         int    l ;
  +         Ndx2StringLen (pNode -> nText,s,l) ;
  +         OutputEscape (r, s, l, (pNode -> bFlags & nflgEscUrl)?Char2Url:Char2Html, 
(pNode -> bFlags & nflgEscChar)?'\\':0) ;
  +         }
  +     else 
  +         {
  +         char * s ;
  +         int    l ;
  +         Ndx2StringLen (pNode -> nText,s,l) ;
  +         owrite (r, s, l);
  +         }
  +
  +     if (nOrderNdx == nOrderIndexNode)
  +         nOrderNdx++ ;
  +
  +     if (pNode -> nType == ntypDocumentFraq)
  +         pNextNode = NULL ;
  +     else
  +         pNextNode = Node_selfFirstChild (pDomTree, pNode) ;
  +     if (pNextNode == NULL)
  +         {
  +         if (pSavedNode && pSavedNodeFrom == pNode)
  +             {
  +             pNode = pSavedNode ;
  +             pSavedNode = NULL ;
  +             }
  +
  +     
  +         pNextNode  = Node_selfNextSibling (pDomTree, pNode) ;
  +         while (pNextNode == NULL)
  +             {
  +             pNextNode = Node_selfParentNode (pDomTree, pNode) ;
  +             if (pNextNode == NULL || pNextNode  == pFirstNode || pNextNode -> 
nType == ntypAttr)
  +                    {
  +                    *pOrderNdx = nOrderNdx ;
  +                    return bCheckpointFound?pNextNode:NULL ;
  +                    }
  +                 
  +             if (pSavedNode && pSavedNodeFrom == pNextNode)
  +                 {
  +                 pNextNode = pSavedNode ;
  +                 pSavedNode = NULL ;
  +                 }
  +             pNode = pNextNode ;
  +             pNextNode  = Node_selfNextSibling (pDomTree, pNextNode) ;
  +             if (pNode -> nType == ntypStartTag && (pNode -> bFlags & nflgIgnore) 
== 0 &&
  +                 (pNextNode == NULL || (pNextNode -> bFlags & nflgCheckpoint) == 0 
|| pDomTree -> pOrder[nOrderNdx].xFromNode == pNextNode -> xNdx))
  +                 {
  +                 oputs (r, "</") ;
  +                 oputs (r, Node_selfNodeName (pNode)) ;
  +                 oputc (r, '>') ;
  +                 pLastStartTag = Node_selfParentNode (pDomTree, 
pNextNode?pNextNode:pNode) ;
  +                 }
  +             }
  +         }
  +     pNode = pNextNode ;
  +     }
  +
  +    *pOrderNdx = nOrderNdx ;
  +
  +    return NULL ;    
  +    }
  +
  +void Node_toString (/*in*/  tDomTree *   pDomTree,
  +                 /*i/o*/ register req * r,
  +                 /*in*/  tNode           xNode)
  +
  +
  +    {
  +    int   nOrderNdx = 0 ;
  +
  +    Node_toString2 (pDomTree, r, xNode, &nOrderNdx) ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* NodeList_toString                                                            */
  +/*                                                                          */
  +/*                                                                          */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +void NodeList_toString (/*in*/  tDomTree *   pDomTree,
  +                     /*in*/ tNode        xNode)
  +
  +
  +    {
  +    xNode = Node_firstChild (pDomTree, xNode) ;
  +
  +    
  +
  +    }
  +
  +    
  +/* ------------------------------------------------------------------------
  +
  +interface Element : Node {
  +  readonly attribute DOMString        tagName;
  +  DOMString          getAttribute(in DOMString name);
  +  void               setAttribute(in DOMString name, 
  +                                  in DOMString value)
  +                                        raises(DOMException);
  +  void               removeAttribute(in DOMString name)
  +                                        raises(DOMException);
  +  Attr               getAttributeNode(in DOMString name);
  +  Attr               setAttributeNode(in Attr newAttr)
  +                                        raises(DOMException);
  +  Attr               removeAttributeNode(in Attr oldAttr)
  +                                        raises(DOMException);
  +  NodeList           getElementsByTagName(in DOMString name);
  +  // Introduced in DOM Level 2:
  +  DOMString          getAttributeNS(in DOMString namespaceURI, 
  +                                    in DOMString localName);
  +  // Introduced in DOM Level 2:
  +  void               setAttributeNS(in DOMString namespaceURI, 
  +                                    in DOMString qualifiedName, 
  +                                    in DOMString value)
  +                                        raises(DOMException);
  +  // Introduced in DOM Level 2:
  +  void               removeAttributeNS(in DOMString namespaceURI, 
  +                                       in DOMString localName)
  +                                        raises(DOMException);
  +  // Introduced in DOM Level 2:
  +  Attr               getAttributeNodeNS(in DOMString namespaceURI, 
  +                                        in DOMString localName);
  +  // Introduced in DOM Level 2:
  +  Attr               setAttributeNodeNS(in Attr newAttr)
  +                                        raises(DOMException);
  +  // Introduced in DOM Level 2:
  +  NodeList           getElementsByTagNameNS(in DOMString namespaceURI, 
  +                                            in DOMString localName);
  +  // Introduced in DOM Level 2:
  +  boolean            hasAttribute(in DOMString name);
  +  // Introduced in DOM Level 2:
  +  boolean            hasAttributeNS(in DOMString namespaceURI, 
  +                                    in DOMString localName);
  +};
  +
  +
  +------------------------------------------------------------------------- */
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Element_selfGetAttribut                                                  */
  +/*                                                                          */
  +/* Get attribute value of Element by name                                   */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tAttrData *  Element_selfGetAttribut (/*in*/ tDomTree *              pDomTree,
  +                                   /*in*/ struct tNodeData * pNode,
  +                                   /*in*/ const char *       sAttrName,
  +                                   /*in*/ int                nAttrNameLen) 
  +
  +    {
  +    int nAttrName = sAttrName?String2NdxNoInc (sAttrName, 
nAttrNameLen):nAttrNameLen ;
  +    struct tAttrData * pAttr = (struct tAttrData * )(pNode + 1) ;
  +    int  n = pNode -> numAttr ;
  +
  +    while (n > 0 && (nAttrName != pAttr -> xName || !pAttr -> bFlags))
  +     {
  +     n-- ;
  +     pAttr++ ;
  +     }
  +
  +    if (n)
  +     return pAttr ;
  +
  +    return NULL ;
  +    }
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Element_selfGetNthAttribut                                               */
  +/*                                                                          */
  +/* Get attribute value of Element by index                                  */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tAttrData *  Element_selfGetNthAttribut (/*in*/ tDomTree *      pDomTree,
  +                                      /*in*/ struct tNodeData * pNode,
  +                                      /*in*/ int                n)
  +
  +    {
  +    struct tAttrData * pAttr = (struct tAttrData * )(pNode + 1) ;
  +    int  num = pNode -> numAttr ;
  +
  +    if (n < 0 || n >= num)
  +        return NULL ;
  +
  +    return pAttr + n ;
  +    }
  +
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Element_selfSetAttribut                                                  */
  +/*                                                                          */
  +/* Set attribute value of Element by name                                   */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tAttrData *  Element_selfSetAttribut (/*in*/ tDomTree *              pDomTree,
  +                                   /*in*/ struct tNodeData * pNode,
  +                                   /*in*/ const char *       sAttrName,
  +                                   /*in*/ int                nAttrNameLen,
  +                                   /*in*/ const char *       sNewValue, 
  +                                   /*in*/ int                nNewValueLen,
  +                                   /*in*/ int                bClone)
  +
  +    {
  +    tAttrData * pAttr ;
  +    tNode xAttr ;
  +    tNodeData * pNewNode ;
  +
  +    pNode = Node_selfCondCloneNode (pDomTree, pNode) ;
  +    pAttr = Element_selfGetAttribut (pDomTree, pNode, sAttrName, nAttrNameLen) ;
  +
  +    if (pAttr)
  +     {
  +     tIndex xValue = sNewValue?String2NdxNoInc (sNewValue, 
nNewValueLen):nNewValueLen ;
  +     NdxStringRefcntInc (xValue) ;
  +
  +     if (bClone)
  +         {
  +         if (pAttr -> xValue != xValue && (pNode -> bFlags & nflgModified))
  +             {
  +             pNewNode = Node_selfCloneNode (pDomTree, pNode, 1) ;
  +             pAttr = Element_selfGetAttribut (pDomTree, pNewNode, sAttrName, 
nAttrNameLen) ;
  +             
  +             DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNewNode -> xNdx) ;
  +             }
  +         else
  +             DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNode -> xNdx) ;
  +
  +         pNode -> bFlags |= nflgReturn | nflgModified ;
  +         }
  +
  +     if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  +         NdxStringFree (pAttr -> xValue) ;
  +
  +     pAttr -> xValue = xValue ;
  +     return pAttr ;
  +     }
  +
  +    if (pNode -> bFlags & nflgModified && bClone)
  +     pNewNode = Node_selfCloneNode (pDomTree, pNode, 1) ;
  +    else
  +     pNewNode = pNode ;
  +
  +    if (bClone)
  +     {
  +     pNode -> bFlags |= nflgReturn | nflgModified ;
  +     DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNewNode -> xNdx) ;
  +     }
  +    
  +    xAttr = Node_appendChild (pDomTree, ntypAttr, 0, sAttrName, nAttrNameLen, 
pNewNode -> xNdx, 0, pNewNode -> nLinenumber) ;
  +    Node_appendChild (pDomTree, ntypAttrValue, 0, sNewValue, nNewValueLen, xAttr, 
0, pNewNode -> nLinenumber) ;
  +    return (tAttrData *)Node_self(pDomTree, xAttr) ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Element_selfRemoveAttribut                                               */
  +/*                                                                          */
  +/* Remove attribute of Element by name                                      */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +tAttrData *  Element_selfRemoveAttribut (/*in*/ tDomTree *           pDomTree,
  +                                   /*in*/ struct tNodeData * pNode,
  +                                   /*in*/ const char *       sAttrName,
  +                                   /*in*/ int                nAttrNameLen,
  +                                   /*in*/ int                bClone)
  +
  +    {
  +    tAttrData * pAttr ;
  +    tNodeData * pNewNode ;
  +    
  +    Node_selfCondCloneNode (pDomTree, pNode) ;
  +    pNode = Node_self (pDomTree, pNode -> xNdx) ;
  +
  +    pAttr = Element_selfGetAttribut (pDomTree, pNode, sAttrName, nAttrNameLen) ;
  +    if (bClone)
  +     {
  +     if (pAttr != NULL && (pNode -> bFlags & nflgModified))
  +         {
  +         pNode -> bFlags |= nflgReturn | nflgModified ;
  +
  +         pNewNode = Node_selfCloneNode (pDomTree, pNode, 1) ;
  +         pAttr = Element_selfGetAttribut (pDomTree, pNewNode, sAttrName, 
nAttrNameLen) ;
  +    
  +         DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNewNode -> xNdx) ;
  +         }
  +     else
  +         {
  +         pNode -> bFlags |= nflgReturn | nflgModified ;
  +
  +         DomTree_selfCheckpoint (pDomTree, pNode -> xNdx, pNode -> xNdx) ;
  +         }
  +     }
  +
  +    if (pAttr)
  +     {
  +     pAttr -> bFlags = 0 ;
  +     if (pAttr -> xName)
  +         NdxStringFree (pAttr -> xName) ;
  +     if (pAttr -> xValue && (pAttr -> bFlags & aflgAttrValue))
  +         NdxStringFree (pAttr -> xValue) ;
  +     }
  +
  +    /*
  +    int    nCopyAttr ;
  +
  +    if (pAttr)
  +     {
  +     nAttr = pAttr - ((struct tAttrData * )(pNode + 1)) ;
  +     pNode -> numAttr-- ;
  +     nCopyAttr = pNode -> numAttr - nAttr  ;
  +     if (nCopyAttr)
  +         {
  +         memcpy (pAttr, pAttr + 1, nCopyAttr * sizeof (tAttrData)) ;
  +         while (nCopyAttr--)
  +             {
  +             pDomTree -> pLookup[pAttr -> xNdx] = pAttr ;
  +             pAttr++ ;
  +             }
  +         }
  +     }
  +    */
  +
  +    return pAttr ;
  +    }
  +
  +
  +/* ------------------------------------------------------------------------
  +
  +
  +interface Attr : Node {
  +  readonly attribute DOMString        name;
  +  readonly attribute boolean          specified;
  +           attribute DOMString        value;
  +                                        // raises(DOMException) on setting
  +
  +  // Introduced in DOM Level 2:
  +  readonly attribute Element          ownerElement;
  +};
  +
  +------------------------------------------------------------------------ */
  +
  +
  +
  +/* ------------------------------------------------------------------------ */
  +/*                                                                          */
  +/* Attr_selfValue                                                        */
  +/*                                                                          */
  +/*                                                                          */
  +/*                                                                          */
  +/* ------------------------------------------------------------------------ */
  +
  +
  +
  +char *       Attr_selfValue (/*in*/ tDomTree *               pDomTree,
  +                          /*in*/ struct tAttrData * pAttr,
  +                         /*out*/ char * *    ppAttr) 
  +
  +    {
  +    struct tNodeData * pNode ;
  +    
  +    if (!pAttr)
  +     return NULL ;
  +
  +    if (!(pAttr -> bFlags & aflgAttrChilds))
  +     return Ndx2String (pAttr -> xValue) ;
  +
  +    pNode = Node_self (pDomTree, pAttr -> xValue) ;
  +    
  +    StringNew (ppAttr, 512) ;
  +
  +    while (pNode)
  +     {
  +     char * s ;
  +     int    l ;
  +
  +     if (pNode -> bFlags & nflgReturn)
  +         {
  +         tIndex xNdx = pNode -> xNdx ;
  +         tNodeData * pUseNode ;
  +         int i = nCheckpointCache - 2 ;
  +     
  +         i &= nCheckpointCacheMask ;
  +         
  +         while (xCheckpointCache[i] && xCheckpointCache[i] != xNdx)
  +             {
  +             i -= 2 ;
  +             i &= nCheckpointCacheMask ;
  +             }
  +
  +         if (xCheckpointCache[i])
  +             xNdx = xCheckpointCache[i+1] ;
  +
  +         pUseNode = Node_self (pDomTree, xNdx) ;
  +         Ndx2StringLen (pUseNode -> nText,s,l) ;
  +         }
  +     else    
  +         Ndx2StringLen (pNode -> nText,s,l) ;
  +     StringAdd (ppAttr, s, l) ;
  +     pNode = Node_selfNextSibling (pDomTree, pNode) ;
  +     }
  +
  +    return *ppAttr ;
  +    }
  
  
  
  1.75.4.19 +7 -7      embperl/epmain.c
  
  Index: epmain.c
  ===================================================================
  RCS file: /home/cvs/embperl/epmain.c,v
  retrieving revision 1.75.4.18
  retrieving revision 1.75.4.19
  diff -u -r1.75.4.18 -r1.75.4.19
  --- epmain.c  2000/12/18 11:38:15     1.75.4.18
  +++ epmain.c  2000/12/18 12:43:24     1.75.4.19
  @@ -41,8 +41,8 @@
   static char sEscModeName   [] = "HTML::Embperl::escmode" ;
   #ifdef EP2
   static char sCurrNodeName   [] = "HTML::Embperl::_ep_node" ;
  -//static char sCheckpointNodeName   [] = "HTML::Embperl::_ep_cp" ;
  -//static char sOutputVarName   [] = "HTML::Embperl::_ep_rp" ;
  +//static char sCheckpointNodeName   [] = "HTML::Embperl::_ep_cp" ;
  +//static char sOutputVarName   [] = "HTML::Embperl::_ep_rp" ;
   static char sTokenHashName [] = "HTML::Embperl::Syntax::Default" ;
   #endif
   
  @@ -330,9 +330,9 @@
   INTMG (TabMode, pCurrReq -> nTabMode, notused, ;) 
   INTMG (EscMode, pCurrReq -> nEscMode, notused, NewEscMode (pCurrReq, pSV)) 
   #ifdef EP2
  -INTMGshort (CurrNode, pCurrReq -> xCurrNode) 
  -//INTMGcall  (CheckpointNode, pCurrReq -> xCurrNode, pCurrReq -> nCurrEscMode = 
pCurrReq -> nEscMode ; pCurrReq -> bEscModeSet = -1 ;  DomTree_checkpoint (pCurrReq -> 
xCurrDomTree, pCurrReq -> xCurrNode)) 
  -//INTMGcall  (OutputVar, pCurrReq -> xCurrNode, Node_replaceWithCDATA (pCurrReq -> 
xCurrDomTree, pCurrReq -> xCurrNode)) 
  +INTMGshort (CurrNode, pCurrReq -> xCurrNode) 
  +//INTMGcall  (CheckpointNode, pCurrReq -> xCurrNode, pCurrReq -> nCurrEscMode = 
pCurrReq -> nEscMode ; pCurrReq -> bEscModeSet = -1 ;  DomTree_checkpoint (pCurrReq -> 
xCurrDomTree, pCurrReq -> xCurrNode)) 
  +//INTMGcall  (OutputVar, pCurrReq -> xCurrNode, Node_replaceWithCDATA (pCurrReq -> 
xCurrDomTree, pCurrReq -> xCurrNode)) 
   #endif
   
   OPTMGRD (optDisableVarCleanup      , pCurrReq -> bOptions) ;
  @@ -1528,8 +1528,8 @@
       ADDINTMG (TabMode) ;
       ADDINTMG (EscMode) ;
   #ifdef EP2
  -    ADDINTMG (CurrNode) ;
  -    //ADDINTMG (CheckpointNode) ;
  +    ADDINTMG (CurrNode) ;
  +    //ADDINTMG (CheckpointNode) ;
       //ADDINTMG (OutputVar) ;
   #endif    
       
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to