Back to index

lightning-sunbird  0.9+nobinonly
Converters.cpp
Go to the documentation of this file.
00001 #include "Converters.h"
00002 #include "nsIStringStream.h"
00003 #include "nsCOMPtr.h"
00004 #include "nsReadableUtils.h"
00005 
00007 // TestConverter
00009 
00010 NS_IMPL_ISUPPORTS2(TestConverter, nsIStreamConverter, nsIStreamListener)
00011 
00012 TestConverter::TestConverter() {
00013 }
00014 
00015 // Convert aFromStream (of type aFromType), to _retval (nsIInputStream of type aToType).
00016 // This Convert method simply converts the stream byte-by-byte, to the first character
00017 // in the aToType "string".
00018 NS_IMETHODIMP
00019 TestConverter::Convert(nsIInputStream *aFromStream, 
00020                        const char *aFromType, 
00021                        const char *aToType, 
00022                        nsISupports *ctxt, 
00023                        nsIInputStream **_retval) {
00024     char buf[1024+1];
00025     PRUint32 read;
00026     nsresult rv = aFromStream->Read(buf, 1024, &read);
00027     if (NS_FAILED(rv) || read == 0) return rv;
00028 
00029     // verify that the data we're converting matches the from type
00030     // if it doesn't then we're being handed the wrong data.
00031     char fromChar = *aFromType;
00032 
00033     if (fromChar != buf[0]) {
00034         printf("We're receiving %c, but are supposed to have %c.\n", buf[0], fromChar);
00035         return NS_ERROR_FAILURE;
00036     }
00037 
00038 
00039     // Get the first character 
00040     char toChar = *aToType;
00041 
00042     for (PRUint32 i = 0; i < read; i++) 
00043         buf[i] = toChar;
00044 
00045     buf[read] = '\0';
00046 
00047     return NS_NewCStringInputStream(_retval, nsDependentCString(buf));
00048 }
00049 
00050 /* This method initializes any internal state before the stream converter
00051  * begins asynchronous conversion */
00052 NS_IMETHODIMP
00053 TestConverter::AsyncConvertData(const char *aFromType,
00054                                 const char *aToType, 
00055                                 nsIStreamListener *aListener, 
00056                                 nsISupports *ctxt) {
00057     NS_ASSERTION(aListener, "null listener");
00058 
00059     mListener = aListener;
00060 
00061     // based on these types, setup internal state to handle the appropriate conversion.
00062     fromType = aFromType;
00063     toType = aToType;
00064 
00065     return NS_OK; 
00066 }
00067 
00068 // nsIStreamListener method
00069 /* This method handles asyncronous conversion of data. */
00070 NS_IMETHODIMP
00071 TestConverter::OnDataAvailable(nsIRequest* request,
00072                                nsISupports *ctxt, 
00073                                nsIInputStream *inStr, 
00074                                PRUint32 sourceOffset, 
00075                                PRUint32 count) {
00076     nsresult rv;
00077     nsCOMPtr<nsIInputStream> convertedStream;
00078     // just make a syncronous call to the Convert() method.
00079     // Anything can happen here, I just happen to be using the sync call to 
00080     // do the actual conversion.
00081     rv = Convert(inStr, fromType.get(), toType.get(), ctxt, getter_AddRefs(convertedStream));
00082     if (NS_FAILED(rv)) return rv;
00083 
00084     PRUint32 len;
00085     convertedStream->Available(&len);
00086     return mListener->OnDataAvailable(request, ctxt, convertedStream, sourceOffset, len);
00087 }
00088 
00089 // nsIRequestObserver methods
00090 /* These methods just pass through directly to the mListener */
00091 NS_IMETHODIMP
00092 TestConverter::OnStartRequest(nsIRequest* request, nsISupports *ctxt) {
00093     return mListener->OnStartRequest(request, ctxt);
00094 }
00095 
00096 NS_IMETHODIMP
00097 TestConverter::OnStopRequest(nsIRequest* request, nsISupports *ctxt, 
00098                              nsresult aStatus) {
00099     return mListener->OnStopRequest(request, ctxt, aStatus);
00100 }
00101 
00102 
00104 // TestConverterFactory
00106 TestConverterFactory::TestConverterFactory(const nsCID &aClass, 
00107                                    const char* className,
00108                                    const char* contractID)
00109     : mClassID(aClass), mClassName(className), mContractID(contractID)
00110 {
00111 }
00112 
00113 TestConverterFactory::~TestConverterFactory()
00114 {
00115 }
00116 
00117 NS_IMPL_ISUPPORTS1(TestConverterFactory, nsIFactory)
00118 
00119 NS_IMETHODIMP
00120 TestConverterFactory::CreateInstance(nsISupports *aOuter,
00121                                  const nsIID &aIID,
00122                                  void **aResult)
00123 {
00124     if (! aResult)
00125         return NS_ERROR_NULL_POINTER;
00126 
00127     if (aOuter)
00128         return NS_ERROR_NO_AGGREGATION;
00129 
00130     *aResult = nsnull;
00131 
00132     nsresult rv = NS_OK;
00133 
00134     nsISupports *inst = nsnull;
00135     if (mClassID.Equals(kTestConverterCID)) {
00136         TestConverter *conv = new TestConverter();
00137         if (!conv) return NS_ERROR_OUT_OF_MEMORY;
00138         conv->QueryInterface(NS_GET_IID(nsISupports), (void**)&inst);
00139     }
00140     else {
00141         return NS_ERROR_NO_INTERFACE;
00142     }
00143 
00144     if (!inst)
00145         return NS_ERROR_OUT_OF_MEMORY;
00146     NS_ADDREF(inst);
00147     *aResult = inst;
00148     NS_RELEASE(inst);
00149     return rv;
00150 }
00151 
00152 nsresult TestConverterFactory::LockFactory(PRBool aLock)
00153 {
00154     // Not implemented in simplest case.
00155     return NS_OK;
00156 }
00158 // TestConverterFactory END
00160