1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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/. */
7 #include "ArrayBufferInputStream.h"
8 #include "nsStreamUtils.h"
10 #include "jsfriendapi.h"
11 #include "mozilla/UniquePtrExtensions.h"
12 #include "mozilla/dom/ScriptSettings.h"
14 using mozilla::dom::RootingCx
;
16 NS_IMPL_ISUPPORTS(ArrayBufferInputStream
, nsIArrayBufferInputStream
,
19 ArrayBufferInputStream::ArrayBufferInputStream()
20 : mBufferLength(0), mPos(0), mClosed(false) {}
23 ArrayBufferInputStream::SetData(JS::Handle
<JS::Value
> aBuffer
,
24 uint32_t aByteOffset
, uint32_t aLength
) {
25 NS_ASSERT_OWNINGTHREAD(ArrayBufferInputStream
);
27 if (!aBuffer
.isObject()) {
28 return NS_ERROR_FAILURE
;
30 JS::RootedObject
arrayBuffer(RootingCx(), &aBuffer
.toObject());
31 if (!JS_IsArrayBufferObject(arrayBuffer
)) {
32 return NS_ERROR_FAILURE
;
35 uint32_t buflen
= JS_GetArrayBufferByteLength(arrayBuffer
);
36 uint32_t offset
= std::min(buflen
, aByteOffset
);
37 uint32_t bufferLength
= std::min(buflen
- offset
, aLength
);
39 mArrayBuffer
= mozilla::MakeUniqueFallible
<char[]>(bufferLength
);
41 return NS_ERROR_OUT_OF_MEMORY
;
44 mBufferLength
= bufferLength
;
46 JS::AutoCheckCannotGC nogc
;
49 (char *)JS_GetArrayBufferData(arrayBuffer
, &isShared
, nogc
) + offset
;
50 memcpy(&mArrayBuffer
[0], src
, mBufferLength
);
55 ArrayBufferInputStream::Close() {
61 ArrayBufferInputStream::Available(uint64_t *aCount
) {
63 return NS_BASE_STREAM_CLOSED
;
66 *aCount
= mBufferLength
? mBufferLength
- mPos
: 0;
74 ArrayBufferInputStream::Read(char *aBuf
, uint32_t aCount
,
75 uint32_t *aReadCount
) {
76 return ReadSegments(NS_CopySegmentToBuffer
, aBuf
, aCount
, aReadCount
);
80 ArrayBufferInputStream::ReadSegments(nsWriteSegmentFun writer
, void *closure
,
81 uint32_t aCount
, uint32_t *result
) {
82 NS_ASSERTION(result
, "null ptr");
83 NS_ASSERTION(mBufferLength
>= mPos
, "bad stream state");
86 return NS_BASE_STREAM_CLOSED
;
89 MOZ_ASSERT(mArrayBuffer
|| (mPos
== mBufferLength
),
90 "stream inited incorrectly");
93 while (mPos
< mBufferLength
) {
94 uint32_t remaining
= mBufferLength
- mPos
;
95 MOZ_ASSERT(mArrayBuffer
);
97 uint32_t count
= std::min(aCount
, remaining
);
103 nsresult rv
= writer(this, closure
, &mArrayBuffer
[0] + mPos
, *result
, count
,
106 // InputStreams do not propagate errors to caller.
110 NS_ASSERTION(written
<= count
,
111 "writer should not write more than we asked it to write");
121 ArrayBufferInputStream::IsNonBlocking(bool *aNonBlocking
) {
122 *aNonBlocking
= true;