Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/base/ArrayBufferInputStream.cpp
Line
Count
Source (jump to first uncovered line)
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
#include "mozilla/UniquePtrExtensions.h"
12
#include "mozilla/dom/ScriptSettings.h"
13
14
using mozilla::dom::RootingCx;
15
16
NS_IMPL_ISUPPORTS(ArrayBufferInputStream, nsIArrayBufferInputStream, nsIInputStream);
17
18
ArrayBufferInputStream::ArrayBufferInputStream()
19
: mBufferLength(0)
20
, mPos(0)
21
, mClosed(false)
22
0
{
23
0
}
24
25
NS_IMETHODIMP
26
ArrayBufferInputStream::SetData(JS::Handle<JS::Value> aBuffer,
27
                                uint32_t aByteOffset,
28
                                uint32_t aLength)
29
0
{
30
0
  NS_ASSERT_OWNINGTHREAD(ArrayBufferInputStream);
31
0
32
0
  if (!aBuffer.isObject()) {
33
0
    return NS_ERROR_FAILURE;
34
0
  }
35
0
  JS::RootedObject arrayBuffer(RootingCx(), &aBuffer.toObject());
36
0
  if (!JS_IsArrayBufferObject(arrayBuffer)) {
37
0
    return NS_ERROR_FAILURE;
38
0
  }
39
0
40
0
  uint32_t buflen = JS_GetArrayBufferByteLength(arrayBuffer);
41
0
  uint32_t offset = std::min(buflen, aByteOffset);
42
0
  uint32_t bufferLength = std::min(buflen - offset, aLength);
43
0
44
0
  mArrayBuffer = mozilla::MakeUniqueFallible<char[]>(bufferLength);
45
0
  if (!mArrayBuffer) {
46
0
    return NS_ERROR_OUT_OF_MEMORY;
47
0
  }
48
0
49
0
  mBufferLength = bufferLength;
50
0
51
0
  JS::AutoCheckCannotGC nogc;
52
0
  bool isShared;
53
0
  char* src = (char*) JS_GetArrayBufferData(arrayBuffer, &isShared, nogc) + offset;
54
0
  memcpy(&mArrayBuffer[0], src, mBufferLength);
55
0
  return NS_OK;
56
0
}
57
58
NS_IMETHODIMP
59
ArrayBufferInputStream::Close()
60
0
{
61
0
  mClosed = true;
62
0
  return NS_OK;
63
0
}
64
65
NS_IMETHODIMP
66
ArrayBufferInputStream::Available(uint64_t* aCount)
67
0
{
68
0
  if (mClosed) {
69
0
    return NS_BASE_STREAM_CLOSED;
70
0
  }
71
0
  if (mArrayBuffer) {
72
0
    *aCount = mBufferLength ? mBufferLength - mPos : 0;
73
0
  } else {
74
0
    *aCount = 0;
75
0
  }
76
0
  return NS_OK;
77
0
}
78
79
NS_IMETHODIMP
80
ArrayBufferInputStream::Read(char* aBuf, uint32_t aCount, uint32_t *aReadCount)
81
0
{
82
0
  return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, aReadCount);
83
0
}
84
85
NS_IMETHODIMP
86
ArrayBufferInputStream::ReadSegments(nsWriteSegmentFun writer, void *closure,
87
                                     uint32_t aCount, uint32_t *result)
88
0
{
89
0
  NS_ASSERTION(result, "null ptr");
90
0
  NS_ASSERTION(mBufferLength >= mPos, "bad stream state");
91
0
92
0
  if (mClosed) {
93
0
    return NS_BASE_STREAM_CLOSED;
94
0
  }
95
0
96
0
  MOZ_ASSERT(mArrayBuffer || (mPos == mBufferLength), "stream inited incorrectly");
97
0
98
0
  *result = 0;
99
0
  while (mPos < mBufferLength) {
100
0
    uint32_t remaining = mBufferLength - mPos;
101
0
    MOZ_ASSERT(mArrayBuffer);
102
0
103
0
    uint32_t count = std::min(aCount, remaining);
104
0
    if (count == 0) {
105
0
      break;
106
0
    }
107
0
108
0
    uint32_t written;
109
0
    nsresult rv = writer(this, closure, &mArrayBuffer[0] + mPos, *result, count, &written);
110
0
    if (NS_FAILED(rv)) {
111
0
      // InputStreams do not propagate errors to caller.
112
0
      return NS_OK;
113
0
    }
114
0
115
0
    NS_ASSERTION(written <= count,
116
0
                 "writer should not write more than we asked it to write");
117
0
    mPos += written;
118
0
    *result += written;
119
0
    aCount -= written;
120
0
  }
121
0
122
0
  return NS_OK;
123
0
}
124
125
NS_IMETHODIMP
126
ArrayBufferInputStream::IsNonBlocking(bool *aNonBlocking)
127
0
{
128
0
  *aNonBlocking = true;
129
0
  return NS_OK;
130
0
}