netwerk/test/TestStreamTransport.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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)
    29 //
    30 // set NSPR_LOG_MODULES=Test:5
    31 //
    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
    46 {
    47 public:
    48     NS_DECL_THREADSAFE_ISUPPORTS
    50     MyCopier()
    51         : mLock(nullptr)
    52         , mInputCondition(NS_OK)
    53     {
    54     }
    56     virtual ~MyCopier()
    57     {
    58         if (mLock)
    59             nsAutoLock::DestroyLock(mLock);
    60         if (mInput)
    61             mInput->Close();
    62         if (mOutput)
    63             mOutput->Close();
    64     }
    66     // called on any thread
    67     NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream *inStr)
    68     {
    69         LOG(("OnInputStreamReady\n"));
    70         nsAutoLock lock(mLock);
    71         NS_ASSERTION(inStr == mInput, "unexpected stream");
    72         Process_Locked();
    73         return NS_OK;
    74     }
    76     // called on any thread
    77     NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream *outStr)
    78     {
    79         LOG(("OnOutputStreamReady\n"));
    80         nsAutoLock lock(mLock);
    81         NS_ASSERTION(outStr == mOutput, "unexpected stream");
    82         Process_Locked();
    83         return NS_OK;
    84     }
    86     void Close_Locked()
    87     {
    88         LOG(("Close_Locked\n"));
    90         mOutput->Close();
    91         mOutput = 0;
    92         mInput->Close();
    93         mInput = 0;
    95         // post done copying event
    96         QuitPumpingEvents();
    97     }
    99     void Process_Locked()
   100     {
   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;
   114             }
   115         }
   116     }
   118     nsresult AsyncCopy(nsITransport *srcTrans, nsITransport *destTrans)
   119     {
   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);
   138     }
   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)
   146     {
   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;
   156     }
   158 protected:
   159     PRLock                        *mLock;
   160     nsCOMPtr<nsIAsyncInputStream>  mInput;
   161     nsCOMPtr<nsIAsyncOutputStream> mOutput;
   162     nsresult                       mInputCondition;
   163 };
   165 NS_IMPL_ISUPPORTS(MyCopier,
   166                   nsIInputStreamCallback,
   167                   nsIOutputStreamCallback)
   169 ////////////////////////////////////////////////////////////////////////////////
   171 /**
   172  * asynchronously copy file.
   173  */
   174 static nsresult
   175 RunTest(nsIFile *srcFile, nsIFile *destFile)
   176 {
   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;
   215 }
   217 ////////////////////////////////////////////////////////////////////////////////
   219 static nsresult
   220 RunBlockingTest(nsIFile *srcFile, nsIFile *destFile)
   221 {
   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;
   255     }
   257     return NS_OK;
   258 }
   260 ////////////////////////////////////////////////////////////////////////////////
   262 int
   263 main(int argc, char* argv[])
   264 {
   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;
   273     }
   274     char* fileName = argv[1];
   275     {
   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.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");
   307         newName = leafName;
   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
   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;
   323 }

mercurial