23 #include "openssl/bio.h" 49 return BIO_new(const_cast<BIO_METHOD*>(&
method));
53 BIO* NodeBIO::NewFixed(
const char*
data,
size_t len) {
58 BIO_write(bio, data, len) != static_cast<int>(len) ||
59 BIO_set_mem_eof_return(bio, 0) != 1) {
68 void NodeBIO::AssignEnvironment(Environment* env) {
74 bio->ptr =
new NodeBIO();
85 int NodeBIO::Free(BIO* bio) {
90 if (bio->init && bio->ptr !=
nullptr) {
100 int NodeBIO::Read(BIO* bio,
char* out,
int len) {
102 BIO_clear_retry_flags(bio);
104 bytes = FromBIO(bio)->Read(out, len);
109 BIO_set_retry_read(bio);
117 char* NodeBIO::Peek(
size_t* size) {
118 *size = read_head_->write_pos_ - read_head_->read_pos_;
119 return read_head_->data_ + read_head_->read_pos_;
123 size_t NodeBIO::PeekMultiple(
char** out,
size_t* size,
size_t* count) {
124 Buffer* pos = read_head_;
129 for (i = 0; i < max; i++) {
130 size[i] = pos->write_pos_ - pos->read_pos_;
132 out[i] = pos->data_ + pos->read_pos_;
135 if (pos == write_head_)
150 int NodeBIO::Write(BIO* bio,
const char* data,
int len) {
151 BIO_clear_retry_flags(bio);
153 FromBIO(bio)->Write(data, len);
159 int NodeBIO::Puts(BIO* bio,
const char* str) {
160 return Write(bio, str, strlen(str));
164 int NodeBIO::Gets(BIO* bio,
char* out,
int size) {
165 NodeBIO* nbio = FromBIO(bio);
167 if (nbio->Length() == 0)
170 int i = nbio->IndexOf(
'\n', size);
173 if (i < size && i >= 0 && static_cast<size_t>(i) < nbio->Length())
189 long NodeBIO::Ctrl(BIO* bio,
int cmd,
long num,
202 ret = nbio->Length() == 0;
204 case BIO_C_SET_BUF_MEM_EOF_RETURN:
208 ret = nbio->Length();
210 *
reinterpret_cast<void**
>(ptr) =
nullptr;
212 case BIO_C_SET_BUF_MEM:
213 CHECK(0 &&
"Can't use SET_BUF_MEM_PTR with NodeBIO");
215 case BIO_C_GET_BUF_MEM_PTR:
216 CHECK(0 &&
"Can't use GET_BUF_MEM_PTR with NodeBIO");
219 case BIO_CTRL_GET_CLOSE:
222 case BIO_CTRL_SET_CLOSE:
225 case BIO_CTRL_WPENDING:
228 case BIO_CTRL_PENDING:
229 ret = nbio->Length();
245 void NodeBIO::TryMoveReadHead() {
250 while (read_head_->read_pos_ != 0 &&
251 read_head_->read_pos_ == read_head_->write_pos_) {
253 read_head_->read_pos_ = 0;
254 read_head_->write_pos_ = 0;
258 if (read_head_ != write_head_)
259 read_head_ = read_head_->next_;
264 size_t NodeBIO::Read(
char* out,
size_t size) {
265 size_t bytes_read = 0;
270 while (bytes_read < expected) {
271 CHECK_LE(read_head_->read_pos_, read_head_->write_pos_);
272 size_t avail = read_head_->write_pos_ - read_head_->read_pos_;
278 memcpy(out + offset, read_head_->data_ + read_head_->read_pos_, avail);
279 read_head_->read_pos_ += avail;
288 CHECK_EQ(expected, bytes_read);
289 length_ -= bytes_read;
298 void NodeBIO::FreeEmpty() {
299 if (write_head_ ==
nullptr)
301 Buffer* child = write_head_->next_;
302 if (child == write_head_ || child == read_head_)
304 Buffer* cur = child->next_;
305 if (cur == write_head_ || cur == read_head_)
308 Buffer* prev = child;
309 while (cur != read_head_) {
310 CHECK_NE(cur, write_head_);
311 CHECK_EQ(cur->write_pos_, cur->read_pos_);
313 Buffer* next = cur->next_;
321 size_t NodeBIO::IndexOf(
char delim,
size_t limit) {
322 size_t bytes_read = 0;
325 Buffer* current = read_head_;
327 while (bytes_read < max) {
328 CHECK_LE(current->read_pos_, current->write_pos_);
329 size_t avail = current->write_pos_ - current->read_pos_;
334 char* tmp = current->data_ + current->read_pos_;
336 while (off < avail && *tmp != delim) {
351 if (current->read_pos_ + avail == current->len_) {
352 current = current->next_;
355 CHECK_EQ(max, bytes_read);
361 void NodeBIO::Write(
const char* data,
size_t size) {
366 TryAllocateForWrite(left);
369 size_t to_write = left;
370 CHECK_LE(write_head_->write_pos_, write_head_->len_);
371 size_t avail = write_head_->len_ - write_head_->write_pos_;
373 if (to_write > avail)
377 memcpy(write_head_->data_ + write_head_->write_pos_,
385 write_head_->write_pos_ += to_write;
386 CHECK_LE(write_head_->write_pos_, write_head_->len_);
390 CHECK_EQ(write_head_->write_pos_, write_head_->len_);
391 TryAllocateForWrite(left);
392 write_head_ = write_head_->next_;
403 char* NodeBIO::PeekWritable(
size_t* size) {
404 TryAllocateForWrite(*size);
406 size_t available = write_head_->len_ - write_head_->write_pos_;
407 if (*size != 0 && available > *size)
412 return write_head_->data_ + write_head_->write_pos_;
416 void NodeBIO::Commit(
size_t size) {
417 write_head_->write_pos_ += size;
419 CHECK_LE(write_head_->write_pos_, write_head_->len_);
423 TryAllocateForWrite(0);
424 if (write_head_->write_pos_ == write_head_->len_) {
425 write_head_ = write_head_->next_;
434 void NodeBIO::TryAllocateForWrite(
size_t hint) {
435 Buffer* w = write_head_;
436 Buffer* r = read_head_;
439 (w->write_pos_ == w->len_ &&
440 (w->next_ == r || w->next_->write_pos_ != 0))) {
441 size_t len = w ==
nullptr ? initial_ :
442 kThroughputBufferLength;
445 Buffer* next =
new Buffer(
env_, len);
452 next->next_ = w->next_;
459 void NodeBIO::Reset() {
460 if (read_head_ ==
nullptr)
463 while (read_head_->read_pos_ != read_head_->write_pos_) {
464 CHECK(read_head_->write_pos_ > read_head_->read_pos_);
466 length_ -= read_head_->write_pos_ - read_head_->read_pos_;
467 read_head_->write_pos_ = 0;
468 read_head_->read_pos_ = 0;
470 read_head_ = read_head_->next_;
472 write_head_ = read_head_;
473 CHECK_EQ(length_, 0);
477 NodeBIO::~NodeBIO() {
478 if (read_head_ ==
nullptr)
481 Buffer* current = read_head_;
483 Buffer* next = current->next_;
486 }
while (current != read_head_);
488 read_head_ =
nullptr;
489 write_head_ =
nullptr;
union node::cares_wrap::@8::CaresAsyncData::@0 data
size_t Length(Local< Value > val)
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)