diff --git a/mozilla/camino/src/bookmarks/BookmarksExport.h b/mozilla/camino/src/bookmarks/BookmarksExport.h index 0d3eb643f86..e187e097c93 100644 --- a/mozilla/camino/src/bookmarks/BookmarksExport.h +++ b/mozilla/camino/src/bookmarks/BookmarksExport.h @@ -42,23 +42,40 @@ #include "nsString.h" -class nsIDOMElement; -class nsIDOMDocument; +#include "nsIDOMDocument.h" +#include "nsIOutputStream.h" -class nsIOutputStream; +class nsIDOMElement; class BookmarksExport { public: + + BookmarksExport(nsIDOMDocument* inBookmarksDoc, const char* inLinebreakStr = "\n"); + ~BookmarksExport(); + + // at some point we could use subclassing to support different export formats + nsresult ExportBookmarksToHTML(const nsAString& inFilePath); - static nsresult ExportBookmarksToHTML(nsIDOMDocument* inBookmarksDoc, const nsAString& inFilePath); +protected: + nsresult SetupOutputStream(const nsAString& inFilePath); + void CloseOutputStream(); + + // return false on failure (mWriteStatus set) + bool WriteChildren(nsIDOMElement* inElement, PRInt32 inDepth); + bool WriteItem(nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot = PR_FALSE); -private: + void WritePrologue(); + void WriteString(const char*inString, PRInt32 inLen); + void WriteLinebreak(); - static nsresult WriteChildren(nsIOutputStream* outputStream, nsIDOMElement* inElement, PRInt32 inDepth); - static nsresult WriteItem(nsIOutputStream* outputStream, nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot = PR_FALSE); +protected: + nsCOMPtr mBookmarksDocument; + nsCOMPtr mOutputStream; + const char* mLinebreakStr; + nsresult mWriteStatus; }; diff --git a/mozilla/camino/src/bookmarks/BookmarksExport.mm b/mozilla/camino/src/bookmarks/BookmarksExport.mm index 19896ff4244..e1d26ca2680 100644 --- a/mozilla/camino/src/bookmarks/BookmarksExport.mm +++ b/mozilla/camino/src/bookmarks/BookmarksExport.mm @@ -51,14 +51,6 @@ #include "nsIDOMDocument.h" #include "nsIContent.h" -const char* const gPrologue = "\n" - "\n" - "\n" - "Bookmarks\n" - "

Bookmarks

\n"; - /* Netscape HTML bookmarks format is: @@ -75,44 +67,60 @@ const char* const gPrologue = "\n" */ -nsresult -BookmarksExport::ExportBookmarksToHTML(nsIDOMDocument* inBookmarksDoc, const nsAString& inFilePath) +BookmarksExport::BookmarksExport(nsIDOMDocument* inBookmarksDoc, const char* inLinebreakStr) +: mBookmarksDocument(inBookmarksDoc) +, mLinebreakStr(inLinebreakStr) +, mWriteStatus(NS_OK) { - nsresult rv; - - nsCOMPtr destFile; - rv = NS_NewLocalFile(inFilePath, PR_FALSE, getter_AddRefs(destFile)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr outputStream; - rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), destFile); - if (NS_FAILED(rv)) return rv; - - PRUint32 bytesWritten; - rv = outputStream->Write(gPrologue, strlen(gPrologue), &bytesWritten); - - if (inBookmarksDoc) - { - nsCOMPtr docElement; - inBookmarksDoc->GetDocumentElement(getter_AddRefs(docElement)); - - rv = WriteItem(outputStream, docElement, 0, PR_TRUE); - } - - rv = outputStream->Close(); - - return NS_OK; } +BookmarksExport::~BookmarksExport() +{ + if (mOutputStream) + (void)mOutputStream->Close(); +} nsresult -BookmarksExport::WriteChildren(nsIOutputStream* outputStream, nsIDOMElement* inElement, PRInt32 inDepth) +BookmarksExport::ExportBookmarksToHTML(const nsAString& inFilePath) +{ + if (!mBookmarksDocument) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv = SetupOutputStream(inFilePath); + if (NS_FAILED(rv)) return rv; + + WritePrologue(); + nsCOMPtr docElement; + mBookmarksDocument->GetDocumentElement(getter_AddRefs(docElement)); + WriteItem(docElement, 0, PR_TRUE); + + CloseOutputStream(); + return mWriteStatus; +} + +nsresult +BookmarksExport::SetupOutputStream(const nsAString& inFilePath) +{ + nsCOMPtr destFile; + nsresult rv = NS_NewLocalFile(inFilePath, PR_FALSE, getter_AddRefs(destFile)); + if (NS_FAILED(rv)) return rv; + + return NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), destFile); +} + +void +BookmarksExport::CloseOutputStream() +{ + (void)mOutputStream->Close(); + mOutputStream = nsnull; +} + +bool +BookmarksExport::WriteChildren(nsIDOMElement* inElement, PRInt32 inDepth) { nsCOMPtr curContent = do_QueryInterface(inElement); - if (!curContent) return NS_ERROR_FAILURE; - - nsresult rv = NS_OK; - + if (!curContent) return false; + // recurse to children PRInt32 numChildren; curContent->ChildCount(numChildren); @@ -122,22 +130,19 @@ BookmarksExport::WriteChildren(nsIOutputStream* outputStream, nsIDOMElement* inE curContent->ChildAt(i, *getter_AddRefs(curChild)); nsCOMPtr curElt = do_QueryInterface(curChild); - rv = WriteItem(outputStream, curElt, inDepth); - if (NS_FAILED(rv)) break; + if (!WriteItem(curElt, inDepth)) + return false; } - return rv; + return true; } -nsresult -BookmarksExport::WriteItem(nsIOutputStream* outputStream, nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot) +bool +BookmarksExport::WriteItem(nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot) { nsCOMPtr curContent = do_QueryInterface(inElement); - if (!inElement || !curContent) return NS_ERROR_FAILURE; - - nsresult rv; - - PRUint32 bytesWritten; + if (!inElement || !curContent) + return false; nsCOMPtr tagName; curContent->GetTag(*getter_AddRefs(tagName)); @@ -155,47 +160,52 @@ BookmarksExport::WriteItem(nsIOutputStream* outputStream, nsIDOMElement* inEleme { if (!isRoot) { - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); + WriteString(indentString, strlen(indentString)); const char* const prefixString = "
Write(prefixString, strlen(prefixString), &bytesWritten); + WriteString(prefixString, strlen(prefixString)); nsAutoString typeAttribute; inElement->GetAttribute(NS_LITERAL_STRING("type"), typeAttribute); if (typeAttribute.Equals(NS_LITERAL_STRING("toolbar"))) { const char* persToolbar = " PERSONAL_TOOLBAR_FOLDER=\"true\""; - rv = outputStream->Write(persToolbar, strlen(persToolbar), &bytesWritten); + WriteString(persToolbar, strlen(persToolbar)); } - rv = outputStream->Write(">", 1, &bytesWritten); + WriteString(">", 1); inElement->GetAttribute(NS_LITERAL_STRING("name"), title); NS_ConvertUCS2toUTF8 titleConverter(title); const char* utf8String = titleConverter.get(); - rv = outputStream->Write(utf8String, strlen(utf8String), &bytesWritten); + // we really need to convert entities in the title, like < > etc. + WriteString(utf8String, strlen(utf8String)); - rv = outputStream->Write("\n", 6, &bytesWritten); + WriteString("", 5); + WriteLinebreak(); } - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); - rv = outputStream->Write("

\n", 8, &bytesWritten); + WriteString(indentString, strlen(indentString)); + WriteString("

", 7); + WriteLinebreak(); - rv = WriteChildren(outputStream, inElement, inDepth + 1); - - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); - rv = outputStream->Write("

\n", 9, &bytesWritten); + if (!WriteChildren(inElement, inDepth + 1)) + return false; + + WriteString(indentString, strlen(indentString)); + WriteString("

", 8); + WriteLinebreak(); } else { if (tagName == BookmarksService::gBookmarkAtom) { - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); + WriteString(indentString, strlen(indentString)); const char* const bookmarkPrefix = "

Write(bookmarkPrefix, strlen(bookmarkPrefix), &bytesWritten); + WriteString(bookmarkPrefix, strlen(bookmarkPrefix)); inElement->GetAttribute(NS_LITERAL_STRING("href"), href); inElement->GetAttribute(NS_LITERAL_STRING("name"), title); @@ -203,24 +213,64 @@ BookmarksExport::WriteItem(nsIOutputStream* outputStream, nsIDOMElement* inEleme NS_ConvertUCS2toUTF8 hrefConverter(href); const char* utf8String = hrefConverter.get(); - rv = outputStream->Write(utf8String, strlen(utf8String), &bytesWritten); - outputStream->Write("\">", 2, &bytesWritten); + WriteString(utf8String, strlen(utf8String)); + WriteString("\">", 2); NS_ConvertUCS2toUTF8 titleConverter(title); utf8String = titleConverter.get(); - rv = outputStream->Write(utf8String, strlen(utf8String), &bytesWritten); - rv = outputStream->Write("\n", 5, &bytesWritten); + WriteString(utf8String, strlen(utf8String)); + WriteString("", 4); + WriteLinebreak(); } else if (tagName == BookmarksService::gSeparatorAtom) { - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); - const char* const hrString = "
\n"; - rv = outputStream->Write(hrString, strlen(hrString), &bytesWritten); + WriteString(indentString, strlen(indentString)); + WriteString("
", 4); + WriteLinebreak(); } - } - return rv; + return true; } +void +BookmarksExport::WritePrologue() +{ + const char* const gPrologueLines[] = { + "", + "", + "", + "Bookmarks", + "

Bookmarks

", + "", + nil + }; + + char* const *linePtr = gPrologueLines; + + while (*linePtr) + { + WriteString(*linePtr, strlen(*linePtr)); + WriteLinebreak(); + linePtr++; + } +} + +void +BookmarksExport::WriteString(const char*inString, PRInt32 inLen) +{ + PRUint32 bytesWritten; + if (mWriteStatus == NS_OK) + mWriteStatus = mOutputStream->Write(inString, inLen, &bytesWritten); +} + +void +BookmarksExport::WriteLinebreak() +{ + WriteString(mLinebreakStr, strlen(mLinebreakStr)); +} + + diff --git a/mozilla/camino/src/bookmarks/BookmarksService.mm b/mozilla/camino/src/bookmarks/BookmarksService.mm index fa62f142ef3..51c45474d06 100644 --- a/mozilla/camino/src/bookmarks/BookmarksService.mm +++ b/mozilla/camino/src/bookmarks/BookmarksService.mm @@ -608,7 +608,14 @@ nsresult BookmarksService::ExportBookmarksToHTML(const nsAString& inFilePath) { nsCOMPtr domDoc = do_QueryInterface(gBookmarksDocument); - return BookmarksExport::ExportBookmarksToHTML(domDoc, inFilePath); + + nsresult rv = NS_ERROR_OUT_OF_MEMORY; + BookmarksExport* exporter = new BookmarksExport(domDoc); + if (exporter) + rv = exporter->ExportBookmarksToHTML(inFilePath); + + delete exporter; + return rv; } void diff --git a/mozilla/chimera/src/bookmarks/BookmarksExport.h b/mozilla/chimera/src/bookmarks/BookmarksExport.h index 0d3eb643f86..e187e097c93 100644 --- a/mozilla/chimera/src/bookmarks/BookmarksExport.h +++ b/mozilla/chimera/src/bookmarks/BookmarksExport.h @@ -42,23 +42,40 @@ #include "nsString.h" -class nsIDOMElement; -class nsIDOMDocument; +#include "nsIDOMDocument.h" +#include "nsIOutputStream.h" -class nsIOutputStream; +class nsIDOMElement; class BookmarksExport { public: + + BookmarksExport(nsIDOMDocument* inBookmarksDoc, const char* inLinebreakStr = "\n"); + ~BookmarksExport(); + + // at some point we could use subclassing to support different export formats + nsresult ExportBookmarksToHTML(const nsAString& inFilePath); - static nsresult ExportBookmarksToHTML(nsIDOMDocument* inBookmarksDoc, const nsAString& inFilePath); +protected: + nsresult SetupOutputStream(const nsAString& inFilePath); + void CloseOutputStream(); + + // return false on failure (mWriteStatus set) + bool WriteChildren(nsIDOMElement* inElement, PRInt32 inDepth); + bool WriteItem(nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot = PR_FALSE); -private: + void WritePrologue(); + void WriteString(const char*inString, PRInt32 inLen); + void WriteLinebreak(); - static nsresult WriteChildren(nsIOutputStream* outputStream, nsIDOMElement* inElement, PRInt32 inDepth); - static nsresult WriteItem(nsIOutputStream* outputStream, nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot = PR_FALSE); +protected: + nsCOMPtr mBookmarksDocument; + nsCOMPtr mOutputStream; + const char* mLinebreakStr; + nsresult mWriteStatus; }; diff --git a/mozilla/chimera/src/bookmarks/BookmarksExport.mm b/mozilla/chimera/src/bookmarks/BookmarksExport.mm index 19896ff4244..e1d26ca2680 100644 --- a/mozilla/chimera/src/bookmarks/BookmarksExport.mm +++ b/mozilla/chimera/src/bookmarks/BookmarksExport.mm @@ -51,14 +51,6 @@ #include "nsIDOMDocument.h" #include "nsIContent.h" -const char* const gPrologue = "\n" - "\n" - "\n" - "Bookmarks\n" - "

Bookmarks

\n"; - /* Netscape HTML bookmarks format is: @@ -75,44 +67,60 @@ const char* const gPrologue = "\n" */ -nsresult -BookmarksExport::ExportBookmarksToHTML(nsIDOMDocument* inBookmarksDoc, const nsAString& inFilePath) +BookmarksExport::BookmarksExport(nsIDOMDocument* inBookmarksDoc, const char* inLinebreakStr) +: mBookmarksDocument(inBookmarksDoc) +, mLinebreakStr(inLinebreakStr) +, mWriteStatus(NS_OK) { - nsresult rv; - - nsCOMPtr destFile; - rv = NS_NewLocalFile(inFilePath, PR_FALSE, getter_AddRefs(destFile)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr outputStream; - rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), destFile); - if (NS_FAILED(rv)) return rv; - - PRUint32 bytesWritten; - rv = outputStream->Write(gPrologue, strlen(gPrologue), &bytesWritten); - - if (inBookmarksDoc) - { - nsCOMPtr docElement; - inBookmarksDoc->GetDocumentElement(getter_AddRefs(docElement)); - - rv = WriteItem(outputStream, docElement, 0, PR_TRUE); - } - - rv = outputStream->Close(); - - return NS_OK; } +BookmarksExport::~BookmarksExport() +{ + if (mOutputStream) + (void)mOutputStream->Close(); +} nsresult -BookmarksExport::WriteChildren(nsIOutputStream* outputStream, nsIDOMElement* inElement, PRInt32 inDepth) +BookmarksExport::ExportBookmarksToHTML(const nsAString& inFilePath) +{ + if (!mBookmarksDocument) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv = SetupOutputStream(inFilePath); + if (NS_FAILED(rv)) return rv; + + WritePrologue(); + nsCOMPtr docElement; + mBookmarksDocument->GetDocumentElement(getter_AddRefs(docElement)); + WriteItem(docElement, 0, PR_TRUE); + + CloseOutputStream(); + return mWriteStatus; +} + +nsresult +BookmarksExport::SetupOutputStream(const nsAString& inFilePath) +{ + nsCOMPtr destFile; + nsresult rv = NS_NewLocalFile(inFilePath, PR_FALSE, getter_AddRefs(destFile)); + if (NS_FAILED(rv)) return rv; + + return NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), destFile); +} + +void +BookmarksExport::CloseOutputStream() +{ + (void)mOutputStream->Close(); + mOutputStream = nsnull; +} + +bool +BookmarksExport::WriteChildren(nsIDOMElement* inElement, PRInt32 inDepth) { nsCOMPtr curContent = do_QueryInterface(inElement); - if (!curContent) return NS_ERROR_FAILURE; - - nsresult rv = NS_OK; - + if (!curContent) return false; + // recurse to children PRInt32 numChildren; curContent->ChildCount(numChildren); @@ -122,22 +130,19 @@ BookmarksExport::WriteChildren(nsIOutputStream* outputStream, nsIDOMElement* inE curContent->ChildAt(i, *getter_AddRefs(curChild)); nsCOMPtr curElt = do_QueryInterface(curChild); - rv = WriteItem(outputStream, curElt, inDepth); - if (NS_FAILED(rv)) break; + if (!WriteItem(curElt, inDepth)) + return false; } - return rv; + return true; } -nsresult -BookmarksExport::WriteItem(nsIOutputStream* outputStream, nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot) +bool +BookmarksExport::WriteItem(nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot) { nsCOMPtr curContent = do_QueryInterface(inElement); - if (!inElement || !curContent) return NS_ERROR_FAILURE; - - nsresult rv; - - PRUint32 bytesWritten; + if (!inElement || !curContent) + return false; nsCOMPtr tagName; curContent->GetTag(*getter_AddRefs(tagName)); @@ -155,47 +160,52 @@ BookmarksExport::WriteItem(nsIOutputStream* outputStream, nsIDOMElement* inEleme { if (!isRoot) { - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); + WriteString(indentString, strlen(indentString)); const char* const prefixString = "
Write(prefixString, strlen(prefixString), &bytesWritten); + WriteString(prefixString, strlen(prefixString)); nsAutoString typeAttribute; inElement->GetAttribute(NS_LITERAL_STRING("type"), typeAttribute); if (typeAttribute.Equals(NS_LITERAL_STRING("toolbar"))) { const char* persToolbar = " PERSONAL_TOOLBAR_FOLDER=\"true\""; - rv = outputStream->Write(persToolbar, strlen(persToolbar), &bytesWritten); + WriteString(persToolbar, strlen(persToolbar)); } - rv = outputStream->Write(">", 1, &bytesWritten); + WriteString(">", 1); inElement->GetAttribute(NS_LITERAL_STRING("name"), title); NS_ConvertUCS2toUTF8 titleConverter(title); const char* utf8String = titleConverter.get(); - rv = outputStream->Write(utf8String, strlen(utf8String), &bytesWritten); + // we really need to convert entities in the title, like < > etc. + WriteString(utf8String, strlen(utf8String)); - rv = outputStream->Write("\n", 6, &bytesWritten); + WriteString("", 5); + WriteLinebreak(); } - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); - rv = outputStream->Write("

\n", 8, &bytesWritten); + WriteString(indentString, strlen(indentString)); + WriteString("

", 7); + WriteLinebreak(); - rv = WriteChildren(outputStream, inElement, inDepth + 1); - - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); - rv = outputStream->Write("

\n", 9, &bytesWritten); + if (!WriteChildren(inElement, inDepth + 1)) + return false; + + WriteString(indentString, strlen(indentString)); + WriteString("

", 8); + WriteLinebreak(); } else { if (tagName == BookmarksService::gBookmarkAtom) { - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); + WriteString(indentString, strlen(indentString)); const char* const bookmarkPrefix = "

Write(bookmarkPrefix, strlen(bookmarkPrefix), &bytesWritten); + WriteString(bookmarkPrefix, strlen(bookmarkPrefix)); inElement->GetAttribute(NS_LITERAL_STRING("href"), href); inElement->GetAttribute(NS_LITERAL_STRING("name"), title); @@ -203,24 +213,64 @@ BookmarksExport::WriteItem(nsIOutputStream* outputStream, nsIDOMElement* inEleme NS_ConvertUCS2toUTF8 hrefConverter(href); const char* utf8String = hrefConverter.get(); - rv = outputStream->Write(utf8String, strlen(utf8String), &bytesWritten); - outputStream->Write("\">", 2, &bytesWritten); + WriteString(utf8String, strlen(utf8String)); + WriteString("\">", 2); NS_ConvertUCS2toUTF8 titleConverter(title); utf8String = titleConverter.get(); - rv = outputStream->Write(utf8String, strlen(utf8String), &bytesWritten); - rv = outputStream->Write("\n", 5, &bytesWritten); + WriteString(utf8String, strlen(utf8String)); + WriteString("", 4); + WriteLinebreak(); } else if (tagName == BookmarksService::gSeparatorAtom) { - rv = outputStream->Write(indentString, strlen(indentString), &bytesWritten); - const char* const hrString = "
\n"; - rv = outputStream->Write(hrString, strlen(hrString), &bytesWritten); + WriteString(indentString, strlen(indentString)); + WriteString("
", 4); + WriteLinebreak(); } - } - return rv; + return true; } +void +BookmarksExport::WritePrologue() +{ + const char* const gPrologueLines[] = { + "", + "", + "", + "Bookmarks", + "

Bookmarks

", + "", + nil + }; + + char* const *linePtr = gPrologueLines; + + while (*linePtr) + { + WriteString(*linePtr, strlen(*linePtr)); + WriteLinebreak(); + linePtr++; + } +} + +void +BookmarksExport::WriteString(const char*inString, PRInt32 inLen) +{ + PRUint32 bytesWritten; + if (mWriteStatus == NS_OK) + mWriteStatus = mOutputStream->Write(inString, inLen, &bytesWritten); +} + +void +BookmarksExport::WriteLinebreak() +{ + WriteString(mLinebreakStr, strlen(mLinebreakStr)); +} + + diff --git a/mozilla/chimera/src/bookmarks/BookmarksService.mm b/mozilla/chimera/src/bookmarks/BookmarksService.mm index fa62f142ef3..51c45474d06 100644 --- a/mozilla/chimera/src/bookmarks/BookmarksService.mm +++ b/mozilla/chimera/src/bookmarks/BookmarksService.mm @@ -608,7 +608,14 @@ nsresult BookmarksService::ExportBookmarksToHTML(const nsAString& inFilePath) { nsCOMPtr domDoc = do_QueryInterface(gBookmarksDocument); - return BookmarksExport::ExportBookmarksToHTML(domDoc, inFilePath); + + nsresult rv = NS_ERROR_OUT_OF_MEMORY; + BookmarksExport* exporter = new BookmarksExport(domDoc); + if (exporter) + rv = exporter->ExportBookmarksToHTML(inFilePath); + + delete exporter; + return rv; } void