netwerk/test/TestMCTransport.cpp

changeset 1
ca08bd8f51b2
equal deleted inserted replaced
-1:000000000000 0:c0fac682ecfd
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include <stdio.h>
7
8 #include "nsIServiceManager.h"
9 #include "nsIEventQueueService.h"
10 #include "nsIOutputStream.h"
11 #include "nsIStreamListener.h"
12 #include "nsITransport.h"
13 #include "nsIInputStream.h"
14 #include "nsIOutputStream.h"
15 #include "nsCOMPtr.h"
16 #include "plstr.h"
17 #include "prprf.h"
18 #include <algorithm>
19
20 #ifndef USE_CREATE_INSTANCE
21 #include "nsICacheService.h"
22 #include "nsICacheSession.h"
23 #include "nsICacheEntryDescriptor.h"
24 #include "nsNetCID.h"
25 static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID);
26 static nsICacheSession *session = nullptr;
27 static nsICacheEntryDescriptor *desc = nullptr;
28 #endif
29
30 /**
31 * This test program exercises the memory cache's nsITransport implementation.
32 *
33 * This test program loads a file into the memory cache (using OpenOutputStream),
34 * and then reads the file back out (using AsyncRead). The data read from the
35 * memory cache is written to a new file (with .out added as a suffix to the file
36 * name).
37 */
38
39 static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
40 static nsIEventQueue *gEventQ = nullptr;
41
42 class TestListener : public nsIStreamListener
43 {
44 public:
45 NS_DECL_ISUPPORTS
46 NS_DECL_NSISTREAMLISTENER
47 NS_DECL_NSIREQUESTOBSERVER
48
49 TestListener(char *);
50 virtual ~TestListener();
51
52 private:
53 char *mFilename;
54 FILE *mFile;
55 };
56
57 NS_IMPL_ISUPPORTS(TestListener,
58 nsIStreamListener,
59 nsIRequestObserver)
60
61 TestListener::TestListener(char *filename)
62 : mFilename(filename)
63 , mFile(nullptr)
64 {
65 }
66
67 TestListener::~TestListener()
68 {
69 }
70
71 NS_IMETHODIMP
72 TestListener::OnStartRequest(nsIRequest *req, nsISupports *ctx)
73 {
74 printf("OnStartRequest\n");
75
76 mFile = fopen(mFilename, "w");
77 if (!mFile)
78 return NS_ERROR_FAILURE;
79
80 return NS_OK;
81 }
82
83 NS_IMETHODIMP
84 TestListener::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
85 {
86 printf("OnStopRequest: status=%x\n", status);
87
88 if (mFile)
89 fclose(mFile);
90
91 return NS_OK;
92 }
93
94 NS_IMETHODIMP
95 TestListener::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
96 nsIInputStream *is,
97 uint64_t offset, uint32_t count)
98 {
99 printf("OnDataAvailable: offset=%llu count=%u\n", offset, count);
100
101 if (!mFile) return NS_ERROR_FAILURE;
102
103 char buf[128];
104 nsresult rv;
105 uint32_t nread = 0;
106
107 while (count) {
108 uint32_t amount = std::min<uint32_t>(count, sizeof(buf));
109
110 rv = is->Read(buf, amount, &nread);
111 if (NS_FAILED(rv)) return rv;
112
113 fwrite(buf, nread, 1, mFile);
114 count -= nread;
115 }
116 return NS_OK;
117 }
118
119 nsresult TestMCTransport(const char *filename)
120 {
121 nsresult rv = NS_OK;
122 nsCOMPtr<nsITransport> transport;
123
124 #ifdef USE_CREATE_INSTANCE
125 transport = do_CreateInstance(
126 "@mozilla.org/network/memory-cache-transport;1", &rv);
127 if (NS_FAILED(rv))
128 return rv;
129 #else
130 nsCOMPtr<nsICacheService> serv(do_GetService(kCacheServiceCID, &rv));
131 if (NS_FAILED(rv)) return rv;
132
133 rv = serv->CreateSession("TestMCTransport",
134 nsICache::STORE_IN_MEMORY, true,
135 &session);
136 if (NS_FAILED(rv)) return rv;
137
138 rv = session->OpenCacheEntry(nsDependentCString(filename),
139 nsICache::ACCESS_READ_WRITE,
140 nsICache::BLOCKING,
141 &desc);
142 if (NS_FAILED(rv)) return rv;
143
144 rv = desc->MarkValid();
145 if (NS_FAILED(rv)) return rv;
146
147 rv = desc->GetTransport(getter_AddRefs(transport));
148 if (NS_FAILED(rv)) return rv;
149 #endif
150
151 nsCOMPtr<nsIOutputStream> os;
152 rv = transport->OpenOutputStream(0, (uint32_t) -1, 0, getter_AddRefs(os));
153 if (NS_FAILED(rv)) return rv;
154
155 char *out = PR_smprintf("%s.out", filename);
156 nsCOMPtr<nsIStreamListener> listener = new TestListener(out);
157 if (!listener)
158 return NS_ERROR_OUT_OF_MEMORY;
159
160 nsCOMPtr<nsIRequest> req;
161 rv = transport->AsyncRead(listener, nullptr, 0, (uint32_t) -1, 0, getter_AddRefs(req));
162 if (NS_FAILED(rv)) return rv;
163
164 FILE *file = fopen(filename, "r");
165 if (!file)
166 return NS_ERROR_FILE_NOT_FOUND;
167
168 char buf[256];
169 uint32_t count, total=0;
170
171 while ((count = fread(buf, 1, sizeof(buf), file)) > 0) {
172 printf("writing %u bytes\n", count);
173 total += count;
174 rv = os->Write(buf, count, &count);
175 if (NS_FAILED(rv)) return rv;
176
177 // process an event
178 PLEvent *event = nullptr;
179 gEventQ->GetEvent(&event);
180 if (event) gEventQ->HandleEvent(event);
181 }
182
183 printf("wrote %u bytes\n", total);
184
185 return rv;
186 }
187
188 int main(int argc, char **argv)
189 {
190 nsresult rv;
191
192 if (argc < 2) {
193 printf("usage: %s filename\n", argv[0]);
194 return -1;
195 }
196
197 nsCOMPtr<nsIEventQueueService> eqs =
198 do_GetService(kEventQueueServiceCID, &rv);
199 if (NS_FAILED(rv)) {
200 printf("failed to create event queue service: rv=%x\n", rv);
201 return -1;
202 }
203
204 rv = eqs->CreateMonitoredThreadEventQueue();
205 if (NS_FAILED(rv)) {
206 printf("failed to create monitored event queue: rv=%x\n", rv);
207 return -1;
208 }
209
210 rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ);
211 if (NS_FAILED(rv)) {
212 printf("failed to get thread event queue: %x\n", rv);
213 return -1;
214 }
215
216 rv = TestMCTransport(argv[1]);
217 printf("TestMCTransport returned %x\n", rv);
218
219 gEventQ->ProcessPendingEvents();
220
221 #ifndef USE_CREATE_INSTANCE
222 NS_IF_RELEASE(desc);
223 NS_IF_RELEASE(session);
224 #endif
225 return 0;
226 }

mercurial