1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/TestStreamTransport.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,323 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "TestCommon.h" 1.9 +#include "nsIComponentRegistrar.h" 1.10 +#include "nsIStreamTransportService.h" 1.11 +#include "nsIAsyncInputStream.h" 1.12 +#include "nsIProgressEventSink.h" 1.13 +#include "nsIInterfaceRequestor.h" 1.14 +#include "nsIInterfaceRequestorUtils.h" 1.15 +#include "nsIRequest.h" 1.16 +#include "nsIServiceManager.h" 1.17 +#include "nsIComponentManager.h" 1.18 +#include "nsCOMPtr.h" 1.19 +#include "nsMemory.h" 1.20 +#include "nsStringAPI.h" 1.21 +#include "nsIFileStreams.h" 1.22 +#include "nsIStreamListener.h" 1.23 +#include "nsIFile.h" 1.24 +#include "nsNetUtil.h" 1.25 +#include "nsAutoLock.h" 1.26 +#include "prlog.h" 1.27 +#include "prenv.h" 1.28 + 1.29 +//////////////////////////////////////////////////////////////////////////////// 1.30 + 1.31 +#if defined(PR_LOGGING) 1.32 +// 1.33 +// set NSPR_LOG_MODULES=Test:5 1.34 +// 1.35 +static PRLogModuleInfo *gTestLog = nullptr; 1.36 +#endif 1.37 +#define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) 1.38 + 1.39 +//////////////////////////////////////////////////////////////////////////////// 1.40 + 1.41 +static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID); 1.42 + 1.43 +//////////////////////////////////////////////////////////////////////////////// 1.44 + 1.45 +#define CHUNK_SIZE 500 1.46 + 1.47 +class MyCopier : public nsIInputStreamCallback 1.48 + , public nsIOutputStreamCallback 1.49 +{ 1.50 +public: 1.51 + NS_DECL_THREADSAFE_ISUPPORTS 1.52 + 1.53 + MyCopier() 1.54 + : mLock(nullptr) 1.55 + , mInputCondition(NS_OK) 1.56 + { 1.57 + } 1.58 + 1.59 + virtual ~MyCopier() 1.60 + { 1.61 + if (mLock) 1.62 + nsAutoLock::DestroyLock(mLock); 1.63 + if (mInput) 1.64 + mInput->Close(); 1.65 + if (mOutput) 1.66 + mOutput->Close(); 1.67 + } 1.68 + 1.69 + // called on any thread 1.70 + NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream *inStr) 1.71 + { 1.72 + LOG(("OnInputStreamReady\n")); 1.73 + nsAutoLock lock(mLock); 1.74 + NS_ASSERTION(inStr == mInput, "unexpected stream"); 1.75 + Process_Locked(); 1.76 + return NS_OK; 1.77 + } 1.78 + 1.79 + // called on any thread 1.80 + NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream *outStr) 1.81 + { 1.82 + LOG(("OnOutputStreamReady\n")); 1.83 + nsAutoLock lock(mLock); 1.84 + NS_ASSERTION(outStr == mOutput, "unexpected stream"); 1.85 + Process_Locked(); 1.86 + return NS_OK; 1.87 + } 1.88 + 1.89 + void Close_Locked() 1.90 + { 1.91 + LOG(("Close_Locked\n")); 1.92 + 1.93 + mOutput->Close(); 1.94 + mOutput = 0; 1.95 + mInput->Close(); 1.96 + mInput = 0; 1.97 + 1.98 + // post done copying event 1.99 + QuitPumpingEvents(); 1.100 + } 1.101 + 1.102 + void Process_Locked() 1.103 + { 1.104 + while (1) { 1.105 + mInputCondition = NS_OK; // reset 1.106 + 1.107 + uint32_t n; 1.108 + nsresult rv = mOutput->WriteSegments(FillOutputBuffer, this, CHUNK_SIZE, &n); 1.109 + if (NS_FAILED(rv) || (n == 0)) { 1.110 + if (rv == NS_BASE_STREAM_WOULD_BLOCK) 1.111 + mOutput->AsyncWait(this, 0, 0, nullptr); 1.112 + else if (mInputCondition == NS_BASE_STREAM_WOULD_BLOCK) 1.113 + mInput->AsyncWait(this, 0, 0, nullptr); 1.114 + else 1.115 + Close_Locked(); 1.116 + break; 1.117 + } 1.118 + } 1.119 + } 1.120 + 1.121 + nsresult AsyncCopy(nsITransport *srcTrans, nsITransport *destTrans) 1.122 + { 1.123 + mLock = nsAutoLock::NewLock("MyCopier::mLock"); 1.124 + if (!mLock) 1.125 + return NS_ERROR_OUT_OF_MEMORY; 1.126 + 1.127 + nsresult rv; 1.128 + 1.129 + nsCOMPtr<nsIInputStream> inStr; 1.130 + rv = srcTrans->OpenInputStream(0, 0, 0, getter_AddRefs(inStr)); 1.131 + if (NS_FAILED(rv)) return rv; 1.132 + 1.133 + nsCOMPtr<nsIOutputStream> outStr; 1.134 + rv = destTrans->OpenOutputStream(0, 0, 0, getter_AddRefs(outStr)); 1.135 + if (NS_FAILED(rv)) return rv; 1.136 + 1.137 + mInput = do_QueryInterface(inStr); 1.138 + mOutput = do_QueryInterface(outStr); 1.139 + 1.140 + return mInput->AsyncWait(this, 0, 0, nullptr); 1.141 + } 1.142 + 1.143 + static NS_METHOD FillOutputBuffer(nsIOutputStream *outStr, 1.144 + void *closure, 1.145 + char *buffer, 1.146 + uint32_t offset, 1.147 + uint32_t count, 1.148 + uint32_t *countRead) 1.149 + { 1.150 + MyCopier *self = (MyCopier *) closure; 1.151 + 1.152 + nsresult rv = self->mInput->Read(buffer, count, countRead); 1.153 + if (NS_FAILED(rv)) 1.154 + self->mInputCondition = rv; 1.155 + else if (*countRead == 0) 1.156 + self->mInputCondition = NS_BASE_STREAM_CLOSED; 1.157 + 1.158 + return self->mInputCondition; 1.159 + } 1.160 + 1.161 +protected: 1.162 + PRLock *mLock; 1.163 + nsCOMPtr<nsIAsyncInputStream> mInput; 1.164 + nsCOMPtr<nsIAsyncOutputStream> mOutput; 1.165 + nsresult mInputCondition; 1.166 +}; 1.167 + 1.168 +NS_IMPL_ISUPPORTS(MyCopier, 1.169 + nsIInputStreamCallback, 1.170 + nsIOutputStreamCallback) 1.171 + 1.172 +//////////////////////////////////////////////////////////////////////////////// 1.173 + 1.174 +/** 1.175 + * asynchronously copy file. 1.176 + */ 1.177 +static nsresult 1.178 +RunTest(nsIFile *srcFile, nsIFile *destFile) 1.179 +{ 1.180 + nsresult rv; 1.181 + 1.182 + LOG(("RunTest\n")); 1.183 + 1.184 + nsCOMPtr<nsIStreamTransportService> sts = 1.185 + do_GetService(kStreamTransportServiceCID, &rv); 1.186 + if (NS_FAILED(rv)) return rv; 1.187 + 1.188 + nsCOMPtr<nsIInputStream> srcStr; 1.189 + rv = NS_NewLocalFileInputStream(getter_AddRefs(srcStr), srcFile); 1.190 + if (NS_FAILED(rv)) return rv; 1.191 + 1.192 + nsCOMPtr<nsIOutputStream> destStr; 1.193 + rv = NS_NewLocalFileOutputStream(getter_AddRefs(destStr), destFile); 1.194 + if (NS_FAILED(rv)) return rv; 1.195 + 1.196 + nsCOMPtr<nsITransport> srcTransport; 1.197 + rv = sts->CreateInputTransport(srcStr, int64_t(-1), int64_t(-1), true, 1.198 + getter_AddRefs(srcTransport)); 1.199 + if (NS_FAILED(rv)) return rv; 1.200 + 1.201 + nsCOMPtr<nsITransport> destTransport; 1.202 + rv = sts->CreateOutputTransport(destStr, int64_t(-1), int64_t(-1), true, 1.203 + getter_AddRefs(destTransport)); 1.204 + if (NS_FAILED(rv)) return rv; 1.205 + 1.206 + MyCopier *copier = new MyCopier(); 1.207 + if (copier == nullptr) 1.208 + return NS_ERROR_OUT_OF_MEMORY; 1.209 + NS_ADDREF(copier); 1.210 + 1.211 + rv = copier->AsyncCopy(srcTransport, destTransport); 1.212 + if (NS_FAILED(rv)) return rv; 1.213 + 1.214 + PumpEvents(); 1.215 + 1.216 + NS_RELEASE(copier); 1.217 + return NS_OK; 1.218 +} 1.219 + 1.220 +//////////////////////////////////////////////////////////////////////////////// 1.221 + 1.222 +static nsresult 1.223 +RunBlockingTest(nsIFile *srcFile, nsIFile *destFile) 1.224 +{ 1.225 + nsresult rv; 1.226 + 1.227 + LOG(("RunBlockingTest\n")); 1.228 + 1.229 + nsCOMPtr<nsIStreamTransportService> sts = 1.230 + do_GetService(kStreamTransportServiceCID, &rv); 1.231 + if (NS_FAILED(rv)) return rv; 1.232 + 1.233 + nsCOMPtr<nsIInputStream> srcIn; 1.234 + rv = NS_NewLocalFileInputStream(getter_AddRefs(srcIn), srcFile); 1.235 + if (NS_FAILED(rv)) return rv; 1.236 + 1.237 + nsCOMPtr<nsIOutputStream> fileOut; 1.238 + rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileOut), destFile); 1.239 + if (NS_FAILED(rv)) return rv; 1.240 + 1.241 + nsCOMPtr<nsITransport> destTransport; 1.242 + rv = sts->CreateOutputTransport(fileOut, int64_t(-1), int64_t(-1), 1.243 + true, getter_AddRefs(destTransport)); 1.244 + if (NS_FAILED(rv)) return rv; 1.245 + 1.246 + nsCOMPtr<nsIOutputStream> destOut; 1.247 + rv = destTransport->OpenOutputStream(nsITransport::OPEN_BLOCKING, 100, 10, getter_AddRefs(destOut)); 1.248 + if (NS_FAILED(rv)) return rv; 1.249 + 1.250 + char buf[120]; 1.251 + uint32_t n; 1.252 + for (;;) { 1.253 + rv = srcIn->Read(buf, sizeof(buf), &n); 1.254 + if (NS_FAILED(rv) || (n == 0)) return rv; 1.255 + 1.256 + rv = destOut->Write(buf, n, &n); 1.257 + if (NS_FAILED(rv)) return rv; 1.258 + } 1.259 + 1.260 + return NS_OK; 1.261 +} 1.262 + 1.263 +//////////////////////////////////////////////////////////////////////////////// 1.264 + 1.265 +int 1.266 +main(int argc, char* argv[]) 1.267 +{ 1.268 + if (test_common_init(&argc, &argv) != 0) 1.269 + return -1; 1.270 + 1.271 + nsresult rv; 1.272 + 1.273 + if (argc < 2) { 1.274 + printf("usage: %s <file-to-read>\n", argv[0]); 1.275 + return -1; 1.276 + } 1.277 + char* fileName = argv[1]; 1.278 + { 1.279 + nsCOMPtr<nsIServiceManager> servMan; 1.280 + NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); 1.281 + nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); 1.282 + NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); 1.283 + if (registrar) 1.284 + registrar->AutoRegister(nullptr); 1.285 + 1.286 +#if defined(PR_LOGGING) 1.287 + gTestLog = PR_NewLogModule("Test"); 1.288 +#endif 1.289 + 1.290 + nsCOMPtr<nsIFile> srcFile; 1.291 + rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(srcFile)); 1.292 + if (NS_FAILED(rv)) return rv; 1.293 + 1.294 + nsCOMPtr<nsIFile> destFile; 1.295 + rv = srcFile->Clone(getter_AddRefs(destFile)); 1.296 + if (NS_FAILED(rv)) return rv; 1.297 + 1.298 + nsAutoCString leafName; 1.299 + rv = destFile->GetNativeLeafName(leafName); 1.300 + if (NS_FAILED(rv)) return rv; 1.301 + 1.302 + nsAutoCString newName(leafName); 1.303 + newName.Append(NS_LITERAL_CSTRING(".1")); 1.304 + rv = destFile->SetNativeLeafName(newName); 1.305 + if (NS_FAILED(rv)) return rv; 1.306 + 1.307 + rv = RunTest(srcFile, destFile); 1.308 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); 1.309 + 1.310 + newName = leafName; 1.311 + newName.Append(NS_LITERAL_CSTRING(".2")); 1.312 + rv = destFile->SetNativeLeafName(newName); 1.313 + if (NS_FAILED(rv)) return rv; 1.314 + 1.315 + rv = RunBlockingTest(srcFile, destFile); 1.316 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunBlockingTest failed"); 1.317 + 1.318 + // give background threads a chance to finish whatever work they may 1.319 + // be doing. 1.320 + PR_Sleep(PR_SecondsToInterval(1)); 1.321 + } // this scopes the nsCOMPtrs 1.322 + // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM 1.323 + rv = NS_ShutdownXPCOM(nullptr); 1.324 + NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); 1.325 + return NS_OK; 1.326 +}