%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/quic/
Upload File :
Create Path :
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/quic/logstream.cc

#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC

#include "logstream.h"
#include <async_wrap-inl.h>
#include <base_object-inl.h>
#include <env-inl.h>
#include <memory_tracker-inl.h>
#include <node_external_reference.h>
#include <stream_base-inl.h>
#include <uv.h>
#include <v8.h>
#include "bindingdata.h"

namespace node {

using v8::FunctionTemplate;
using v8::Local;
using v8::Object;

namespace quic {

Local<FunctionTemplate> LogStream::GetConstructorTemplate(Environment* env) {
  auto& state = BindingData::Get(env);
  auto tmpl = state.logstream_constructor_template();
  if (tmpl.IsEmpty()) {
    tmpl = FunctionTemplate::New(env->isolate());
    tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
    tmpl->InstanceTemplate()->SetInternalFieldCount(
        StreamBase::kInternalFieldCount);
    tmpl->SetClassName(state.logstream_string());
    StreamBase::AddMethods(env, tmpl);
    state.set_logstream_constructor_template(tmpl);
  }
  return tmpl;
}

BaseObjectPtr<LogStream> LogStream::Create(Environment* env) {
  v8::Local<v8::Object> obj;
  if (!GetConstructorTemplate(env)
           ->InstanceTemplate()
           ->NewInstance(env->context())
           .ToLocal(&obj)) {
    return BaseObjectPtr<LogStream>();
  }
  return MakeDetachedBaseObject<LogStream>(env, obj);
}

LogStream::LogStream(Environment* env, Local<Object> obj)
    : AsyncWrap(env, obj, AsyncWrap::PROVIDER_QUIC_LOGSTREAM), StreamBase(env) {
  MakeWeak();
  StreamBase::AttachToObject(GetObject());
}

void LogStream::Emit(const uint8_t* data, size_t len, EmitOption option) {
  if (fin_seen_) return;
  fin_seen_ = option == EmitOption::FIN;

  size_t remaining = len;
  // If the len is greater than the size of the buffer returned by
  // EmitAlloc then EmitRead will be called multiple times.
  while (remaining != 0) {
    uv_buf_t buf = EmitAlloc(len);
    size_t len = std::min<size_t>(remaining, buf.len);
    memcpy(buf.base, data, len);
    remaining -= len;
    data += len;
    // If we are actively reading from the stream, we'll call emit
    // read immediately. Otherwise we buffer the chunk and will push
    // the chunks out the next time ReadStart() is called.
    if (reading_) {
      EmitRead(len, buf);
    } else {
      // The total measures the total memory used so we always
      // increment but buf.len and not chunk len.
      ensure_space(buf.len);
      total_ += buf.len;
      buffer_.push_back(Chunk{len, buf});
    }
  }

  if (ended_ && reading_) {
    EmitRead(UV_EOF);
  }
}

void LogStream::Emit(const std::string_view line, EmitOption option) {
  Emit(reinterpret_cast<const uint8_t*>(line.data()), line.length(), option);
}

void LogStream::End() {
  ended_ = true;
}

int LogStream::ReadStart() {
  if (reading_) return 0;
  // Flush any chunks that have already been buffered.
  for (const auto& chunk : buffer_) EmitRead(chunk.len, chunk.buf);
  total_ = 0;
  buffer_.clear();
  if (fin_seen_) {
    // If we've already received the fin, there's nothing else to wait for.
    EmitRead(UV_EOF);
    return ReadStop();
  }
  // Otherwise, we're going to wait for more chunks to be written.
  reading_ = true;
  return 0;
}

int LogStream::ReadStop() {
  reading_ = false;
  return 0;
}

// We do not use either of these.
int LogStream::DoShutdown(ShutdownWrap* req_wrap) {
  UNREACHABLE();
}
int LogStream::DoWrite(WriteWrap* w,
                       uv_buf_t* bufs,
                       size_t count,
                       uv_stream_t* send_handle) {
  UNREACHABLE();
}

bool LogStream::IsAlive() {
  return !ended_;
}

bool LogStream::IsClosing() {
  return ended_;
}

AsyncWrap* LogStream::GetAsyncWrap() {
  return this;
}

void LogStream::MemoryInfo(MemoryTracker* tracker) const {
  tracker->TrackFieldWithSize("buffer", total_);
}

// The LogStream buffer enforces a maximum size of kMaxLogStreamBuffer.
void LogStream::ensure_space(size_t amt) {
  while (total_ + amt > kMaxLogStreamBuffer) {
    total_ -= buffer_.front().buf.len;
    buffer_.pop_front();
  }
}
}  // namespace quic
}  // namespace node

#endif  // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC

Zerion Mini Shell 1.0