/* -*- 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.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/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-1999 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): Akkana Peck. */ #include "nsTextConverter.h" #include "nsParserCIID.h" #include "nsIParser.h" #include "CNavDTD.h" #include "nsXIFDTD.h" #include "nsHTMLContentSinkStream.h" #include "nsHTMLToTXTSinkStream.h" #include "nsCOMPtr.h" #include "nsIStringStream.h" ////////////////////////////////////////////////// // nsTextConverter ////////////////////////////////////////////////// NS_IMPL_ISUPPORTS2(nsTextConverter, nsIStreamConverter, nsIStreamListener); nsTextConverter::nsTextConverter() { NS_INIT_ISUPPORTS(); } // Convert from mime type aFromType), to _retval // (nsIInputStream of mime type aToType). NS_IMETHODIMP nsTextConverter::Convert(nsIInputStream *aFromStream, const PRUnichar *aFromType, const PRUnichar *aToType, nsISupports *ctxt, nsIInputStream **_retval) { nsCOMPtr parser; static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID); static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID); nsresult rv = nsComponentManager::CreateInstance(kCParserCID, nsnull, kCParserIID, getter_AddRefs(parser)); if (NS_FAILED(rv)) return rv; nsCOMPtr sink; nsString toType (aToType); if (toType == "text/html") rv = NS_New_HTML_ContentSinkStream(getter_AddRefs(sink), aStream, charset, mFlags); else if (toType == "text/plain") rv = NS_New_HTMLToTXT_SinkStream(getter_AddRefs(sink), aStream, charset, mWrapColumn, mFlags); else return NS_ERROR_ILLEGAL_VALUE; if (NS_FAILED(rv)) return rv; nsCOMPtr dtd; nsString fromType(aFromType); if (fromType == "text/xif") rv = NS_NewXIFDTD(getter_AddRefs(dtd)); else if (fromType == "text/html") rv = NS_NewNavHTMLDTD(getter_AddRefs(dtd)); else return NS_ERROR_ILLEGAL_VALUE; if (NS_FAILED(rv)) return rv; parser->SetContentSink(sink); parser->RegisterDTD(dtd); parser->Parse(*aFromStream, PR_FALSE, 0); #if 0 char buf[1024]; PRUint32 read; nsresult rv = aFromStream->Read(buf, 1024, &read); if (NS_FAILED(rv)) return rv; // Get the first character nsString2 to(aToType); char *toMIME = to.ToNewCString(); char toChar = *toMIME; for (PRUint32 i = 0; i < read; i++) buf[i] = toChar; nsString2 convDataStr(buf); nsIInputStream *inputData = nsnull; nsISupports *inputDataSup = nsnull; rv = NS_NewStringInputStream(&inputDataSup, convDataStr); if (NS_FAILED(rv)) return rv; rv = inputDataSup->QueryInterface(NS_GET_IID(nsIInputStream), (void**)&inputData); NS_RELEASE(inputDataSup); *_retval = inputData; if (NS_FAILED(rv)) return rv; return NS_OK; #endif } /* This method initializes any internal state before the stream converter * begins asyncronous conversion */ NS_IMETHODIMP nsTextConverter::AsyncConvertData(const PRUnichar *aFromType, const PRUnichar *aToType, nsIStreamListener *aListener, nsISupports *ctxt) { NS_ASSERTION(aListener, "null listener"); mListener = aListener; NS_ADDREF(mListener); // based on these types, setup internal state to handle the appropriate conversion. fromType = aFromType; toType = aToType; return NS_OK; }; // nsIStreamListener method /* This method handles asyncronous conversion of data. */ NS_IMETHODIMP nsTextConverter::OnDataAvailable(nsIChannel *channel, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) { nsresult rv; nsIInputStream *convertedStream = nsnull; // just make a syncronous call to the Convert() method. // Anything can happen here, I just happen to be using the sync call to // do the actual conversion. rv = Convert(inStr, fromType.GetUnicode(), toType.GetUnicode(), ctxt, &convertedStream); if (NS_FAILED(rv)) return rv; PRUint32 len; convertedStream->GetLength(&len); return mListener->OnDataAvailable(channel, ctxt, convertedStream, sourceOffset, len); }; // nsIStreamObserver methods /* These methods just pass through directly to the mListener */ NS_IMETHODIMP nsTextConverter::OnStartRequest(nsIChannel *channel, nsISupports *ctxt) { return mListener->OnStartRequest(channel, ctxt); }; NS_IMETHODIMP nsTextConverter::OnStopRequest(nsIChannel *channel, nsISupports *ctxt, nsresult status, const PRUnichar *errorMsg) { return mListener->OnStopRequest(channel, ctxt, status, errorMsg); }; //////////////////////////////////////////////////////////////////////// // nsTextConverterFactory //////////////////////////////////////////////////////////////////////// nsTextConverterFactory::nsTextConverterFactory(const nsCID &aClass, const char* className, const char* progID) : mClassID(aClass), mClassName(className), mProgID(progID) { NS_INIT_ISUPPORTS(); } nsTextConverterFactory::~nsTextConverterFactory() { } NS_IMPL_ISUPPORTS(nsTextConverterFactory, NS_GET_IID(nsIFactory)); NS_IMETHODIMP nsTextConverterFactory::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(knsTextConverterCID)) { nsTextConverter *conv = new nsTextConverter(); if (!conv) return NS_ERROR_OUT_OF_MEMORY; conv->QueryInterface(NS_GET_IID(nsISupports), (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 nsTextConverterFactory::LockFactory(PRBool aLock) { // Not implemented in simplest case. return NS_OK; } //////////////////////////////////////////////////////////////////////// // nsTextConverterFactory END ////////////////////////////////////////////////////////////////////////