GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#include "js_stream.h" |
||
2 |
|||
3 |
#include "async_wrap.h" |
||
4 |
#include "env-inl.h" |
||
5 |
#include "node_buffer.h" |
||
6 |
#include "node_errors.h" |
||
7 |
#include "stream_base-inl.h" |
||
8 |
#include "util-inl.h" |
||
9 |
#include "v8.h" |
||
10 |
|||
11 |
namespace node { |
||
12 |
|||
13 |
using errors::TryCatchScope; |
||
14 |
|||
15 |
using v8::Array; |
||
16 |
using v8::Context; |
||
17 |
using v8::FunctionCallbackInfo; |
||
18 |
using v8::FunctionTemplate; |
||
19 |
using v8::HandleScope; |
||
20 |
using v8::Int32; |
||
21 |
using v8::Local; |
||
22 |
using v8::Object; |
||
23 |
using v8::String; |
||
24 |
using v8::Value; |
||
25 |
|||
26 |
|||
27 |
10577 |
JSStream::JSStream(Environment* env, Local<Object> obj) |
|
28 |
: AsyncWrap(env, obj, AsyncWrap::PROVIDER_JSSTREAM), |
||
29 |
10577 |
StreamBase(env) { |
|
30 |
10577 |
MakeWeak(); |
|
31 |
10577 |
StreamBase::AttachToObject(obj); |
|
32 |
10577 |
} |
|
33 |
|||
34 |
|||
35 |
11200 |
AsyncWrap* JSStream::GetAsyncWrap() { |
|
36 |
11200 |
return static_cast<AsyncWrap*>(this); |
|
37 |
} |
||
38 |
|||
39 |
|||
40 |
10597 |
bool JSStream::IsAlive() { |
|
41 |
10597 |
return true; |
|
42 |
} |
||
43 |
|||
44 |
|||
45 |
bool JSStream::IsClosing() { |
||
46 |
HandleScope scope(env()->isolate()); |
||
47 |
Context::Scope context_scope(env()->context()); |
||
48 |
TryCatchScope try_catch(env()); |
||
49 |
Local<Value> value; |
||
50 |
if (!MakeCallback(env()->isclosing_string(), 0, nullptr).ToLocal(&value)) { |
||
51 |
if (try_catch.HasCaught() && !try_catch.HasTerminated()) |
||
52 |
errors::TriggerUncaughtException(env()->isolate(), try_catch); |
||
53 |
return true; |
||
54 |
} |
||
55 |
return value->IsTrue(); |
||
56 |
} |
||
57 |
|||
58 |
|||
59 |
10603 |
int JSStream::ReadStart() { |
|
60 |
10603 |
HandleScope scope(env()->isolate()); |
|
61 |
10603 |
Context::Scope context_scope(env()->context()); |
|
62 |
21206 |
TryCatchScope try_catch(env()); |
|
63 |
Local<Value> value; |
||
64 |
10603 |
int value_int = UV_EPROTO; |
|
65 |
✓✗✗✓ ✓✗✗✓ |
53015 |
if (!MakeCallback(env()->onreadstart_string(), 0, nullptr).ToLocal(&value) || |
66 |
✓✗ | 42412 |
!value->Int32Value(env()->context()).To(&value_int)) { |
67 |
if (try_catch.HasCaught() && !try_catch.HasTerminated()) |
||
68 |
errors::TriggerUncaughtException(env()->isolate(), try_catch); |
||
69 |
} |
||
70 |
21206 |
return value_int; |
|
71 |
} |
||
72 |
|||
73 |
|||
74 |
38 |
int JSStream::ReadStop() { |
|
75 |
38 |
HandleScope scope(env()->isolate()); |
|
76 |
38 |
Context::Scope context_scope(env()->context()); |
|
77 |
76 |
TryCatchScope try_catch(env()); |
|
78 |
Local<Value> value; |
||
79 |
38 |
int value_int = UV_EPROTO; |
|
80 |
✓✓✗✓ ✓✗✓✓ |
188 |
if (!MakeCallback(env()->onreadstop_string(), 0, nullptr).ToLocal(&value) || |
81 |
✓✓ | 149 |
!value->Int32Value(env()->context()).To(&value_int)) { |
82 |
✗✓✗✗ ✗✓ |
1 |
if (try_catch.HasCaught() && !try_catch.HasTerminated()) |
83 |
errors::TriggerUncaughtException(env()->isolate(), try_catch); |
||
84 |
} |
||
85 |
76 |
return value_int; |
|
86 |
} |
||
87 |
|||
88 |
|||
89 |
8 |
int JSStream::DoShutdown(ShutdownWrap* req_wrap) { |
|
90 |
8 |
HandleScope scope(env()->isolate()); |
|
91 |
8 |
Context::Scope context_scope(env()->context()); |
|
92 |
|||
93 |
Local<Value> argv[] = { |
||
94 |
req_wrap->object() |
||
95 |
16 |
}; |
|
96 |
|||
97 |
16 |
TryCatchScope try_catch(env()); |
|
98 |
Local<Value> value; |
||
99 |
8 |
int value_int = UV_EPROTO; |
|
100 |
✗✓ | 16 |
if (!MakeCallback(env()->onshutdown_string(), |
101 |
8 |
arraysize(argv), |
|
102 |
✓✗✗✓ ✗✓ |
56 |
argv).ToLocal(&value) || |
103 |
✓✗ | 32 |
!value->Int32Value(env()->context()).To(&value_int)) { |
104 |
if (try_catch.HasCaught() && !try_catch.HasTerminated()) |
||
105 |
errors::TriggerUncaughtException(env()->isolate(), try_catch); |
||
106 |
} |
||
107 |
16 |
return value_int; |
|
108 |
} |
||
109 |
|||
110 |
|||
111 |
603 |
int JSStream::DoWrite(WriteWrap* w, |
|
112 |
uv_buf_t* bufs, |
||
113 |
size_t count, |
||
114 |
uv_stream_t* send_handle) { |
||
115 |
✗✓ | 603 |
CHECK_NULL(send_handle); |
116 |
|||
117 |
603 |
HandleScope scope(env()->isolate()); |
|
118 |
603 |
Context::Scope context_scope(env()->context()); |
|
119 |
|||
120 |
603 |
Local<Array> bufs_arr = Array::New(env()->isolate(), count); |
|
121 |
Local<Object> buf; |
||
122 |
✓✓ | 1248 |
for (size_t i = 0; i < count; i++) { |
123 |
1290 |
buf = Buffer::Copy(env(), bufs[i].base, bufs[i].len).ToLocalChecked(); |
|
124 |
1935 |
bufs_arr->Set(env()->context(), i, buf).Check(); |
|
125 |
} |
||
126 |
|||
127 |
Local<Value> argv[] = { |
||
128 |
w->object(), |
||
129 |
bufs_arr |
||
130 |
1809 |
}; |
|
131 |
|||
132 |
1205 |
TryCatchScope try_catch(env()); |
|
133 |
Local<Value> value; |
||
134 |
603 |
int value_int = UV_EPROTO; |
|
135 |
✓✓ | 1206 |
if (!MakeCallback(env()->onwrite_string(), |
136 |
603 |
arraysize(argv), |
|
137 |
✓✓✗✓ ✗✓ |
4215 |
argv).ToLocal(&value) || |
138 |
✓✓ | 2403 |
!value->Int32Value(env()->context()).To(&value_int)) { |
139 |
✓✓✓✗ ✓✓ |
3 |
if (try_catch.HasCaught() && !try_catch.HasTerminated()) |
140 |
2 |
errors::TriggerUncaughtException(env()->isolate(), try_catch); |
|
141 |
} |
||
142 |
1204 |
return value_int; |
|
143 |
} |
||
144 |
|||
145 |
|||
146 |
10577 |
void JSStream::New(const FunctionCallbackInfo<Value>& args) { |
|
147 |
// This constructor should not be exposed to public javascript. |
||
148 |
// Therefore we assert that we are not trying to call this as a |
||
149 |
// normal function. |
||
150 |
✗✓ | 10577 |
CHECK(args.IsConstructCall()); |
151 |
10577 |
Environment* env = Environment::GetCurrent(args); |
|
152 |
10577 |
new JSStream(env, args.This()); |
|
153 |
10577 |
} |
|
154 |
|||
155 |
|||
156 |
template <class Wrap> |
||
157 |
603 |
void JSStream::Finish(const FunctionCallbackInfo<Value>& args) { |
|
158 |
✗✓✗✓ |
1206 |
CHECK(args[0]->IsObject()); |
159 |
1206 |
Wrap* w = static_cast<Wrap*>(StreamReq::FromObject(args[0].As<Object>())); |
|
160 |
|||
161 |
✗✓✗✓ |
1206 |
CHECK(args[1]->IsInt32()); |
162 |
1809 |
w->Done(args[1].As<Int32>()->Value()); |
|
163 |
603 |
} |
|
164 |
|||
165 |
|||
166 |
643 |
void JSStream::ReadBuffer(const FunctionCallbackInfo<Value>& args) { |
|
167 |
JSStream* wrap; |
||
168 |
✗✓ | 1285 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); |
169 |
|||
170 |
643 |
ArrayBufferViewContents<char> buffer(args[0]); |
|
171 |
643 |
const char* data = buffer.data(); |
|
172 |
643 |
int len = buffer.length(); |
|
173 |
|||
174 |
// Repeatedly ask the stream's owner for memory, copy the data that we |
||
175 |
// just read from JS into those buffers and emit them as reads. |
||
176 |
✓✓ | 1941 |
while (len != 0) { |
177 |
656 |
uv_buf_t buf = wrap->EmitAlloc(len); |
|
178 |
656 |
ssize_t avail = len; |
|
179 |
✓✓ | 656 |
if (static_cast<ssize_t>(buf.len) < avail) |
180 |
13 |
avail = buf.len; |
|
181 |
|||
182 |
656 |
memcpy(buf.base, data, avail); |
|
183 |
656 |
data += avail; |
|
184 |
656 |
len -= avail; |
|
185 |
656 |
wrap->EmitRead(avail, buf); |
|
186 |
} |
||
187 |
} |
||
188 |
|||
189 |
|||
190 |
9 |
void JSStream::EmitEOF(const FunctionCallbackInfo<Value>& args) { |
|
191 |
JSStream* wrap; |
||
192 |
✗✓ | 18 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); |
193 |
|||
194 |
9 |
wrap->EmitRead(UV_EOF); |
|
195 |
} |
||
196 |
|||
197 |
|||
198 |
561 |
void JSStream::Initialize(Local<Object> target, |
|
199 |
Local<Value> unused, |
||
200 |
Local<Context> context, |
||
201 |
void* priv) { |
||
202 |
561 |
Environment* env = Environment::GetCurrent(context); |
|
203 |
|||
204 |
561 |
Local<FunctionTemplate> t = env->NewFunctionTemplate(New); |
|
205 |
Local<String> jsStreamString = |
||
206 |
561 |
FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream"); |
|
207 |
561 |
t->SetClassName(jsStreamString); |
|
208 |
561 |
t->InstanceTemplate() |
|
209 |
1122 |
->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); |
|
210 |
1122 |
t->Inherit(AsyncWrap::GetConstructorTemplate(env)); |
|
211 |
|||
212 |
561 |
env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>); |
|
213 |
561 |
env->SetProtoMethod(t, "finishShutdown", Finish<ShutdownWrap>); |
|
214 |
561 |
env->SetProtoMethod(t, "readBuffer", ReadBuffer); |
|
215 |
561 |
env->SetProtoMethod(t, "emitEOF", EmitEOF); |
|
216 |
|||
217 |
561 |
StreamBase::AddMethods(env, t); |
|
218 |
target->Set(env->context(), |
||
219 |
jsStreamString, |
||
220 |
2244 |
t->GetFunction(context).ToLocalChecked()).Check(); |
|
221 |
561 |
} |
|
222 |
|||
223 |
} // namespace node |
||
224 |
|||
225 |
5030 |
NODE_MODULE_CONTEXT_AWARE_INTERNAL(js_stream, node::JSStream::Initialize) |
Generated by: GCOVR (Version 3.4) |