nsPreloadedStream.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  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. #include "nsPreloadedStream.h"
  6. #include "nsIRunnable.h"
  7. #include "nsThreadUtils.h"
  8. #include <algorithm>
  9. namespace mozilla {
  10. namespace net {
  11. NS_IMPL_ISUPPORTS(nsPreloadedStream,
  12. nsIInputStream,
  13. nsIAsyncInputStream)
  14. nsPreloadedStream::nsPreloadedStream(nsIAsyncInputStream *aStream,
  15. const char *data, uint32_t datalen)
  16. : mStream(aStream),
  17. mOffset(0),
  18. mLen(datalen)
  19. {
  20. mBuf = (char *) moz_xmalloc(datalen);
  21. memcpy(mBuf, data, datalen);
  22. }
  23. nsPreloadedStream::~nsPreloadedStream()
  24. {
  25. free(mBuf);
  26. }
  27. NS_IMETHODIMP
  28. nsPreloadedStream::Close()
  29. {
  30. mLen = 0;
  31. return mStream->Close();
  32. }
  33. NS_IMETHODIMP
  34. nsPreloadedStream::Available(uint64_t *_retval)
  35. {
  36. uint64_t avail = 0;
  37. nsresult rv = mStream->Available(&avail);
  38. if (NS_FAILED(rv))
  39. return rv;
  40. *_retval = avail + mLen;
  41. return NS_OK;
  42. }
  43. NS_IMETHODIMP
  44. nsPreloadedStream::Read(char *aBuf, uint32_t aCount,
  45. uint32_t *_retval)
  46. {
  47. if (!mLen)
  48. return mStream->Read(aBuf, aCount, _retval);
  49. uint32_t toRead = std::min(mLen, aCount);
  50. memcpy(aBuf, mBuf + mOffset, toRead);
  51. mOffset += toRead;
  52. mLen -= toRead;
  53. *_retval = toRead;
  54. return NS_OK;
  55. }
  56. NS_IMETHODIMP
  57. nsPreloadedStream::ReadSegments(nsWriteSegmentFun aWriter,
  58. void *aClosure, uint32_t aCount,
  59. uint32_t *result)
  60. {
  61. if (!mLen)
  62. return mStream->ReadSegments(aWriter, aClosure, aCount, result);
  63. *result = 0;
  64. while (mLen > 0 && aCount > 0) {
  65. uint32_t toRead = std::min(mLen, aCount);
  66. uint32_t didRead = 0;
  67. nsresult rv;
  68. rv = aWriter(this, aClosure, mBuf + mOffset, *result, toRead, &didRead);
  69. if (NS_FAILED(rv))
  70. return NS_OK;
  71. *result += didRead;
  72. mOffset += didRead;
  73. mLen -= didRead;
  74. aCount -= didRead;
  75. }
  76. return NS_OK;
  77. }
  78. NS_IMETHODIMP
  79. nsPreloadedStream::IsNonBlocking(bool *_retval)
  80. {
  81. return mStream->IsNonBlocking(_retval);
  82. }
  83. NS_IMETHODIMP
  84. nsPreloadedStream::CloseWithStatus(nsresult aStatus)
  85. {
  86. mLen = 0;
  87. return mStream->CloseWithStatus(aStatus);
  88. }
  89. class RunOnThread : public Runnable
  90. {
  91. public:
  92. RunOnThread(nsIAsyncInputStream *aStream,
  93. nsIInputStreamCallback *aCallback)
  94. : mStream(aStream),
  95. mCallback(aCallback) {}
  96. virtual ~RunOnThread() {}
  97. NS_IMETHOD Run() override
  98. {
  99. mCallback->OnInputStreamReady(mStream);
  100. return NS_OK;
  101. }
  102. private:
  103. nsCOMPtr<nsIAsyncInputStream> mStream;
  104. nsCOMPtr<nsIInputStreamCallback> mCallback;
  105. };
  106. NS_IMETHODIMP
  107. nsPreloadedStream::AsyncWait(nsIInputStreamCallback *aCallback,
  108. uint32_t aFlags,
  109. uint32_t aRequestedCount,
  110. nsIEventTarget *aEventTarget)
  111. {
  112. if (!mLen)
  113. return mStream->AsyncWait(aCallback, aFlags, aRequestedCount,
  114. aEventTarget);
  115. if (!aCallback)
  116. return NS_OK;
  117. if (!aEventTarget)
  118. return aCallback->OnInputStreamReady(this);
  119. nsCOMPtr<nsIRunnable> event =
  120. new RunOnThread(this, aCallback);
  121. return aEventTarget->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
  122. }
  123. } // namespace net
  124. } // namespace mozilla