--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/src/OpmlParser.cpp Thu Feb 25 14:29:19 2010 +0000
@@ -0,0 +1,237 @@
+/*
+* Copyright (c) 2007-2010 Sebastian Brannstrom, Lars Persson, EmbedDev AB
+*
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* EmbedDev AB - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "OpmlParser.h"
+#include "debug.h"
+#include <f32file.h>
+#include <bautils.h>
+#include <s32file.h>
+#include <charconv.h>
+#include <xml/stringdictionarycollection.h>
+#include <utf.h>
+
+using namespace Xml;
+const TInt KMaxParseBuffer = 2048;
+const TInt KMaxStringBuffer = 1024;
+COpmlParser::COpmlParser(CFeedEngine& aFeedEngine, RFs& aFs) : iFeedEngine(aFeedEngine),iFs(aFs)
+{
+}
+
+COpmlParser::~COpmlParser()
+{
+}
+
+void COpmlParser::ParseOpmlL(const TFileName &feedFileName, TBool aSearching)
+ {
+ DP1("ParseOpmlL BEGIN: %S", &feedFileName);
+
+ iSearching = aSearching;
+ _LIT8(KXmlMimeType, "text/xml");
+ // Contruct the parser object
+ CParser* parser = CParser::NewLC(KXmlMimeType, *this);
+ iOpmlState = EStateOpmlRoot;
+ iEncoding = EUtf8;
+ iNumFeedsAdded = 0;
+ ParseL(*parser, iFs, feedFileName);
+
+ CleanupStack::PopAndDestroy(parser);
+ //DP("ParseFeedL END");
+ }
+
+// from MContentHandler
+void COpmlParser::OnStartDocumentL(const RDocumentParameters& aDocParam, TInt /*aErrorCode*/)
+ {
+ DP("OnStartDocumentL()");
+ HBufC* charset = HBufC::NewLC(KMaxParseBuffer);
+ charset->Des().Copy(aDocParam.CharacterSetName().DesC());
+ iEncoding = EUtf8;
+ if (charset->CompareF(_L("utf-8")) == 0) {
+ DP("setting UTF8");
+ iEncoding = EUtf8;
+ } else if (charset->CompareF(_L("ISO-8859-1")) == 0) {
+ iEncoding = EUtf8; //Latin1;
+ } else {
+ DP1("unknown charset: %S", &charset);
+ }
+ CleanupStack::PopAndDestroy(charset);
+ }
+
+void COpmlParser::OnEndDocumentL(TInt /*aErrorCode*/)
+ {
+ iFeedEngine.OpmlParsingComplete(iNumFeedsAdded);
+ //DP("OnEndDocumentL()");
+ }
+
+void COpmlParser::OnStartElementL(const RTagInfo& aElement, const RAttributeArray& aAttributes, TInt /*aErrorCode*/)
+ {
+ TBuf<KMaxStringBuffer> str;
+ str.Copy(aElement.LocalName().DesC());
+ DP2("OnStartElementL START state=%d, element=%S", iOpmlState, &str);
+ iBuffer.Zero();
+ switch (iOpmlState) {
+ case EStateOpmlRoot:
+ // <body>
+ if (str.CompareF(KTagBody) == 0) {
+ iOpmlState = EStateOpmlBody;
+ }
+ break;
+ case EStateOpmlBody:
+ // <body> <outline>
+
+ if(str.CompareF(KTagOutline) == 0) {
+ iOpmlState = EStateOpmlOutline;
+ }
+ break;
+ case EStateOpmlOutline:
+ // <body> <outline> <outline...
+ if(str.CompareF(KTagOutline) == 0) {
+ iOpmlState=EStateOpmlOutlineOutline;
+ CFeedInfo* newFeed = CFeedInfo::NewLC();
+
+ TBool hasTitle = EFalse;
+ TBool hasUrl = EFalse;
+
+ for (int i=0;i<aAttributes.Count();i++) {
+ RAttribute attr = aAttributes[i];
+ TBuf<KMaxStringBuffer> attr16;
+ attr16.Copy(attr.Attribute().LocalName().DesC().Left(KMaxStringBuffer));
+ HBufC* val16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(
+ attr.Value().DesC().Left(KMaxParseBuffer));
+ CleanupStack::PushL(val16);
+
+ // xmlUrl=...
+ if (attr16.Compare(KTagXmlUrl) == 0 || attr16.Compare(KTagUrl) == 0) {
+ newFeed->SetUrlL(*val16);
+ hasUrl = ETrue;
+ // htmlUrl
+ } else if (attr16.Compare(KTagHtmlUrl) == 0) {
+ newFeed->SetLinkL(*val16);
+ hasUrl = ETrue;
+ // text=...
+ } else if (attr16.Compare(KTagTitle) == 0) {
+ newFeed->SetTitleL(*val16);
+ newFeed->SetCustomTitle();
+ hasTitle = ETrue;
+ // description=
+ } else if (attr16.Compare(KTagDescription) == 0) {
+ newFeed->SetDescriptionL(*val16);
+ } else if (attr16.Compare(KTagText) == 0) {
+ if (!hasTitle) {
+ newFeed->SetTitleL(*val16);
+ newFeed->SetCustomTitle();
+ hasTitle = ETrue;
+ }
+ }
+ CleanupStack::PopAndDestroy(val16);
+ }
+
+ if (!hasUrl) {
+ break;
+ }
+
+ if (!hasTitle) {
+ newFeed->SetTitleL(newFeed->Url());
+ }
+
+ if (iSearching) {
+ iFeedEngine.AddSearchResultL(newFeed);
+ CleanupStack::Pop(newFeed);
+ } else {
+ iFeedEngine.AddFeedL(*newFeed);
+ CleanupStack::PopAndDestroy(newFeed);
+ iNumFeedsAdded++;
+ }
+ }
+ break;
+ default:
+ DP2("Ignoring tag %S when in state %d", &str, iOpmlState);
+ break;
+ }
+ DP1("OnStartElementL END state=%d", iOpmlState);
+ }
+
+void COpmlParser::OnEndElementL(const RTagInfo& aElement, TInt /*aErrorCode*/)
+ {
+
+ TDesC8 lName = aElement.LocalName().DesC();
+ TBuf<KMaxStringBuffer> str;
+ str.Copy(aElement.LocalName().DesC());
+
+ DP2("OnEndElementL START state=%d, element=%S", iOpmlState, &str);
+
+ switch (iOpmlState) {
+ case EStateOpmlOutlineOutline:
+ iOpmlState=EStateOpmlOutline;
+ break;
+ case EStateOpmlOutline:
+ iOpmlState=EStateOpmlBody;
+ break;
+ case EStateOpmlBody:
+ iOpmlState = EStateOpmlRoot;
+ break;
+ default:
+ // fall back to body level when in doubt
+ iOpmlState = EStateOpmlBody;
+ //DP("Don't know how to handle end tag %S when in state %d"), &str, iFeedState);
+ break;
+ }
+
+ DP1("OnEndElementL END state=%d", iOpmlState);
+ }
+
+void COpmlParser::OnContentL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/)
+ {
+ //DP("OnContentL()");
+ }
+
+void COpmlParser::OnStartPrefixMappingL(const RString& /*aPrefix*/, const RString& /*aUri*/, TInt /*aErrorCode*/)
+ {
+ //DP("OnStartPrefixMappingL()");
+ }
+
+void COpmlParser::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt /*aErrorCode*/)
+ {
+ //DP("OnEndPrefixMappingL()");
+ }
+
+void COpmlParser::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/)
+ {
+ //DP("OnIgnorableWhiteSpaceL()");
+ }
+
+void COpmlParser::OnSkippedEntityL(const RString& /*aName*/, TInt /*aErrorCode*/)
+ {
+ //DP("OnSkippedEntityL()");
+ }
+
+void COpmlParser::OnProcessingInstructionL(const TDesC8& /*aTarget*/, const TDesC8& /*aData*/, TInt /*aErrorCode*/)
+ {
+ //DP("OnProcessingInstructionL()");
+ }
+
+void COpmlParser::OnError(TInt aErrorCode)
+ {
+ DP1("COpmlParser::OnError %d", aErrorCode);
+ iFeedEngine.OpmlParsingComplete(iNumFeedsAdded);
+ }
+
+TAny* COpmlParser::GetExtendedInterface(const TInt32 /*aUid*/)
+ {
+ //DP("GetExtendedInterface()");
+ return NULL;
+ }