1 #pragma once
2
3 #include <aliased_struct.h>
4 #include <env.h>
5 #include <node_errors.h>
6 #include <uv.h>
7 #include <v8.h>
8
9 namespace node {
10 namespace quic {
11
12 template <typename Opt, std::string Opt::*member>
SetOption(Environment * env,Opt * options,const v8::Local<v8::Object> & object,const v8::Local<v8::String> & name)13 bool SetOption(Environment* env,
14 Opt* options,
15 const v8::Local<v8::Object>& object,
16 const v8::Local<v8::String>& name) {
17 v8::Local<v8::Value> value;
18 if (!object->Get(env->context(), name).ToLocal(&value)) return false;
19 if (!value->IsUndefined()) {
20 Utf8Value utf8(env->isolate(), value);
21 options->*member = *utf8;
22 }
23 return true;
24 }
25
26 template <typename Opt, bool Opt::*member>
SetOption(Environment * env,Opt * options,const v8::Local<v8::Object> & object,const v8::Local<v8::String> & name)27 bool SetOption(Environment* env,
28 Opt* options,
29 const v8::Local<v8::Object>& object,
30 const v8::Local<v8::String>& name) {
31 v8::Local<v8::Value> value;
32 if (!object->Get(env->context(), name).ToLocal(&value)) return false;
33 if (!value->IsUndefined()) {
34 CHECK(value->IsBoolean());
35 options->*member = value->IsTrue();
36 }
37 return true;
38 }
39
40 template <typename Opt, uint64_t Opt::*member>
SetOption(Environment * env,Opt * options,const v8::Local<v8::Object> & object,const v8::Local<v8::String> & name)41 bool SetOption(Environment* env,
42 Opt* options,
43 const v8::Local<v8::Object>& object,
44 const v8::Local<v8::String>& name) {
45 v8::Local<v8::Value> value;
46 if (!object->Get(env->context(), name).ToLocal(&value)) return false;
47
48 if (!value->IsUndefined()) {
49 CHECK_IMPLIES(!value->IsBigInt(), value->IsNumber());
50
51 uint64_t val = 0;
52 if (value->IsBigInt()) {
53 bool lossless = true;
54 val = value.As<v8::BigInt>()->Uint64Value(&lossless);
55 if (!lossless) {
56 Utf8Value label(env->isolate(), name);
57 THROW_ERR_OUT_OF_RANGE(
58 env, ("options." + label.ToString() + " is out of range").c_str());
59 return false;
60 }
61 } else {
62 val = static_cast<int64_t>(value.As<v8::Number>()->Value());
63 }
64 options->*member = val;
65 }
66 return true;
67 }
68
69 // Utilities used to update the stats for Endpoint, Session, and Stream
70 // objects. The stats themselves are maintained in an AliasedStruct within
71 // each of the relevant classes.
72
73 template <typename Stats, uint64_t Stats::*member>
74 void IncrementStat(Stats* stats, uint64_t amt = 1) {
75 stats->*member += amt;
76 }
77
78 template <typename Stats, uint64_t Stats::*member>
RecordTimestampStat(Stats * stats)79 void RecordTimestampStat(Stats* stats) {
80 stats->*member = uv_hrtime();
81 }
82
83 template <typename Stats, uint64_t Stats::*member>
SetStat(Stats * stats,uint64_t val)84 void SetStat(Stats* stats, uint64_t val) {
85 stats->*member = val;
86 }
87
88 template <typename Stats, uint64_t Stats::*member>
GetStat(Stats * stats)89 uint64_t GetStat(Stats* stats) {
90 return stats->*member;
91 }
92
93 #define STAT_INCREMENT(Type, name) IncrementStat<Type, &Type::name>(&stats_);
94 #define STAT_INCREMENT_N(Type, name, amt) \
95 IncrementStat<Type, &Type::name>(&stats_, amt);
96 #define STAT_RECORD_TIMESTAMP(Type, name) \
97 RecordTimestampStat<Type, &Type::name>(&stats_);
98 #define STAT_SET(Type, name, val) SetStat<Type, &Type::name>(&stats_, val);
99 #define STAT_GET(Type, name) GetStat<Type, &Type::name>(&stats_);
100
101 } // namespace quic
102 } // namespace node
103