1999-08-23 03:48:53 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
1999-08-23 03:48:53 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* 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.
|
1999-08-23 03:48:53 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
1999-11-06 03:43:54 +00:00
|
|
|
* Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
2000-07-26 23:46:56 +00:00
|
|
|
* Original Author(s):
|
|
|
|
* Chris Waterson <waterson@netscape.com>
|
|
|
|
* Robert John Churchill <rjc@netscape.com>
|
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* Contributor(s):
|
2000-01-11 20:49:15 +00:00
|
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
1999-08-23 03:48:53 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
A directory viewer object. Parses "application/http-index-format"
|
|
|
|
per Lou Montulli's original spec:
|
|
|
|
|
|
|
|
http://www.area.com/~roeber/file_format.html
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2000-08-26 07:37:59 +00:00
|
|
|
#include "nsDirectoryViewer.h"
|
1999-08-23 03:48:53 +00:00
|
|
|
#include "jsapi.h"
|
|
|
|
#include "nsCOMPtr.h"
|
2000-01-24 21:28:28 +00:00
|
|
|
#include "nsCRT.h"
|
1999-08-24 04:16:33 +00:00
|
|
|
#include "nsEscape.h"
|
1999-08-23 03:48:53 +00:00
|
|
|
#include "nsIDocumentLoader.h"
|
|
|
|
#include "nsIDocumentViewer.h"
|
|
|
|
#include "nsIEnumerator.h"
|
|
|
|
#include "nsIRDFService.h"
|
|
|
|
#include "nsIScriptContext.h"
|
1999-12-03 09:24:22 +00:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
1999-08-23 03:48:53 +00:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsISupportsArray.h"
|
|
|
|
#include "nsIXPConnect.h"
|
|
|
|
#include "nsEnumeratorUtils.h"
|
|
|
|
#include "nsRDFCID.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsVoidArray.h"
|
|
|
|
#include "nsXPIDLString.h"
|
|
|
|
#include "rdf.h"
|
1999-11-13 07:36:28 +00:00
|
|
|
#include "nsIInterfaceRequestor.h"
|
2000-07-14 09:07:13 +00:00
|
|
|
#include "nsITextToSubURI.h"
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-08-23 03:48:53 +00:00
|
|
|
// Common CIDs
|
2000-02-08 01:17:27 +00:00
|
|
|
//
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|
|
|
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
// Note: due to aggregation, the HTTPINDEX namespace should match
|
|
|
|
// what's used in the rest of the application
|
|
|
|
#define HTTPINDEX_NAMESPACE_URI NC_NAMESPACE_URI
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-08-23 03:48:53 +00:00
|
|
|
// nsHTTPIndex
|
2000-02-08 01:17:27 +00:00
|
|
|
//
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-08-23 03:48:53 +00:00
|
|
|
// nsHTTPIndexParser
|
|
|
|
//
|
|
|
|
|
|
|
|
class nsHTTPIndexParser : public nsIStreamListener
|
|
|
|
{
|
1999-08-23 04:19:48 +00:00
|
|
|
protected:
|
2000-04-17 05:07:26 +00:00
|
|
|
static nsrefcnt gRefCntParser;
|
1999-08-23 03:48:53 +00:00
|
|
|
static nsIRDFService* gRDF;
|
2000-08-28 04:24:49 +00:00
|
|
|
static nsITextToSubURI* gTextToSubURI;
|
1999-08-23 03:48:53 +00:00
|
|
|
static nsIRDFResource* kHTTPIndex_Comment;
|
|
|
|
static nsIRDFResource* kHTTPIndex_Filename;
|
2000-04-17 05:07:26 +00:00
|
|
|
static nsIRDFResource* kHTTPIndex_Filetype;
|
1999-09-21 21:43:41 +00:00
|
|
|
static nsIRDFResource* kHTTPIndex_Loading;
|
2000-08-28 04:24:49 +00:00
|
|
|
static nsIRDFResource* kNC_Child;
|
1999-09-21 21:43:41 +00:00
|
|
|
static nsIRDFLiteral* kTrueLiteral;
|
2000-08-28 09:50:20 +00:00
|
|
|
static nsIRDFLiteral* kFalseLiteral;
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
static nsresult ParseLiteral(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult);
|
|
|
|
static nsresult ParseDate(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult);
|
|
|
|
static nsresult ParseInt(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult);
|
1999-08-26 05:54:04 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
struct Field {
|
2000-04-17 05:07:26 +00:00
|
|
|
const char *mName;
|
|
|
|
const char *mResName;
|
2000-08-28 09:50:20 +00:00
|
|
|
nsresult (*mParse)(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult);
|
1999-08-26 05:54:04 +00:00
|
|
|
nsIRDFResource* mProperty;
|
1999-08-23 03:48:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static Field gFieldTable[];
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
nsIHTTPIndex* mHTTPIndex; // [WEAK]
|
1999-08-23 03:48:53 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFDataSource> mDataSource;
|
|
|
|
nsCOMPtr<nsIRDFResource> mDirectory;
|
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
nsCString mURI;
|
2000-02-08 01:17:27 +00:00
|
|
|
nsCString mBuf;
|
2000-08-28 04:24:49 +00:00
|
|
|
PRInt32 mLineStart;
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
nsresult ProcessData(nsISupports *context);
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult ParseFormat(const char* aFormatStr);
|
2000-08-28 09:50:20 +00:00
|
|
|
nsresult ParseData(nsString* values, const char *baseStr, const char *encodingStr, char* aDataStr, nsIRDFResource *parentRes);
|
1999-08-23 03:48:53 +00:00
|
|
|
|
|
|
|
nsAutoString mComment;
|
|
|
|
|
|
|
|
nsVoidArray mFormat;
|
|
|
|
|
1999-11-13 07:36:28 +00:00
|
|
|
nsHTTPIndexParser(nsHTTPIndex* aHTTPIndex, nsISupports* aContainer);
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult Init();
|
|
|
|
|
|
|
|
virtual ~nsHTTPIndexParser();
|
|
|
|
|
|
|
|
// If this is set, then we need to bind the nsIHTTPIndex object to
|
|
|
|
// the global object when we get an OnStartRequest() notification
|
|
|
|
// (at this point, we'll know that the XUL document has been
|
|
|
|
// embedded and the global object won't get clobbered.
|
1999-11-13 07:36:28 +00:00
|
|
|
nsISupports* mContainer;
|
1999-08-23 03:48:53 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
static nsresult Create(nsHTTPIndex* aHTTPIndex,
|
1999-11-13 07:36:28 +00:00
|
|
|
nsISupports* aContainer,
|
1999-08-23 03:48:53 +00:00
|
|
|
nsIStreamListener** aResult);
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
1999-09-16 01:16:22 +00:00
|
|
|
NS_DECL_NSISTREAMOBSERVER
|
|
|
|
NS_DECL_NSISTREAMLISTENER
|
1999-08-23 03:48:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
|
|
|
|
nsrefcnt nsHTTPIndexParser::gRefCntParser = 0;
|
1999-08-23 03:48:53 +00:00
|
|
|
nsIRDFService* nsHTTPIndexParser::gRDF;
|
2000-08-28 04:24:49 +00:00
|
|
|
nsITextToSubURI *nsHTTPIndexParser::gTextToSubURI;
|
1999-08-23 03:48:53 +00:00
|
|
|
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Comment;
|
|
|
|
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Filename;
|
2000-04-17 05:07:26 +00:00
|
|
|
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Filetype;
|
1999-09-21 21:43:41 +00:00
|
|
|
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Loading;
|
2000-08-28 04:24:49 +00:00
|
|
|
nsIRDFResource* nsHTTPIndexParser::kNC_Child;
|
1999-09-21 21:43:41 +00:00
|
|
|
nsIRDFLiteral* nsHTTPIndexParser::kTrueLiteral;
|
2000-08-28 09:50:20 +00:00
|
|
|
nsIRDFLiteral* nsHTTPIndexParser::kFalseLiteral;
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
|
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
// This table tells us how to parse the fields in the HTTP-index
|
|
|
|
// stream into an RDF graph.
|
1999-08-23 03:48:53 +00:00
|
|
|
nsHTTPIndexParser::Field
|
|
|
|
nsHTTPIndexParser::gFieldTable[] = {
|
2000-04-17 05:07:26 +00:00
|
|
|
{ "Filename", "http://home.netscape.com/NC-rdf#Name", nsHTTPIndexParser::ParseLiteral, nsnull },
|
|
|
|
{ "Content-Length", "http://home.netscape.com/NC-rdf#Content-Length", nsHTTPIndexParser::ParseInt, nsnull },
|
|
|
|
{ "Last-Modified", "http://home.netscape.com/WEB-rdf#LastModifiedDate", nsHTTPIndexParser::ParseDate, nsnull },
|
|
|
|
{ "Content-Type", "http://home.netscape.com/NC-rdf#Content-Type", nsHTTPIndexParser::ParseLiteral, nsnull },
|
|
|
|
{ "File-Type", "http://home.netscape.com/NC-rdf#File-Type", nsHTTPIndexParser::ParseLiteral, nsnull },
|
|
|
|
{ "Permissions", "http://home.netscape.com/NC-rdf#Permissions", nsHTTPIndexParser::ParseLiteral, nsnull },
|
|
|
|
{ nsnull, "", nsHTTPIndexParser::ParseLiteral, nsnull },
|
1999-08-23 03:48:53 +00:00
|
|
|
};
|
|
|
|
|
1999-11-13 07:36:28 +00:00
|
|
|
nsHTTPIndexParser::nsHTTPIndexParser(nsHTTPIndex* aHTTPIndex, nsISupports* aContainer)
|
1999-08-23 03:48:53 +00:00
|
|
|
: mHTTPIndex(aHTTPIndex),
|
2000-08-28 04:24:49 +00:00
|
|
|
mLineStart(0),
|
1999-08-23 03:48:53 +00:00
|
|
|
mContainer(aContainer)
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult
|
|
|
|
nsHTTPIndexParser::Init()
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(mHTTPIndex != nsnull, "not initialized");
|
|
|
|
if (! mHTTPIndex)
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
rv = mHTTPIndex->GetDataSource(getter_AddRefs(mDataSource));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-09-21 01:41:29 +00:00
|
|
|
// No datasource. Uh oh. We won't be much use then.
|
|
|
|
if (! mDataSource)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
if (gRefCntParser++ == 0) {
|
2000-09-13 23:57:52 +00:00
|
|
|
rv = nsServiceManager::GetService("@mozilla.org/rdf/rdf-service;1",
|
2000-01-11 20:49:15 +00:00
|
|
|
NS_GET_IID(nsIRDFService),
|
2000-09-06 22:33:58 +00:00
|
|
|
NS_REINTERPRET_CAST(nsISupports**, &gRDF));
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-09-13 23:57:52 +00:00
|
|
|
rv = nsServiceManager::GetService(NS_ITEXTTOSUBURI_CONTRACTID,
|
2000-08-28 04:24:49 +00:00
|
|
|
NS_GET_IID(nsITextToSubURI),
|
|
|
|
NS_REINTERPRET_CAST(nsISupports**, &gTextToSubURI));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "Comment", &kHTTPIndex_Comment);
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "Name", &kHTTPIndex_Filename);
|
2000-04-17 05:07:26 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "File-Type", &kHTTPIndex_Filetype);
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "loading", &kHTTPIndex_Loading);
|
1999-09-21 21:43:41 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetResource(NC_NAMESPACE_URI "child", &kNC_Child);
|
2000-08-28 04:24:49 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetLiteral(NS_ConvertASCIItoUCS2("true").GetUnicode(), &kTrueLiteral);
|
1999-09-21 21:43:41 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetLiteral(NS_ConvertASCIItoUCS2("false").GetUnicode(), &kFalseLiteral);
|
2000-08-28 09:50:20 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-09-21 21:43:41 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
for (Field* field = gFieldTable; field->mName; ++field) {
|
2000-04-17 05:07:26 +00:00
|
|
|
nsCAutoString str(field->mResName);
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetResource(str, &field->mProperty);
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsHTTPIndexParser::~nsHTTPIndexParser()
|
|
|
|
{
|
2000-04-17 05:07:26 +00:00
|
|
|
if (--gRefCntParser == 0) {
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IF_RELEASE(kHTTPIndex_Comment);
|
|
|
|
NS_IF_RELEASE(kHTTPIndex_Filename);
|
2000-04-17 05:07:26 +00:00
|
|
|
NS_IF_RELEASE(kHTTPIndex_Filetype);
|
1999-09-21 21:43:41 +00:00
|
|
|
NS_IF_RELEASE(kHTTPIndex_Loading);
|
2000-08-28 04:24:49 +00:00
|
|
|
NS_IF_RELEASE(kNC_Child);
|
1999-09-21 21:43:41 +00:00
|
|
|
NS_IF_RELEASE(kTrueLiteral);
|
2000-08-28 09:50:20 +00:00
|
|
|
NS_IF_RELEASE(kFalseLiteral);
|
1999-08-23 03:48:53 +00:00
|
|
|
|
|
|
|
for (Field* field = gFieldTable; field->mName; ++field) {
|
1999-08-26 05:54:04 +00:00
|
|
|
NS_IF_RELEASE(field->mProperty);
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
if (gRDF)
|
2000-08-28 04:24:49 +00:00
|
|
|
{
|
2000-09-13 23:57:52 +00:00
|
|
|
nsServiceManager::ReleaseService("@mozilla.org/rdf/rdf-service;1", gRDF);
|
2000-09-06 22:33:58 +00:00
|
|
|
gRDF = nsnull;
|
2000-08-28 04:24:49 +00:00
|
|
|
}
|
|
|
|
if (gTextToSubURI)
|
|
|
|
{
|
2000-09-13 23:57:52 +00:00
|
|
|
nsServiceManager::ReleaseService(NS_ITEXTTOSUBURI_CONTRACTID, gTextToSubURI);
|
2000-08-28 04:24:49 +00:00
|
|
|
gTextToSubURI = nsnull;
|
|
|
|
}
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult
|
|
|
|
nsHTTPIndexParser::Create(nsHTTPIndex* aHTTPIndex,
|
1999-11-13 07:36:28 +00:00
|
|
|
nsISupports* aContainer,
|
1999-08-23 03:48:53 +00:00
|
|
|
nsIStreamListener** aResult)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aHTTPIndex != nsnull, "null ptr");
|
|
|
|
if (! aHTTPIndex)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsHTTPIndexParser* result = new nsHTTPIndexParser(aHTTPIndex, aContainer);
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
nsresult rv = result->Init();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
delete result;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ADDREF(result);
|
|
|
|
*aResult = result;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-07-26 23:46:56 +00:00
|
|
|
|
2000-03-05 21:26:01 +00:00
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsHTTPIndexParser, nsIStreamListener, nsIStreamObserver);
|
1999-08-23 03:48:53 +00:00
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IMETHODIMP
|
2001-02-21 20:38:08 +00:00
|
|
|
nsHTTPIndexParser::OnStartRequest(nsIRequest *request, nsISupports* aContext)
|
1999-08-23 03:48:53 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-12-06 23:45:34 +00:00
|
|
|
// This should only run once...
|
|
|
|
if (mContainer) {
|
|
|
|
// We need to undo the AddRef() on the nsHTTPIndex object that
|
|
|
|
// happened in nsDirectoryViewerFactory::CreateInstance(). We'll
|
|
|
|
// stuff it into an nsCOMPtr (because we _know_ it'll get release
|
|
|
|
// if any errors occur)...
|
|
|
|
nsCOMPtr<nsIHTTPIndex> httpindex = do_QueryInterface(mHTTPIndex);
|
|
|
|
|
|
|
|
// ...and then _force_ a release here
|
|
|
|
mHTTPIndex->Release();
|
|
|
|
|
|
|
|
// Now get the content viewer container's script object.
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(do_GetInterface(mContainer));
|
|
|
|
NS_ENSURE_TRUE(scriptGlobal, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptContext> context;
|
|
|
|
rv = scriptGlobal->GetContext(getter_AddRefs(context));
|
|
|
|
NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
JSContext* jscontext = NS_REINTERPRET_CAST(JSContext*, context->GetNativeContext());
|
1999-12-18 20:29:29 +00:00
|
|
|
JSObject* global = JS_GetGlobalObject(jscontext);
|
1999-12-06 23:45:34 +00:00
|
|
|
|
|
|
|
// Using XPConnect, wrap the HTTP index object...
|
|
|
|
static NS_DEFINE_CID(kXPConnectCID, NS_XPCONNECT_CID);
|
|
|
|
NS_WITH_SERVICE(nsIXPConnect, xpc, kXPConnectCID, &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-01-26 08:38:10 +00:00
|
|
|
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
|
1999-12-06 23:45:34 +00:00
|
|
|
rv = xpc->WrapNative(jscontext,
|
1999-12-18 20:29:29 +00:00
|
|
|
global,
|
1999-12-06 23:45:34 +00:00
|
|
|
httpindex,
|
2000-01-11 20:49:15 +00:00
|
|
|
NS_GET_IID(nsIHTTPIndex),
|
1999-12-06 23:45:34 +00:00
|
|
|
getter_AddRefs(wrapper));
|
1999-08-23 03:48:53 +00:00
|
|
|
|
1999-12-06 23:45:34 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap http-index");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-23 03:48:53 +00:00
|
|
|
|
1999-12-06 23:45:34 +00:00
|
|
|
JSObject* jsobj;
|
|
|
|
rv = wrapper->GetJSObject(&jsobj);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get jsobj from xpconnect wrapper");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-23 03:48:53 +00:00
|
|
|
|
1999-12-06 23:45:34 +00:00
|
|
|
jsval jslistener = OBJECT_TO_JSVAL(jsobj);
|
1999-08-23 03:48:53 +00:00
|
|
|
|
1999-12-06 23:45:34 +00:00
|
|
|
// ...and stuff it into the global context
|
|
|
|
PRBool ok;
|
|
|
|
ok = JS_SetProperty(jscontext, global, "HTTPIndex", &jslistener);
|
1999-08-23 03:48:53 +00:00
|
|
|
|
1999-12-06 23:45:34 +00:00
|
|
|
NS_ASSERTION(ok, "unable to set Listener property");
|
|
|
|
if (! ok)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2001-02-21 20:38:08 +00:00
|
|
|
nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
// Save off some information about the stream we're about to parse.
|
2000-08-28 04:24:49 +00:00
|
|
|
nsCOMPtr<nsIURI> mDirectoryURI;
|
1999-08-23 03:48:53 +00:00
|
|
|
rv = aChannel->GetURI(getter_AddRefs(mDirectoryURI));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsXPIDLCString uristr;
|
|
|
|
rv = mDirectoryURI->GetSpec(getter_Copies(uristr));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-04-27 01:17:10 +00:00
|
|
|
// we know that this is a directory (due to being a HTTP-INDEX response)
|
|
|
|
// so ensure it ends with a slash if its a FTP URL
|
2000-08-28 04:24:49 +00:00
|
|
|
mURI.Assign(uristr);
|
|
|
|
if ((mURI.Find("ftp://", PR_TRUE) == 0) && (mURI.Last() != (PRUnichar('/'))))
|
2000-04-27 01:17:10 +00:00
|
|
|
{
|
2000-08-28 04:24:49 +00:00
|
|
|
mURI.Append('/');
|
2000-04-27 01:17:10 +00:00
|
|
|
}
|
|
|
|
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetResource(mURI, getter_AddRefs(mDirectory));
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-09-21 21:43:41 +00:00
|
|
|
// Mark the directory as "loading"
|
|
|
|
rv = mDataSource->Assert(mDirectory, kHTTPIndex_Loading, kTrueLiteral, PR_TRUE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IMETHODIMP
|
2001-02-21 20:38:08 +00:00
|
|
|
nsHTTPIndexParser::OnStopRequest(nsIRequest *request,
|
1999-08-23 03:48:53 +00:00
|
|
|
nsISupports* aContext,
|
|
|
|
nsresult aStatus,
|
|
|
|
const PRUnichar* aErrorMsg)
|
|
|
|
{
|
1999-09-21 01:41:29 +00:00
|
|
|
// If mDirectory isn't set, then we should just bail. Either an
|
|
|
|
// error occurred and OnStartRequest() never got called, or
|
|
|
|
// something exploded in OnStartRequest().
|
|
|
|
if (! mDirectory)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// XXX Should we do anything different if aStatus != NS_OK?
|
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
// Clean up any remaining data
|
2000-08-28 04:24:49 +00:00
|
|
|
if (mBuf.Length() > (PRUint32) mLineStart)
|
2000-08-28 09:50:20 +00:00
|
|
|
{
|
2000-04-17 05:07:26 +00:00
|
|
|
ProcessData(aContext);
|
2000-08-28 09:50:20 +00:00
|
|
|
}
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
// free up buffer after processing all the data
|
|
|
|
mBuf.Truncate();
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFLiteral> comment;
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetLiteral(mComment.GetUnicode(), getter_AddRefs(comment));
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = mDataSource->Assert(mDirectory, kHTTPIndex_Comment, comment, PR_TRUE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
// hack: Remove the 'loading' annotation (ignore errors)
|
|
|
|
mHTTPIndex->AddElement(mDirectory, kHTTPIndex_Loading, kTrueLiteral);
|
1999-09-21 21:43:41 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2001-02-21 20:38:08 +00:00
|
|
|
nsHTTPIndexParser::OnDataAvailable(nsIRequest *request,
|
1999-08-23 03:48:53 +00:00
|
|
|
nsISupports* aContext,
|
|
|
|
nsIInputStream* aStream,
|
|
|
|
PRUint32 aSourceOffset,
|
|
|
|
PRUint32 aCount)
|
|
|
|
{
|
2000-02-08 01:17:27 +00:00
|
|
|
// Make sure there's some data to process...
|
|
|
|
if (aCount < 1)
|
|
|
|
return NS_OK;
|
1999-11-10 23:51:10 +00:00
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
PRInt32 len = mBuf.Length();
|
1999-11-10 23:51:10 +00:00
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
// Ensure that our mBuf has capacity to hold the data we're about to
|
|
|
|
// read.
|
|
|
|
mBuf.SetCapacity(len + aCount + 1);
|
|
|
|
if (! mBuf.mStr)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
1999-11-10 23:51:10 +00:00
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
// Now read the data into our buffer.
|
|
|
|
nsresult rv;
|
|
|
|
PRUint32 count;
|
|
|
|
rv = aStream->Read(mBuf.mStr + len, aCount, &count);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-10 23:51:10 +00:00
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
// Set the string's length according to the amount of data we've read.
|
|
|
|
//
|
|
|
|
// XXX You'd think that mBuf.SetLength() would do this, but it
|
|
|
|
// doesn't. It calls Truncate(), so you can't set the length to
|
|
|
|
// something longer.
|
|
|
|
mBuf.mLength = len + count;
|
|
|
|
AddNullTerminator(mBuf);
|
1999-11-10 23:51:10 +00:00
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
return ProcessData(aContext);
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult
|
2000-04-17 05:07:26 +00:00
|
|
|
nsHTTPIndexParser::ProcessData(nsISupports *context)
|
1999-08-23 03:48:53 +00:00
|
|
|
{
|
2000-08-28 04:24:49 +00:00
|
|
|
nsXPIDLCString encodingStr;
|
|
|
|
if (mHTTPIndex)
|
|
|
|
{
|
|
|
|
mHTTPIndex->GetEncoding(getter_Copies(encodingStr));
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFResource> parentRes = do_QueryInterface(context);
|
2000-08-28 09:50:20 +00:00
|
|
|
if (!parentRes)
|
|
|
|
{
|
|
|
|
return(NS_ERROR_UNEXPECTED);
|
|
|
|
}
|
2000-08-28 04:24:49 +00:00
|
|
|
|
|
|
|
// First, we'll iterate through the values and remember each (using
|
|
|
|
// an array of autostrings allocated on the stack, if possible). We
|
|
|
|
// have to do this, because we don't know up-front the filename for
|
|
|
|
// which this 201 refers.
|
|
|
|
#define MAX_AUTO_VALUES 8
|
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
nsString autovalues[MAX_AUTO_VALUES];
|
|
|
|
nsString* values = autovalues;
|
2000-08-28 04:24:49 +00:00
|
|
|
|
|
|
|
if (mFormat.Count() > MAX_AUTO_VALUES) {
|
|
|
|
// Yeah, we really -do- want to create nsAutoStrings in the heap
|
|
|
|
// here, because most of the fields will be l.t. 32 characters:
|
|
|
|
// this avoids an extra allocation for the nsString's buffer.
|
2000-08-28 09:50:20 +00:00
|
|
|
values = new nsString[mFormat.Count()];
|
2000-08-28 04:24:49 +00:00
|
|
|
if (! values)
|
2000-08-28 09:50:20 +00:00
|
|
|
{
|
2000-08-28 04:24:49 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2000-08-28 09:50:20 +00:00
|
|
|
}
|
2000-08-28 04:24:49 +00:00
|
|
|
}
|
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
PRInt32 numItems = 0;
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
while(PR_TRUE)
|
|
|
|
{
|
2000-08-28 09:50:20 +00:00
|
|
|
++numItems;
|
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
PRInt32 eol = mBuf.FindCharInSet("\n\r", mLineStart);
|
1999-11-10 23:51:10 +00:00
|
|
|
if (eol < 0) break;
|
2000-08-28 04:24:49 +00:00
|
|
|
mBuf.SetCharAt(PRUnichar('\0'), eol);
|
|
|
|
|
|
|
|
const char *line = &mBuf.mStr[mLineStart];
|
|
|
|
PRInt32 lineLen = eol - mLineStart;
|
|
|
|
mLineStart = eol + 1;
|
1999-11-10 23:51:10 +00:00
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
if (lineLen >= 4)
|
1999-11-10 23:51:10 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
2000-02-08 01:17:27 +00:00
|
|
|
const char *buf = line;
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
if (buf[0] == '1')
|
|
|
|
{
|
|
|
|
if (buf[1] == '0')
|
|
|
|
{
|
|
|
|
if (buf[2] == '0' && buf[3] == ':')
|
|
|
|
{
|
|
|
|
// 100. Human-readable comment line. Ignore
|
|
|
|
}
|
|
|
|
else if (buf[2] == '1' && buf[3] == ':')
|
|
|
|
{
|
|
|
|
// 101. Human-readable information line.
|
2000-04-18 23:53:10 +00:00
|
|
|
mComment.AppendWithConversion(buf + 4);
|
1999-11-10 23:51:10 +00:00
|
|
|
}
|
|
|
|
else if (buf[2] == '2' && buf[3] == ':')
|
|
|
|
{
|
|
|
|
// 102. Human-readable information line, HTML.
|
2000-04-18 23:53:10 +00:00
|
|
|
mComment.AppendWithConversion(buf + 4);
|
1999-11-10 23:51:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (buf[0] == '2')
|
|
|
|
{
|
|
|
|
if (buf[1] == '0')
|
|
|
|
{
|
|
|
|
if (buf[2] == '0' && buf[3] == ':')
|
|
|
|
{
|
|
|
|
// 200. Define field names
|
|
|
|
rv = ParseFormat(buf + 4);
|
2000-08-28 09:50:20 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
{
|
|
|
|
return rv;
|
|
|
|
}
|
1999-11-10 23:51:10 +00:00
|
|
|
}
|
|
|
|
else if (buf[2] == '1' && buf[3] == ':')
|
|
|
|
{
|
|
|
|
// 201. Field data
|
2000-08-28 04:24:49 +00:00
|
|
|
rv = ParseData(values, mURI, encodingStr, ((char *)buf) + 4, parentRes);
|
2000-08-28 09:50:20 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
{
|
|
|
|
return rv;
|
|
|
|
}
|
1999-11-10 23:51:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (buf[0] == '3')
|
|
|
|
{
|
|
|
|
if (buf[1] == '0')
|
|
|
|
{
|
|
|
|
if (buf[2] == '0' && buf[3] == ':')
|
|
|
|
{
|
|
|
|
// 300. Self-referring URL
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-08-28 04:24:49 +00:00
|
|
|
|
|
|
|
// If we needed to spill values onto the heap, make sure we clean up
|
|
|
|
// here.
|
|
|
|
if (values != autovalues)
|
|
|
|
delete[] values;
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
return(NS_OK);
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult
|
|
|
|
nsHTTPIndexParser::ParseFormat(const char* aFormatStr)
|
|
|
|
{
|
|
|
|
// Parse a "200" format line, and remember the fields and their
|
|
|
|
// ordering in mFormat. Multiple 200 lines stomp on each other.
|
|
|
|
mFormat.Clear();
|
|
|
|
|
|
|
|
do {
|
2000-03-12 09:14:14 +00:00
|
|
|
while (*aFormatStr && nsCRT::IsAsciiSpace(PRUnichar(*aFormatStr)))
|
1999-08-23 03:48:53 +00:00
|
|
|
++aFormatStr;
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
if (! *aFormatStr)
|
1999-08-23 03:48:53 +00:00
|
|
|
break;
|
|
|
|
|
1999-08-24 04:16:33 +00:00
|
|
|
nsCAutoString name;
|
1999-11-10 23:51:10 +00:00
|
|
|
PRInt32 len = 0;
|
2000-03-12 09:14:14 +00:00
|
|
|
while (aFormatStr[len] && !nsCRT::IsAsciiSpace(PRUnichar(aFormatStr[len])))
|
1999-11-10 23:51:10 +00:00
|
|
|
++len;
|
|
|
|
name.SetCapacity(len + 1);
|
|
|
|
name.Append(aFormatStr, len);
|
|
|
|
aFormatStr += len;
|
1999-08-24 04:16:33 +00:00
|
|
|
|
|
|
|
// Okay, we're gonna monkey with the nsStr. Bold!
|
|
|
|
name.mLength = nsUnescapeCount(name.mStr);
|
1999-08-23 03:48:53 +00:00
|
|
|
|
1999-08-26 05:54:04 +00:00
|
|
|
Field* field = nsnull;
|
|
|
|
for (Field* i = gFieldTable; i->mName; ++i) {
|
|
|
|
if (name.EqualsIgnoreCase(i->mName)) {
|
|
|
|
field = i;
|
1999-08-23 03:48:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-08-26 05:54:04 +00:00
|
|
|
mFormat.AppendElement(field);
|
1999-08-23 03:48:53 +00:00
|
|
|
} while (*aFormatStr);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
2000-07-14 09:07:13 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::SetEncoding(const char *encoding)
|
|
|
|
{
|
|
|
|
mEncoding = encoding;
|
|
|
|
return(NS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetEncoding(char **encoding)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(encoding != nsnull, "null ptr");
|
|
|
|
if (! encoding)
|
|
|
|
return(NS_ERROR_NULL_POINTER);
|
|
|
|
|
|
|
|
if ((*encoding = nsXPIDLCString::Copy(mEncoding)) == nsnull)
|
|
|
|
return(NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
return(NS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult
|
2000-08-28 09:50:20 +00:00
|
|
|
nsHTTPIndexParser::ParseData(nsString* values, const char *baseStr, const char *encodingStr,
|
2000-08-28 04:24:49 +00:00
|
|
|
register char* aDataStr, nsIRDFResource *parentRes)
|
1999-08-23 03:48:53 +00:00
|
|
|
{
|
|
|
|
// Parse a "201" data line, using the field ordering specified in
|
|
|
|
// mFormat.
|
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
PRInt32 numFormats = mFormat.Count();
|
|
|
|
|
|
|
|
if (numFormats == 0) {
|
1999-08-23 03:48:53 +00:00
|
|
|
// Ignore if we haven't seen a format yet.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
nsresult rv = NS_OK;
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
nsCAutoString filename;
|
|
|
|
PRBool isDirType = PR_FALSE;
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
for (PRInt32 i = 0; i < numFormats; ++i) {
|
1999-08-23 03:48:53 +00:00
|
|
|
// If we've exhausted the data before we run out of fields, just
|
|
|
|
// bail.
|
|
|
|
if (! *aDataStr)
|
|
|
|
break;
|
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
while (*aDataStr && nsCRT::IsAsciiSpace(*aDataStr))
|
1999-08-23 03:48:53 +00:00
|
|
|
++aDataStr;
|
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
char *value = aDataStr;
|
1999-08-23 03:48:53 +00:00
|
|
|
|
|
|
|
if (*aDataStr == '"' || *aDataStr == '\'') {
|
|
|
|
// it's a quoted string. snarf everything up to the next quote character
|
|
|
|
const char quotechar = *(aDataStr++);
|
2000-08-28 04:24:49 +00:00
|
|
|
++value;
|
|
|
|
while (*aDataStr && *aDataStr != quotechar)
|
|
|
|
++aDataStr;
|
|
|
|
*aDataStr++ = '\0';
|
1999-08-23 03:48:53 +00:00
|
|
|
|
|
|
|
if (! aDataStr) {
|
|
|
|
NS_WARNING("quoted value not terminated");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// it's unquoted. snarf until we see whitespace.
|
2000-08-28 04:24:49 +00:00
|
|
|
value = aDataStr;
|
|
|
|
while (*aDataStr && (!nsCRT::IsAsciiSpace(*aDataStr)))
|
|
|
|
++aDataStr;
|
|
|
|
*aDataStr++ = '\0';
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
|
|
|
|
1999-08-26 05:54:04 +00:00
|
|
|
Field* field = NS_STATIC_CAST(Field*, mFormat.ElementAt(i));
|
2000-07-14 09:07:13 +00:00
|
|
|
if (field && field->mProperty == kHTTPIndex_Filename)
|
|
|
|
{
|
|
|
|
// don't unescape at this point, so that UnEscapeAndConvert() can
|
2000-08-28 04:24:49 +00:00
|
|
|
filename = value;
|
2000-07-14 09:07:13 +00:00
|
|
|
|
|
|
|
PRBool success = PR_FALSE;
|
|
|
|
|
|
|
|
nsAutoString entryuri;
|
2000-08-28 04:24:49 +00:00
|
|
|
|
|
|
|
if (gTextToSubURI)
|
2000-07-14 09:07:13 +00:00
|
|
|
{
|
|
|
|
PRUnichar *result = nsnull;
|
2000-08-28 04:24:49 +00:00
|
|
|
if (NS_SUCCEEDED(rv = gTextToSubURI->UnEscapeAndConvert(encodingStr, filename,
|
2000-07-14 23:21:48 +00:00
|
|
|
&result)) && (result))
|
2000-07-14 09:07:13 +00:00
|
|
|
{
|
2000-07-14 23:21:48 +00:00
|
|
|
if (nsCRT::strlen(result) > 0)
|
|
|
|
{
|
2000-08-28 04:24:49 +00:00
|
|
|
values[i].Assign(result);
|
2000-07-14 23:21:48 +00:00
|
|
|
success = PR_TRUE;
|
|
|
|
}
|
2000-07-14 09:07:13 +00:00
|
|
|
Recycle(result);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NS_WARNING("UnEscapeAndConvert error");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (success == PR_FALSE)
|
|
|
|
{
|
2000-07-14 23:21:48 +00:00
|
|
|
// if unsuccessfully at charset conversion, then
|
2000-08-28 04:24:49 +00:00
|
|
|
// just fallback to unescape'ing in-place
|
|
|
|
nsUnescape(value);
|
|
|
|
values[i].AssignWithConversion(value);
|
2000-07-14 09:07:13 +00:00
|
|
|
}
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
}
|
2000-07-14 09:07:13 +00:00
|
|
|
else
|
|
|
|
{
|
2000-08-28 04:24:49 +00:00
|
|
|
// unescape in-place
|
|
|
|
nsUnescape(value);
|
|
|
|
values[i].AssignWithConversion(value);
|
2000-07-14 09:07:13 +00:00
|
|
|
|
|
|
|
if (field && field->mProperty == kHTTPIndex_Filetype)
|
|
|
|
{
|
2000-08-28 04:24:49 +00:00
|
|
|
if (!nsCRT::strcasecmp(value, "directory"))
|
|
|
|
{
|
|
|
|
isDirType = PR_TRUE;
|
|
|
|
}
|
2000-07-14 09:07:13 +00:00
|
|
|
}
|
2000-04-17 05:07:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
// we found the filename; construct a resource for its entry
|
2000-08-28 04:24:49 +00:00
|
|
|
nsCAutoString entryuriC(baseStr);
|
|
|
|
entryuriC.Append(filename);
|
2000-07-14 09:07:13 +00:00
|
|
|
|
|
|
|
// if its a directory, make sure it ends with a trailing slash
|
2000-08-28 04:24:49 +00:00
|
|
|
if (isDirType == PR_TRUE)
|
2000-04-17 05:07:26 +00:00
|
|
|
{
|
2000-08-28 04:24:49 +00:00
|
|
|
entryuriC.Append('/');
|
2000-04-17 05:07:26 +00:00
|
|
|
}
|
2000-08-28 04:24:49 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFResource> entry;
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetResource(entryuriC, getter_AddRefs(entry));
|
1999-08-23 03:48:53 +00:00
|
|
|
|
|
|
|
// At this point, we'll (hopefully) have found the filename and
|
|
|
|
// constructed a resource for it, stored in entry. So now take a
|
|
|
|
// second pass through the values and add as statements to the RDF
|
|
|
|
// datasource.
|
|
|
|
if (entry && NS_SUCCEEDED(rv)) {
|
2000-08-28 09:50:20 +00:00
|
|
|
for (PRInt32 indx = 0; indx < numFormats; ++indx) {
|
|
|
|
Field* field = NS_STATIC_CAST(Field*, mFormat.ElementAt(indx));
|
|
|
|
// Field* field = NS_REINTERPRET_CAST(Field*, mFormat.ElementAt(indx));
|
1999-08-26 05:54:04 +00:00
|
|
|
if (! field)
|
1999-08-23 03:48:53 +00:00
|
|
|
continue;
|
|
|
|
|
2000-08-28 04:24:49 +00:00
|
|
|
nsCOMPtr<nsIRDFNode> nodeValue;
|
|
|
|
rv = (*field->mParse)(field->mProperty, values[indx], getter_AddRefs(nodeValue));
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) break;
|
2000-08-28 04:24:49 +00:00
|
|
|
if (nodeValue)
|
1999-11-10 23:51:10 +00:00
|
|
|
{
|
2000-08-28 04:24:49 +00:00
|
|
|
rv = mDataSource->Assert(entry, field->mProperty, nodeValue, PR_TRUE);
|
1999-11-10 23:51:10 +00:00
|
|
|
if (NS_FAILED(rv)) break;
|
|
|
|
}
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
2000-08-28 09:50:20 +00:00
|
|
|
// instead of
|
|
|
|
// rv = mDataSource->Assert(parentRes, kNC_Child, entry, PR_TRUE);
|
|
|
|
// if (NS_FAILED(rv)) return rv;
|
|
|
|
// defer insertion onto a timer so that the UI isn't starved
|
|
|
|
mHTTPIndex->AddElement(parentRes, kNC_Child, entry);
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-26 05:54:04 +00:00
|
|
|
nsresult
|
2000-08-28 09:50:20 +00:00
|
|
|
nsHTTPIndexParser::ParseLiteral(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult)
|
1999-08-26 05:54:04 +00:00
|
|
|
{
|
2000-08-30 05:26:56 +00:00
|
|
|
nsresult rv = NS_OK;
|
2000-08-28 09:50:20 +00:00
|
|
|
nsCOMPtr<nsIRDFLiteral> result;
|
1999-08-26 05:54:04 +00:00
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
if (arc == kHTTPIndex_Filename)
|
|
|
|
{
|
|
|
|
// strip off trailing slash(s) from directory names
|
|
|
|
PRInt32 len = aValue.Length();
|
|
|
|
if (len > 0)
|
|
|
|
{
|
|
|
|
if (aValue[len - 1] == '/')
|
|
|
|
{
|
|
|
|
nsAutoString temp(aValue);
|
|
|
|
temp.SetLength(len - 1);
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetLiteral(temp.GetUnicode(), getter_AddRefs(result));
|
2000-08-28 09:50:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-11-10 23:51:10 +00:00
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
if (!result)
|
|
|
|
{
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetLiteral(aValue.GetUnicode(), getter_AddRefs(result));
|
2000-08-28 09:50:20 +00:00
|
|
|
}
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-26 05:54:04 +00:00
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
return result->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) aResult);
|
1999-08-26 05:54:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-26 05:54:04 +00:00
|
|
|
nsresult
|
2000-08-28 09:50:20 +00:00
|
|
|
nsHTTPIndexParser::ParseDate(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult)
|
1999-08-26 05:54:04 +00:00
|
|
|
{
|
2000-10-12 08:08:39 +00:00
|
|
|
*aResult = nsnull;
|
1999-08-26 05:54:04 +00:00
|
|
|
PRTime tm;
|
2000-04-26 01:13:55 +00:00
|
|
|
nsCAutoString avalueC;
|
|
|
|
avalueC.AssignWithConversion(aValue);
|
|
|
|
PRStatus err = PR_ParseTimeString(avalueC, PR_FALSE, &tm);
|
1999-08-26 05:54:04 +00:00
|
|
|
if (err != PR_SUCCESS)
|
2000-10-12 08:08:39 +00:00
|
|
|
return NS_OK; // if unable to parse the date/time string, that's OK, just return no value
|
1999-08-26 05:54:04 +00:00
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIRDFDate> result;
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetDateLiteral(tm, getter_AddRefs(result));
|
1999-08-26 05:54:04 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-11 20:49:15 +00:00
|
|
|
return result->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) aResult);
|
1999-08-26 05:54:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-26 05:54:04 +00:00
|
|
|
nsresult
|
2000-08-28 09:50:20 +00:00
|
|
|
nsHTTPIndexParser::ParseInt(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult)
|
1999-08-26 05:54:04 +00:00
|
|
|
{
|
|
|
|
PRInt32 err;
|
|
|
|
PRInt32 i = aValue.ToInteger(&err);
|
|
|
|
if (nsresult(err) != NS_OK)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
if (i == 0)
|
|
|
|
{
|
|
|
|
// disregard "zero" values
|
|
|
|
*aResult = nsnull;
|
|
|
|
return(NS_OK);
|
|
|
|
}
|
|
|
|
|
1999-08-26 05:54:04 +00:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIRDFInt> result;
|
2000-09-06 22:33:58 +00:00
|
|
|
rv = gRDF->GetIntLiteral(i, getter_AddRefs(result));
|
1999-08-26 05:54:04 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-11 20:49:15 +00:00
|
|
|
return result->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) aResult);
|
1999-08-26 05:54:04 +00:00
|
|
|
}
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-08-23 03:48:53 +00:00
|
|
|
// nsHTTPIndex implementation
|
2000-02-08 01:17:27 +00:00
|
|
|
//
|
1999-08-23 03:48:53 +00:00
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
nsHTTPIndex::nsHTTPIndex()
|
2000-08-15 01:43:42 +00:00
|
|
|
: mContainer(nsnull)
|
2000-04-17 05:07:26 +00:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-11-13 07:36:28 +00:00
|
|
|
nsHTTPIndex::nsHTTPIndex(nsISupports* aContainer)
|
2000-08-15 01:43:42 +00:00
|
|
|
: mContainer(aContainer)
|
1999-08-23 03:48:53 +00:00
|
|
|
{
|
2000-04-17 05:07:26 +00:00
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsHTTPIndex::~nsHTTPIndex()
|
|
|
|
{
|
2000-08-15 01:43:42 +00:00
|
|
|
// note: these are NOT statics due to the native of nsHTTPIndex
|
|
|
|
// where it may or may not be treated as a singleton
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-08-15 01:43:42 +00:00
|
|
|
NS_IF_RELEASE(kNC_Child);
|
|
|
|
NS_IF_RELEASE(kNC_loading);
|
|
|
|
NS_IF_RELEASE(kTrueLiteral);
|
2000-08-28 09:50:20 +00:00
|
|
|
NS_IF_RELEASE(kFalseLiteral);
|
2000-07-26 23:46:56 +00:00
|
|
|
|
2000-11-02 07:34:46 +00:00
|
|
|
if (mTimer)
|
|
|
|
{
|
|
|
|
// be sure to cancel the timer, as it holds a
|
|
|
|
// weak reference back to nsHTTPIndex
|
|
|
|
mTimer->Cancel();
|
|
|
|
mTimer = nsnull;
|
|
|
|
}
|
2000-07-26 23:46:56 +00:00
|
|
|
|
2000-11-02 07:34:46 +00:00
|
|
|
mConnectionList = nsnull;
|
|
|
|
mNodeList = nsnull;
|
2000-08-15 01:43:42 +00:00
|
|
|
|
2000-11-02 07:34:46 +00:00
|
|
|
if (mDirRDF)
|
2000-08-15 01:43:42 +00:00
|
|
|
{
|
2000-11-02 07:34:46 +00:00
|
|
|
// UnregisterDataSource() may fail; just ignore errors
|
|
|
|
mDirRDF->UnregisterDataSource(this);
|
|
|
|
}
|
2000-04-17 05:07:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
2000-08-15 01:43:42 +00:00
|
|
|
nsHTTPIndex::CommonInit()
|
2000-04-17 05:07:26 +00:00
|
|
|
{
|
2000-08-15 01:43:42 +00:00
|
|
|
nsresult rv = NS_OK;
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-08-15 01:43:42 +00:00
|
|
|
// set initial/default encoding to ISO-8859-1 (not UTF-8)
|
|
|
|
mEncoding = "ISO-8859-1";
|
2000-07-14 09:07:13 +00:00
|
|
|
|
2000-11-02 07:34:46 +00:00
|
|
|
mDirRDF = do_GetService(kRDFServiceCID, &rv);
|
2000-08-15 01:43:42 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
|
2000-11-02 07:34:46 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
{
|
|
|
|
return(rv);
|
|
|
|
}
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-08-15 01:43:42 +00:00
|
|
|
if (NS_FAILED(rv = nsComponentManager::CreateInstance(kRDFInMemoryDataSourceCID,
|
|
|
|
nsnull, NS_GET_IID(nsIRDFDataSource), (void**) getter_AddRefs(mInner))))
|
|
|
|
{
|
|
|
|
return(rv);
|
|
|
|
}
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-11-02 07:34:46 +00:00
|
|
|
mDirRDF->GetResource(NC_NAMESPACE_URI "child", &kNC_Child);
|
|
|
|
mDirRDF->GetResource(NC_NAMESPACE_URI "loading", &kNC_loading);
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-11-02 07:34:46 +00:00
|
|
|
rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUCS2("true").GetUnicode(), &kTrueLiteral);
|
2000-08-28 09:50:20 +00:00
|
|
|
if (NS_FAILED(rv)) return(rv);
|
2000-11-02 07:34:46 +00:00
|
|
|
rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUCS2("false").GetUnicode(), &kFalseLiteral);
|
2000-08-28 09:50:20 +00:00
|
|
|
if (NS_FAILED(rv)) return(rv);
|
2000-07-26 23:46:56 +00:00
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
rv = NS_NewISupportsArray(getter_AddRefs(mConnectionList));
|
|
|
|
if (NS_FAILED(rv)) return(rv);
|
2000-08-15 01:43:42 +00:00
|
|
|
|
|
|
|
// note: don't register DS here
|
|
|
|
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTTPIndex::Init()
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// set initial/default encoding to ISO-8859-1 (not UTF-8)
|
|
|
|
mEncoding = "ISO-8859-1";
|
|
|
|
|
|
|
|
rv = CommonInit();
|
|
|
|
if (NS_FAILED(rv)) return(rv);
|
|
|
|
|
|
|
|
// (do this last) register this as a named data source with the RDF service
|
2000-11-02 07:34:46 +00:00
|
|
|
rv = mDirRDF->RegisterDataSource(this, PR_FALSE);
|
2000-08-15 01:43:42 +00:00
|
|
|
if (NS_FAILED(rv)) return(rv);
|
2000-07-26 23:46:56 +00:00
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
return(NS_OK);
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult
|
|
|
|
nsHTTPIndex::Init(nsIURI* aBaseURL)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aBaseURL != nsnull, "null ptr");
|
|
|
|
if (! aBaseURL)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
2000-08-15 01:43:42 +00:00
|
|
|
rv = CommonInit();
|
|
|
|
if (NS_FAILED(rv)) return(rv);
|
|
|
|
|
|
|
|
// note: don't register DS here (singleton case)
|
|
|
|
|
1999-08-25 01:32:40 +00:00
|
|
|
nsXPIDLCString url;
|
|
|
|
rv = aBaseURL->GetSpec(getter_Copies(url));
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-03-26 11:48:10 +00:00
|
|
|
mBaseURL.Assign(url);
|
1999-08-25 01:32:40 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult
|
1999-11-13 07:36:28 +00:00
|
|
|
nsHTTPIndex::Create(nsIURI* aBaseURL, nsISupports* aContainer, nsIHTTPIndex** aResult)
|
1999-08-23 03:48:53 +00:00
|
|
|
{
|
2000-08-15 01:43:42 +00:00
|
|
|
*aResult = nsnull;
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsHTTPIndex* result = new nsHTTPIndex(aContainer);
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2000-08-15 01:43:42 +00:00
|
|
|
nsresult rv = result->Init(aBaseURL);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
{
|
|
|
|
NS_ADDREF(result);
|
|
|
|
*aResult = result;
|
2000-04-17 05:07:26 +00:00
|
|
|
}
|
2000-08-15 01:43:42 +00:00
|
|
|
else
|
|
|
|
{
|
1999-08-23 03:48:53 +00:00
|
|
|
delete result;
|
|
|
|
}
|
2000-08-15 01:43:42 +00:00
|
|
|
return rv;
|
1999-08-23 03:48:53 +00:00
|
|
|
}
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
2000-07-26 23:46:56 +00:00
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsHTTPIndex, nsIHTTPIndex, nsIRDFDataSource);
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetBaseURL(char** _result)
|
|
|
|
{
|
|
|
|
*_result = nsXPIDLCString::Copy(mBaseURL);
|
|
|
|
if (! *_result)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetDataSource(nsIRDFDataSource** _result)
|
|
|
|
{
|
2000-04-17 05:07:26 +00:00
|
|
|
*_result = this;
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IF_ADDREF(*_result);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::CreateListener(nsIStreamListener** _result)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
rv = nsHTTPIndexParser::Create(this, mContainer, _result);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Clear this: we only need to pass it through once.
|
|
|
|
mContainer = nsnull;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
|
|
|
|
// rjc: isWellknownContainerURI() decides whether a URI is a container for which,
|
|
|
|
// when asked (say, by the template builder), we'll make a network connection
|
|
|
|
// to get its contents. For the moment, all we speak is ftp:// URLs, even though
|
|
|
|
// a) we can get "http-index" mimetypes for really anything
|
|
|
|
// b) we could easily handle file:// URLs here
|
|
|
|
// Q: Why don't we?
|
|
|
|
// A: The file system datasource ("rdf:file"); at some point, the two
|
|
|
|
// should be perhaps united. Until then, we can't aggregate both
|
|
|
|
// "rdf:file" and "http-index" (such as with bookmarks) because we'd
|
|
|
|
// get double the # of answers we really want... also, "rdf:file" is
|
|
|
|
// less expensive in terms of both memory usage as well as speed
|
|
|
|
|
|
|
|
static const char kFTPProtocol[] = "ftp://";
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsHTTPIndex::isWellknownContainerURI(nsIRDFResource *r)
|
|
|
|
{
|
|
|
|
PRBool isContainerFlag = PR_FALSE;
|
|
|
|
const char *uri = nsnull;
|
|
|
|
|
|
|
|
r->GetValueConst(&uri);
|
|
|
|
if ((uri) && (!strncmp(uri, kFTPProtocol, sizeof(kFTPProtocol) - 1)))
|
|
|
|
{
|
|
|
|
if (uri[strlen(uri)-1] == '/')
|
|
|
|
{
|
|
|
|
isContainerFlag = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(isContainerFlag);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-04-17 05:22:50 +00:00
|
|
|
nsHTTPIndex::GetURI(char * *uri)
|
2000-04-17 05:07:26 +00:00
|
|
|
{
|
2000-04-17 05:22:50 +00:00
|
|
|
NS_PRECONDITION(uri != nsnull, "null ptr");
|
|
|
|
if (! uri)
|
|
|
|
return(NS_ERROR_NULL_POINTER);
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-04-17 05:22:50 +00:00
|
|
|
if ((*uri = nsXPIDLCString::Copy("rdf:httpindex")) == nsnull)
|
|
|
|
return(NS_ERROR_OUT_OF_MEMORY);
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-04-17 05:22:50 +00:00
|
|
|
return(NS_OK);
|
2000-04-17 05:07:26 +00:00
|
|
|
}
|
|
|
|
|
2000-04-17 05:22:50 +00:00
|
|
|
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetSource(nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue,
|
|
|
|
nsIRDFResource **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
*_retval = nsnull;
|
|
|
|
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->GetSource(aProperty, aTarget, aTruthValue, _retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue,
|
|
|
|
nsISimpleEnumerator **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->GetSources(aProperty, aTarget, aTruthValue, _retval);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rv = NS_NewEmptyEnumerator(_retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBool aTruthValue,
|
|
|
|
nsIRDFNode **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
*_retval = nsnull;
|
|
|
|
|
|
|
|
if (isWellknownContainerURI(aSource) && (aProperty == kNC_Child) && (aTruthValue))
|
|
|
|
{
|
|
|
|
// fake out the generic builder (i.e. return anything in this case)
|
|
|
|
// so that search containers never appear to be empty
|
|
|
|
NS_IF_ADDREF(aSource);
|
|
|
|
*_retval = aSource;
|
|
|
|
return(NS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->GetTarget(aSource, aProperty, aTruthValue, _retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBool aTruthValue,
|
|
|
|
nsISimpleEnumerator **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
|
2000-07-26 23:46:56 +00:00
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->GetTargets(aSource, aProperty, aTruthValue, _retval);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rv = NS_NewEmptyEnumerator(_retval);
|
|
|
|
}
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
if (isWellknownContainerURI(aSource) && (aProperty == kNC_Child))
|
|
|
|
{
|
|
|
|
PRBool doNetworkRequest = PR_TRUE;
|
|
|
|
if (NS_SUCCEEDED(rv) && (_retval))
|
|
|
|
{
|
|
|
|
// check and see if we already have data for the search in question;
|
2000-07-26 23:46:56 +00:00
|
|
|
// if we do, don't bother doing the search again
|
2000-04-17 05:07:26 +00:00
|
|
|
PRBool hasResults = PR_FALSE;
|
2000-07-26 23:46:56 +00:00
|
|
|
if (NS_SUCCEEDED((*_retval)->HasMoreElements(&hasResults)) &&
|
|
|
|
(hasResults == PR_TRUE))
|
2000-04-17 05:07:26 +00:00
|
|
|
{
|
|
|
|
doNetworkRequest = PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
2000-07-26 23:46:56 +00:00
|
|
|
|
|
|
|
// Note: if we need to do a network request, do it out-of-band
|
|
|
|
// (because the XUL template builder isn't re-entrant)
|
|
|
|
// by using a global connection list and an immediately-firing timer
|
|
|
|
|
|
|
|
if ((doNetworkRequest == PR_TRUE) && (mConnectionList))
|
2000-04-17 05:07:26 +00:00
|
|
|
{
|
2000-07-26 23:46:56 +00:00
|
|
|
PRInt32 connectionIndex = mConnectionList->IndexOf(aSource);
|
|
|
|
if (connectionIndex < 0)
|
|
|
|
{
|
|
|
|
// add aSource into list of connections to make
|
|
|
|
mConnectionList->AppendElement(aSource);
|
|
|
|
|
|
|
|
// if we don't have a timer about to fire, create one
|
|
|
|
// which should fire as soon as possible (out-of-band)
|
|
|
|
if (!mTimer)
|
|
|
|
{
|
2000-09-13 23:57:52 +00:00
|
|
|
mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
2000-07-26 23:46:56 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer");
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
{
|
|
|
|
mTimer->Init(nsHTTPIndex::FireTimer, this, 1,
|
|
|
|
NS_PRIORITY_LOWEST, NS_TYPE_ONE_SHOT);
|
|
|
|
// Note: don't addref "this" as we'll cancel the
|
|
|
|
// timer in the httpIndex destructor
|
2000-08-28 09:50:20 +00:00
|
|
|
}
|
2000-07-26 23:46:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-07-26 23:46:56 +00:00
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::AddElement(nsIRDFResource *parent, nsIRDFResource *prop, nsIRDFNode *child)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (!mNodeList)
|
|
|
|
{
|
|
|
|
rv = NS_NewISupportsArray(getter_AddRefs(mNodeList));
|
|
|
|
if (NS_FAILED(rv)) return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
// order required: parent, prop, then child
|
|
|
|
mNodeList->AppendElement(parent);
|
|
|
|
mNodeList->AppendElement(prop);
|
|
|
|
mNodeList->AppendElement(child);
|
|
|
|
|
|
|
|
if (!mTimer)
|
|
|
|
{
|
2000-09-13 23:57:52 +00:00
|
|
|
mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
2000-08-28 09:50:20 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer");
|
|
|
|
if (NS_FAILED(rv)) return(rv);
|
|
|
|
|
2000-08-30 05:26:56 +00:00
|
|
|
mTimer->Init(nsHTTPIndex::FireTimer, this, 10,
|
2000-08-28 09:50:20 +00:00
|
|
|
NS_PRIORITY_LOWEST, NS_TYPE_ONE_SHOT);
|
|
|
|
// Note: don't addref "this" as we'll cancel the
|
|
|
|
// timer in the httpIndex destructor
|
|
|
|
}
|
|
|
|
|
|
|
|
return(NS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-07-26 23:46:56 +00:00
|
|
|
void
|
|
|
|
nsHTTPIndex::FireTimer(nsITimer* aTimer, void* aClosure)
|
|
|
|
{
|
|
|
|
nsHTTPIndex *httpIndex = NS_STATIC_CAST(nsHTTPIndex *, aClosure);
|
|
|
|
if (!httpIndex) return;
|
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
// don't return out of this loop as mTimer may need to be cancelled afterwards
|
|
|
|
PRBool refireTimer = PR_FALSE;
|
|
|
|
|
|
|
|
PRUint32 numItems = 0;
|
|
|
|
PRInt32 loop;
|
2000-07-26 23:46:56 +00:00
|
|
|
if (httpIndex->mConnectionList)
|
|
|
|
{
|
|
|
|
httpIndex->mConnectionList->Count(&numItems);
|
|
|
|
if (numItems > 0)
|
|
|
|
{
|
2000-08-28 09:50:20 +00:00
|
|
|
// Note: process ALL outstanding connection requests;
|
2000-07-26 23:46:56 +00:00
|
|
|
for (loop=((PRInt32)numItems)-1; loop>=0; loop--)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsISupports> isupports;
|
|
|
|
httpIndex->mConnectionList->GetElementAt((PRUint32)loop, getter_AddRefs(isupports));
|
|
|
|
httpIndex->mConnectionList->RemoveElementAt((PRUint32)loop);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFResource> aSource;
|
|
|
|
if (isupports) aSource = do_QueryInterface(isupports);
|
|
|
|
const char *uri = nsnull;
|
|
|
|
if (aSource) aSource->GetValueConst(&uri);
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIURI> url;
|
|
|
|
if (uri)
|
|
|
|
{
|
|
|
|
rv = NS_NewURI(getter_AddRefs(url), uri);
|
|
|
|
}
|
2000-04-17 05:07:26 +00:00
|
|
|
nsCOMPtr<nsIChannel> channel;
|
2000-07-26 23:46:56 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && (url))
|
|
|
|
{
|
|
|
|
rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull);
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIStreamListener> listener;
|
|
|
|
if (NS_SUCCEEDED(rv) && (channel))
|
|
|
|
{
|
|
|
|
rv = httpIndex->CreateListener(getter_AddRefs(listener));
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rv) && (listener))
|
|
|
|
{
|
2001-02-21 20:38:08 +00:00
|
|
|
rv = channel->AsyncOpen(listener, aSource);
|
2000-07-26 23:46:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-08-28 09:50:20 +00:00
|
|
|
httpIndex->mConnectionList->Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (httpIndex->mNodeList)
|
|
|
|
{
|
|
|
|
httpIndex->mNodeList->Count(&numItems);
|
|
|
|
if (numItems > 0)
|
|
|
|
{
|
|
|
|
// account for order required: src, prop, then target
|
|
|
|
numItems /=3;
|
|
|
|
if (numItems > 10) numItems = 10;
|
|
|
|
|
|
|
|
for (loop=0; loop<(PRInt32)numItems; loop++)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsISupports> isupports;
|
|
|
|
httpIndex->mNodeList->GetElementAt((PRUint32)0, getter_AddRefs(isupports));
|
|
|
|
httpIndex->mNodeList->RemoveElementAt((PRUint32)0);
|
|
|
|
nsCOMPtr<nsIRDFResource> src;
|
|
|
|
if (isupports) src = do_QueryInterface(isupports);
|
|
|
|
|
|
|
|
httpIndex->mNodeList->GetElementAt((PRUint32)0, getter_AddRefs(isupports));
|
|
|
|
httpIndex->mNodeList->RemoveElementAt((PRUint32)0);
|
|
|
|
nsCOMPtr<nsIRDFResource> prop;
|
|
|
|
if (isupports) prop = do_QueryInterface(isupports);
|
|
|
|
|
|
|
|
httpIndex->mNodeList->GetElementAt((PRUint32)0, getter_AddRefs(isupports));
|
|
|
|
httpIndex->mNodeList->RemoveElementAt((PRUint32)0);
|
|
|
|
nsCOMPtr<nsIRDFNode> target;
|
|
|
|
if (isupports) target = do_QueryInterface(isupports);
|
|
|
|
|
|
|
|
if (src && prop && target)
|
|
|
|
{
|
2000-08-28 09:51:42 +00:00
|
|
|
if (prop.get() == httpIndex->kNC_loading)
|
2000-08-28 09:50:20 +00:00
|
|
|
{
|
|
|
|
httpIndex->Unassert(src, prop, target);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
httpIndex->Assert(src, prop, target, PR_TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-07-26 23:46:56 +00:00
|
|
|
}
|
2000-04-17 05:07:26 +00:00
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
// check both lists to see if the timer needs to continue firing
|
|
|
|
if (httpIndex->mConnectionList)
|
|
|
|
{
|
|
|
|
httpIndex->mConnectionList->Count(&numItems);
|
|
|
|
if (numItems > 0)
|
|
|
|
{
|
|
|
|
refireTimer = PR_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
httpIndex->mConnectionList->Clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (httpIndex->mNodeList)
|
|
|
|
{
|
|
|
|
httpIndex->mNodeList->Count(&numItems);
|
|
|
|
if (numItems > 0)
|
|
|
|
{
|
|
|
|
refireTimer = PR_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
httpIndex->mNodeList->Clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-30 05:26:56 +00:00
|
|
|
// be sure to cancel the timer, as it holds a
|
|
|
|
// weak reference back to nsHTTPIndex
|
|
|
|
httpIndex->mTimer->Cancel();
|
|
|
|
httpIndex->mTimer = nsnull;
|
|
|
|
|
2000-08-28 09:50:20 +00:00
|
|
|
// after firing off any/all of the connections be sure
|
|
|
|
// to cancel the timer if we don't need to refire it
|
|
|
|
if (refireTimer == PR_TRUE)
|
|
|
|
{
|
2000-09-13 23:57:52 +00:00
|
|
|
httpIndex->mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
2000-08-30 05:26:56 +00:00
|
|
|
if (httpIndex->mTimer)
|
|
|
|
{
|
|
|
|
httpIndex->mTimer->Init(nsHTTPIndex::FireTimer, aClosure, 10,
|
|
|
|
NS_PRIORITY_LOWEST, NS_TYPE_ONE_SHOT);
|
|
|
|
// Note: don't addref "this" as we'll cancel the
|
|
|
|
// timer in the httpIndex destructor
|
|
|
|
}
|
2000-04-17 05:07:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget,
|
|
|
|
PRBool aTruthValue)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->Unassert(aSource, aProperty, aTarget);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::Change(nsIRDFResource *aSource, nsIRDFResource *aProperty,
|
|
|
|
nsIRDFNode *aOldTarget, nsIRDFNode *aNewTarget)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::Move(nsIRDFResource *aOldSource, nsIRDFResource *aNewSource,
|
|
|
|
nsIRDFResource *aProperty, nsIRDFNode *aTarget)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty,
|
|
|
|
nsIRDFNode *aTarget, PRBool aTruthValue, PRBool *_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, _retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::AddObserver(nsIRDFObserver *aObserver)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->AddObserver(aObserver);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::RemoveObserver(nsIRDFObserver *aObserver)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->RemoveObserver(aObserver);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
2000-07-19 03:58:25 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, PRBool *result)
|
|
|
|
{
|
|
|
|
if (!mInner) {
|
|
|
|
*result = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return mInner->HasArcIn(aNode, aArc, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, PRBool *result)
|
|
|
|
{
|
|
|
|
if (aArc == kNC_Child && isWellknownContainerURI(aSource)) {
|
|
|
|
*result = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mInner) {
|
|
|
|
return mInner->HasArcOut(aSource, aArc, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
*result = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-04-17 05:07:26 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->ArcLabelsIn(aNode, _retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
*_retval = nsnull;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupportsArray> array;
|
|
|
|
rv = NS_NewISupportsArray(getter_AddRefs(array));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (isWellknownContainerURI(aSource))
|
|
|
|
{
|
|
|
|
array->AppendElement(kNC_Child);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> anonArcs;
|
|
|
|
rv = mInner->ArcLabelsOut(aSource, getter_AddRefs(anonArcs));
|
|
|
|
PRBool hasResults = PR_TRUE;
|
2000-07-19 03:58:25 +00:00
|
|
|
while (NS_SUCCEEDED(rv) &&
|
|
|
|
NS_SUCCEEDED(anonArcs->HasMoreElements(&hasResults)) &&
|
|
|
|
hasResults == PR_TRUE)
|
2000-04-17 05:07:26 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsISupports> anonArc;
|
|
|
|
if (NS_FAILED(anonArcs->GetNext(getter_AddRefs(anonArc))))
|
|
|
|
break;
|
|
|
|
array->AppendElement(anonArc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsISimpleEnumerator* result = new nsArrayEnumerator(array);
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
NS_ADDREF(result);
|
|
|
|
*_retval = result;
|
|
|
|
return(NS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetAllResources(nsISimpleEnumerator **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->GetAllResources(_retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetAllCommands(nsIRDFResource *aSource, nsIEnumerator **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->GetAllCommands(aSource, _retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::IsCommandEnabled(nsISupportsArray *aSources, nsIRDFResource *aCommand,
|
|
|
|
nsISupportsArray *aArguments, PRBool *_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->IsCommandEnabled(aSources, aCommand, aArguments, _retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::DoCommand(nsISupportsArray *aSources, nsIRDFResource *aCommand,
|
|
|
|
nsISupportsArray *aArguments)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->DoCommand(aSources, aCommand, aArguments);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTTPIndex::GetAllCmds(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
if (mInner)
|
|
|
|
{
|
|
|
|
rv = mInner->GetAllCmds(aSource, _retval);
|
|
|
|
}
|
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-08-23 03:48:53 +00:00
|
|
|
// nsDirectoryViewerFactory
|
|
|
|
//
|
|
|
|
nsDirectoryViewerFactory::nsDirectoryViewerFactory()
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
nsDirectoryViewerFactory::~nsDirectoryViewerFactory()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-02-08 01:17:27 +00:00
|
|
|
NS_IMPL_ISUPPORTS1(nsDirectoryViewerFactory, nsIDocumentLoaderFactory);
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsDirectoryViewerFactory::CreateInstance(const char *aCommand,
|
|
|
|
nsIChannel* aChannel,
|
|
|
|
nsILoadGroup* aLoadGroup,
|
|
|
|
const char* aContentType,
|
1999-11-15 07:29:23 +00:00
|
|
|
nsISupports* aContainer,
|
1999-08-23 03:48:53 +00:00
|
|
|
nsISupports* aExtraInfo,
|
|
|
|
nsIStreamListener** aDocListenerResult,
|
|
|
|
nsIContentViewer** aDocViewerResult)
|
|
|
|
{
|
2000-01-13 23:25:25 +00:00
|
|
|
// This is where we shunt the HTTP/Index stream into our datasource,
|
|
|
|
// and open the directory viewer XUL file as the content stream to
|
|
|
|
// load in its place.
|
1999-08-23 03:48:53 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Create a dummy loader that will load a stub XUL document.
|
|
|
|
nsCOMPtr<nsIDocumentLoaderFactory> factory;
|
2000-09-13 23:57:52 +00:00
|
|
|
rv = nsComponentManager::CreateInstance(NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=text/xul",
|
1999-08-23 03:48:53 +00:00
|
|
|
nsnull,
|
2000-01-11 20:49:15 +00:00
|
|
|
NS_GET_IID(nsIDocumentLoaderFactory),
|
1999-08-23 03:48:53 +00:00
|
|
|
getter_AddRefs(factory));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
2000-04-19 21:42:30 +00:00
|
|
|
rv = NS_NewURI(getter_AddRefs(uri), "chrome://communicator/content/directory/directory.xul");
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIChannel> channel;
|
2000-03-29 03:58:50 +00:00
|
|
|
rv = NS_OpenURI(getter_AddRefs(channel), uri, nsnull, aLoadGroup);
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStreamListener> listener;
|
|
|
|
rv = factory->CreateInstance("view", channel, aLoadGroup, "text/xul",
|
|
|
|
aContainer, aExtraInfo, getter_AddRefs(listener),
|
|
|
|
aDocViewerResult);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2001-02-21 20:38:08 +00:00
|
|
|
rv = channel->AsyncOpen(listener, nsnull);
|
1999-08-23 03:48:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Create an HTTPIndex object so that we can stuff it into the script context
|
|
|
|
nsCOMPtr<nsIURI> baseuri;
|
|
|
|
rv = aChannel->GetURI(getter_AddRefs(baseuri));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIHTTPIndex> httpindex;
|
|
|
|
rv = nsHTTPIndex::Create(baseuri, aContainer, getter_AddRefs(httpindex));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Now shanghai the stream into our http-index parsing datasource
|
|
|
|
// wrapper beastie.
|
|
|
|
rv = httpindex->CreateListener(aDocListenerResult);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-08-24 04:16:33 +00:00
|
|
|
// addref the nsIHTTPIndex so that it'll live long enough to get
|
|
|
|
// added to the embedder's script global object; this happens when
|
|
|
|
// the stream's OnStartRequest() is called. (We can feel safe that
|
|
|
|
// this'll happen because of the flow-of-control in nsWebShell.cpp)
|
|
|
|
nsIHTTPIndex* dummy = httpindex;
|
|
|
|
NS_ADDREF(dummy);
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-10 23:51:10 +00:00
|
|
|
|
|
|
|
|
1999-08-23 03:48:53 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-15 07:29:23 +00:00
|
|
|
nsDirectoryViewerFactory::CreateInstanceForDocument(nsISupports* aContainer,
|
1999-08-23 03:48:53 +00:00
|
|
|
nsIDocument* aDocument,
|
|
|
|
const char *aCommand,
|
|
|
|
nsIContentViewer** aDocViewerResult)
|
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("didn't expect to get here");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|