netwerk/streamconv/test/TestStreamConv.cpp

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

mercurial