bug 340603: getting table updates consumes large amounts of memory

patch: interface for streaming updates
r+a=darin
This commit is contained in:
tony%ponderer.org 2006-06-15 19:10:04 +00:00
parent 77d2863c98
commit 788b00d2ae
10 changed files with 592 additions and 17 deletions

View File

@ -77,6 +77,9 @@
#define NS_URLCLASSIFIERDBSERVICE_CONTRACTID \
"@mozilla.org/url-classifier/dbservice;1"
#define NS_URLCLASSIFIERSTREAMUPDATER_CONTRACTID \
"@mozilla.org/url-classifier/streamupdater;1"
#define NS_SCRIPTABLEUNESCAPEHTML_CONTRACTID "@mozilla.org/feed-unescapehtml;1"
/////////////////////////////////////////////////////////////////////////////
@ -119,9 +122,15 @@
// {e7f70966-9a37-48d7-8aeb-35998f31090e}
#define NS_TYPEAHEADFIND_CID \
{ 0xe7f70966, 0x9a37, 0x48d7, { 0x8a, 0xeb, 0x35, 0x99, 0x8f, 0x31, 0x09, 0x0e} }
// {5eb7c3c1-ec1f-4007-87cc-eefb37d68ce6}
#define NS_URLCLASSIFIERDBSERVICE_CID \
{ 0x5eb7c3c1, 0xec1f, 0x4007, { 0x87, 0xcc, 0xee, 0xfb, 0x37, 0xd6, 0x8c, 0xe6} }
// {c2be6dc0-ef1e-4abd-86a2-4f864ddc57f6}
#define NS_URLCLASSIFIERSTREAMUPDATER_CID \
{ 0xc2be6dc0, 0xef1e, 0x4abd, { 0x86, 0xa2, 0x4f, 0x86, 0x4d, 0xdc, 0x57, 0xf6} }
// {10f2f5f0-f103-4901-980f-ba11bd70d60d}
#define NS_SCRIPTABLEUNESCAPEHTML_CID \
{ 0x10f2f5f0, 0xf103, 0x4901, { 0x98, 0x0f, 0xba, 0x11, 0xbd, 0x70, 0xd6, 0x0d} }

View File

@ -56,6 +56,7 @@
#ifdef MOZ_URL_CLASSIFIER
#include "nsUrlClassifierDBService.h"
#include "nsUrlClassifierStreamUpdater.h"
#endif
#ifdef MOZ_FEEDS
@ -84,6 +85,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsTypeAheadFind)
#ifdef MOZ_URL_CLASSIFIER
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsUrlClassifierDBService,
nsUrlClassifierDBService::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlClassifierStreamUpdater)
#endif
#ifdef MOZ_FEEDS
@ -132,6 +134,10 @@ static const nsModuleComponentInfo components[] =
NS_URLCLASSIFIERDBSERVICE_CID,
NS_URLCLASSIFIERDBSERVICE_CONTRACTID,
nsUrlClassifierDBServiceConstructor },
{ "Url Classifier Stream Updater",
NS_URLCLASSIFIERSTREAMUPDATER_CID,
NS_URLCLASSIFIERSTREAMUPDATER_CONTRACTID,
nsUrlClassifierStreamUpdaterConstructor },
#endif
#ifdef MOZ_FEEDS
{ "Unescape HTML",

View File

@ -9,6 +9,7 @@ MODULE = url-classifier
XPIDL_MODULE = url-classifier
XPIDLSRCS = nsIUrlClassifierDBService.idl \
nsIUrlClassifierStreamUpdater.idl \
nsIUrlClassifierTable.idl \
nsIUrlListManager.idl \
$(NULL)

View File

@ -49,7 +49,7 @@ interface nsIUrlClassifierCallback : nsISupports {
* It provides async methods for querying and updating the database. As the
* methods complete, they call the callback function.
*/
[scriptable, uuid(88519724-2225-4b4f-8ba7-365b4d138c3a)]
[scriptable, uuid(61759a52-fbbb-4c5e-b1df-fce67b6d10c8)]
interface nsIUrlClassifierDBService : nsISupports
{
/**
@ -67,6 +67,30 @@ interface nsIUrlClassifierDBService : nsISupports
* allows us to keep track of the table version in our main thread.
*/
void updateTables(in ACString updateString, in nsIUrlClassifierCallback c);
////////////////////////////////////////////////////////////////////////////
// Incremental update methods. These are named to match similar methods
// in, e.g., nsICryptoHash.
/**
* Update the table incrementally.
*/
void update(in ACString updateChunk);
// It would be nice to have an updateFromStream method to round out the
// interface, but it's tricky because of XPCOM proxies.
/**
* Finish an incremental update. This commits any pending tables and
* calls the callback for each completed table.
*/
void finish(in nsIUrlClassifierCallback c);
/**
* Cancel an incremental update. This rolls back and pending changes.
* and resets the stream interface.
*/
void cancelStream();
};
/**

View File

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Url Classifier code
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Tony Chang <tony@ponderer.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIUrlClassifierDBService.idl"
/**
* This is a class to help with the
*/
[scriptable, uuid(45b57a99-0c1a-4096-9d16-c4766d75fbea)]
interface nsIUrlClassifierStreamUpdater : nsISupports
{
/**
* The Url to download from. Should be plain ascii text.
*/
attribute ACString updateUrl;
/**
* Try to download updates from updateUrl. Only one instance of this
* runs at a time, so we return false if another instance is already
* running.
*/
boolean downloadUpdates(in nsIUrlClassifierCallback c);
};

View File

@ -12,14 +12,15 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
* The Original Code is Url Classifier code
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Tony Chang <tony@ponderer.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@ -12,13 +12,15 @@ MOZILLA_INTERNAL_API = 1
FORCE_STATIC_LIB = 1
REQUIRES = storage \
REQUIRES = necko \
storage \
string \
xpcom \
$(NULL)
CPPSRCS = \
nsUrlClassifierDBService.cpp \
nsUrlClassifierStreamUpdater.cpp \
$(NULL)
LOCAL_INCLUDES = \

View File

@ -51,11 +51,12 @@
#include "nsIProxyObjectManager.h"
#include "nsToolkitCompsCID.h"
#include "nsUrlClassifierDBService.h"
#include "nsThreadUtils.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
#include "prlog.h"
#include "prmon.h"
// NSPR_LOG_MODULES=UrlClassifierDbService:5
#if defined(PR_LOGGING)
static const PRLogModuleInfo *gUrlClassifierDbServiceLog = nsnull;
#define LOG(args) PR_LOG(gUrlClassifierDbServiceLog, PR_LOG_DEBUG, args)
@ -149,13 +150,25 @@ private:
// to be created in the background thread (currently mozStorageConnection
// isn't thread safe).
mozIStorageConnection* mConnection;
// True if we're in the middle of a streaming update.
PRBool mHasPendingUpdate;
// For incremental updates, keep track of tables that have been updated.
// When finish() is called, we go ahead and pass these update lines to
// the callback.
nsTArray<nsCString> mTableUpdateLines;
// We receive data in small chunks that may be broken in the middle of
// a line. So we save the last partial line here.
nsCString mPendingStreamUpdate;
};
NS_IMPL_THREADSAFE_ISUPPORTS1(nsUrlClassifierDBServiceWorker,
nsIUrlClassifierDBServiceWorker)
nsUrlClassifierDBServiceWorker::nsUrlClassifierDBServiceWorker()
: mConnection(nsnull)
: mConnection(nsnull), mHasPendingUpdate(PR_FALSE), mTableUpdateLines()
{
}
nsUrlClassifierDBServiceWorker::~nsUrlClassifierDBServiceWorker()
@ -170,7 +183,8 @@ nsUrlClassifierDBServiceWorker::~nsUrlClassifierDBServiceWorker()
NS_IMETHODIMP
nsUrlClassifierDBServiceWorker::Exists(const nsACString& tableName,
const nsACString& key,
nsIUrlClassifierCallback *c) {
nsIUrlClassifierCallback *c)
{
LOG(("Exists\n"));
nsresult rv = OpenDb();
@ -214,7 +228,8 @@ nsUrlClassifierDBServiceWorker::Exists(const nsACString& tableName,
// we call the callback with the table line.
NS_IMETHODIMP
nsUrlClassifierDBServiceWorker::UpdateTables(const nsACString& updateString,
nsIUrlClassifierCallback *c) {
nsIUrlClassifierCallback *c)
{
LOG(("Updating tables\n"));
nsresult rv = OpenDb();
@ -251,11 +266,14 @@ nsUrlClassifierDBServiceWorker::UpdateTables(const nsACString& updateString,
getter_AddRefs(deleteStatement));
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "malformed table line");
if (NS_SUCCEEDED(rv)) {
// If it's a new table, we must have completed the last table.
// Go ahead and post the completion to the UI thread.
// XXX This shouldn't happen before we commit the transaction.
if (lastTableLine.Length() > 0)
// If it's a new table, we may have completed a table.
// Go ahead and post the completion to the UI thread and db.
if (lastTableLine.Length() > 0) {
mConnection->CommitTransaction();
c->HandleEvent(lastTableLine);
mConnection->BeginTransaction();
}
lastTableLine.Assign(line);
}
} else {
@ -276,6 +294,109 @@ nsUrlClassifierDBServiceWorker::UpdateTables(const nsACString& updateString,
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierDBServiceWorker::Update(const nsACString& chunk)
{
LOG(("Update from Stream."));
nsresult rv = OpenDb();
if (NS_FAILED(rv)) {
NS_ERROR("Unable to open database");
return NS_ERROR_FAILURE;
}
nsCAutoString updateString(mPendingStreamUpdate);
updateString.Append(chunk);
nsCOMPtr<mozIStorageStatement> updateStatement;
nsCOMPtr<mozIStorageStatement> deleteStatement;
nsCAutoString dbTableName;
// If we're not in the middle of an update, we start a new transaction.
// Otherwise, we need to pick up where we left off.
if (!mHasPendingUpdate) {
mConnection->BeginTransaction();
mHasPendingUpdate = PR_TRUE;
} else {
PRUint32 numTables = mTableUpdateLines.Length();
if (numTables > 0) {
const nsDependentCSubstring &line = Substring(
mTableUpdateLines[numTables - 1], 0);
rv = ProcessNewTable(line, &dbTableName,
getter_AddRefs(updateStatement),
getter_AddRefs(deleteStatement));
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "malformed table line");
}
}
PRUint32 cur = 0;
PRInt32 next;
while(cur < updateString.Length() &&
(next = updateString.FindChar('\n', cur)) != kNotFound) {
const nsDependentCSubstring &line = Substring(updateString,
cur, next - cur);
cur = next + 1; // prepare for next run
// Skip blank lines
if (line.Length() == 0)
continue;
if ('[' == line[0]) {
rv = ProcessNewTable(line, &dbTableName,
getter_AddRefs(updateStatement),
getter_AddRefs(deleteStatement));
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "malformed table line");
if (NS_SUCCEEDED(rv)) {
// Add the line to our array of table lines.
mTableUpdateLines.AppendElement(line);
}
} else {
rv = ProcessUpdateTable(line, dbTableName, updateStatement,
deleteStatement);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "malformed update line");
}
}
// Save the remaining string fragment.
mPendingStreamUpdate = Substring(updateString, cur);
LOG(("pending stream update: %s", mPendingStreamUpdate.get()));
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierDBServiceWorker::Finish(nsIUrlClassifierCallback *c)
{
if (!mHasPendingUpdate)
return NS_OK;
LOG(("Finish, committing transaction"));
mConnection->CommitTransaction();
for (PRUint32 i = 0; i < mTableUpdateLines.Length(); ++i) {
c->HandleEvent(mTableUpdateLines[i]);
}
mTableUpdateLines.Clear();
mPendingStreamUpdate.Truncate();
mHasPendingUpdate = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierDBServiceWorker::CancelStream()
{
if (!mHasPendingUpdate)
return NS_OK;
LOG(("CancelStream, rolling back transaction"));
mConnection->RollbackTransaction();
mTableUpdateLines.Clear();
mPendingStreamUpdate.Truncate();
mHasPendingUpdate = PR_FALSE;
return NS_OK;
}
// Allows the main thread to delete the connection which may be in
// a background thread.
// XXX This could be turned into a single shutdown event so the logic
@ -409,7 +530,8 @@ nsUrlClassifierDBServiceWorker::OpenDb()
}
nsresult
nsUrlClassifierDBServiceWorker::MaybeCreateTable(const nsCString& aTableName) {
nsUrlClassifierDBServiceWorker::MaybeCreateTable(const nsCString& aTableName)
{
LOG(("MaybeCreateTable %s\n", aTableName.get()));
nsCOMPtr<mozIStorageStatement> createStatement;
@ -426,7 +548,8 @@ nsUrlClassifierDBServiceWorker::MaybeCreateTable(const nsCString& aTableName) {
void
nsUrlClassifierDBServiceWorker::GetDbTableName(const nsACString& aTableName,
nsCString* aDbTableName) {
nsCString* aDbTableName)
{
aDbTableName->Assign(aTableName);
aDbTableName->ReplaceChar('-', '_');
}
@ -568,6 +691,75 @@ nsUrlClassifierDBService::UpdateTables(const nsACString& updateString,
return proxy->UpdateTables(updateString, proxyCallback);
}
NS_IMETHODIMP
nsUrlClassifierDBService::Update(const nsACString& aUpdateChunk)
{
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
nsresult rv;
// The actual worker uses the background thread.
nsCOMPtr<nsIUrlClassifierDBServiceWorker> proxy;
rv = NS_GetProxyForObject(gDbBackgroundThread,
NS_GET_IID(nsIUrlClassifierDBServiceWorker),
mWorker,
NS_PROXY_ASYNC,
getter_AddRefs(proxy));
NS_ENSURE_SUCCESS(rv, rv);
return proxy->Update(aUpdateChunk);
}
NS_IMETHODIMP
nsUrlClassifierDBService::Finish(nsIUrlClassifierCallback *c)
{
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
nsCOMPtr<nsIUrlClassifierCallback> wrapper =
new nsUrlClassifierCallbackWrapper(c);
NS_ENSURE_TRUE(wrapper, NS_ERROR_OUT_OF_MEMORY);
nsresult rv;
// The proxy callback uses the current thread.
nsCOMPtr<nsIUrlClassifierCallback> proxyCallback;
rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD,
NS_GET_IID(nsIUrlClassifierCallback),
wrapper,
NS_PROXY_ASYNC,
getter_AddRefs(proxyCallback));
NS_ENSURE_SUCCESS(rv, rv);
// The actual worker uses the background thread.
nsCOMPtr<nsIUrlClassifierDBServiceWorker> proxy;
rv = NS_GetProxyForObject(gDbBackgroundThread,
NS_GET_IID(nsIUrlClassifierDBServiceWorker),
mWorker,
NS_PROXY_ASYNC,
getter_AddRefs(proxy));
NS_ENSURE_SUCCESS(rv, rv);
return proxy->Finish(proxyCallback);
}
NS_IMETHODIMP
nsUrlClassifierDBService::CancelStream()
{
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
nsresult rv;
// The actual worker uses the background thread.
nsCOMPtr<nsIUrlClassifierDBServiceWorker> proxy;
rv = NS_GetProxyForObject(gDbBackgroundThread,
NS_GET_IID(nsIUrlClassifierDBServiceWorker),
mWorker,
NS_PROXY_ASYNC,
getter_AddRefs(proxy));
NS_ENSURE_SUCCESS(rv, rv);
return proxy->CancelStream();
}
NS_IMETHODIMP
nsUrlClassifierDBService::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *aData)

View File

@ -0,0 +1,209 @@
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Url Classifier code
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Tony Chang <tony@ponderer.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIURI.h"
#include "nsIUrlClassifierDBService.h"
#include "nsNetUtil.h"
#include "nsStreamUtils.h"
#include "nsToolkitCompsCID.h"
#include "nsUrlClassifierStreamUpdater.h"
#include "prlog.h"
// NSPR_LOG_MODULES=UrlClassifierStreamUpdater:5
#if defined(PR_LOGGING)
static const PRLogModuleInfo *gUrlClassifierStreamUpdaterLog = nsnull;
#define LOG(args) PR_LOG(gUrlClassifierStreamUpdaterLog, PR_LOG_DEBUG, args)
#else
#define LOG(args)
#endif
///////////////////////////////////////////////////////////////////////////////
// Stream listener for incremental download of url tables.
class nsUrlClassifierStreamUpdater;
class TableUpdateListener : public nsIStreamListener
{
public:
TableUpdateListener(nsIUrlClassifierCallback *c);
nsCOMPtr<nsIUrlClassifierDBService> mDBService;
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
private:
~TableUpdateListener() {};
// Callback when table updates complete.
nsCOMPtr<nsIUrlClassifierCallback> mCallback;
};
TableUpdateListener::TableUpdateListener(nsIUrlClassifierCallback *c)
{
mCallback = c;
}
NS_IMPL_ISUPPORTS2(TableUpdateListener, nsIStreamListener, nsIRequestObserver)
NS_IMETHODIMP
TableUpdateListener::OnStartRequest(nsIRequest *request, nsISupports* context)
{
nsresult rv;
if (!mDBService) {
mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
NS_IMETHODIMP
TableUpdateListener::OnDataAvailable(nsIRequest *request,
nsISupports* context,
nsIInputStream *aIStream,
PRUint32 aSourceOffset,
PRUint32 aLength)
{
LOG(("OnDataAvailable (%d bytes)", aLength));
NS_ASSERTION(mDBService != nsnull, "UrlClassifierDBService is null");
nsresult rv;
// Copy the data into a nsCString
nsCString chunk;
rv = NS_ConsumeStream(aIStream, aLength, chunk);
NS_ENSURE_SUCCESS(rv, rv);
LOG(("Chunk (%d): %s\n\n", chunk.Length(), chunk.get()));
rv = mDBService->Update(chunk);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
TableUpdateListener::OnStopRequest(nsIRequest *request, nsISupports* context,
nsresult aStatus)
{
LOG(("OnStopRequest status: %d", aStatus));
// If we got the whole stream, call Finish to commit the changes.
// Otherwise, call Cancel to rollback the changes.
if (NS_SUCCEEDED(aStatus))
mDBService->Finish(mCallback);
else
mDBService->CancelStream();
nsUrlClassifierStreamUpdater* updater =
NS_STATIC_CAST(nsUrlClassifierStreamUpdater*, context);
NS_ASSERTION(updater != nsnull, "failed to cast context");
updater->mIsUpdating = PR_FALSE;
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////
// nsIUrlClassiferStreamUpdater implementation
// Handles creating/running the stream listener
nsUrlClassifierStreamUpdater::nsUrlClassifierStreamUpdater()
: mIsUpdating(PR_FALSE), mUpdateUrl(nsnull)
{
#if defined(PR_LOGGING)
if (!gUrlClassifierStreamUpdaterLog)
gUrlClassifierStreamUpdaterLog = PR_NewLogModule("UrlClassifierStreamUpdater");
#endif
}
NS_IMPL_ISUPPORTS1(nsUrlClassifierStreamUpdater, nsIUrlClassifierStreamUpdater)
NS_IMETHODIMP
nsUrlClassifierStreamUpdater::GetUpdateUrl(nsACString & aUpdateUrl)
{
if (mUpdateUrl) {
mUpdateUrl->GetSpec(aUpdateUrl);
} else {
aUpdateUrl.Truncate();
}
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierStreamUpdater::SetUpdateUrl(const nsACString & aUpdateUrl)
{
nsresult rv = NS_NewURI(getter_AddRefs(mUpdateUrl), aUpdateUrl);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierStreamUpdater::DownloadUpdates(nsIUrlClassifierCallback *c,
PRBool *_retval)
{
if (mIsUpdating) {
LOG(("already updating, skipping update"));
*_retval = PR_FALSE;
return NS_OK;
}
if (!mUpdateUrl) {
NS_ERROR("updateUrl not set");
return NS_ERROR_NOT_INITIALIZED;
}
// Ok, try to create the download channel.
nsresult rv;
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel), mUpdateUrl);
NS_ENSURE_SUCCESS(rv, rv);
if (!mListener) {
mListener = new TableUpdateListener(c);
}
// Make the request
rv = channel->AsyncOpen(mListener.get(), this);
NS_ENSURE_SUCCESS(rv, rv);
mIsUpdating = PR_TRUE;
*_retval = PR_TRUE;
return NS_OK;
}

View File

@ -0,0 +1,72 @@
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Url Classifier code
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Tony Chang <tony@ponderer.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsUrlClassifierStreamUpdater_h_
#define nsUrlClassifierStreamUpdater_h_
#include <nsISupportsUtils.h>
#include "nsCOMPtr.h"
#include "nsIUrlClassifierStreamUpdater.h"
#include "nsIStreamListener.h"
// Forward declare pointers
class nsIURI;
class nsUrlClassifierStreamUpdater : public nsIUrlClassifierStreamUpdater
{
public:
nsUrlClassifierStreamUpdater();
NS_DECL_ISUPPORTS
NS_DECL_NSIURLCLASSIFIERSTREAMUPDATER
PRBool mIsUpdating;
private:
// No subclassing
~nsUrlClassifierStreamUpdater() {};
// Disallow copy constructor
nsUrlClassifierStreamUpdater(nsUrlClassifierStreamUpdater&);
nsCOMPtr<nsIURI> mUpdateUrl;
nsCOMPtr<nsIStreamListener> mListener;
};
#endif // nsUrlClassifierStreamUpdater_h_