📄 eaxp_dom.cpp
字号:
/*
* $Id: eaxp_dom.cpp,v 1.5 2006/10/20 12:41:21 matti Exp $
*
* EAXP - Lightweight XML SAX parser for Symbian Environments
* Copyright (C) 2004-2006 Matti Dahlbom
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: Matti Dahlbom <matti at 777-team.org>
*/
#include "eaxp_dom.h"
///////////////////////////////////////////
// CDomNodeBase
///////////////////////////////////////////
CDomNodeBase::CDomNodeBase( TDomNodeType aNodeType )
: iNodeType( aNodeType )
{
}
CDomNodeBase::~CDomNodeBase()
{
iChildren.ResetAndDestroy();
iChildren.Close();
}
EXPORT_C void CDomNodeBase::AddChildL( CDomNodeBase* iChild )
{
User::LeaveIfError( iChildren.Append( iChild ) );
}
void CDomNodeBase::Overflow( TDes16& aDes )
{
User::Leave( KErrOverflow );
}
void CDomNodeBase::EncodeEntitiesL( TDes& aBuffer, const TDesC& aText )
{
for ( TInt i = 0; i < aText.Length(); i++ )
{
TUint c = aText[i];
switch ( c )
{
case KLessThan:
aBuffer.AppendFormat( KEncLt, this );
break;
case KGreaterThan:
aBuffer.AppendFormat( KEncGt, this );
break;
case KDoubleQuote:
aBuffer.AppendFormat( KEncQuot, this );
break;
case KApostrophe:
aBuffer.AppendFormat( KEncApos, this );
break;
case KAmpersand:
aBuffer.AppendFormat( KEncAmp, this );
break;
default:
aBuffer.AppendFormat( _L("%c"), this, c );
break;
}
}
}
///////////////////////////////////////////
// CDomDocumentNode
///////////////////////////////////////////
EXPORT_C CDomDocumentNode* CDomDocumentNode::NewLC()
{
CDomDocumentNode* node = new (ELeave) CDomDocumentNode();
CleanupStack::PushL( node );
node->ConstructL();
return node;
}
CDomDocumentNode::CDomDocumentNode()
: CDomNodeBase( EDocumentNode )
{
}
EXPORT_C CDomDocumentNode::~CDomDocumentNode()
{
}
void CDomDocumentNode::ConstructL()
{
}
EXPORT_C HBufC* CDomDocumentNode::GetXmlLC()
{
TInt bufferSize = KInitialBufferSize;
HBufC* buffer = NULL;
while ( ETrue )
{
buffer = HBufC::NewLC( bufferSize );
TPtr ptr( buffer->Des() );
TRAPD( err, WriteXmlL( ptr, 0 ) );
if ( err == KErrNone )
{
return buffer;
}
else if ( err == KErrOverflow )
{
// XML didnt fit in the buffer; try with a bigger buffer
CleanupStack::PopAndDestroy( buffer );
buffer = NULL;
bufferSize += KBufferSizeIncrement;
}
else
{
// other error occurred; leave
CleanupStack::Pop( buffer );
User::Leave( err );
}
}
}
void CDomDocumentNode::WriteXmlL( TDes& aBuffer, TInt aDepth )
{
aBuffer.AppendFormat( KXmlHeader, this );
for ( TInt i = 0; i < iChildren.Count(); i++ )
{
iChildren[i]->WriteXmlL( aBuffer, aDepth + 1 );
}
}
///////////////////////////////////////////
// CDomElementNode
///////////////////////////////////////////
EXPORT_C CDomElementNode* CDomElementNode::NewLC( const TDesC& aName,
const TDesC& aNamespace )
{
CDomElementNode* node = new (ELeave) CDomElementNode();
CleanupStack::PushL( node );
node->ConstructL( aName, aNamespace );
return node;
}
CDomElementNode::CDomElementNode()
: CDomNodeBase( EElementNode )
{
}
EXPORT_C CDomElementNode::~CDomElementNode()
{
delete iName;
delete iNamespace;
iAttributes.ResetAndDestroy();
iAttributes.Close();
}
void CDomElementNode::ConstructL( const TDesC& aName, const TDesC& aNamespace )
{
iName = aName.AllocL();
iNamespace = aNamespace.AllocL();
}
EXPORT_C void CDomElementNode::AddAttributeL( CAttribute* aAttribute )
{
User::LeaveIfError( iAttributes.Append( aAttribute ) );
}
EXPORT_C void CDomElementNode::AddAttributeL( const TDesC& aName,
const TDesC& aNamespace,
const TDesC& aValue )
{
CAttribute* attr = CAttribute::NewL( aName, aNamespace, aValue );
CleanupStack::PushL( attr );
User::LeaveIfError( iAttributes.Append( attr ) );
CleanupStack::Pop( attr );
}
void CDomElementNode::IndentL( TDes& aBuffer, TInt aDepth, TBool aAddNewline )
{
TInt requiredChars = KXmlIndent().Length() * aDepth + 1;
if ( requiredChars > (aBuffer.MaxLength() - aBuffer.Length()) )
{
User::Leave( KErrOverflow );
}
if ( aAddNewline )
{
aBuffer.Append('\n');
}
for ( TInt i = 0; i < aDepth; i++ )
{
aBuffer.Append( KXmlIndent );
}
}
void CDomElementNode::WriteXmlL( TDes& aBuffer, TInt aDepth )
{
// open the node by "<ns:nodename"
_LIT( KOpenNodeNsFmt, "<%S:%S" );
_LIT( KOpenNodeFmt, "<%S" );
IndentL( aBuffer, aDepth );
if ( iNamespace->Length() > 0 )
{
aBuffer.AppendFormat( KOpenNodeNsFmt, this, iNamespace, iName );
}
else
{
aBuffer.AppendFormat( KOpenNodeFmt, this, iName );
}
// if the node has any attributes, write them now
_LIT( KAttrNsFmt, " %S:%S=\"");
_LIT( KAttrFmt, " %S=\"");
for ( TInt i = 0; i < iAttributes.Count(); i++ )
{
CAttribute* attr = iAttributes[i];
if ( attr->GetNamespace().Length() > 0 )
{
aBuffer.AppendFormat( KAttrNsFmt, this, &(attr->GetNamespace()),
&(attr->GetName()) );
EncodeEntitiesL( aBuffer, attr->GetValue() );
aBuffer.AppendFormat( _L("\""), this );
}
else
{
aBuffer.AppendFormat( KAttrFmt, this, &(attr->GetName()), &(attr->GetValue()) );
EncodeEntitiesL( aBuffer, attr->GetValue() );
aBuffer.AppendFormat( _L("\""), this );
}
}
// if the node has any children, write them now. otherwise close node now
_LIT( KEndNodeNoChildrenFmt, " />" );
_LIT( KEndNodeChildrenFmt, ">" );
if ( iChildren.Count () == 0 )
{
aBuffer.AppendFormat( KEndNodeNoChildrenFmt, this );
}
else
{
aBuffer.AppendFormat( KEndNodeChildrenFmt, this );
TDomNodeType lastChildType = EElementNode;
for ( TInt i = 0; i < iChildren.Count(); i++ )
{
// recurse into each child
CDomNodeBase* node = iChildren[i];
lastChildType = node->GetNodeType();
node->WriteXmlL( aBuffer, aDepth + 1 );
}
_LIT( KCloseNodeFmt, "</%S>" );
_LIT( KCloseNodeNsFmt, "</%S:%S>" );
if ( lastChildType == EElementNode )
{
IndentL( aBuffer, aDepth );
}
if ( iNamespace->Length() > 0 )
{
aBuffer.AppendFormat( KCloseNodeNsFmt, this, iNamespace, iName );
}
else
{
aBuffer.AppendFormat( KCloseNodeFmt, this, iName );
}
}
}
///////////////////////////////////////////
// CDomElementNode
///////////////////////////////////////////
EXPORT_C CDomTextNode* CDomTextNode::NewLC( const TDesC& aText )
{
CDomTextNode* node = new (ELeave) CDomTextNode();
CleanupStack::PushL( node );
node->ConstructL( aText );
return node;
}
EXPORT_C CDomTextNode::~CDomTextNode()
{
delete iText;
}
CDomTextNode::CDomTextNode()
: CDomNodeBase( ETextNode )
{
}
void CDomTextNode::ConstructL( const TDesC& aText )
{
iText = aText.AllocL();
}
void CDomTextNode::WriteXmlL( TDes& aBuffer, TInt /*aDepth*/ )
{
EncodeEntitiesL( aBuffer, *iText );
// we ignore any children this node might have
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -