|
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/. */ |
|
4 |
|
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 <algorithm> |
|
25 |
|
26 //////////////////////////////////////////////////////////////////////////////// |
|
27 |
|
28 #if defined(PR_LOGGING) |
|
29 // |
|
30 // set NSPR_LOG_MODULES=Test:5 |
|
31 // |
|
32 static PRLogModuleInfo *gTestLog = nullptr; |
|
33 #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) |
|
34 #else |
|
35 #define LOG(args) |
|
36 #endif |
|
37 |
|
38 //////////////////////////////////////////////////////////////////////////////// |
|
39 |
|
40 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); |
|
41 |
|
42 //////////////////////////////////////////////////////////////////////////////// |
|
43 |
|
44 class MyListener : public nsIStreamListener |
|
45 { |
|
46 public: |
|
47 NS_DECL_ISUPPORTS |
|
48 |
|
49 MyListener() {} |
|
50 virtual ~MyListener() {} |
|
51 |
|
52 NS_IMETHOD OnStartRequest(nsIRequest *req, nsISupports *ctx) |
|
53 { |
|
54 LOG(("MyListener::OnStartRequest\n")); |
|
55 return NS_OK; |
|
56 } |
|
57 |
|
58 NS_IMETHOD OnDataAvailable(nsIRequest *req, nsISupports *ctx, |
|
59 nsIInputStream *stream, |
|
60 uint32_t offset, uint32_t count) |
|
61 { |
|
62 LOG(("MyListener::OnDataAvailable [offset=%u count=%u]\n", offset, count)); |
|
63 |
|
64 char buf[500]; |
|
65 nsresult rv; |
|
66 |
|
67 while (count) { |
|
68 uint32_t n, amt = std::min<uint32_t>(count, sizeof(buf)); |
|
69 |
|
70 rv = stream->Read(buf, amt, &n); |
|
71 if (NS_FAILED(rv)) { |
|
72 LOG((" read returned 0x%08x\n", rv)); |
|
73 return rv; |
|
74 } |
|
75 |
|
76 LOG((" read %u bytes\n", n)); |
|
77 count -= n; |
|
78 } |
|
79 |
|
80 return NS_OK; |
|
81 } |
|
82 |
|
83 NS_IMETHOD OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) |
|
84 { |
|
85 LOG(("MyListener::OnStopRequest [status=%x]\n", status)); |
|
86 QuitPumpingEvents(); |
|
87 return NS_OK; |
|
88 } |
|
89 }; |
|
90 |
|
91 NS_IMPL_ISUPPORTS(MyListener, |
|
92 nsIRequestObserver, |
|
93 nsIStreamListener) |
|
94 |
|
95 //////////////////////////////////////////////////////////////////////////////// |
|
96 |
|
97 class MyCallbacks : public nsIInterfaceRequestor |
|
98 , public nsIProgressEventSink |
|
99 { |
|
100 public: |
|
101 NS_DECL_ISUPPORTS |
|
102 |
|
103 MyCallbacks() {} |
|
104 virtual ~MyCallbacks() {} |
|
105 |
|
106 NS_IMETHOD GetInterface(const nsID &iid, void **result) |
|
107 { |
|
108 return QueryInterface(iid, result); |
|
109 } |
|
110 |
|
111 NS_IMETHOD OnStatus(nsIRequest *req, nsISupports *ctx, nsresult status, |
|
112 const char16_t *statusArg) |
|
113 { |
|
114 LOG(("MyCallbacks::OnStatus [status=%x]\n", status)); |
|
115 return NS_OK; |
|
116 } |
|
117 |
|
118 NS_IMETHOD OnProgress(nsIRequest *req, nsISupports *ctx, |
|
119 uint64_t progress, uint64_t progressMax) |
|
120 { |
|
121 LOG(("MyCallbacks::OnProgress [progress=%llu/%llu]\n", progress, progressMax)); |
|
122 return NS_OK; |
|
123 } |
|
124 }; |
|
125 |
|
126 NS_IMPL_ISUPPORTS(MyCallbacks, |
|
127 nsIInterfaceRequestor, |
|
128 nsIProgressEventSink) |
|
129 |
|
130 //////////////////////////////////////////////////////////////////////////////// |
|
131 |
|
132 /** |
|
133 * asynchronously copy file. |
|
134 */ |
|
135 static nsresult |
|
136 RunTest(nsIFile *file) |
|
137 { |
|
138 nsresult rv; |
|
139 |
|
140 LOG(("RunTest\n")); |
|
141 |
|
142 nsCOMPtr<nsIInputStream> stream; |
|
143 rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file); |
|
144 if (NS_FAILED(rv)) return rv; |
|
145 |
|
146 nsCOMPtr<nsIURI> uri = do_CreateInstance(kSimpleURICID); |
|
147 if (uri) |
|
148 uri->SetSpec(NS_LITERAL_CSTRING("foo://bar")); |
|
149 |
|
150 nsCOMPtr<nsIChannel> chan; |
|
151 rv = NS_NewInputStreamChannel(getter_AddRefs(chan), uri, stream); |
|
152 if (NS_FAILED(rv)) return rv; |
|
153 |
|
154 rv = chan->SetNotificationCallbacks(new MyCallbacks()); |
|
155 if (NS_FAILED(rv)) return rv; |
|
156 |
|
157 rv = chan->AsyncOpen(new MyListener(), nullptr); |
|
158 if (NS_FAILED(rv)) return rv; |
|
159 |
|
160 PumpEvents(); |
|
161 return NS_OK; |
|
162 } |
|
163 |
|
164 //////////////////////////////////////////////////////////////////////////////// |
|
165 |
|
166 int |
|
167 main(int argc, char* argv[]) |
|
168 { |
|
169 if (test_common_init(&argc, &argv) != 0) |
|
170 return -1; |
|
171 |
|
172 nsresult rv; |
|
173 |
|
174 if (argc < 2) { |
|
175 printf("usage: %s <file-to-read>\n", argv[0]); |
|
176 return -1; |
|
177 } |
|
178 char* fileName = argv[1]; |
|
179 { |
|
180 nsCOMPtr<nsIServiceManager> servMan; |
|
181 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); |
|
182 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); |
|
183 NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); |
|
184 if (registrar) |
|
185 registrar->AutoRegister(nullptr); |
|
186 |
|
187 #if defined(PR_LOGGING) |
|
188 gTestLog = PR_NewLogModule("Test"); |
|
189 #endif |
|
190 |
|
191 nsCOMPtr<nsIFile> file; |
|
192 rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(file)); |
|
193 if (NS_FAILED(rv)) return rv; |
|
194 |
|
195 rv = RunTest(file); |
|
196 NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); |
|
197 |
|
198 // give background threads a chance to finish whatever work they may |
|
199 // be doing. |
|
200 PR_Sleep(PR_SecondsToInterval(1)); |
|
201 } // this scopes the nsCOMPtrs |
|
202 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM |
|
203 rv = NS_ShutdownXPCOM(nullptr); |
|
204 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); |
|
205 return NS_OK; |
|
206 } |