15 static char THIS_FILE[]=__FILE__;
22 void CMarkupSTL::operator=(
const CMarkupSTL& markup )
24 m_iPosParent = markup.m_iPosParent;
25 m_iPos = markup.m_iPos;
26 m_iPosChild = markup.m_iPosChild;
27 m_iPosFree = markup.m_iPosFree;
28 m_nNodeType = markup.m_nNodeType;
29 m_aPos = markup.m_aPos;
30 m_strDoc = markup.m_strDoc;
34 bool CMarkupSTL::SetDoc(
const char* szDoc )
39 m_mapSavedPos.clear();
50 int nStartSize = m_strDoc.size() / 64 + 8;
51 if ( m_aPos.size() < nStartSize )
52 m_aPos.resize( nStartSize );
55 bool bWellFormed =
false;
56 if ( m_strDoc.size() )
59 int iPos = x_ParseElem( 0 );
62 m_aPos[0].iElemChild = iPos;
78 bool CMarkupSTL::IsWellFormed()
80 if ( m_aPos.size() && m_aPos[0].iElemChild )
85 bool CMarkupSTL::Load(
const char* szFileName )
89 FILE* fp = fopen( szFileName,
"rb" );
93 fseek( fp, 0L, SEEK_END );
94 int nFileLen = ftell(fp);
95 fseek( fp, 0L, SEEK_SET );
99 allocator<char>::pointer pBuffer = mem.allocate(nFileLen+1, NULL);
100 if ( fread( pBuffer, nFileLen, 1, fp ) == 1 )
102 pBuffer[nFileLen] =
'\0';
103 bResult = SetDoc( pBuffer );
106 mem.deallocate(pBuffer,1);
110 MARKUP_SETDEBUGSTATE;
114 bool CMarkupSTL::Save(
const char* szFileName )
117 bool bResult =
false;
118 FILE* fp = fopen( szFileName,
"wb" );
122 int nFileLen = m_strDoc.size();
125 else if ( fwrite( m_strDoc.c_str(), nFileLen, 1, fp ) == 1 )
132 bool CMarkupSTL::FindElem(
const char* szName )
138 int iPos = x_FindElem( m_iPosParent, m_iPos, szName );
142 x_SetPos( m_aPos[iPos].iElemParent, iPos, 0 );
149 bool CMarkupSTL::FindChildElem(
const char* szName )
158 int iPosChild = x_FindElem( m_iPos, m_iPosChild, szName );
162 int iPos = m_aPos[iPosChild].iElemParent;
163 x_SetPos( m_aPos[iPos].iElemParent, iPos, iPosChild );
170 std::string CMarkupSTL::GetTagName()
const
173 std::string strTagName;
176 strTagName = x_GetTagName( m_iPos );
180 bool CMarkupSTL::IntoElem()
190 if ( m_iPos && m_nNodeType == MNT_ELEMENT )
192 x_SetPos( m_iPos, m_iPosChild, 0 );
198 bool CMarkupSTL::OutOfElem()
203 x_SetPos( m_aPos[m_iPosParent].iElemParent, m_iPosParent, m_iPos );
209 std::string CMarkupSTL::GetAttribName(
int n )
const
212 if ( ! m_iPos || m_nNodeType != MNT_ELEMENT )
215 TokenPos token( m_strDoc.c_str() );
216 token.nNext = m_aPos[m_iPos].nStartL + 1;
217 for (
int nAttrib=0; nAttrib<=n; ++nAttrib )
218 if ( ! x_FindAttrib(token) )
222 return x_GetToken( token );
225 bool CMarkupSTL::SavePos(
const char* szPosName )
231 savedpos.iPosParent = m_iPosParent;
232 savedpos.iPos = m_iPos;
233 savedpos.iPosChild = m_iPosChild;
234 string strPosName = szPosName;
235 m_mapSavedPos[strPosName] = savedpos;
241 bool CMarkupSTL::RestorePos(
const char* szPosName )
246 std::string strPosName = szPosName;
247 mapSavedPosT::const_iterator iterSavePos = m_mapSavedPos.find( strPosName );
248 if ( iterSavePos != m_mapSavedPos.end() )
250 SavedPos savedpos = (*iterSavePos).second;
251 x_SetPos( savedpos.iPosParent, savedpos.iPos, savedpos.iPosChild );
258 bool CMarkupSTL::GetOffsets(
int& nStart,
int& nEnd )
const
264 nStart = m_aPos[m_iPos].nStartL;
265 nEnd = m_aPos[m_iPos].nEndR;
271 std::string CMarkupSTL::GetChildSubDoc()
const
275 int nL = m_aPos[m_iPosChild].nStartL;
276 int nR = m_aPos[m_iPosChild].nEndR + 1;
277 TokenPos token( m_strDoc.c_str() );
279 if ( ! x_FindToken(token) || m_strDoc[token.nL] ==
'<' )
281 return m_strDoc.substr( nL, nR - nL );
286 bool CMarkupSTL::RemoveElem()
289 if ( m_iPos && m_nNodeType == MNT_ELEMENT )
291 int iPos = x_RemoveElem( m_iPos );
292 x_SetPos( m_iPosParent, iPos, 0 );
298 bool CMarkupSTL::RemoveChildElem()
303 int iPosChild = x_RemoveElem( m_iPosChild );
304 x_SetPos( m_iPosParent, m_iPos, iPosChild );
314 int CMarkupSTL::x_GetFreePos()
319 if ( m_iPosFree == m_aPos.size() )
320 m_aPos.resize( m_iPosFree + m_iPosFree / 2 );
322 return m_iPosFree - 1;
325 int CMarkupSTL::x_ReleasePos()
335 int CMarkupSTL::x_ParseError(
const char* szError,
const char* szName )
340 sprintf( szFormat, szError, szName );
341 m_strError = szFormat;
344 m_strError = szError;
349 int CMarkupSTL::x_ParseElem(
int iPosParent )
356 int iPos = x_GetFreePos();
357 m_aPos[iPos].nStartL = m_aPos[iPosParent].nEndL;
358 m_aPos[iPos].iElemParent = iPosParent;
359 m_aPos[iPos].iElemChild = 0;
360 m_aPos[iPos].iElemNext = 0;
367 TokenPos token( m_strDoc.c_str() );
368 token.nNext = m_aPos[iPosParent].nEndL;
370 while ( strName.empty() )
373 m_aPos[iPos].nStartL = token.nNext;
374 if ( ! x_FindChar( token.szDoc, m_aPos[iPos].nStartL,
'<' ) )
375 return x_ParseError(
"Element tag not found" );
378 m_aPos[iPosParent].nEndL = m_aPos[iPos].nStartL;
381 token.nNext = m_aPos[iPos].nStartL + 1;
382 if ( x_FindToken( token ) )
384 if ( token.bIsString )
385 return x_ParseError(
"Tag starts with quote" );
386 char cFirstChar = m_strDoc[token.nL];
387 if ( cFirstChar ==
'?' || cFirstChar ==
'!' )
389 token.nNext = m_aPos[iPos].nStartL;
390 if ( ! x_ParseNode(token) )
391 return x_ParseError(
"Invalid node" );
393 else if ( cFirstChar !=
'/' )
395 strName = x_GetToken( token );
397 if ( ! x_FindChar(token.szDoc, token.nNext,
'>') )
398 return x_ParseError(
"End of tag not found" );
401 return x_ReleasePos();
404 return x_ParseError(
"Abrupt end within tag" );
406 m_aPos[iPos].nStartR = token.nNext;
409 if ( m_strDoc[m_aPos[iPos].nStartR-1] ==
'/' )
413 m_aPos[iPos].nEndL = m_aPos[iPos].nStartR-1;
414 m_aPos[iPos].nEndR = m_aPos[iPos].nStartR;
421 int iInner, iInnerPrev = 0;
422 m_aPos[iPos].nEndL = m_aPos[iPos].nStartR + 1;
423 while ( (iInner = x_ParseElem( iPos )) > 0 )
427 m_aPos[iInnerPrev].iElemNext = iInner;
429 m_aPos[iPos].iElemChild = iInner;
433 m_aPos[iPos].nEndL = m_aPos[iInner].nEndR + 1;
439 if ( ! x_FindChar( token.szDoc, m_aPos[iPos].nEndL,
'<' ) )
440 return x_ParseError(
"End tag of %s element not found", strName.c_str() );
443 token.nNext = m_aPos[iPos].nEndL + 1;
445 while ( x_FindToken( token ) )
448 if ( ! token.bIsString )
451 if ( nTokenCount == 1 && m_strDoc[token.nL] !=
'/' )
452 return x_ParseError(
"Expecting end tag of element %s", strName.c_str() );
454 else if ( nTokenCount == 2 && ! token.Match(strName.c_str()) )
455 return x_ParseError(
"End tag does not correspond to %s", strName.c_str() );
458 else if ( m_strDoc[token.nL] ==
'>' )
464 if ( ! token.szDoc[token.nL] || nTokenCount < 2 )
465 return x_ParseError(
"End tag not completed for element %s", strName.c_str() );
466 m_aPos[iPos].nEndR = token.nL;
473 bool CMarkupSTL::x_FindChar(
const char* szDoc,
int& nChar,
char c )
476 const char* pChar = &szDoc[nChar];
477 while ( *pChar && *pChar != c )
479 nChar = pChar - szDoc;
496 const char* szDoc = token.szDoc;
497 int nChar = token.nNext;
498 token.bIsString =
false;
501 while ( szDoc[nChar] && strchr(
" \t\n\r",szDoc[nChar]) )
503 if ( ! szDoc[nChar] )
513 char cFirstChar = szDoc[nChar];
514 if ( cFirstChar ==
'\"' || cFirstChar ==
'\'' )
516 token.bIsString =
true;
523 x_FindChar( token.szDoc, nChar, cFirstChar );
526 token.nR = nChar - 1;
536 while ( szDoc[nChar] && ! strchr(
" \t\n\r<>=\\/?!",szDoc[nChar]) )
540 if ( nChar == token.nL )
542 token.nR = nChar - 1;
554 if ( token.nL > token.nR )
556 return m_strDoc.substr( token.nL,
557 token.nR - token.nL + ((token.nR<m_strDoc.size())? 1:0) );
560 int CMarkupSTL::x_FindElem(
int iPosParent,
int iPos,
const char* szPath )
566 iPos = m_aPos[iPos].iElemNext;
568 iPos = m_aPos[iPosParent].iElemChild;
571 if ( szPath == NULL || !szPath[0] )
575 TokenPos token( m_strDoc.c_str() );
579 token.nNext = m_aPos[iPos].nStartL + 1;
580 x_FindToken( token );
581 if ( token.Match(szPath) )
583 iPos = m_aPos[iPos].iElemNext;
595 const char* szDoc = token.szDoc;
596 token.nL = token.nNext;
597 if ( szDoc[token.nL] ==
'<' )
606 if ( ! szDoc[token.nL+1] || ! szDoc[token.nL+2] )
608 char cFirstChar = szDoc[token.nL+1];
609 const char* szEndOfNode = NULL;
610 if ( cFirstChar ==
'?' )
612 nTypeFound = MNT_PROCESSING_INSTRUCTION;
615 else if ( cFirstChar ==
'!' )
617 char cSecondChar = szDoc[token.nL+2];
618 if ( cSecondChar ==
'[' )
620 nTypeFound = MNT_CDATA_SECTION;
623 else if ( cSecondChar ==
'-' )
625 nTypeFound = MNT_COMMENT;
633 while ( x_FindToken(token) )
635 if ( ! token.bIsString )
637 char cChar = szDoc[token.nL];
640 else if ( cChar ==
']' )
642 else if ( nBrackets == 0 && cChar ==
'>' )
644 nTypeFound = MNT_DOCUMENT_TYPE;
653 else if ( cFirstChar ==
'/' )
660 nTypeFound = MNT_ELEMENT;
666 const char* pEnd = strstr( &szDoc[token.nNext], szEndOfNode );
669 token.nNext = (pEnd - szDoc) + strlen(szEndOfNode);
672 else if ( szDoc[token.nL] )
675 nTypeFound = MNT_WHITESPACE;
676 if ( x_FindToken(token) )
678 if ( szDoc[token.nL] ==
'<' )
679 token.nNext = token.nL;
682 nTypeFound = MNT_TEXT;
683 x_FindChar( token.szDoc, token.nNext,
'<' );
690 std::string CMarkupSTL::x_GetTagName(
int iPos )
const
693 TokenPos token( m_strDoc.c_str() );
694 token.nNext = m_aPos[iPos].nStartL + 1;
695 if ( ! iPos || ! x_FindToken( token ) )
699 return x_GetToken( token );
707 for (
int nCount = 0; x_FindToken(token); ++nCount )
709 if ( ! token.bIsString )
712 if ( m_strDoc[token.nL] ==
'>' || m_strDoc[token.nL] ==
'/' )
716 if ( m_strDoc[token.nL] ==
'=' )
720 if ( ! nAttrib && nCount )
723 if ( ! szAttrib || ! szAttrib[0] )
727 if ( token.Match(szAttrib) )
731 else if ( nAttrib && nCount == nAttrib + 2 )
741 std::string CMarkupSTL::x_GetAttrib(
int iPos,
const char* szAttrib )
const
744 if ( ! iPos || m_nNodeType != MNT_ELEMENT )
747 TokenPos token( m_strDoc.c_str() );
748 token.nNext = m_aPos[iPos].nStartL + 1;
749 if ( szAttrib && x_FindAttrib( token, szAttrib ) )
750 return x_TextFromDoc( token.nL, token.nR - ((token.nR<m_strDoc.size())?0:1) );
754 bool CMarkupSTL::x_SetAttrib(
int iPos,
const char* szAttrib,
int nValue )
758 sprintf( szVal,
"%d", nValue );
759 return x_SetAttrib( iPos, szAttrib, szVal );
762 bool CMarkupSTL::x_SetAttrib(
int iPos,
const char* szAttrib,
const char* szValue )
765 if ( ! iPos || m_nNodeType != MNT_ELEMENT )
768 TokenPos token( m_strDoc.c_str() );
769 token.nNext = m_aPos[iPos].nStartL + 1;
770 int nInsertAt, nReplace = 0;
771 std::string strInsert;
772 if ( x_FindAttrib( token, szAttrib ) )
776 strInsert = x_TextToDoc( szValue,
true );
777 nInsertAt = token.nL;
778 nReplace = token.nR-token.nL+1;
783 std::string strFormat;
785 strFormat += szAttrib;
787 strFormat += x_TextToDoc( szValue,
true );
789 strInsert = strFormat;
792 nInsertAt = m_aPos[iPos].nStartR - (m_aPos[iPos].IsEmptyElement()?1:0);
795 x_DocChange( nInsertAt, nReplace, strInsert );
796 int nAdjust = strInsert.size() - nReplace;
797 m_aPos[iPos].nStartR += nAdjust;
798 m_aPos[iPos].AdjustEnd( nAdjust );
799 x_Adjust( iPos, nAdjust );
800 MARKUP_SETDEBUGSTATE;
804 bool CMarkupSTL::x_CreateNode( std::string& strNode,
int nNodeType,
const char* szText )
811 case MNT_CDATA_SECTION:
812 if ( strstr(szText,
"]]>") != NULL )
814 strNode =
"<![CDATA[";
822 bool CMarkupSTL::x_SetData(
int iPos,
const char* szData,
int nCDATA )
826 std::string strInsert;
829 if ( ! iPos || m_aPos[iPos].iElemChild )
835 if ( ! x_CreateNode(strInsert, MNT_CDATA_SECTION, szData) )
838 strInsert = x_TextToDoc( szData );
841 int nInsertAt, nReplace;
842 if ( m_aPos[iPos].IsEmptyElement() )
844 nInsertAt = m_aPos[iPos].nEndL;
848 std::string strTagName = x_GetTagName( iPos );
849 m_aPos[iPos].nStartR -= 1;
850 m_aPos[iPos].nEndL -= (1 + strTagName.size());
851 std::string strFormat;
853 strFormat += strInsert;
855 strFormat += strTagName;
856 strInsert = strFormat;
860 nInsertAt = m_aPos[iPos].nStartR+1;
861 nReplace = m_aPos[iPos].nEndL - m_aPos[iPos].nStartR - 1;
863 x_DocChange( nInsertAt, nReplace, strInsert );
864 int nAdjust = strInsert.size() - nReplace;
865 x_Adjust( iPos, nAdjust );
866 m_aPos[iPos].AdjustEnd( nAdjust );
867 MARKUP_SETDEBUGSTATE;
871 std::string CMarkupSTL::x_GetData(
int iPos )
const
875 if ( ! m_aPos[iPos].iElemChild && ! m_aPos[iPos].IsEmptyElement() )
878 TokenPos token( m_strDoc.c_str() );
879 token.nNext = m_aPos[iPos].nStartR+1;
880 if ( x_FindToken( token ) && m_strDoc[token.nL] ==
'<'
881 && token.nL + 11 < m_aPos[iPos].nEndL
882 && strncmp( &token.szDoc[token.nL+1],
"![CDATA[", 8 ) == 0 )
884 int nEndCDATA = m_strDoc.find(
"]]>", token.nNext );
885 if ( nEndCDATA != std::string::npos && nEndCDATA < m_aPos[iPos].nEndL )
887 return m_strDoc.substr( token.nL+9, nEndCDATA-token.nL-9 );
890 return x_TextFromDoc( m_aPos[iPos].nStartR+1, m_aPos[iPos].nEndL-1 );
895 std::string CMarkupSTL::x_TextToDoc(
const char* szText,
bool bAttrib )
const
907 static char* szaReplace[] = {
"<",
"&",
">",
"'",
""" };
908 const char* pFind = bAttrib?
"<&>\'\"":
"<&>";
909 const char* pSource = szText;
910 std::string strResult;
911 int nLen = strlen( szText );
912 strResult.reserve( nLen + nLen / 10 );
913 char cSource = *pSource;
917 if ( (pFound=strchr((
char *) pFind,cSource)) != NULL )
919 pFound = szaReplace[pFound-pFind];
920 strResult.append(pFound);
924 strResult += cSource;
926 cSource = *(++pSource);
931 std::string CMarkupSTL::x_TextFromDoc(
int nLeft,
int nRight )
const
936 static char* szaCode[] = {
"lt;",
"amp;",
"gt;",
"apos;",
"quot;" };
937 static int anCodeLen[] = { 3,4,3,5,5 };
938 static char* szSymbol =
"<&>\'\"";
939 std::string strResult;
940 strResult.reserve( nRight - nLeft + 1 );
941 const char* pSource = m_strDoc.c_str();
943 char cSource = pSource[nChar];
944 while ( nChar <= nRight )
946 if ( cSource ==
'&' )
950 for (
int nMatch = 0; nMatch < 5; ++nMatch )
952 if ( nChar <= nRight - anCodeLen[nMatch]
953 && strncmp(szaCode[nMatch],&pSource[nChar+1],anCodeLen[nMatch]) == 0 )
955 cSource = szSymbol[nMatch];
956 nChar += anCodeLen[nMatch];
961 strResult += cSource;
963 cSource = pSource[nChar];
968 void CMarkupSTL::x_DocChange(
int nLeft,
int nReplace,
const std::string& strInsert )
972 m_strDoc.replace( nLeft, nReplace, strInsert);
975 void CMarkupSTL::x_Adjust(
int iPos,
int nShift,
bool bAfterPos )
984 int iPosTop = m_aPos[iPos].iElemParent;
985 bool bPosFirst = bAfterPos;
989 bool bPosTop =
false;
990 if ( iPos == iPosTop )
993 iPosTop = m_aPos[iPos].iElemParent;
998 if ( ! bPosTop && ! bPosFirst && m_aPos[iPos].iElemChild )
1001 iPos = m_aPos[iPos].iElemChild;
1003 else if ( m_aPos[iPos].iElemNext )
1005 iPos = m_aPos[iPos].iElemNext;
1011 while ( (iPos=m_aPos[iPos].iElemParent) != 0 && iPos != iPosTop )
1012 if ( m_aPos[iPos].iElemNext )
1014 iPos = m_aPos[iPos].iElemNext;
1021 if ( iPos != iPosTop )
1022 m_aPos[iPos].AdjustStart( nShift );
1023 m_aPos[iPos].AdjustEnd( nShift );
1027 void CMarkupSTL::x_LocateNew(
int iPosParent,
int& iPosRel,
int& nOffset,
int nLength,
int nFlags )
1031 bool bInsert = (nFlags&1)?
true:
false;
1032 bool bHonorWhitespace = (nFlags&2)?
true:
false;
1041 nStartL = nOffset + nLength;
1047 nStartL = m_aPos[iPosRel].nStartL;
1049 nStartL = m_aPos[iPosRel].nEndR + 1;
1051 else if ( m_aPos[iPosParent].IsEmptyElement() )
1054 nStartL = m_aPos[iPosParent].nStartR;
1059 nStartL = m_aPos[iPosParent].nStartR + 1;
1061 nStartL = m_aPos[iPosParent].nEndL;
1065 if ( ! bHonorWhitespace && ! m_aPos[iPosParent].IsEmptyElement() )
1067 TokenPos token( m_strDoc.c_str() );
1068 token.nNext = nStartL;
1069 if ( ! x_FindToken(token) || m_strDoc[token.nL] ==
'<' )
1080 int iPosPrev = m_aPos[iPosParent].iElemChild;
1081 if ( iPosPrev != iPosRel )
1084 while ( m_aPos[iPosPrev].iElemNext != iPosRel )
1085 iPosPrev = m_aPos[iPosPrev].iElemNext;
1086 iPosBefore = iPosPrev;
1091 iPosBefore = iPosRel;
1094 else if ( m_aPos[iPosParent].iElemChild )
1099 int iPosLast = m_aPos[iPosParent].iElemChild;
1100 int iPosNext = iPosLast;
1103 iPosLast = iPosNext;
1104 iPosNext = m_aPos[iPosNext].iElemNext;
1106 iPosBefore = iPosLast;
1111 iPosRel = iPosBefore;
1114 bool CMarkupSTL::x_AddElem(
const char* szName,
const char* szValue,
bool bInsert,
bool bAddChild )
1122 else if ( m_iPosParent == 0 )
1125 if ( IsWellFormed() )
1129 m_aPos[0].nEndL = m_strDoc.size();
1133 int iPosParent, iPosBefore, nOffset = 0, nLength = 0;
1136 iPosParent = m_iPos;
1137 iPosBefore = m_iPosChild;
1141 iPosParent = m_iPosParent;
1142 iPosBefore = m_iPos;
1144 int nFlags = bInsert?1:0;
1145 x_LocateNew( iPosParent, iPosBefore, nOffset, nLength, nFlags );
1146 bool bEmptyParent = m_aPos[iPosParent].IsEmptyElement();
1154 int iPos = x_GetFreePos();
1155 m_aPos[iPos].nStartL = nOffset;
1158 m_aPos[iPos].iElemParent = iPosParent;
1159 m_aPos[iPos].iElemChild = 0;
1160 m_aPos[iPos].iElemNext = 0;
1164 m_aPos[iPos].iElemNext = m_aPos[iPosBefore].iElemNext;
1165 m_aPos[iPosBefore].iElemNext = iPos;
1170 m_aPos[iPos].iElemNext = m_aPos[iPosParent].iElemChild;
1171 m_aPos[iPosParent].iElemChild = iPos;
1175 std::string strInsert;
1176 int nLenName = strlen(szName);
1177 int nLenValue = szValue? strlen(szValue) : 0;
1182 strInsert += szName;
1183 strInsert +=
"/>\r\n";
1184 m_aPos[iPos].nStartR = m_aPos[iPos].nStartL + nLenName + 2;
1185 m_aPos[iPos].nEndL = m_aPos[iPos].nStartR - 1;
1186 m_aPos[iPos].nEndR = m_aPos[iPos].nEndL + 1;
1191 std::string strValue = x_TextToDoc( szValue );
1192 nLenValue = strValue.size();
1194 strInsert += szName;
1196 strInsert += strValue;
1198 strInsert += szName;
1199 strInsert +=
">\r\n";
1200 m_aPos[iPos].nStartR = m_aPos[iPos].nStartL + nLenName + 1;
1201 m_aPos[iPos].nEndL = m_aPos[iPos].nStartR + nLenValue + 1;
1202 m_aPos[iPos].nEndR = m_aPos[iPos].nEndL + nLenName + 2;
1206 int nReplace = 0, nLeft = m_aPos[iPos].nStartL;
1209 std::string strParentTagName = x_GetTagName(iPosParent);
1210 std::string strFormat;
1211 strFormat =
">\r\n";
1212 strFormat += strInsert;
1214 strFormat += strParentTagName;
1215 strInsert = strFormat;
1222 m_aPos[iPosParent].nStartR -= 1;
1227 m_aPos[iPosParent].nEndL -= (strParentTagName.size() + 1);
1229 x_DocChange( nLeft, nReplace, strInsert );
1230 x_Adjust( iPos, strInsert.size() - nReplace );
1233 x_SetPos( m_iPosParent, iPosParent, iPos );
1235 x_SetPos( iPosParent, iPos, 0 );
1239 bool CMarkupSTL::x_AddSubDoc(
const char* szSubDoc,
bool bInsert,
bool bAddChild )
1243 int nOffset = 0, iPosParent, iPosBefore;
1249 iPosParent = m_iPos;
1250 iPosBefore = m_iPosChild;
1254 iPosParent = m_iPosParent;
1255 iPosBefore = m_iPos;
1257 int nFlags = bInsert?1:0;
1258 x_LocateNew( iPosParent, iPosBefore, nOffset, 0, nFlags );
1259 bool bEmptyParent = m_aPos[iPosParent].IsEmptyElement();
1264 int nParentEndLBeforeAdd = m_aPos[iPosParent].nEndL;
1265 int iPosFreeBeforeAdd = m_iPosFree;
1268 TokenPos token( szSubDoc );
1269 int nNodeType = x_ParseNode( token );
1270 while ( nNodeType && nNodeType != MNT_ELEMENT )
1272 token.szDoc = &szSubDoc[token.nNext];
1274 nNodeType = x_ParseNode( token );
1276 std::string strInsert = token.szDoc;
1279 m_aPos[iPosParent].nEndL = nOffset;
1280 int nReplace = 0, nLeft = nOffset;
1281 std::string strParentTagName;
1284 strParentTagName = x_GetTagName(iPosParent);
1285 std::string strFormat;
1286 strFormat =
">\r\n";
1287 strFormat += strInsert;
1289 strFormat += strParentTagName;
1290 strInsert = strFormat;
1291 m_aPos[iPosParent].nEndL = m_aPos[iPosParent].nStartR + 2;
1292 nLeft = m_aPos[iPosParent].nStartR - 1;
1295 x_DocChange( nLeft, nReplace, strInsert );
1298 int iPos = x_ParseElem(iPosParent);
1299 m_aPos[iPosParent].nEndL = nParentEndLBeforeAdd;
1303 std::string strRevert = bEmptyParent?
"/":
"";
1304 x_DocChange( nLeft, strInsert.size(), strRevert );
1305 m_iPosFree = iPosFreeBeforeAdd;
1311 m_aPos[iPos].iElemParent = iPosParent;
1314 m_aPos[iPos].iElemNext = m_aPos[iPosBefore].iElemNext;
1315 m_aPos[iPosBefore].iElemNext = iPos;
1319 m_aPos[iPos].iElemNext = m_aPos[iPosParent].iElemChild;
1320 m_aPos[iPosParent].iElemChild = iPos;
1326 m_aPos[iPosParent].nStartR -= 1;
1327 m_aPos[iPosParent].nEndL -= (strParentTagName.size() + 1);
1331 x_Adjust( iPos, strInsert.size() - nReplace, true );
1336 x_SetPos( m_iPosParent, iPosParent, iPos );
1338 x_SetPos( m_iPosParent, iPos, 0 );
1342 int CMarkupSTL::x_RemoveElem(
int iPos )
1347 int iPosParent = m_aPos[iPos].iElemParent;
1351 int iPosLook = m_aPos[iPosParent].iElemChild;
1353 while ( iPosLook != iPos )
1355 iPosPrev = iPosLook;
1356 iPosLook = m_aPos[iPosLook].iElemNext;
1359 m_aPos[iPosPrev].iElemNext = m_aPos[iPos].iElemNext;
1361 m_aPos[iPosParent].iElemChild = m_aPos[iPos].iElemNext;
1366 int nAfterEnd = m_aPos[iPos].nEndR + 1;
1367 TokenPos token( m_strDoc.c_str() );
1368 token.nNext = nAfterEnd;
1369 if ( ! x_FindToken(token) || token.szDoc[token.nL] ==
'<' )
1370 nAfterEnd = token.nL;
1371 int nLen = nAfterEnd - m_aPos[iPos].nStartL;
1372 x_DocChange( m_aPos[iPos].nStartL, nLen, std::string() );
1373 x_Adjust( iPos, - nLen,
true );
Namespace for the standard utility objects.