• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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