Node.js  v8.x
Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine
stream_base-inl.h
Go to the documentation of this file.
1 #ifndef SRC_STREAM_BASE_INL_H_
2 #define SRC_STREAM_BASE_INL_H_
3 
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5 
6 #include "stream_base.h"
7 
8 #include "node.h"
9 #include "env.h"
10 #include "env-inl.h"
11 #include "v8.h"
12 
13 namespace node {
14 
15 using v8::External;
16 using v8::FunctionCallbackInfo;
17 using v8::FunctionTemplate;
18 using v8::HandleScope;
19 using v8::Local;
20 using v8::Object;
21 using v8::PropertyAttribute;
22 using v8::PropertyCallbackInfo;
23 using v8::String;
24 using v8::Value;
25 
27 
28 template <class Base>
29 void StreamBase::AddMethods(Environment* env,
30  Local<FunctionTemplate> t,
31  int flags) {
32  HandleScope scope(env->isolate());
33 
34  enum PropertyAttribute attributes =
35  static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
36  t->InstanceTemplate()->SetAccessor(env->fd_string(),
37  GetFD<Base>,
38  nullptr,
39  env->as_external(),
40  v8::DEFAULT,
41  attributes);
42 
43  t->InstanceTemplate()->SetAccessor(env->external_stream_string(),
44  GetExternal<Base>,
45  nullptr,
46  env->as_external(),
47  v8::DEFAULT,
48  attributes);
49 
50  t->InstanceTemplate()->SetAccessor(env->bytes_read_string(),
51  GetBytesRead<Base>,
52  nullptr,
53  env->as_external(),
54  v8::DEFAULT,
55  attributes);
56 
57  env->SetProtoMethod(t, "readStart", JSMethod<Base, &StreamBase::ReadStart>);
58  env->SetProtoMethod(t, "readStop", JSMethod<Base, &StreamBase::ReadStop>);
59  if ((flags & kFlagNoShutdown) == 0)
60  env->SetProtoMethod(t, "shutdown", JSMethod<Base, &StreamBase::Shutdown>);
61  if ((flags & kFlagHasWritev) != 0)
62  env->SetProtoMethod(t, "writev", JSMethod<Base, &StreamBase::Writev>);
63  env->SetProtoMethod(t,
64  "writeBuffer",
65  JSMethod<Base, &StreamBase::WriteBuffer>);
66  env->SetProtoMethod(t,
67  "writeAsciiString",
68  JSMethod<Base, &StreamBase::WriteString<ASCII> >);
69  env->SetProtoMethod(t,
70  "writeUtf8String",
71  JSMethod<Base, &StreamBase::WriteString<UTF8> >);
72  env->SetProtoMethod(t,
73  "writeUcs2String",
74  JSMethod<Base, &StreamBase::WriteString<UCS2> >);
75  env->SetProtoMethod(t,
76  "writeLatin1String",
77  JSMethod<Base, &StreamBase::WriteString<LATIN1> >);
78 }
79 
80 
81 template <class Base>
82 void StreamBase::GetFD(Local<String> key,
83  const PropertyCallbackInfo<Value>& args) {
84  Base* handle = Unwrap<Base>(args.Holder());
85 
86  // Mimic implementation of StreamBase::GetFD() and UDPWrap::GetFD().
87  ASSIGN_OR_RETURN_UNWRAP(&handle,
88  args.Holder(),
89  args.GetReturnValue().Set(UV_EINVAL));
90 
91  StreamBase* wrap = static_cast<StreamBase*>(handle);
92  if (!wrap->IsAlive())
93  return args.GetReturnValue().Set(UV_EINVAL);
94 
95  args.GetReturnValue().Set(wrap->GetFD());
96 }
97 
98 
99 template <class Base>
100 void StreamBase::GetBytesRead(Local<String> key,
101  const PropertyCallbackInfo<Value>& args) {
102  Base* handle = Unwrap<Base>(args.Holder());
103 
104  // The handle instance hasn't been set. So no bytes could have been read.
105  ASSIGN_OR_RETURN_UNWRAP(&handle,
106  args.Holder(),
107  args.GetReturnValue().Set(0));
108 
109  StreamBase* wrap = static_cast<StreamBase*>(handle);
110  // uint64_t -> double. 53bits is enough for all real cases.
111  args.GetReturnValue().Set(static_cast<double>(wrap->bytes_read_));
112 }
113 
114 
115 template <class Base>
116 void StreamBase::GetExternal(Local<String> key,
117  const PropertyCallbackInfo<Value>& args) {
118  Base* handle = Unwrap<Base>(args.Holder());
119 
120  ASSIGN_OR_RETURN_UNWRAP(&handle, args.Holder());
121 
122  StreamBase* wrap = static_cast<StreamBase*>(handle);
123  Local<External> ext = External::New(args.GetIsolate(), wrap);
124  args.GetReturnValue().Set(ext);
125 }
126 
127 
128 template <class Base,
129  int (StreamBase::*Method)(const FunctionCallbackInfo<Value>& args)>
130 void StreamBase::JSMethod(const FunctionCallbackInfo<Value>& args) {
131  Base* handle = Unwrap<Base>(args.Holder());
132 
133  ASSIGN_OR_RETURN_UNWRAP(&handle, args.Holder());
134 
135  StreamBase* wrap = static_cast<StreamBase*>(handle);
136  if (!wrap->IsAlive())
137  return args.GetReturnValue().Set(UV_EINVAL);
138 
139  AsyncHooks::InitScope init_scope(handle->env(), handle->get_id());
140  args.GetReturnValue().Set((wrap->*Method)(args));
141 }
142 
143 
144 WriteWrap* WriteWrap::New(Environment* env,
145  Local<Object> obj,
146  StreamBase* wrap,
147  DoneCb cb,
148  size_t extra) {
149  size_t storage_size = ROUND_UP(sizeof(WriteWrap), kAlignSize) + extra;
150  char* storage = new char[storage_size];
151 
152  return new(storage) WriteWrap(env, obj, wrap, cb, storage_size);
153 }
154 
155 
156 void WriteWrap::Dispose() {
157  this->~WriteWrap();
158  delete[] reinterpret_cast<char*>(this);
159 }
160 
161 
162 char* WriteWrap::Extra(size_t offset) {
163  return reinterpret_cast<char*>(this) +
164  ROUND_UP(sizeof(*this), kAlignSize) +
165  offset;
166 }
167 
168 } // namespace node
169 
170 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
171 
172 #endif // SRC_STREAM_BASE_INL_H_
QueryWrap * wrap
Definition: cares_wrap.cc:478
dtrace t
Definition: v8ustack.d:582
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
Definition: node_buffer.cc:241
node::Environment::AsyncHooks AsyncHooks
Definition: async-wrap.cc:60