|
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 "nsISeekableStream.h" |
|
16 #include "nsCOMPtr.h" |
|
17 #include "nsMemory.h" |
|
18 #include "nsStringAPI.h" |
|
19 #include "nsIFileStreams.h" |
|
20 #include "nsIStreamListener.h" |
|
21 #include "nsIFile.h" |
|
22 #include "nsNetUtil.h" |
|
23 #include "nsAutoLock.h" |
|
24 #include "prlog.h" |
|
25 #include "prprf.h" |
|
26 #include <algorithm> |
|
27 |
|
28 //////////////////////////////////////////////////////////////////////////////// |
|
29 |
|
30 #if defined(PR_LOGGING) |
|
31 // |
|
32 // set NSPR_LOG_MODULES=Test:5 |
|
33 // |
|
34 static PRLogModuleInfo *gTestLog = nullptr; |
|
35 #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) |
|
36 #else |
|
37 #define LOG(args) |
|
38 #endif |
|
39 |
|
40 //////////////////////////////////////////////////////////////////////////////// |
|
41 |
|
42 class MyListener : public nsIStreamListener |
|
43 { |
|
44 public: |
|
45 NS_DECL_ISUPPORTS |
|
46 |
|
47 MyListener() {} |
|
48 virtual ~MyListener() {} |
|
49 |
|
50 NS_IMETHOD OnStartRequest(nsIRequest *req, nsISupports *ctx) |
|
51 { |
|
52 LOG(("MyListener::OnStartRequest\n")); |
|
53 return NS_OK; |
|
54 } |
|
55 |
|
56 NS_IMETHOD OnDataAvailable(nsIRequest *req, nsISupports *ctx, |
|
57 nsIInputStream *stream, |
|
58 uint64_t offset, uint32_t count) |
|
59 { |
|
60 LOG(("MyListener::OnDataAvailable [offset=%llu count=%u]\n", offset, count)); |
|
61 |
|
62 char buf[500]; |
|
63 nsresult rv; |
|
64 |
|
65 while (count) { |
|
66 uint32_t n, amt = std::min<uint32_t>(count, sizeof(buf)); |
|
67 |
|
68 rv = stream->Read(buf, amt, &n); |
|
69 if (NS_FAILED(rv)) { |
|
70 LOG((" read returned 0x%08x\n", rv)); |
|
71 return rv; |
|
72 } |
|
73 |
|
74 fwrite(buf, n, 1, stdout); |
|
75 printf("\n"); |
|
76 |
|
77 LOG((" read %u bytes\n", n)); |
|
78 count -= n; |
|
79 } |
|
80 |
|
81 return NS_OK; |
|
82 } |
|
83 |
|
84 NS_IMETHOD OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) |
|
85 { |
|
86 LOG(("MyListener::OnStopRequest [status=%x]\n", status)); |
|
87 QuitPumpingEvents(); |
|
88 return NS_OK; |
|
89 } |
|
90 }; |
|
91 |
|
92 NS_IMPL_ISUPPORTS(MyListener, |
|
93 nsIRequestObserver, |
|
94 nsIStreamListener) |
|
95 |
|
96 //////////////////////////////////////////////////////////////////////////////// |
|
97 |
|
98 /** |
|
99 * asynchronously copy file. |
|
100 */ |
|
101 static nsresult |
|
102 RunTest(nsIFile *file, int64_t offset, int64_t length) |
|
103 { |
|
104 nsresult rv; |
|
105 |
|
106 LOG(("RunTest\n")); |
|
107 |
|
108 nsCOMPtr<nsIInputStream> stream; |
|
109 rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file); |
|
110 if (NS_FAILED(rv)) return rv; |
|
111 |
|
112 nsCOMPtr<nsIInputStreamPump> pump; |
|
113 rv = NS_NewInputStreamPump(getter_AddRefs(pump), stream, offset, length); |
|
114 if (NS_FAILED(rv)) return rv; |
|
115 |
|
116 rv = pump->AsyncRead(new MyListener(), nullptr); |
|
117 if (NS_FAILED(rv)) return rv; |
|
118 |
|
119 PumpEvents(); |
|
120 return NS_OK; |
|
121 } |
|
122 |
|
123 //////////////////////////////////////////////////////////////////////////////// |
|
124 |
|
125 int |
|
126 main(int argc, char* argv[]) |
|
127 { |
|
128 if (test_common_init(&argc, &argv) != 0) |
|
129 return -1; |
|
130 |
|
131 nsresult rv; |
|
132 |
|
133 if (argc < 4) { |
|
134 printf("usage: %s <file-to-read> <start-offset> <read-length>\n", argv[0]); |
|
135 return -1; |
|
136 } |
|
137 char* fileName = argv[1]; |
|
138 int64_t offset, length; |
|
139 int err = PR_sscanf(argv[2], "%lld", &offset); |
|
140 if (err == -1) { |
|
141 printf("Start offset must be an integer!\n"); |
|
142 return 1; |
|
143 } |
|
144 err = PR_sscanf(argv[3], "%lld", &length); |
|
145 if (err == -1) { |
|
146 printf("Length must be an integer!\n"); |
|
147 return 1; |
|
148 } |
|
149 |
|
150 { |
|
151 nsCOMPtr<nsIServiceManager> servMan; |
|
152 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); |
|
153 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); |
|
154 NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); |
|
155 if (registrar) |
|
156 registrar->AutoRegister(nullptr); |
|
157 |
|
158 #if defined(PR_LOGGING) |
|
159 gTestLog = PR_NewLogModule("Test"); |
|
160 #endif |
|
161 |
|
162 nsCOMPtr<nsIFile> file; |
|
163 rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(file)); |
|
164 if (NS_FAILED(rv)) return rv; |
|
165 |
|
166 rv = RunTest(file, offset, length); |
|
167 NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); |
|
168 |
|
169 // give background threads a chance to finish whatever work they may |
|
170 // be doing. |
|
171 PR_Sleep(PR_SecondsToInterval(1)); |
|
172 } // this scopes the nsCOMPtrs |
|
173 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM |
|
174 rv = NS_ShutdownXPCOM(nullptr); |
|
175 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); |
|
176 return NS_OK; |
|
177 } |