11cb0ef41Sopenharmony_ci#pragma once
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci#include <aliased_struct.h>
41cb0ef41Sopenharmony_ci#include <env.h>
51cb0ef41Sopenharmony_ci#include <node_errors.h>
61cb0ef41Sopenharmony_ci#include <uv.h>
71cb0ef41Sopenharmony_ci#include <v8.h>
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cinamespace node {
101cb0ef41Sopenharmony_cinamespace quic {
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_citemplate <typename Opt, std::string Opt::*member>
131cb0ef41Sopenharmony_cibool SetOption(Environment* env,
141cb0ef41Sopenharmony_ci               Opt* options,
151cb0ef41Sopenharmony_ci               const v8::Local<v8::Object>& object,
161cb0ef41Sopenharmony_ci               const v8::Local<v8::String>& name) {
171cb0ef41Sopenharmony_ci  v8::Local<v8::Value> value;
181cb0ef41Sopenharmony_ci  if (!object->Get(env->context(), name).ToLocal(&value)) return false;
191cb0ef41Sopenharmony_ci  if (!value->IsUndefined()) {
201cb0ef41Sopenharmony_ci    Utf8Value utf8(env->isolate(), value);
211cb0ef41Sopenharmony_ci    options->*member = *utf8;
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci  return true;
241cb0ef41Sopenharmony_ci}
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_citemplate <typename Opt, bool Opt::*member>
271cb0ef41Sopenharmony_cibool SetOption(Environment* env,
281cb0ef41Sopenharmony_ci               Opt* options,
291cb0ef41Sopenharmony_ci               const v8::Local<v8::Object>& object,
301cb0ef41Sopenharmony_ci               const v8::Local<v8::String>& name) {
311cb0ef41Sopenharmony_ci  v8::Local<v8::Value> value;
321cb0ef41Sopenharmony_ci  if (!object->Get(env->context(), name).ToLocal(&value)) return false;
331cb0ef41Sopenharmony_ci  if (!value->IsUndefined()) {
341cb0ef41Sopenharmony_ci    CHECK(value->IsBoolean());
351cb0ef41Sopenharmony_ci    options->*member = value->IsTrue();
361cb0ef41Sopenharmony_ci  }
371cb0ef41Sopenharmony_ci  return true;
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_citemplate <typename Opt, uint64_t Opt::*member>
411cb0ef41Sopenharmony_cibool SetOption(Environment* env,
421cb0ef41Sopenharmony_ci               Opt* options,
431cb0ef41Sopenharmony_ci               const v8::Local<v8::Object>& object,
441cb0ef41Sopenharmony_ci               const v8::Local<v8::String>& name) {
451cb0ef41Sopenharmony_ci  v8::Local<v8::Value> value;
461cb0ef41Sopenharmony_ci  if (!object->Get(env->context(), name).ToLocal(&value)) return false;
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  if (!value->IsUndefined()) {
491cb0ef41Sopenharmony_ci    CHECK_IMPLIES(!value->IsBigInt(), value->IsNumber());
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci    uint64_t val = 0;
521cb0ef41Sopenharmony_ci    if (value->IsBigInt()) {
531cb0ef41Sopenharmony_ci      bool lossless = true;
541cb0ef41Sopenharmony_ci      val = value.As<v8::BigInt>()->Uint64Value(&lossless);
551cb0ef41Sopenharmony_ci      if (!lossless) {
561cb0ef41Sopenharmony_ci        Utf8Value label(env->isolate(), name);
571cb0ef41Sopenharmony_ci        THROW_ERR_OUT_OF_RANGE(
581cb0ef41Sopenharmony_ci            env, ("options." + label.ToString() + " is out of range").c_str());
591cb0ef41Sopenharmony_ci        return false;
601cb0ef41Sopenharmony_ci      }
611cb0ef41Sopenharmony_ci    } else {
621cb0ef41Sopenharmony_ci      val = static_cast<int64_t>(value.As<v8::Number>()->Value());
631cb0ef41Sopenharmony_ci    }
641cb0ef41Sopenharmony_ci    options->*member = val;
651cb0ef41Sopenharmony_ci  }
661cb0ef41Sopenharmony_ci  return true;
671cb0ef41Sopenharmony_ci}
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci// Utilities used to update the stats for Endpoint, Session, and Stream
701cb0ef41Sopenharmony_ci// objects. The stats themselves are maintained in an AliasedStruct within
711cb0ef41Sopenharmony_ci// each of the relevant classes.
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_citemplate <typename Stats, uint64_t Stats::*member>
741cb0ef41Sopenharmony_civoid IncrementStat(Stats* stats, uint64_t amt = 1) {
751cb0ef41Sopenharmony_ci  stats->*member += amt;
761cb0ef41Sopenharmony_ci}
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_citemplate <typename Stats, uint64_t Stats::*member>
791cb0ef41Sopenharmony_civoid RecordTimestampStat(Stats* stats) {
801cb0ef41Sopenharmony_ci  stats->*member = uv_hrtime();
811cb0ef41Sopenharmony_ci}
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_citemplate <typename Stats, uint64_t Stats::*member>
841cb0ef41Sopenharmony_civoid SetStat(Stats* stats, uint64_t val) {
851cb0ef41Sopenharmony_ci  stats->*member = val;
861cb0ef41Sopenharmony_ci}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_citemplate <typename Stats, uint64_t Stats::*member>
891cb0ef41Sopenharmony_ciuint64_t GetStat(Stats* stats) {
901cb0ef41Sopenharmony_ci  return stats->*member;
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci#define STAT_INCREMENT(Type, name) IncrementStat<Type, &Type::name>(&stats_);
941cb0ef41Sopenharmony_ci#define STAT_INCREMENT_N(Type, name, amt)                                      \
951cb0ef41Sopenharmony_ci  IncrementStat<Type, &Type::name>(&stats_, amt);
961cb0ef41Sopenharmony_ci#define STAT_RECORD_TIMESTAMP(Type, name)                                      \
971cb0ef41Sopenharmony_ci  RecordTimestampStat<Type, &Type::name>(&stats_);
981cb0ef41Sopenharmony_ci#define STAT_SET(Type, name, val) SetStat<Type, &Type::name>(&stats_, val);
991cb0ef41Sopenharmony_ci#define STAT_GET(Type, name) GetStat<Type, &Type::name>(&stats_);
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci}  // namespace quic
1021cb0ef41Sopenharmony_ci}  // namespace node
103