TestStreamPump.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. #include "TestCommon.h"
  5. #include "nsIComponentRegistrar.h"
  6. #include "nsIStreamTransportService.h"
  7. #include "nsIAsyncInputStream.h"
  8. #include "nsIProgressEventSink.h"
  9. #include "nsIInterfaceRequestor.h"
  10. #include "nsIInterfaceRequestorUtils.h"
  11. #include "nsIRequest.h"
  12. #include "nsIServiceManager.h"
  13. #include "nsIComponentManager.h"
  14. #include "nsISeekableStream.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 "mozilla/Logging.h"
  24. #include "prprf.h"
  25. #include <algorithm>
  26. ////////////////////////////////////////////////////////////////////////////////
  27. //
  28. // set NSPR_LOG_MODULES=Test:5
  29. //
  30. static PRLogModuleInfo *gTestLog = nullptr;
  31. #define LOG(args) MOZ_LOG(gTestLog, mozilla::LogLevel::Debug, args)
  32. ////////////////////////////////////////////////////////////////////////////////
  33. class MyListener : public nsIStreamListener
  34. {
  35. public:
  36. NS_DECL_ISUPPORTS
  37. MyListener() {}
  38. virtual ~MyListener() {}
  39. NS_IMETHOD OnStartRequest(nsIRequest *req, nsISupports *ctx)
  40. {
  41. LOG(("MyListener::OnStartRequest\n"));
  42. return NS_OK;
  43. }
  44. NS_IMETHOD OnDataAvailable(nsIRequest *req, nsISupports *ctx,
  45. nsIInputStream *stream,
  46. uint64_t offset, uint32_t count)
  47. {
  48. LOG(("MyListener::OnDataAvailable [offset=%llu count=%u]\n", offset, count));
  49. char buf[500];
  50. nsresult rv;
  51. while (count) {
  52. uint32_t n, amt = std::min<uint32_t>(count, sizeof(buf));
  53. rv = stream->Read(buf, amt, &n);
  54. if (NS_FAILED(rv)) {
  55. LOG((" read returned 0x%08x\n", rv));
  56. return rv;
  57. }
  58. fwrite(buf, n, 1, stdout);
  59. printf("\n");
  60. LOG((" read %u bytes\n", n));
  61. count -= n;
  62. }
  63. return NS_OK;
  64. }
  65. NS_IMETHOD OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
  66. {
  67. LOG(("MyListener::OnStopRequest [status=%x]\n", status));
  68. QuitPumpingEvents();
  69. return NS_OK;
  70. }
  71. };
  72. NS_IMPL_ISUPPORTS(MyListener,
  73. nsIRequestObserver,
  74. nsIStreamListener)
  75. ////////////////////////////////////////////////////////////////////////////////
  76. /**
  77. * asynchronously copy file.
  78. */
  79. static nsresult
  80. RunTest(nsIFile *file, int64_t offset, int64_t length)
  81. {
  82. nsresult rv;
  83. LOG(("RunTest\n"));
  84. nsCOMPtr<nsIInputStream> stream;
  85. rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
  86. if (NS_FAILED(rv)) return rv;
  87. nsCOMPtr<nsIInputStreamPump> pump;
  88. rv = NS_NewInputStreamPump(getter_AddRefs(pump), stream, offset, length);
  89. if (NS_FAILED(rv)) return rv;
  90. rv = pump->AsyncRead(new MyListener(), nullptr);
  91. if (NS_FAILED(rv)) return rv;
  92. PumpEvents();
  93. return NS_OK;
  94. }
  95. ////////////////////////////////////////////////////////////////////////////////
  96. int
  97. main(int argc, char* argv[])
  98. {
  99. if (test_common_init(&argc, &argv) != 0)
  100. return -1;
  101. nsresult rv;
  102. if (argc < 4) {
  103. printf("usage: %s <file-to-read> <start-offset> <read-length>\n", argv[0]);
  104. return -1;
  105. }
  106. char* fileName = argv[1];
  107. int64_t offset, length;
  108. int err = PR_sscanf(argv[2], "%lld", &offset);
  109. if (err == -1) {
  110. printf("Start offset must be an integer!\n");
  111. return 1;
  112. }
  113. err = PR_sscanf(argv[3], "%lld", &length);
  114. if (err == -1) {
  115. printf("Length must be an integer!\n");
  116. return 1;
  117. }
  118. {
  119. nsCOMPtr<nsIServiceManager> servMan;
  120. NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr);
  121. nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
  122. NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
  123. if (registrar)
  124. registrar->AutoRegister(nullptr);
  125. gTestLog = PR_NewLogModule("Test");
  126. nsCOMPtr<nsIFile> file;
  127. rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(file));
  128. if (NS_FAILED(rv)) return rv;
  129. rv = RunTest(file, offset, length);
  130. NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed");
  131. // give background threads a chance to finish whatever work they may
  132. // be doing.
  133. PR_Sleep(PR_SecondsToInterval(1));
  134. } // this scopes the nsCOMPtrs
  135. // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
  136. rv = NS_ShutdownXPCOM(nullptr);
  137. NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
  138. return NS_OK;
  139. }