netwerk/base/src/ArrayBufferInputStream.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:2084c96bf7a4
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/. */
5
6 #include <algorithm>
7 #include "ArrayBufferInputStream.h"
8 #include "nsStreamUtils.h"
9 #include "jsapi.h"
10 #include "jsfriendapi.h"
11
12 NS_IMPL_ISUPPORTS(ArrayBufferInputStream, nsIArrayBufferInputStream, nsIInputStream);
13
14 ArrayBufferInputStream::ArrayBufferInputStream()
15 : mBuffer(nullptr)
16 , mBufferLength(0)
17 , mOffset(0)
18 , mPos(0)
19 , mClosed(false)
20 {
21 }
22
23 NS_IMETHODIMP
24 ArrayBufferInputStream::SetData(JS::Handle<JS::Value> aBuffer,
25 uint32_t aByteOffset,
26 uint32_t aLength,
27 JSContext* aCx)
28 {
29 if (!aBuffer.isObject()) {
30 return NS_ERROR_FAILURE;
31 }
32 JS::RootedObject arrayBuffer(aCx, &aBuffer.toObject());
33 if (!JS_IsArrayBufferObject(arrayBuffer)) {
34 return NS_ERROR_FAILURE;
35 }
36
37 mArrayBuffer.construct(aCx, aBuffer);
38
39 uint32_t buflen = JS_GetArrayBufferByteLength(arrayBuffer);
40 mOffset = std::min(buflen, aByteOffset);
41 mBufferLength = std::min(buflen - mOffset, aLength);
42 mBuffer = JS_GetStableArrayBufferData(aCx, arrayBuffer);
43 if (!mBuffer) {
44 return NS_ERROR_FAILURE;
45 }
46 return NS_OK;
47 }
48
49 NS_IMETHODIMP
50 ArrayBufferInputStream::Close()
51 {
52 mClosed = true;
53 return NS_OK;
54 }
55
56 NS_IMETHODIMP
57 ArrayBufferInputStream::Available(uint64_t* aCount)
58 {
59 if (mClosed) {
60 return NS_BASE_STREAM_CLOSED;
61 }
62 *aCount = mBufferLength - mPos;
63 return NS_OK;
64 }
65
66 NS_IMETHODIMP
67 ArrayBufferInputStream::Read(char* aBuf, uint32_t aCount, uint32_t *aReadCount)
68 {
69 return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, aReadCount);
70 }
71
72 NS_IMETHODIMP
73 ArrayBufferInputStream::ReadSegments(nsWriteSegmentFun writer, void *closure,
74 uint32_t aCount, uint32_t *result)
75 {
76 NS_ASSERTION(result, "null ptr");
77 NS_ASSERTION(mBufferLength >= mPos, "bad stream state");
78
79 if (mClosed) {
80 return NS_BASE_STREAM_CLOSED;
81 }
82
83 uint32_t remaining = mBufferLength - mPos;
84 if (!mArrayBuffer.empty()) {
85 JSObject* buf = &mArrayBuffer.ref().get().toObject();
86 uint32_t byteLength = JS_GetArrayBufferByteLength(buf);
87 if (byteLength == 0 && remaining != 0) {
88 mClosed = true;
89 return NS_BASE_STREAM_CLOSED;
90 }
91 } else {
92 MOZ_ASSERT(remaining == 0, "stream inited incorrectly");
93 }
94
95 if (!remaining) {
96 *result = 0;
97 return NS_OK;
98 }
99
100 if (aCount > remaining) {
101 aCount = remaining;
102 }
103 nsresult rv = writer(this, closure, (char*)(mBuffer + mOffset) + mPos,
104 0, aCount, result);
105 if (NS_SUCCEEDED(rv)) {
106 NS_ASSERTION(*result <= aCount,
107 "writer should not write more than we asked it to write");
108 mPos += *result;
109 }
110
111 return NS_OK;
112 }
113
114 NS_IMETHODIMP
115 ArrayBufferInputStream::IsNonBlocking(bool *aNonBlocking)
116 {
117 *aNonBlocking = true;
118 return NS_OK;
119 }

mercurial