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]