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"
17 #include "nsStringAPI.h"
18 #include "nsIFileStreams.h"
19 #include "nsIStreamListener.h"
21 #include "nsNetUtil.h"
22 #include "nsAutoLock.h"
26 ////////////////////////////////////////////////////////////////////////////////
28 #if defined(PR_LOGGING)
30 // set NSPR_LOG_MODULES=Test:5
32 static PRLogModuleInfo
*gTestLog
= nullptr;
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
48 NS_DECL_THREADSAFE_ISUPPORTS
52 , mInputCondition(NS_OK
)
59 nsAutoLock::DestroyLock(mLock
);
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");
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");
88 LOG(("Close_Locked\n"));
95 // post done copying event
102 mInputCondition
= NS_OK
; // reset
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);
118 nsresult
AsyncCopy(nsITransport
*srcTrans
, nsITransport
*destTrans
)
120 mLock
= nsAutoLock::NewLock("MyCopier::mLock");
122 return NS_ERROR_OUT_OF_MEMORY
;
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
,
147 MyCopier
*self
= (MyCopier
*) closure
;
149 nsresult rv
= self
->mInput
->Read(buffer
, count
, countRead
);
151 self
->mInputCondition
= rv
;
152 else if (*countRead
== 0)
153 self
->mInputCondition
= NS_BASE_STREAM_CLOSED
;
155 return self
->mInputCondition
;
160 nsCOMPtr
<nsIAsyncInputStream
> mInput
;
161 nsCOMPtr
<nsIAsyncOutputStream
> mOutput
;
162 nsresult mInputCondition
;
165 NS_IMPL_ISUPPORTS2(MyCopier
,
166 nsIInputStreamCallback
,
167 nsIOutputStreamCallback
)
169 ////////////////////////////////////////////////////////////////////////////////
172 * asynchronously copy file.
175 RunTest(nsIFile
*srcFile
, nsIFile
*destFile
)
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
;
208 rv
= copier
->AsyncCopy(srcTransport
, destTransport
);
209 if (NS_FAILED(rv
)) return rv
;
217 ////////////////////////////////////////////////////////////////////////////////
220 RunBlockingTest(nsIFile
*srcFile
, nsIFile
*destFile
)
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
;
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
;
260 ////////////////////////////////////////////////////////////////////////////////
263 main(int argc
, char* argv
[])
265 if (test_common_init(&argc
, &argv
) != 0)
271 printf("usage: %s <file-to-read>\n", argv
[0]);
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");
281 registrar
->AutoRegister(nullptr);
283 #if defined(PR_LOGGING)
284 gTestLog
= PR_NewLogModule("Test");
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
.Append(NS_LITERAL_CSTRING(".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");
308 newName
.Append(NS_LITERAL_CSTRING(".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
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");