netwerk/streamconv/test/TestStreamConv.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsIServiceManager.h"
michael@0 7 #include "nsIStreamConverterService.h"
michael@0 8 #include "nsIStreamConverter.h"
michael@0 9 #include "nsICategoryManager.h"
michael@0 10 #include "mozilla/Module.h"
michael@0 11 #include "nsXULAppAPI.h"
michael@0 12 #include "nsIStringStream.h"
michael@0 13 #include "nsCOMPtr.h"
michael@0 14 #include "nsThreadUtils.h"
michael@0 15 #include "mozilla/Attributes.h"
michael@0 16 #include "nsMemory.h"
michael@0 17 #include "nsServiceManagerUtils.h"
michael@0 18 #include "nsComponentManagerUtils.h"
michael@0 19 #include "nsIRequest.h"
michael@0 20 #include "nsNetCID.h"
michael@0 21
michael@0 22 #define ASYNC_TEST // undefine this if you want to test sycnronous conversion.
michael@0 23
michael@0 24 /////////////////////////////////
michael@0 25 // Event pump setup
michael@0 26 /////////////////////////////////
michael@0 27 #ifdef XP_WIN
michael@0 28 #include <windows.h>
michael@0 29 #endif
michael@0 30
michael@0 31 static int gKeepRunning = 0;
michael@0 32 /////////////////////////////////
michael@0 33 // Event pump END
michael@0 34 /////////////////////////////////
michael@0 35
michael@0 36
michael@0 37 /////////////////////////////////
michael@0 38 // Test converters include
michael@0 39 /////////////////////////////////
michael@0 40 #include "Converters.h"
michael@0 41
michael@0 42 // CID setup
michael@0 43 static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
michael@0 44
michael@0 45 ////////////////////////////////////////////////////////////////////////
michael@0 46 // EndListener - This listener is the final one in the chain. It
michael@0 47 // receives the fully converted data, although it doesn't do anything with
michael@0 48 // the data.
michael@0 49 ////////////////////////////////////////////////////////////////////////
michael@0 50 class EndListener MOZ_FINAL : public nsIStreamListener {
michael@0 51 public:
michael@0 52 // nsISupports declaration
michael@0 53 NS_DECL_ISUPPORTS
michael@0 54
michael@0 55 EndListener() {}
michael@0 56
michael@0 57 // nsIStreamListener method
michael@0 58 NS_IMETHOD OnDataAvailable(nsIRequest* request, nsISupports *ctxt, nsIInputStream *inStr,
michael@0 59 uint64_t sourceOffset, uint32_t count)
michael@0 60 {
michael@0 61 nsresult rv;
michael@0 62 uint32_t read;
michael@0 63 uint64_t len64;
michael@0 64 rv = inStr->Available(&len64);
michael@0 65 if (NS_FAILED(rv)) return rv;
michael@0 66 uint32_t len = (uint32_t)std::min(len64, (uint64_t)(UINT32_MAX - 1));
michael@0 67
michael@0 68 char *buffer = (char*)nsMemory::Alloc(len + 1);
michael@0 69 if (!buffer) return NS_ERROR_OUT_OF_MEMORY;
michael@0 70
michael@0 71 rv = inStr->Read(buffer, len, &read);
michael@0 72 buffer[len] = '\0';
michael@0 73 if (NS_SUCCEEDED(rv)) {
michael@0 74 printf("CONTEXT %p: Received %u bytes and the following data: \n %s\n\n",
michael@0 75 static_cast<void*>(ctxt), read, buffer);
michael@0 76 }
michael@0 77 nsMemory::Free(buffer);
michael@0 78
michael@0 79 return NS_OK;
michael@0 80 }
michael@0 81
michael@0 82 // nsIRequestObserver methods
michael@0 83 NS_IMETHOD OnStartRequest(nsIRequest* request, nsISupports *ctxt) { return NS_OK; }
michael@0 84
michael@0 85 NS_IMETHOD OnStopRequest(nsIRequest* request, nsISupports *ctxt,
michael@0 86 nsresult aStatus) { return NS_OK; }
michael@0 87 };
michael@0 88
michael@0 89 NS_IMPL_ISUPPORTS(EndListener,
michael@0 90 nsIStreamListener,
michael@0 91 nsIRequestObserver)
michael@0 92
michael@0 93 ////////////////////////////////////////////////////////////////////////
michael@0 94 // EndListener END
michael@0 95 ////////////////////////////////////////////////////////////////////////
michael@0 96
michael@0 97 nsresult SendData(const char * aData, nsIStreamListener* aListener, nsIRequest* request) {
michael@0 98 nsresult rv;
michael@0 99
michael@0 100 nsCOMPtr<nsIStringInputStream> dataStream
michael@0 101 (do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv));
michael@0 102 NS_ENSURE_SUCCESS(rv, rv);
michael@0 103
michael@0 104 rv = dataStream->SetData(aData, strlen(aData));
michael@0 105 NS_ENSURE_SUCCESS(rv, rv);
michael@0 106
michael@0 107 uint64_t avail = 0;
michael@0 108 dataStream->Available(&avail);
michael@0 109
michael@0 110 uint64_t offset = 0;
michael@0 111 while (avail > 0) {
michael@0 112 uint32_t count = saturated(avail);
michael@0 113 rv = aListener->OnDataAvailable(request, nullptr, dataStream,
michael@0 114 offset, count);
michael@0 115 if (NS_FAILED(rv)) return rv;
michael@0 116
michael@0 117 offset += count;
michael@0 118 avail -= count;
michael@0 119 }
michael@0 120 return NS_OK;
michael@0 121 }
michael@0 122 #define SEND_DATA(x) SendData(x, converterListener, request)
michael@0 123
michael@0 124 static const mozilla::Module::CIDEntry kTestCIDs[] = {
michael@0 125 { &kTestConverterCID, false, nullptr, CreateTestConverter },
michael@0 126 { nullptr }
michael@0 127 };
michael@0 128
michael@0 129 static const mozilla::Module::ContractIDEntry kTestContracts[] = {
michael@0 130 { NS_ISTREAMCONVERTER_KEY "?from=a/foo&to=b/foo", &kTestConverterCID },
michael@0 131 { NS_ISTREAMCONVERTER_KEY "?from=b/foo&to=c/foo", &kTestConverterCID },
michael@0 132 { NS_ISTREAMCONVERTER_KEY "?from=b/foo&to=d/foo", &kTestConverterCID },
michael@0 133 { NS_ISTREAMCONVERTER_KEY "?from=c/foo&to=d/foo", &kTestConverterCID },
michael@0 134 { NS_ISTREAMCONVERTER_KEY "?from=d/foo&to=e/foo", &kTestConverterCID },
michael@0 135 { NS_ISTREAMCONVERTER_KEY "?from=d/foo&to=f/foo", &kTestConverterCID },
michael@0 136 { NS_ISTREAMCONVERTER_KEY "?from=t/foo&to=k/foo", &kTestConverterCID },
michael@0 137 { nullptr }
michael@0 138 };
michael@0 139
michael@0 140 static const mozilla::Module::CategoryEntry kTestCategories[] = {
michael@0 141 { NS_ISTREAMCONVERTER_KEY, "?from=a/foo&to=b/foo", "x" },
michael@0 142 { NS_ISTREAMCONVERTER_KEY, "?from=b/foo&to=c/foo", "x" },
michael@0 143 { NS_ISTREAMCONVERTER_KEY, "?from=b/foo&to=d/foo", "x" },
michael@0 144 { NS_ISTREAMCONVERTER_KEY, "?from=c/foo&to=d/foo", "x" },
michael@0 145 { NS_ISTREAMCONVERTER_KEY, "?from=d/foo&to=e/foo", "x" },
michael@0 146 { NS_ISTREAMCONVERTER_KEY, "?from=d/foo&to=f/foo", "x" },
michael@0 147 { NS_ISTREAMCONVERTER_KEY, "?from=t/foo&to=k/foo", "x" },
michael@0 148 { nullptr }
michael@0 149 };
michael@0 150
michael@0 151 static const mozilla::Module kTestModule = {
michael@0 152 mozilla::Module::kVersion,
michael@0 153 kTestCIDs,
michael@0 154 kTestContracts,
michael@0 155 kTestCategories
michael@0 156 };
michael@0 157
michael@0 158 int
michael@0 159 main(int argc, char* argv[])
michael@0 160 {
michael@0 161 nsresult rv;
michael@0 162 {
michael@0 163 XRE_AddStaticComponent(&kTestModule);
michael@0 164
michael@0 165 nsCOMPtr<nsIServiceManager> servMan;
michael@0 166 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr);
michael@0 167
michael@0 168 nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
michael@0 169
michael@0 170 nsCOMPtr<nsICategoryManager> catman =
michael@0 171 do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
michael@0 172 if (NS_FAILED(rv)) return -1;
michael@0 173 nsCString previous;
michael@0 174
michael@0 175 nsCOMPtr<nsIStreamConverterService> StreamConvService =
michael@0 176 do_GetService(kStreamConverterServiceCID, &rv);
michael@0 177 if (NS_FAILED(rv)) return -1;
michael@0 178
michael@0 179 // Define the *from* content type and *to* content-type for conversion.
michael@0 180 static const char fromStr[] = "a/foo";
michael@0 181 static const char toStr[] = "c/foo";
michael@0 182
michael@0 183 #ifdef ASYNC_TEST
michael@0 184 // ASYNCHRONOUS conversion
michael@0 185
michael@0 186 // Build up a channel that represents the content we're
michael@0 187 // starting the transaction with.
michael@0 188 //
michael@0 189 // sample multipart mixed content-type string:
michael@0 190 // "multipart/x-mixed-replacE;boundary=thisrandomstring"
michael@0 191 #if 0
michael@0 192 nsCOMPtr<nsIChannel> channel;
michael@0 193 nsCOMPtr<nsIURI> dummyURI;
michael@0 194 rv = NS_NewURI(getter_AddRefs(dummyURI), "http://meaningless");
michael@0 195 if (NS_FAILED(rv)) return -1;
michael@0 196
michael@0 197 rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
michael@0 198 dummyURI,
michael@0 199 nullptr, // inStr
michael@0 200 "text/plain", // content-type
michael@0 201 -1); // XXX fix contentLength
michael@0 202 if (NS_FAILED(rv)) return -1;
michael@0 203
michael@0 204 nsCOMPtr<nsIRequest> request(do_QueryInterface(channel));
michael@0 205 #endif
michael@0 206
michael@0 207 nsCOMPtr<nsIRequest> request;
michael@0 208
michael@0 209 // setup a listener to receive the converted data. This guy is the end
michael@0 210 // listener in the chain, he wants the fully converted (toType) data.
michael@0 211 // An example of this listener in mozilla would be the DocLoader.
michael@0 212 nsIStreamListener *dataReceiver = new EndListener();
michael@0 213 NS_ADDREF(dataReceiver);
michael@0 214
michael@0 215 // setup a listener to push the data into. This listener sits inbetween the
michael@0 216 // unconverted data of fromType, and the final listener in the chain (in this case
michael@0 217 // the dataReceiver.
michael@0 218 nsIStreamListener *converterListener = nullptr;
michael@0 219 rv = StreamConvService->AsyncConvertData(fromStr, toStr,
michael@0 220 dataReceiver, nullptr, &converterListener);
michael@0 221 if (NS_FAILED(rv)) return -1;
michael@0 222 NS_RELEASE(dataReceiver);
michael@0 223
michael@0 224 // at this point we have a stream listener to push data to, and the one
michael@0 225 // that will receive the converted data. Let's mimic On*() calls and get the conversion
michael@0 226 // going. Typically these On*() calls would be made inside their respective wrappers On*()
michael@0 227 // methods.
michael@0 228 rv = converterListener->OnStartRequest(request, nullptr);
michael@0 229 if (NS_FAILED(rv)) return -1;
michael@0 230
michael@0 231 rv = SEND_DATA("aaa");
michael@0 232 if (NS_FAILED(rv)) return -1;
michael@0 233
michael@0 234 rv = SEND_DATA("aaa");
michael@0 235 if (NS_FAILED(rv)) return -1;
michael@0 236
michael@0 237 // Finish the request.
michael@0 238 rv = converterListener->OnStopRequest(request, nullptr, rv);
michael@0 239 if (NS_FAILED(rv)) return -1;
michael@0 240
michael@0 241 NS_RELEASE(converterListener);
michael@0 242 #else
michael@0 243 // SYNCHRONOUS conversion
michael@0 244 nsCOMPtr<nsIInputStream> convertedData;
michael@0 245 rv = StreamConvService->Convert(inputData, fromStr, toStr,
michael@0 246 nullptr, getter_AddRefs(convertedData));
michael@0 247 if (NS_FAILED(rv)) return -1;
michael@0 248 #endif
michael@0 249
michael@0 250 // Enter the message pump to allow the URL load to proceed.
michael@0 251 while ( gKeepRunning ) {
michael@0 252 if (!NS_ProcessNextEvent(thread))
michael@0 253 break;
michael@0 254 }
michael@0 255 } // this scopes the nsCOMPtrs
michael@0 256 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
michael@0 257 NS_ShutdownXPCOM(nullptr);
michael@0 258 return 0;
michael@0 259 }

mercurial