📄 simplexml.inl
字号:
// space, and reduce all internal white space to single blanks.
TBool started = EFalse; // for leading white-space elimination
TBool space = EFalse; // for space reduction
TInt length = 0; // for accumulating output length
for (i = 0;
(c = iCurXml[i]) != '<' && c != '>' && !(aQuote && c == aQuote);
++i)
{
if (c.IsSpace())
space = ETrue;
else
{
if (space && started)
{
if (pass == 2) output[length] = ' '; // output a single space
++length;
}
space = EFalse; // no pending space
started = ETrue;
if (c == '&')
{
// process an entity reference
if (iCurXml.Mid(i, XmlEntityAmp_Len) == *XmlEntityAmp_Ptr)
{
i += XmlEntityAmp_Len - 1;
}
else if (iCurXml.Mid(i, XmlEntityLt_Len) == *XmlEntityLt_Ptr)
{
c = '<';
i += XmlEntityLt_Len - 1;
}
else if (iCurXml.Mid(i, XmlEntityGt_Len) == *XmlEntityGt_Ptr)
{
c = '>';
i += XmlEntityGt_Len - 1;
}
else if (iCurXml.Mid(i, XmlEntityApos_Len) == *XmlEntityApos_Ptr)
{
c = '\'';
i += XmlEntityApos_Len - 1;
}
else if (iCurXml.Mid(i, XmlEntityQuot_Len) == *XmlEntityQuot_Ptr)
{
c = '"';
i += XmlEntityQuot_Len - 1;
}
else
{
// Unknown entity reference
//User::Leave(/*KErrArgument*/KErrOverflow);
}
}
if (pass == 2) output[length] = (TXmlText) c; // output a character
++length;
}
}
if (pass == 1)
{
aText = HXmlBufC::NewL(length); // The buffer is a gift to our caller
output.Set(aText->Des());
output.SetLength(length);
}
else
{
iCurXml.Set(iCurXml.Mid(i)); // step the current pointer to the
// text end delimiter
}
}
}
/**
* OutputL
*/
void CSimpleXml::OutputL(CXmlElement& aElement)
{
if (++iNesting > iMaxNesting)
{
User::Leave(KErrArgument);
}
// Output the element start tag, complete with attributes
OutputL('<');
OutputL(aElement.Name());
TInt attribCount = aElement.AttributeCount();
TInt i;
for (i = 0; i < attribCount; ++i)
{
CXmlAttribute& attrib = aElement.Attribute(i);
OutputL(' ');
OutputL(attrib.Keyword());
OutputL('=');
OutputL('"');
ConvOutputL(attrib.Value());
OutputL('"');
}
OutputL('>');
// Output any contained chunks (text or embedded element)
TInt chunkCount = aElement.ChunkCount();
for (i = 0; i < chunkCount; ++i)
{
CXmlChunk& chunk = aElement.Chunk(i);
if (chunk.Type() == EElement)
{
OutputL(chunk.Element());
}
else
{
ConvOutputL(chunk.Text().Contents());
}
}
// Output the element end tag
OutputL('<');
OutputL('/');
OutputL(aElement.Name());
OutputL('>');
--iNesting; // reduce nesting level
}
void CSimpleXml::OutputL(const TXmlDesC& aDesc)
{
iTempBuf->AppendL(aDesc.Ptr(), aDesc.Length());
}
void CSimpleXml::OutputL(TXmlText aText)
{
iTempBuf->AppendL(aText);
}
/**
* ConvOutputL
* Output XML text, with conversion to encode entity references if necessary.
* The text may either be the textual content of an element, or the value of
* an attribute. The encodings are:
* "&" ==> "&"
* "<" ==> "<"
* ">" ==> ">"
* "'" ==> "'"
* """ ==> """
* (though ' and " are not really needed for element text, and ' is
* not really necessary for attribute values either, since we will always use double quotes
* to delimit attribute values in our output)
*/
void CSimpleXml::ConvOutputL(const TXmlDesC& aDesc)
{
for (TInt i = 0; i < aDesc.Length(); ++i)
{
TXmlText c = aDesc[i];
switch (c)
{
case '&':
XML_USE_STRING(XmlEntityAmp);
OutputL(*XmlEntityAmp_Ptr);
break;
case '<':
XML_USE_STRING(XmlEntityLt);
OutputL(*XmlEntityLt_Ptr);
break;
case '>':
XML_USE_STRING(XmlEntityGt);
OutputL(*XmlEntityGt_Ptr);
break;
case '\'':
XML_USE_STRING(XmlEntityApos);
OutputL(*XmlEntityApos_Ptr);
break;
case '"':
XML_USE_STRING(XmlEntityQuot);
OutputL(*XmlEntityQuot_Ptr);
break;
default:
OutputL(c);
break;
}
}
}
/*
* ============================================================================
* CXmlAttribute class implementation
* ============================================================================
*/
CXmlAttribute::CXmlAttribute()
{
}
CXmlAttribute::~CXmlAttribute()
{
delete iKeyword;
delete iValue;
}
/**
* Accessor for keyword
*/
const TXmlDesC& CXmlAttribute::Keyword() const
{
if (!iKeyword) CSimpleXml::Panic(CSimpleXml::EPanicNoAttributeKeyword);
return *iKeyword;
}
/**
* Accessor for value
*/
const TXmlDesC& CXmlAttribute::Value() const
{
if (!iValue) CSimpleXml::Panic(CSimpleXml::EPanicNoAttributeValue);
return *iValue;
}
/*
* ============================================================================
* CXmlChunk class implementation
* ============================================================================
*/
CXmlChunk::CXmlChunk()
{
}
CXmlChunk::~CXmlChunk()
{
}
/**
* Element
* Accessor for the CElement derived object
* Allows safe downcast and avoids compiler non-const reference binding errors
*/
CXmlElement& CXmlChunk::Element()
{
if (Type() != EElement)
{
CSimpleXml::Panic(CSimpleXml::EPanicChunkNotElement);
}
return *(CXmlElement *) this;
}
/**
* Text
* Accessor for the CXmlText<> derived object
* Allows safe downcast and avoids compiler non-const reference binding errors
*/
CXmlText& CXmlChunk::Text()
{
if (Type() != EText)
{
CSimpleXml::Panic(CSimpleXml::EPanicChunkNotText);
}
return *(CXmlText *) this;
}
/*
* ============================================================================
* CXmlElement class implementation
* ============================================================================
*/
CXmlElement::CXmlElement()
{
}
CXmlElement::~CXmlElement()
{
iChunks.ResetAndDestroy();
iAttributes.ResetAndDestroy();
delete iName;
}
/**
* Get type
*/
TType CXmlElement::Type() const
{
return EElement;
}
/**
* Accessor for name
*/
const TXmlDesC& CXmlElement::Name() const
{
if (!iName) CSimpleXml::Panic(CSimpleXml::EPanicNoElementName);
return *iName;
}
/**
* Get number of attributes
*/
TInt CXmlElement::AttributeCount() const
{
return iAttributes.Count();
}
/**
* Accessor for an attribute
*/
CXmlAttribute& CXmlElement::Attribute(TInt aAttribNum)
{
return *iAttributes[aAttribNum];
}
/**
* Get number of chunks
*/
TInt CXmlElement::ChunkCount() const
{
return iChunks.Count();
}
/**
* Accessor for a chunk
*/
CXmlChunk& CXmlElement::Chunk(TInt aChunkNum)
{
return *iChunks[aChunkNum];
}
/**
* Add an attribute
*/
CXmlAttribute& CXmlElement::AddAttributeL(const TXmlDesC& aKeyword,
const TXmlDesC& aValue)
{
CXmlAttribute& newAttribute = CXmlAttribute::AddAttributeToListL(iAttributes);
newAttribute.iKeyword = aKeyword.AllocL();
newAttribute.iValue = aValue.AllocL();
return newAttribute;
}
CXmlAttribute& CXmlAttribute::AddAttributeToListL(RPointerArray<CXmlAttribute >& aAttributeList)
{
CXmlAttribute *attrib = new (ELeave) CXmlAttribute;
TInt err = aAttributeList.Append(attrib);
if (err != KErrNone)
{
delete attrib;
User::Leave(err);
}
return *attrib;
}
/**
* Add an element
*/
CXmlElement& CXmlElement::AddElementL(const TXmlDesC& aName)
{
CXmlElement& newElement = AddElementL();
newElement.iName = aName.AllocL();
return newElement;
}
CXmlElement& CXmlElement::AddElementL()
{
CXmlElement* newElement = new (ELeave) CXmlElement;
AddChunkL(newElement);
return *newElement;
}
/**
* Add a chunk of text
*/
CXmlText& CXmlElement::AddTextL(const TXmlDesC& aText)
{
CXmlText& newText = AddTextL();
newText.iText = aText.AllocL();
return newText;
}
CXmlText& CXmlElement::AddTextL()
{
CXmlText* newText = new (ELeave) CXmlText;
AddChunkL(newText);
return *newText;
}
/**
* Private helper method to add an untyped chunk
* Takes responsibility for the chunk even if it Leaves -
* so caller doesn't need to push the chunk on the cleanup stack
*/
void CXmlElement::AddChunkL(CXmlChunk *aNewChunk)
{
TInt err = iChunks.Append(aNewChunk);
if (err != KErrNone)
{
delete aNewChunk;
User::Leave(err);
}
}
/*
* ============================================================================
* CXmlText class implementation
* ============================================================================
*/
CXmlText::CXmlText()
{
}
CXmlText::~CXmlText()
{
delete iText;
}
/**
* Get type
*/
TType CXmlText::Type() const
{
return EText;
}
/**
* Accessor for the contained text
*/
const TXmlDesC& CXmlText::Contents()
{
return *iText;
}
/**
* Panic
*/
_LIT(KSimpleXmlPanic, "CSimpleXml");
void CSimpleXml::Panic(CSimpleXml::TPanic aPanic)
{
User::Panic(KSimpleXmlPanic, aPanic);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -