Bumping manifests a=b2g-bump
[gecko.git] / netwerk / test / TestStreamTransport.cpp
blob9fbcc109b312399128d07c4fed2f3194dcb98077
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "TestCommon.h"
6 #include "nsIComponentRegistrar.h"
7 #include "nsIStreamTransportService.h"
8 #include "nsIAsyncInputStream.h"
9 #include "nsIProgressEventSink.h"
10 #include "nsIInterfaceRequestor.h"
11 #include "nsIInterfaceRequestorUtils.h"
12 #include "nsIRequest.h"
13 #include "nsIServiceManager.h"
14 #include "nsIComponentManager.h"
15 #include "nsCOMPtr.h"
16 #include "nsMemory.h"
17 #include "nsStringAPI.h"
18 #include "nsIFileStreams.h"
19 #include "nsIStreamListener.h"
20 #include "nsIFile.h"
21 #include "nsNetUtil.h"
22 #include "nsAutoLock.h"
23 #include "prlog.h"
24 #include "prenv.h"
26 ////////////////////////////////////////////////////////////////////////////////
28 #if defined(PR_LOGGING)
30 // set NSPR_LOG_MODULES=Test:5
32 static PRLogModuleInfo *gTestLog = nullptr;
33 #endif
34 #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args)
36 ////////////////////////////////////////////////////////////////////////////////
38 static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
40 ////////////////////////////////////////////////////////////////////////////////
42 #define CHUNK_SIZE 500
44 class MyCopier : public nsIInputStreamCallback
45 , public nsIOutputStreamCallback
47 public:
48 NS_DECL_THREADSAFE_ISUPPORTS
50 MyCopier()
51 : mLock(nullptr)
52 , mInputCondition(NS_OK)
56 virtual ~MyCopier()
58 if (mLock)
59 nsAutoLock::DestroyLock(mLock);
60 if (mInput)
61 mInput->Close();
62 if (mOutput)
63 mOutput->Close();
66 // called on any thread
67 NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream *inStr)
69 LOG(("OnInputStreamReady\n"));
70 nsAutoLock lock(mLock);
71 NS_ASSERTION(inStr == mInput, "unexpected stream");
72 Process_Locked();
73 return NS_OK;
76 // called on any thread
77 NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream *outStr)
79 LOG(("OnOutputStreamReady\n"));
80 nsAutoLock lock(mLock);
81 NS_ASSERTION(outStr == mOutput, "unexpected stream");
82 Process_Locked();
83 return NS_OK;
86 void Close_Locked()
88 LOG(("Close_Locked\n"));
90 mOutput->Close();
91 mOutput = 0;
92 mInput->Close();
93 mInput = 0;
95 // post done copying event
96 QuitPumpingEvents();
99 void Process_Locked()
101 while (1) {
102 mInputCondition = NS_OK; // reset
104 uint32_t n;
105 nsresult rv = mOutput->WriteSegments(FillOutputBuffer, this, CHUNK_SIZE, &n);
106 if (NS_FAILED(rv) || (n == 0)) {
107 if (rv == NS_BASE_STREAM_WOULD_BLOCK)
108 mOutput->AsyncWait(this, 0, 0, nullptr);
109 else if (mInputCondition == NS_BASE_STREAM_WOULD_BLOCK)
110 mInput->AsyncWait(this, 0, 0, nullptr);
111 else
112 Close_Locked();
113 break;
118 nsresult AsyncCopy(nsITransport *srcTrans, nsITransport *destTrans)
120 mLock = nsAutoLock::NewLock("MyCopier::mLock");
121 if (!mLock)
122 return NS_ERROR_OUT_OF_MEMORY;
124 nsresult rv;
126 nsCOMPtr<nsIInputStream> inStr;
127 rv = srcTrans->OpenInputStream(0, 0, 0, getter_AddRefs(inStr));
128 if (NS_FAILED(rv)) return rv;
130 nsCOMPtr<nsIOutputStream> outStr;
131 rv = destTrans->OpenOutputStream(0, 0, 0, getter_AddRefs(outStr));
132 if (NS_FAILED(rv)) return rv;
134 mInput = do_QueryInterface(inStr);
135 mOutput = do_QueryInterface(outStr);
137 return mInput->AsyncWait(this, 0, 0, nullptr);
140 static NS_METHOD FillOutputBuffer(nsIOutputStream *outStr,
141 void *closure,
142 char *buffer,
143 uint32_t offset,
144 uint32_t count,
145 uint32_t *countRead)
147 MyCopier *self = (MyCopier *) closure;
149 nsresult rv = self->mInput->Read(buffer, count, countRead);
150 if (NS_FAILED(rv))
151 self->mInputCondition = rv;
152 else if (*countRead == 0)
153 self->mInputCondition = NS_BASE_STREAM_CLOSED;
155 return self->mInputCondition;
158 protected:
159 PRLock *mLock;
160 nsCOMPtr<nsIAsyncInputStream> mInput;
161 nsCOMPtr<nsIAsyncOutputStream> mOutput;
162 nsresult mInputCondition;
165 NS_IMPL_ISUPPORTS(MyCopier,
166 nsIInputStreamCallback,
167 nsIOutputStreamCallback)
169 ////////////////////////////////////////////////////////////////////////////////
172 * asynchronously copy file.
174 static nsresult
175 RunTest(nsIFile *srcFile, nsIFile *destFile)
177 nsresult rv;
179 LOG(("RunTest\n"));
181 nsCOMPtr<nsIStreamTransportService> sts =
182 do_GetService(kStreamTransportServiceCID, &rv);
183 if (NS_FAILED(rv)) return rv;
185 nsCOMPtr<nsIInputStream> srcStr;
186 rv = NS_NewLocalFileInputStream(getter_AddRefs(srcStr), srcFile);
187 if (NS_FAILED(rv)) return rv;
189 nsCOMPtr<nsIOutputStream> destStr;
190 rv = NS_NewLocalFileOutputStream(getter_AddRefs(destStr), destFile);
191 if (NS_FAILED(rv)) return rv;
193 nsCOMPtr<nsITransport> srcTransport;
194 rv = sts->CreateInputTransport(srcStr, int64_t(-1), int64_t(-1), true,
195 getter_AddRefs(srcTransport));
196 if (NS_FAILED(rv)) return rv;
198 nsCOMPtr<nsITransport> destTransport;
199 rv = sts->CreateOutputTransport(destStr, int64_t(-1), int64_t(-1), true,
200 getter_AddRefs(destTransport));
201 if (NS_FAILED(rv)) return rv;
203 MyCopier *copier = new MyCopier();
204 if (copier == nullptr)
205 return NS_ERROR_OUT_OF_MEMORY;
206 NS_ADDREF(copier);
208 rv = copier->AsyncCopy(srcTransport, destTransport);
209 if (NS_FAILED(rv)) return rv;
211 PumpEvents();
213 NS_RELEASE(copier);
214 return NS_OK;
217 ////////////////////////////////////////////////////////////////////////////////
219 static nsresult
220 RunBlockingTest(nsIFile *srcFile, nsIFile *destFile)
222 nsresult rv;
224 LOG(("RunBlockingTest\n"));
226 nsCOMPtr<nsIStreamTransportService> sts =
227 do_GetService(kStreamTransportServiceCID, &rv);
228 if (NS_FAILED(rv)) return rv;
230 nsCOMPtr<nsIInputStream> srcIn;
231 rv = NS_NewLocalFileInputStream(getter_AddRefs(srcIn), srcFile);
232 if (NS_FAILED(rv)) return rv;
234 nsCOMPtr<nsIOutputStream> fileOut;
235 rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileOut), destFile);
236 if (NS_FAILED(rv)) return rv;
238 nsCOMPtr<nsITransport> destTransport;
239 rv = sts->CreateOutputTransport(fileOut, int64_t(-1), int64_t(-1),
240 true, getter_AddRefs(destTransport));
241 if (NS_FAILED(rv)) return rv;
243 nsCOMPtr<nsIOutputStream> destOut;
244 rv = destTransport->OpenOutputStream(nsITransport::OPEN_BLOCKING, 100, 10, getter_AddRefs(destOut));
245 if (NS_FAILED(rv)) return rv;
247 char buf[120];
248 uint32_t n;
249 for (;;) {
250 rv = srcIn->Read(buf, sizeof(buf), &n);
251 if (NS_FAILED(rv) || (n == 0)) return rv;
253 rv = destOut->Write(buf, n, &n);
254 if (NS_FAILED(rv)) return rv;
257 return NS_OK;
260 ////////////////////////////////////////////////////////////////////////////////
263 main(int argc, char* argv[])
265 if (test_common_init(&argc, &argv) != 0)
266 return -1;
268 nsresult rv;
270 if (argc < 2) {
271 printf("usage: %s <file-to-read>\n", argv[0]);
272 return -1;
274 char* fileName = argv[1];
276 nsCOMPtr<nsIServiceManager> servMan;
277 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr);
278 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
279 NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
280 if (registrar)
281 registrar->AutoRegister(nullptr);
283 #if defined(PR_LOGGING)
284 gTestLog = PR_NewLogModule("Test");
285 #endif
287 nsCOMPtr<nsIFile> srcFile;
288 rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(srcFile));
289 if (NS_FAILED(rv)) return rv;
291 nsCOMPtr<nsIFile> destFile;
292 rv = srcFile->Clone(getter_AddRefs(destFile));
293 if (NS_FAILED(rv)) return rv;
295 nsAutoCString leafName;
296 rv = destFile->GetNativeLeafName(leafName);
297 if (NS_FAILED(rv)) return rv;
299 nsAutoCString newName(leafName);
300 newName.AppendLiteral(".1");
301 rv = destFile->SetNativeLeafName(newName);
302 if (NS_FAILED(rv)) return rv;
304 rv = RunTest(srcFile, destFile);
305 NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed");
307 newName = leafName;
308 newName.AppendLiteral(".2");
309 rv = destFile->SetNativeLeafName(newName);
310 if (NS_FAILED(rv)) return rv;
312 rv = RunBlockingTest(srcFile, destFile);
313 NS_ASSERTION(NS_SUCCEEDED(rv), "RunBlockingTest failed");
315 // give background threads a chance to finish whatever work they may
316 // be doing.
317 PR_Sleep(PR_SecondsToInterval(1));
318 } // this scopes the nsCOMPtrs
319 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
320 rv = NS_ShutdownXPCOM(nullptr);
321 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
322 return NS_OK;