Line data Source code
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/. */
6 :
7 : #include "nsScriptableInputStream.h"
8 : #include "nsMemory.h"
9 : #include "nsString.h"
10 :
11 0 : NS_IMPL_ISUPPORTS(nsScriptableInputStream, nsIScriptableInputStream)
12 :
13 : // nsIScriptableInputStream methods
14 : NS_IMETHODIMP
15 0 : nsScriptableInputStream::Close()
16 : {
17 0 : if (!mInputStream) {
18 0 : return NS_ERROR_NOT_INITIALIZED;
19 : }
20 0 : return mInputStream->Close();
21 : }
22 :
23 : NS_IMETHODIMP
24 0 : nsScriptableInputStream::Init(nsIInputStream* aInputStream)
25 : {
26 0 : if (!aInputStream) {
27 0 : return NS_ERROR_NULL_POINTER;
28 : }
29 0 : mInputStream = aInputStream;
30 0 : return NS_OK;
31 : }
32 :
33 : NS_IMETHODIMP
34 0 : nsScriptableInputStream::Available(uint64_t* aResult)
35 : {
36 0 : if (!mInputStream) {
37 0 : return NS_ERROR_NOT_INITIALIZED;
38 : }
39 0 : return mInputStream->Available(aResult);
40 : }
41 :
42 : NS_IMETHODIMP
43 0 : nsScriptableInputStream::Read(uint32_t aCount, char** aResult)
44 : {
45 0 : nsresult rv = NS_OK;
46 0 : uint64_t count64 = 0;
47 0 : char* buffer = nullptr;
48 :
49 0 : if (!mInputStream) {
50 0 : return NS_ERROR_NOT_INITIALIZED;
51 : }
52 :
53 0 : rv = mInputStream->Available(&count64);
54 0 : if (NS_FAILED(rv)) {
55 0 : return rv;
56 : }
57 :
58 : // bug716556 - Ensure count+1 doesn't overflow
59 : uint32_t count =
60 0 : XPCOM_MIN((uint32_t)XPCOM_MIN<uint64_t>(count64, aCount), UINT32_MAX - 1);
61 0 : buffer = (char*)malloc(count + 1); // make room for '\0'
62 0 : if (!buffer) {
63 0 : return NS_ERROR_OUT_OF_MEMORY;
64 : }
65 :
66 0 : rv = ReadHelper(buffer, count);
67 0 : if (NS_FAILED(rv)) {
68 0 : free(buffer);
69 0 : return rv;
70 : }
71 :
72 0 : buffer[count] = '\0';
73 0 : *aResult = buffer;
74 0 : return NS_OK;
75 : }
76 :
77 : NS_IMETHODIMP
78 0 : nsScriptableInputStream::ReadBytes(uint32_t aCount, nsACString& aResult)
79 : {
80 0 : if (!mInputStream) {
81 0 : return NS_ERROR_NOT_INITIALIZED;
82 : }
83 :
84 0 : if (!aResult.SetLength(aCount, fallible)) {
85 0 : return NS_ERROR_OUT_OF_MEMORY;
86 : }
87 :
88 0 : MOZ_ASSERT(aResult.Length() == aCount);
89 0 : char* ptr = aResult.BeginWriting();
90 0 : nsresult rv = ReadHelper(ptr, aCount);
91 0 : if (NS_FAILED(rv)) {
92 0 : aResult.Truncate();
93 : }
94 0 : return rv;
95 : }
96 :
97 : nsresult
98 0 : nsScriptableInputStream::ReadHelper(char* aBuffer, uint32_t aCount)
99 : {
100 0 : uint32_t totalBytesRead = 0;
101 : while (1) {
102 : uint32_t bytesRead;
103 0 : nsresult rv = mInputStream->Read(aBuffer + totalBytesRead,
104 : aCount - totalBytesRead,
105 0 : &bytesRead);
106 0 : if (NS_FAILED(rv)) {
107 0 : return rv;
108 : }
109 :
110 0 : totalBytesRead += bytesRead;
111 0 : if (totalBytesRead == aCount) {
112 0 : break;
113 : }
114 :
115 : // If we have read zero bytes, we have hit EOF.
116 0 : if (bytesRead == 0) {
117 0 : return NS_ERROR_FAILURE;
118 : }
119 :
120 0 : }
121 0 : return NS_OK;
122 : }
123 :
124 : nsresult
125 0 : nsScriptableInputStream::Create(nsISupports* aOuter, REFNSIID aIID,
126 : void** aResult)
127 : {
128 0 : if (aOuter) {
129 0 : return NS_ERROR_NO_AGGREGATION;
130 : }
131 :
132 0 : RefPtr<nsScriptableInputStream> sis = new nsScriptableInputStream();
133 0 : return sis->QueryInterface(aIID, aResult);
134 : }
|