content/media/BufferMediaResource.h

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

michael@0 1 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #if !defined(BufferMediaResource_h_)
michael@0 7 #define BufferMediaResource_h_
michael@0 8
michael@0 9 #include "MediaResource.h"
michael@0 10 #include "nsISeekableStream.h"
michael@0 11 #include "nsIPrincipal.h"
michael@0 12 #include <algorithm>
michael@0 13
michael@0 14 namespace mozilla {
michael@0 15
michael@0 16 // A simple MediaResource based on an in memory buffer. This class accepts
michael@0 17 // the address and the length of the buffer, and simulates a read/seek API
michael@0 18 // on top of it. The Read implementation involves copying memory, which is
michael@0 19 // unfortunate, but the MediaResource interface mandates that.
michael@0 20 class BufferMediaResource : public MediaResource
michael@0 21 {
michael@0 22 public:
michael@0 23 BufferMediaResource(const uint8_t* aBuffer,
michael@0 24 uint32_t aLength,
michael@0 25 nsIPrincipal* aPrincipal,
michael@0 26 const nsACString& aContentType) :
michael@0 27 mBuffer(aBuffer),
michael@0 28 mLength(aLength),
michael@0 29 mOffset(0),
michael@0 30 mPrincipal(aPrincipal),
michael@0 31 mContentType(aContentType)
michael@0 32 {
michael@0 33 MOZ_COUNT_CTOR(BufferMediaResource);
michael@0 34 }
michael@0 35
michael@0 36 virtual ~BufferMediaResource()
michael@0 37 {
michael@0 38 MOZ_COUNT_DTOR(BufferMediaResource);
michael@0 39 }
michael@0 40
michael@0 41 virtual nsresult Close() { return NS_OK; }
michael@0 42 virtual void Suspend(bool aCloseImmediately) {}
michael@0 43 virtual void Resume() {}
michael@0 44 // Get the current principal for the channel
michael@0 45 virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal()
michael@0 46 {
michael@0 47 nsCOMPtr<nsIPrincipal> principal = mPrincipal;
michael@0 48 return principal.forget();
michael@0 49 }
michael@0 50 virtual bool CanClone() { return false; }
michael@0 51 virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder)
michael@0 52 {
michael@0 53 return nullptr;
michael@0 54 }
michael@0 55
michael@0 56 // These methods are called off the main thread.
michael@0 57 // The mode is initially MODE_PLAYBACK.
michael@0 58 virtual void SetReadMode(MediaCacheStream::ReadMode aMode) {}
michael@0 59 virtual void SetPlaybackRate(uint32_t aBytesPerSecond) {}
michael@0 60 virtual nsresult Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
michael@0 61 {
michael@0 62 *aBytes = std::min(mLength - mOffset, aCount);
michael@0 63 memcpy(aBuffer, mBuffer + mOffset, *aBytes);
michael@0 64 mOffset += *aBytes;
michael@0 65 MOZ_ASSERT(mOffset <= mLength);
michael@0 66 return NS_OK;
michael@0 67 }
michael@0 68 virtual nsresult ReadAt(int64_t aOffset, char* aBuffer,
michael@0 69 uint32_t aCount, uint32_t* aBytes)
michael@0 70 {
michael@0 71 nsresult rv = Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
michael@0 72 if (NS_FAILED(rv)) return rv;
michael@0 73 return Read(aBuffer, aCount, aBytes);
michael@0 74 }
michael@0 75 virtual nsresult Seek(int32_t aWhence, int64_t aOffset)
michael@0 76 {
michael@0 77 MOZ_ASSERT(aOffset <= UINT32_MAX);
michael@0 78 switch (aWhence) {
michael@0 79 case nsISeekableStream::NS_SEEK_SET:
michael@0 80 if (aOffset < 0 || aOffset > mLength) {
michael@0 81 return NS_ERROR_FAILURE;
michael@0 82 }
michael@0 83 mOffset = static_cast<uint32_t> (aOffset);
michael@0 84 break;
michael@0 85 case nsISeekableStream::NS_SEEK_CUR:
michael@0 86 if (aOffset >= mLength - mOffset) {
michael@0 87 return NS_ERROR_FAILURE;
michael@0 88 }
michael@0 89 mOffset += static_cast<uint32_t> (aOffset);
michael@0 90 break;
michael@0 91 case nsISeekableStream::NS_SEEK_END:
michael@0 92 if (aOffset < 0 || aOffset > mLength) {
michael@0 93 return NS_ERROR_FAILURE;
michael@0 94 }
michael@0 95 mOffset = mLength - aOffset;
michael@0 96 break;
michael@0 97 }
michael@0 98
michael@0 99 return NS_OK;
michael@0 100 }
michael@0 101 virtual void StartSeekingForMetadata() {}
michael@0 102 virtual void EndSeekingForMetadata() {}
michael@0 103 virtual int64_t Tell() { return mOffset; }
michael@0 104
michael@0 105 virtual void Pin() {}
michael@0 106 virtual void Unpin() {}
michael@0 107 virtual double GetDownloadRate(bool* aIsReliable) { return 0.; }
michael@0 108 virtual int64_t GetLength() { return mLength; }
michael@0 109 virtual int64_t GetNextCachedData(int64_t aOffset) { return aOffset; }
michael@0 110 virtual int64_t GetCachedDataEnd(int64_t aOffset) { return mLength; }
michael@0 111 virtual bool IsDataCachedToEndOfResource(int64_t aOffset) { return true; }
michael@0 112 virtual bool IsSuspendedByCache() { return false; }
michael@0 113 virtual bool IsSuspended() { return false; }
michael@0 114 virtual nsresult ReadFromCache(char* aBuffer,
michael@0 115 int64_t aOffset,
michael@0 116 uint32_t aCount)
michael@0 117 {
michael@0 118 if (aOffset < 0) {
michael@0 119 return NS_ERROR_FAILURE;
michael@0 120 }
michael@0 121
michael@0 122 uint32_t bytes = std::min(mLength - static_cast<uint32_t>(aOffset), aCount);
michael@0 123 memcpy(aBuffer, mBuffer + aOffset, bytes);
michael@0 124 return NS_OK;
michael@0 125 }
michael@0 126
michael@0 127 virtual nsresult Open(nsIStreamListener** aStreamListener)
michael@0 128 {
michael@0 129 return NS_ERROR_FAILURE;
michael@0 130 }
michael@0 131
michael@0 132 virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
michael@0 133 {
michael@0 134 aRanges.AppendElement(MediaByteRange(0, mLength));
michael@0 135 return NS_OK;
michael@0 136 }
michael@0 137
michael@0 138 bool IsTransportSeekable() MOZ_OVERRIDE { return true; }
michael@0 139
michael@0 140 virtual const nsCString& GetContentType() const MOZ_OVERRIDE
michael@0 141 {
michael@0 142 return mContentType;
michael@0 143 }
michael@0 144
michael@0 145 virtual size_t SizeOfExcludingThis(
michael@0 146 MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
michael@0 147 {
michael@0 148 // Not owned:
michael@0 149 // - mBuffer
michael@0 150 // - mPrincipal
michael@0 151 size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
michael@0 152 size += mContentType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
michael@0 153
michael@0 154 return size;
michael@0 155 }
michael@0 156
michael@0 157 virtual size_t SizeOfIncludingThis(
michael@0 158 MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
michael@0 159 {
michael@0 160 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
michael@0 161 }
michael@0 162
michael@0 163 private:
michael@0 164 const uint8_t * mBuffer;
michael@0 165 uint32_t mLength;
michael@0 166 uint32_t mOffset;
michael@0 167 nsCOMPtr<nsIPrincipal> mPrincipal;
michael@0 168 const nsAutoCString mContentType;
michael@0 169 };
michael@0 170
michael@0 171 }
michael@0 172
michael@0 173 #endif

mercurial