Bumping manifests a=b2g-bump
[gecko.git] / xpcom / io / nsScriptableInputStream.cpp
blob08bc938f98536ac654ce3a60b72d0c5e803497b0
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsScriptableInputStream.h"
8 #include "nsMemory.h"
9 #include "nsString.h"
11 NS_IMPL_ISUPPORTS(nsScriptableInputStream, nsIScriptableInputStream)
13 // nsIScriptableInputStream methods
14 NS_IMETHODIMP
15 nsScriptableInputStream::Close()
17 if (!mInputStream) {
18 return NS_ERROR_NOT_INITIALIZED;
20 return mInputStream->Close();
23 NS_IMETHODIMP
24 nsScriptableInputStream::Init(nsIInputStream* aInputStream)
26 if (!aInputStream) {
27 return NS_ERROR_NULL_POINTER;
29 mInputStream = aInputStream;
30 return NS_OK;
33 NS_IMETHODIMP
34 nsScriptableInputStream::Available(uint64_t* aResult)
36 if (!mInputStream) {
37 return NS_ERROR_NOT_INITIALIZED;
39 return mInputStream->Available(aResult);
42 NS_IMETHODIMP
43 nsScriptableInputStream::Read(uint32_t aCount, char** aResult)
45 nsresult rv = NS_OK;
46 uint64_t count64 = 0;
47 char* buffer = nullptr;
49 if (!mInputStream) {
50 return NS_ERROR_NOT_INITIALIZED;
53 rv = mInputStream->Available(&count64);
54 if (NS_FAILED(rv)) {
55 return rv;
58 // bug716556 - Ensure count+1 doesn't overflow
59 uint32_t count =
60 XPCOM_MIN((uint32_t)XPCOM_MIN<uint64_t>(count64, aCount), UINT32_MAX - 1);
61 buffer = (char*)moz_malloc(count + 1); // make room for '\0'
62 if (!buffer) {
63 return NS_ERROR_OUT_OF_MEMORY;
66 rv = ReadHelper(buffer, count);
67 if (NS_FAILED(rv)) {
68 nsMemory::Free(buffer);
69 return rv;
72 buffer[count] = '\0';
73 *aResult = buffer;
74 return NS_OK;
77 NS_IMETHODIMP
78 nsScriptableInputStream::ReadBytes(uint32_t aCount, nsACString& aResult)
80 if (!mInputStream) {
81 return NS_ERROR_NOT_INITIALIZED;
84 aResult.SetLength(aCount);
85 if (aResult.Length() != aCount) {
86 return NS_ERROR_OUT_OF_MEMORY;
89 char* ptr = aResult.BeginWriting();
90 nsresult rv = ReadHelper(ptr, aCount);
91 if (NS_FAILED(rv)) {
92 aResult.Truncate();
94 return rv;
97 nsresult
98 nsScriptableInputStream::ReadHelper(char* aBuffer, uint32_t aCount)
100 uint32_t totalBytesRead = 0;
101 while (1) {
102 uint32_t bytesRead;
103 nsresult rv = mInputStream->Read(aBuffer + totalBytesRead,
104 aCount - totalBytesRead,
105 &bytesRead);
106 if (NS_FAILED(rv)) {
107 return rv;
110 totalBytesRead += bytesRead;
111 if (totalBytesRead == aCount) {
112 break;
115 // If we have read zero bytes, we have hit EOF.
116 if (bytesRead == 0) {
117 return NS_ERROR_FAILURE;
121 return NS_OK;
124 nsresult
125 nsScriptableInputStream::Create(nsISupports* aOuter, REFNSIID aIID,
126 void** aResult)
128 if (aOuter) {
129 return NS_ERROR_NO_AGGREGATION;
132 nsScriptableInputStream* sis = new nsScriptableInputStream();
133 if (!sis) {
134 return NS_ERROR_OUT_OF_MEMORY;
137 NS_ADDREF(sis);
138 nsresult rv = sis->QueryInterface(aIID, aResult);
139 NS_RELEASE(sis);
140 return rv;