1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/TestMCTransport.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,226 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include <stdio.h> 1.10 + 1.11 +#include "nsIServiceManager.h" 1.12 +#include "nsIEventQueueService.h" 1.13 +#include "nsIOutputStream.h" 1.14 +#include "nsIStreamListener.h" 1.15 +#include "nsITransport.h" 1.16 +#include "nsIInputStream.h" 1.17 +#include "nsIOutputStream.h" 1.18 +#include "nsCOMPtr.h" 1.19 +#include "plstr.h" 1.20 +#include "prprf.h" 1.21 +#include <algorithm> 1.22 + 1.23 +#ifndef USE_CREATE_INSTANCE 1.24 +#include "nsICacheService.h" 1.25 +#include "nsICacheSession.h" 1.26 +#include "nsICacheEntryDescriptor.h" 1.27 +#include "nsNetCID.h" 1.28 +static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID); 1.29 +static nsICacheSession *session = nullptr; 1.30 +static nsICacheEntryDescriptor *desc = nullptr; 1.31 +#endif 1.32 + 1.33 +/** 1.34 + * This test program exercises the memory cache's nsITransport implementation. 1.35 + * 1.36 + * This test program loads a file into the memory cache (using OpenOutputStream), 1.37 + * and then reads the file back out (using AsyncRead). The data read from the 1.38 + * memory cache is written to a new file (with .out added as a suffix to the file 1.39 + * name). 1.40 + */ 1.41 + 1.42 +static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); 1.43 +static nsIEventQueue *gEventQ = nullptr; 1.44 + 1.45 +class TestListener : public nsIStreamListener 1.46 +{ 1.47 +public: 1.48 + NS_DECL_ISUPPORTS 1.49 + NS_DECL_NSISTREAMLISTENER 1.50 + NS_DECL_NSIREQUESTOBSERVER 1.51 + 1.52 + TestListener(char *); 1.53 + virtual ~TestListener(); 1.54 + 1.55 +private: 1.56 + char *mFilename; 1.57 + FILE *mFile; 1.58 +}; 1.59 + 1.60 +NS_IMPL_ISUPPORTS(TestListener, 1.61 + nsIStreamListener, 1.62 + nsIRequestObserver) 1.63 + 1.64 +TestListener::TestListener(char *filename) 1.65 + : mFilename(filename) 1.66 + , mFile(nullptr) 1.67 +{ 1.68 +} 1.69 + 1.70 +TestListener::~TestListener() 1.71 +{ 1.72 +} 1.73 + 1.74 +NS_IMETHODIMP 1.75 +TestListener::OnStartRequest(nsIRequest *req, nsISupports *ctx) 1.76 +{ 1.77 + printf("OnStartRequest\n"); 1.78 + 1.79 + mFile = fopen(mFilename, "w"); 1.80 + if (!mFile) 1.81 + return NS_ERROR_FAILURE; 1.82 + 1.83 + return NS_OK; 1.84 +} 1.85 + 1.86 +NS_IMETHODIMP 1.87 +TestListener::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) 1.88 +{ 1.89 + printf("OnStopRequest: status=%x\n", status); 1.90 + 1.91 + if (mFile) 1.92 + fclose(mFile); 1.93 + 1.94 + return NS_OK; 1.95 +} 1.96 + 1.97 +NS_IMETHODIMP 1.98 +TestListener::OnDataAvailable(nsIRequest *req, nsISupports *ctx, 1.99 + nsIInputStream *is, 1.100 + uint64_t offset, uint32_t count) 1.101 +{ 1.102 + printf("OnDataAvailable: offset=%llu count=%u\n", offset, count); 1.103 + 1.104 + if (!mFile) return NS_ERROR_FAILURE; 1.105 + 1.106 + char buf[128]; 1.107 + nsresult rv; 1.108 + uint32_t nread = 0; 1.109 + 1.110 + while (count) { 1.111 + uint32_t amount = std::min<uint32_t>(count, sizeof(buf)); 1.112 + 1.113 + rv = is->Read(buf, amount, &nread); 1.114 + if (NS_FAILED(rv)) return rv; 1.115 + 1.116 + fwrite(buf, nread, 1, mFile); 1.117 + count -= nread; 1.118 + } 1.119 + return NS_OK; 1.120 +} 1.121 + 1.122 +nsresult TestMCTransport(const char *filename) 1.123 +{ 1.124 + nsresult rv = NS_OK; 1.125 + nsCOMPtr<nsITransport> transport; 1.126 + 1.127 +#ifdef USE_CREATE_INSTANCE 1.128 + transport = do_CreateInstance( 1.129 + "@mozilla.org/network/memory-cache-transport;1", &rv); 1.130 + if (NS_FAILED(rv)) 1.131 + return rv; 1.132 +#else 1.133 + nsCOMPtr<nsICacheService> serv(do_GetService(kCacheServiceCID, &rv)); 1.134 + if (NS_FAILED(rv)) return rv; 1.135 + 1.136 + rv = serv->CreateSession("TestMCTransport", 1.137 + nsICache::STORE_IN_MEMORY, true, 1.138 + &session); 1.139 + if (NS_FAILED(rv)) return rv; 1.140 + 1.141 + rv = session->OpenCacheEntry(nsDependentCString(filename), 1.142 + nsICache::ACCESS_READ_WRITE, 1.143 + nsICache::BLOCKING, 1.144 + &desc); 1.145 + if (NS_FAILED(rv)) return rv; 1.146 + 1.147 + rv = desc->MarkValid(); 1.148 + if (NS_FAILED(rv)) return rv; 1.149 + 1.150 + rv = desc->GetTransport(getter_AddRefs(transport)); 1.151 + if (NS_FAILED(rv)) return rv; 1.152 +#endif 1.153 + 1.154 + nsCOMPtr<nsIOutputStream> os; 1.155 + rv = transport->OpenOutputStream(0, (uint32_t) -1, 0, getter_AddRefs(os)); 1.156 + if (NS_FAILED(rv)) return rv; 1.157 + 1.158 + char *out = PR_smprintf("%s.out", filename); 1.159 + nsCOMPtr<nsIStreamListener> listener = new TestListener(out); 1.160 + if (!listener) 1.161 + return NS_ERROR_OUT_OF_MEMORY; 1.162 + 1.163 + nsCOMPtr<nsIRequest> req; 1.164 + rv = transport->AsyncRead(listener, nullptr, 0, (uint32_t) -1, 0, getter_AddRefs(req)); 1.165 + if (NS_FAILED(rv)) return rv; 1.166 + 1.167 + FILE *file = fopen(filename, "r"); 1.168 + if (!file) 1.169 + return NS_ERROR_FILE_NOT_FOUND; 1.170 + 1.171 + char buf[256]; 1.172 + uint32_t count, total=0; 1.173 + 1.174 + while ((count = fread(buf, 1, sizeof(buf), file)) > 0) { 1.175 + printf("writing %u bytes\n", count); 1.176 + total += count; 1.177 + rv = os->Write(buf, count, &count); 1.178 + if (NS_FAILED(rv)) return rv; 1.179 + 1.180 + // process an event 1.181 + PLEvent *event = nullptr; 1.182 + gEventQ->GetEvent(&event); 1.183 + if (event) gEventQ->HandleEvent(event); 1.184 + } 1.185 + 1.186 + printf("wrote %u bytes\n", total); 1.187 + 1.188 + return rv; 1.189 +} 1.190 + 1.191 +int main(int argc, char **argv) 1.192 +{ 1.193 + nsresult rv; 1.194 + 1.195 + if (argc < 2) { 1.196 + printf("usage: %s filename\n", argv[0]); 1.197 + return -1; 1.198 + } 1.199 + 1.200 + nsCOMPtr<nsIEventQueueService> eqs = 1.201 + do_GetService(kEventQueueServiceCID, &rv); 1.202 + if (NS_FAILED(rv)) { 1.203 + printf("failed to create event queue service: rv=%x\n", rv); 1.204 + return -1; 1.205 + } 1.206 + 1.207 + rv = eqs->CreateMonitoredThreadEventQueue(); 1.208 + if (NS_FAILED(rv)) { 1.209 + printf("failed to create monitored event queue: rv=%x\n", rv); 1.210 + return -1; 1.211 + } 1.212 + 1.213 + rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); 1.214 + if (NS_FAILED(rv)) { 1.215 + printf("failed to get thread event queue: %x\n", rv); 1.216 + return -1; 1.217 + } 1.218 + 1.219 + rv = TestMCTransport(argv[1]); 1.220 + printf("TestMCTransport returned %x\n", rv); 1.221 + 1.222 + gEventQ->ProcessPendingEvents(); 1.223 + 1.224 +#ifndef USE_CREATE_INSTANCE 1.225 + NS_IF_RELEASE(desc); 1.226 + NS_IF_RELEASE(session); 1.227 +#endif 1.228 + return 0; 1.229 +}