This commit is contained in:
valeski%netscape.com 1999-07-22 19:11:33 +00:00
Родитель 40f2c7b9c9
Коммит 81f815e9aa
12 изменённых файлов: 942 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,33 @@
#! gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
MODULE = streamconv
include $(DEPTH)/config/autoconf.mk
DIRS= \
public \
src \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,27 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ..\..
MODULE = streamconv
DIRS= \
public \
src \
$(NULL)
include <$(DEPTH)\config\rules.mak>

Просмотреть файл

@ -0,0 +1,41 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
MODULE = streamconv
XPIDL_MODULE = necko_stream_converter
XPIDLSRCS = \
nsIStreamConverter.idl \
nsIStreamConverterService.idl \
$(NULL)
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
# hack until necko lands
ifndef NECKO
PUBLIC = $(DEPTH)/netwerk/dist/include
endif
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,39 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
MODULE = streamconv
DEPTH = ..\..\..
// temporary, until we land:
!ifndef NECKO
include <$(DEPTH)/config/config.mak>
PUBLIC = $(DEPTH)\netwerk\dist\include
!endif
XPIDLSRCS = \
.\nsIStreamConverter.idl \
.\nsIStreamConverterService.idl \
$(NULL)
include <$(DEPTH)/config/rules.mak>
$(DEPTH)\netwerk\dist\include:
-mkdir $(DEPTH)\netwerk\dist
-mkdir $(DEPTH)\netwerk\dist\include

Просмотреть файл

@ -0,0 +1,50 @@
#include "nsIStreamListener.idl"
#include "nsIInputStream.idl"
#include "nsIURI.idl"
// There are three ways to use a stream converter:
// 1. SYNCRONOUS. Stream to Stream.
// You can supply the service with a stream of type X
// and it will convert it to your desired output type and return
// a converted stream to you.
//
// 2. ASYNCRONOUS. Stream to nsIStreamListener
// You can supply the service with a stream of type X
// and it will convert it to your desired output type and return
// converted data to you via the nsIStreamListener you passed in
// by calling its nsIStreamListener::OnDataAvailable() method.
//
// 3. ASYNCRONOUS. nsIStreamListener to nsIStreamListener
// You can supply data directly to the service by calling it's
// nsIStreamListener::OnDataAvailable() method. It will then
// convert that data from type X to your desired output type and
// return converted data to you via the nsIStreamListener you passed
// in by calling its OnDataAvailable() method.
[scriptable, uuid(46484B30-3BD2-11d3-A16C-0050041CAF44)]
interface nsIStreamConverter : nsIStreamListener {
// SYNCRONOUS VERSION
// Converts aFromStream of type aFromType, to a resulting stream of type aToType.
// Use this when you have a stream as input.
nsIInputStream Convert(in nsIInputStream aFromStream,
in wstring aFromType,
in wstring aToType);
// ASYNCRONOUS VERSIONS
// Converts aFromStream of type aFromType, to type aToType pushing the converted
// data out to the caller via aListener::OnDataAvailable().
void AsyncConvertStream(in nsIInputStream aFromStream,
in wstring aFromType,
in wstring aToType,
in nsIStreamListener aListener);
// Converts data arriving via the service's nsIStreamListener::OnDataAvailable() method
// from type aFromType to aToType pushing the converted data out to the caller via
// aListener::OnDataAvailable().
void AsyncConvertData(in wstring aFromType,
in wstring aToType,
in nsIStreamListener aListener);
};

Просмотреть файл

@ -0,0 +1,25 @@
#include "nsIStreamConverter.idl"
// The nsIStreamConverterService acts as a higher level stream converter factory
// responsible for locating and creating the appropriate stream converters in order
// to convert data from type X to type Z. It is responsible for any intermediary
// conversion required in order to get from X to Z, if direct conversion is not
// possible.
//
%{C++
#define NS_STREAMCONVERTERSERVICE_CID \
{ /* 892FFEB0-3F80-11d3-A16C-0050041CAF44 */ \
0x892ffeb0, \
0x3f80, \
0x11d3, \
{0xa1, 0x6c, 0x00, 0x50, 0x04, 0x1c, 0xaf, 0x44} \
}
%}
[scriptable, uuid(00362090-3B97-11d3-A16C-0050041CAF44)]
interface nsIStreamConverterService : nsIStreamConverter {
// no methods. only implements nsIStreamConverter
};

Просмотреть файл

@ -0,0 +1,46 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
MODULE = streamconv
LIBRARY_NAME = streamconv
IS_COMPONENT = 1
include $(DEPTH)/config/autoconf.mk
CPPSRCS = \
nsStreamConverterService.cpp \
nsStreamConvServiceFactory.cpp \
$(NULL)
include $(topsrcdir)/config/config.mk
REQUIRES = xpcom
# hack until necko lands
ifndef NECKO
PUBLIC = $(DEPTH)/netwerk/dist/include
endif
TARGET = $(LIBARY)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,56 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ..\..\..
// temporary, until we land:
!ifndef NECKO
include <$(DEPTH)/config/config.mak>
PUBLIC = $(DEPTH)\netwerk\dist\include
!endif
MODULE = streamconv
IS_COMPONENT=1
MAKE_OBJ_TYPE=DLL
DLLNAME=streamconv
DLL=.\$(OBJDIR)\$(DLLNAME).dll
LLIBS= $(LLIBS) \
$(DIST)\lib\xpcom.lib \
$(NULL)
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
CPP_OBJS = \
.\$(OBJDIR)\nsStreamConverterService.obj \
.\$(OBJDIR)\nsStreamConvServiceFactory.obj \
$(NULL)
LOCAL_INCLUDES=-I.
INCLUDES = $(LOCAL_INCLUDES)
INCS = $(INCS) \
-I$(DEPTH)\dist\include \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) $(DLL) $(DIST)\bin\components
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

Просмотреть файл

@ -0,0 +1,178 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsCOMPtr.h"
#include "nscore.h"
#include "nsIStreamConverterService.h"
#include "nsStreamConverterService.h"
#include "nsStreamConvServiceFactory.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsXPComFactory.h"
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kStreamConvServiceCID, NS_STREAMCONVERTERSERVICE_CID);
////////////////////////////////////////////////////////////////////////
nsStreamConvServiceFactory::nsStreamConvServiceFactory(const nsCID &aClass,
const char* className,
const char* progID)
: mClassID(aClass), mClassName(className), mProgID(progID)
{
NS_INIT_REFCNT();
}
nsStreamConvServiceFactory::~nsStreamConvServiceFactory()
{
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
}
NS_IMETHODIMP
nsStreamConvServiceFactory::QueryInterface(const nsIID &aIID, void **aResult)
{
if (! aResult)
return NS_ERROR_NULL_POINTER;
// Always NULL result, in case of failure
*aResult = nsnull;
if (aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
*aResult = NS_STATIC_CAST(nsISupports*, this);
AddRef();
return NS_OK;
} else if (aIID.Equals(kIFactoryIID)) {
*aResult = NS_STATIC_CAST(nsIFactory*, this);
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsStreamConvServiceFactory);
NS_IMPL_RELEASE(nsStreamConvServiceFactory);
NS_IMETHODIMP
nsStreamConvServiceFactory::CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult)
{
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
*aResult = nsnull;
nsresult rv = NS_OK;
nsISupports *inst = nsnull;
if (mClassID.Equals(kStreamConvServiceCID)) {
nsStreamConverterService *service = new nsStreamConverterService();
if (!service) return NS_ERROR_OUT_OF_MEMORY;
rv = service->Init();
if (NS_FAILED(rv)) {
delete service;
return rv;
}
service->QueryInterface(nsCOMTypeInfo<nsISupports>::GetIID(), (void**)&inst);
}
else {
return NS_ERROR_NO_INTERFACE;
}
if (!inst)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(inst);
*aResult = inst;
NS_RELEASE(inst);
return rv;
}
nsresult nsStreamConvServiceFactory::LockFactory(PRBool aLock)
{
// Not implemented in simplest case.
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// return the proper factory to the caller
extern "C" PR_IMPLEMENT(nsresult)
NSGetFactory(nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
{
if (! aFactory)
return NS_ERROR_NULL_POINTER;
nsStreamConvServiceFactory* factory = new nsStreamConvServiceFactory(aClass, aClassName, aProgID);
if (factory == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(factory);
*aFactory = factory;
return NS_OK;
}
extern "C" PR_IMPLEMENT(nsresult)
NSRegisterSelf(nsISupports* aServMgr , const char* aPath)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIComponentManager, compMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterComponent(kStreamConvServiceCID,
"Stream Converter Service",
"component:||netscape|streamConverters",
aPath, PR_TRUE, PR_TRUE);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
extern "C" PR_IMPLEMENT(nsresult)
NSUnregisterSelf(nsISupports* aServMgr, const char* aPath)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIComponentManager, compMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->UnregisterComponent(kStreamConvServiceCID, aPath);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,44 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIFactory.h"
class nsStreamConvServiceFactory : public nsIFactory
{
public:
nsStreamConvServiceFactory(const nsCID &aClass, const char* className, const char* progID);
// nsISupports methods
NS_DECL_ISUPPORTS
// nsIFactory methods
NS_IMETHOD CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
protected:
virtual ~nsStreamConvServiceFactory();
protected:
nsCID mClassID;
const char* mClassName;
const char* mProgID;
};

Просмотреть файл

@ -0,0 +1,328 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsStreamConverterService.h"
#include "nsIServiceManager.h"
#include "nsString2.h"
#include "nsIAtom.h"
#include "nsDeque.h"
////////////////////////////////////////////////////////////
// nsISupports methods
NS_IMPL_ISUPPORTS(nsStreamConverterService, nsCOMTypeInfo<nsIStreamConverterService>::GetIID());
////////////////////////////////////////////////////////////
// nsIStreamConverterService methods
// Builds the graph represented as an adjacency list (and built up in
// memory using an nsHashtable and nsVoidArray combination).
//
// RegisterConverter takes the given PROGID and parses a single edge from it.
// An edge in this case is comprised of a FROM and TO MIME type combination. The
// edge is then inserted into the service's adjacency list.
// It then turns around and registers the PROGID and the converter with the service
// manager; the true registration mechanism.
//
// PROGID format:
// component://netscape/strmconv?from=text/html?to=text/plain
// XXX curently we only handle a single from and to combo, we should repeat the
// XXX registration process for any series of from-to combos.
// XXX can use nsTokenizer for this.
//
typedef struct _tableData {
nsHashKey *key;
nsString2 *keyString;
void *data;
} tableData;
NS_IMETHODIMP
nsStreamConverterService::RegisterConverter(const char *aProgID, nsISupports *aConverter) {
NS_ASSERTION(aProgID, "progid required");
nsresult rv;
// first parse out the FROM and TO MIME-types being registered.
nsString2 ProgIDStr(aProgID, eOneByte);
PRInt32 fromLoc = ProgIDStr.Find("from=") + 5;
PRInt32 toLoc = ProgIDStr.Find("to=") + 3;
if (-1 == fromLoc || -1 == toLoc ) return NS_ERROR_FAILURE;
nsString2 fromStr(eOneByte), toStr(eOneByte);
PRInt32 fromLen = toLoc - 4 - fromLoc;
PRInt32 toLen = ProgIDStr.Length() - toLoc;
ProgIDStr.Mid(fromStr, fromLoc, fromLen);
ProgIDStr.Mid(toStr, toLoc, toLen);
// Each MIME-type is a vertex in the graph, so first lets make sure
// each MIME-type is represented as a key in our hashtable.
nsStringKey *fromKey = new nsStringKey(fromStr.GetBuffer());
nsStringKey *toKey = new nsStringKey(toStr.GetBuffer());
tableData *edges = (tableData*)mAdjacencyList->Get(fromKey);
if (!edges) {
// There is no fromStr vertex, create one.
tableData *data = new tableData;
if (!data) return NS_ERROR_OUT_OF_MEMORY;
data->key = fromKey;
data->keyString = new nsString2(fromStr.GetBuffer());
data->data = new nsVoidArray();
if (!data->data) return NS_ERROR_OUT_OF_MEMORY;
mAdjacencyList->Put(fromKey, data);
}
edges = (tableData*)mAdjacencyList->Get(toKey);
if (!edges) {
// There is no toStr vertex, create one.
tableData *data = new tableData;
if (!data) return NS_ERROR_OUT_OF_MEMORY;
data->key = toKey;
data->keyString = new nsString2(toStr.GetBuffer());
data->data = new nsVoidArray();
if (!data->data) return NS_ERROR_OUT_OF_MEMORY;
mAdjacencyList->Put(toKey, data);
}
// Now we know the FROM and TO types are represented as keys in the hashtable.
// Let's "connect" the verticies, making an edge.
edges = (tableData*)mAdjacencyList->Get(fromKey);
NS_ASSERTION(edges, "something wrong in adjacency list construction");
nsIAtom *vertex = NS_NewAtom(toStr);
if (!vertex) return NS_ERROR_OUT_OF_MEMORY;
nsVoidArray *adjacencyList = (nsVoidArray*)edges->data;
adjacencyList->AppendElement(vertex);
// We're done building our adjacency list, let's move onto the service
// manager registration.
rv = nsServiceManager::RegisterService(aProgID, aConverter);
return rv;
}
////////////////////////////////////////////////////////////
// nsStreamConverterService methods
nsStreamConverterService::nsStreamConverterService() {
NS_INIT_REFCNT();
}
nsStreamConverterService::~nsStreamConverterService() {
//mAdjacencyList->Enumerate(DeleteEntry, nsnull);
//mAdjacencyList->Reset();
delete mAdjacencyList;
}
nsresult
nsStreamConverterService::Init() {
mAdjacencyList = new nsHashtable();
if (!mAdjacencyList) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
enum colors {white, gray, black};
typedef struct _BFSState {
colors color;
PRInt32 distance;
nsHashKey *predecessor;
} BFSState;
// nsHashtable enumerator functions.
// Initializes the color table.
PRBool InitBFSTable(nsHashKey *aKey, void *aData, void* closure) {
nsHashtable *BFSTable = (nsHashtable*)closure;
if (!BFSTable) return PR_FALSE;
BFSState *state = new BFSState;
if (!state) return NS_ERROR_OUT_OF_MEMORY;
state->color = white;
state->distance = -1;
state->predecessor = nsnull;
tableData *data = new tableData;
if (!data) return NS_ERROR_OUT_OF_MEMORY;
data->key = aKey->Clone();
tableData *origData = (tableData*)aData;
NS_ASSERTION(origData, "no data in the table enumeration");
data->keyString = new nsString2(*origData->keyString);
data->data = state;
BFSTable->Put(aKey, data);
return PR_TRUE;
};
nsresult
nsStreamConverterService::FindConverter(const char *aProgID, PRBool direct, nsCID *aCID, nsVoidArray **aEdgeList) {
// FIRST. try a direct lookup.
// Direct lookup didn't succeed, walk the graph.
// walk the graph in search of the appropriate converter.
PRInt32 vertexCount = mAdjacencyList->Count();
if (0 >= vertexCount)
return NS_ERROR_FAILURE;
// Create a corresponding color table for each vertex in the graph.
nsHashtable lBFSTable;
mAdjacencyList->Enumerate(InitBFSTable, &lBFSTable);
NS_ASSERTION(lBFSTable.Count() == vertexCount, "strmconv BFS table init problem");
// This is our source vertex; our starting point.
nsStringKey *source = new nsStringKey(aProgID);
if (!source) return NS_ERROR_OUT_OF_MEMORY;
tableData *data = (tableData*)lBFSTable.Get(source);
BFSState *state = (BFSState*)data->data;
// XXX probably don't need this check.
if (!state)
return NS_ERROR_FAILURE;
state->color = gray;
state->distance = 0;
nsDeque *grayQ = new nsDeque(0);
// Now generate the shortest path tree.
grayQ->Push(source);
while (0 < grayQ->GetSize()) {
nsHashKey *currentHead = (nsHashKey*)grayQ->Pop();
tableData *data = (tableData*)mAdjacencyList->Get(currentHead);
nsVoidArray *edges = (nsVoidArray*)data->data;
NS_ASSERTION(edges, "something went wrong with BFS strmconv algorithm");
// Get the state of the current head to calculate the distance of each
// reachable vertex in the loop.
data = (tableData*)lBFSTable.Get(currentHead);
BFSState *headVertexState = (BFSState*)data->data;
NS_ASSERTION(headVertexState, "problem with the BFS strmconv algorithm");
PRInt32 edgeCount = edges->Count();
for (int i = 0; i < edgeCount; i++) {
nsIAtom *curVertexAtom = (nsIAtom*)edges->ElementAt(i);
nsString2 curVertexStr;
curVertexAtom->ToString(curVertexStr);
char * curVertexCString = curVertexStr.ToNewCString();
nsStringKey *curVertex = new nsStringKey(curVertexCString);
delete [] curVertexCString;
tableData *data = (tableData*)lBFSTable.Get(curVertex);
BFSState *curVertexState = (BFSState*)data->data;
NS_ASSERTION(curVertexState, "something went wrong with the BFS strmconv algorithm");
if (white == curVertexState->color) {
curVertexState->color = gray;
curVertexState->distance = headVertexState->distance + 1;
curVertexState->predecessor = currentHead->Clone();
grayQ->Push(curVertex);
}
}
headVertexState->color = black;
grayQ->Pop();
}
// The shortest path (if any) has been generated and is represetned by the chain of
// BFSState->predecessor keys. Start at the bottom and work our way up.
// first parse out the FROM and TO MIME-types being registered.
nsString2 ProgIDStr(aProgID, eOneByte);
PRInt32 fromLoc = ProgIDStr.Find("from=") + 5;
PRInt32 toLoc = ProgIDStr.Find("to=") + 3;
if (-1 == fromLoc || -1 == toLoc ) return NS_ERROR_FAILURE;
nsString2 fromStr(eOneByte), toStr(eOneByte);
PRInt32 fromLen = toLoc - 4 - fromLoc;
PRInt32 toLen = ProgIDStr.Length() - toLoc;
ProgIDStr.Mid(fromStr, fromLoc, fromLen);
ProgIDStr.Mid(toStr, toLoc, toLen);
// get the root PROGID
nsString2 ProgIDPrefix(ProgIDStr);
ProgIDPrefix.Truncate(fromLoc - 5);
nsVoidArray *shortestPath = new nsVoidArray();
nsStringKey *toMIMEType = new nsStringKey(toStr);
data = (tableData*)lBFSTable.Get(toMIMEType);
NS_ASSERTION(data, "problem w/ strmconv BFS algorithm");
while (data) {
BFSState *curState = (BFSState*)data->data;
if (data->keyString->Equals(fromStr)) {
// found it. We're done here.
direct = PR_FALSE;
*aEdgeList = shortestPath;
return NS_OK;
}
// reconstruct the PROGID.
// Get the predecessor.
tableData *predecessorData = (tableData*)lBFSTable.Get(curState->predecessor);
NS_ASSERTION(predecessorData, "can't get predecessor data");
// build out the PROGID.
nsString2 *newProgID = new nsString2(ProgIDPrefix);
newProgID->Append("from=");
char *from = predecessorData->keyString->ToNewCString();
newProgID->Append(from);
delete [] from;
newProgID->Append("?to=");
char *to = data->keyString->ToNewCString();
newProgID->Append(to);
delete [] to;
// Add this PROGID to the chain.
shortestPath->AppendElement(newProgID);
// move up the tree.
data = predecessorData;
}
return NS_ERROR_FAILURE; // couldn't find a stream converter or chain.
}
NS_IMETHODIMP
nsStreamConverterService::OnDataAvailable(nsIChannel *channel, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsStreamConverterService::OnStartRequest(nsIChannel *channel, nsISupports *ctxt) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsStreamConverterService::OnStopRequest(nsIChannel *channel, nsISupports *ctxt, nsresult status, const PRUnichar *errorMsg) {
return NS_ERROR_NOT_IMPLEMENTED;
}

Просмотреть файл

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef __nsstreamconverterservice__h___
#define __nsstreamconverterservice__h___
#include "nsIStreamConverterService.h"
#include "nsIStreamListener.h"
#include "nsHashtable.h"
#include "nsVoidArray.h"
class nsStreamConverterService : public nsIStreamConverterService {
public:
/////////////////////////////////////////////////////
// nsISupports methods
NS_DECL_ISUPPORTS
/////////////////////////////////////////////////////
// nsIStreamConverterService methods
NS_IMETHOD RegisterConverter(const char *aProgID, nsISupports *aConverter);
/////////////////////////////////////////////////////
// nsIStreamConverter methods
NS_IMETHOD Convert(nsIInputStream *aFromStream, const PRUnichar *aFromType, const PRUnichar *aToType, nsIInputStream **_retval)
{ return NS_ERROR_NOT_IMPLEMENTED;};
NS_IMETHOD AsyncConvertStream(nsIInputStream *aFromStream, const PRUnichar *aFromType, const PRUnichar *aToType, nsIStreamListener *aListener)
{ return NS_ERROR_NOT_IMPLEMENTED;};
NS_IMETHOD AsyncConvertData(const PRUnichar *aFromType, const PRUnichar *aToType, nsIStreamListener *aListener)
{ return NS_ERROR_NOT_IMPLEMENTED;};
/////////////////////////////////////////////////////
// nsIStreamListener methods
NS_IMETHOD OnDataAvailable(nsIChannel *channel, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count);
/////////////////////////////////////////////////////
// nsIStreamObserver methods
NS_IMETHOD OnStartRequest(nsIChannel *channel, nsISupports *ctxt);
NS_IMETHOD OnStopRequest(nsIChannel *channel, nsISupports *ctxt, nsresult status, const PRUnichar *errorMsg);
/////////////////////////////////////////////////////
// nsStreamConverterService methods
nsStreamConverterService();
virtual ~nsStreamConverterService();
// Initialization routine. Must be called after this object is constructed.
nsresult Init();
private:
// Responsible for finding a converter for the given MIME-type.
nsresult FindConverter(const char *aProgID, PRBool direct, nsCID *aCID, nsVoidArray **aEdgeList);
// member variables
nsHashtable *mAdjacencyList;
};
#endif // __nsstreamconverterservice__h___