|
@ -178,28 +178,33 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, void* ptr) { |
|
|
size_t NodeBIO::Read(char* out, size_t size) { |
|
|
size_t NodeBIO::Read(char* out, size_t size) { |
|
|
size_t bytes_read = 0; |
|
|
size_t bytes_read = 0; |
|
|
size_t expected = Length() > size ? size : Length(); |
|
|
size_t expected = Length() > size ? size : Length(); |
|
|
|
|
|
size_t offset = 0; |
|
|
|
|
|
size_t left = size; |
|
|
|
|
|
|
|
|
while (bytes_read < expected) { |
|
|
while (bytes_read < expected) { |
|
|
assert(read_head_->read_pos_ <= read_head_->write_pos_); |
|
|
assert(read_head_->read_pos_ <= read_head_->write_pos_); |
|
|
size_t avail = read_head_->write_pos_ - read_head_->read_pos_; |
|
|
size_t avail = read_head_->write_pos_ - read_head_->read_pos_; |
|
|
if (avail > size) |
|
|
if (avail > left) |
|
|
avail = size; |
|
|
avail = left; |
|
|
|
|
|
|
|
|
// Copy data
|
|
|
// Copy data
|
|
|
if (out != NULL) |
|
|
if (out != NULL) |
|
|
memcpy(out, read_head_->data_ + read_head_->read_pos_, avail); |
|
|
memcpy(out + offset, read_head_->data_ + read_head_->read_pos_, avail); |
|
|
read_head_->read_pos_ += avail; |
|
|
read_head_->read_pos_ += avail; |
|
|
|
|
|
|
|
|
// Move pointers
|
|
|
// Move pointers
|
|
|
bytes_read += avail; |
|
|
bytes_read += avail; |
|
|
out += avail; |
|
|
offset += avail; |
|
|
size -= avail; |
|
|
left -= avail; |
|
|
|
|
|
|
|
|
// Move to next buffer
|
|
|
// Move to next buffer
|
|
|
if (read_head_->read_pos_ == read_head_->write_pos_) { |
|
|
if (read_head_->read_pos_ == read_head_->write_pos_) { |
|
|
read_head_->read_pos_ = 0; |
|
|
read_head_->read_pos_ = 0; |
|
|
read_head_->write_pos_ = 0; |
|
|
read_head_->write_pos_ = 0; |
|
|
read_head_ = read_head_->next_; |
|
|
|
|
|
|
|
|
// But not get beyond write_head_
|
|
|
|
|
|
if (bytes_read != expected) |
|
|
|
|
|
read_head_ = read_head_->next_; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
assert(expected == bytes_read); |
|
|
assert(expected == bytes_read); |
|
@ -212,13 +217,14 @@ size_t NodeBIO::Read(char* out, size_t size) { |
|
|
size_t NodeBIO::IndexOf(char delim, size_t limit) { |
|
|
size_t NodeBIO::IndexOf(char delim, size_t limit) { |
|
|
size_t bytes_read = 0; |
|
|
size_t bytes_read = 0; |
|
|
size_t max = Length() > limit ? limit : Length(); |
|
|
size_t max = Length() > limit ? limit : Length(); |
|
|
|
|
|
size_t left = limit; |
|
|
Buffer* current = read_head_; |
|
|
Buffer* current = read_head_; |
|
|
|
|
|
|
|
|
while (bytes_read < max) { |
|
|
while (bytes_read < max) { |
|
|
assert(current->read_pos_ <= current->write_pos_); |
|
|
assert(current->read_pos_ <= current->write_pos_); |
|
|
size_t avail = current->write_pos_ - current->read_pos_; |
|
|
size_t avail = current->write_pos_ - current->read_pos_; |
|
|
if (avail > limit) |
|
|
if (avail > left) |
|
|
avail = limit; |
|
|
avail = left; |
|
|
|
|
|
|
|
|
// Walk through data
|
|
|
// Walk through data
|
|
|
char* tmp = current->data_ + current->read_pos_; |
|
|
char* tmp = current->data_ + current->read_pos_; |
|
@ -230,7 +236,7 @@ size_t NodeBIO::IndexOf(char delim, size_t limit) { |
|
|
|
|
|
|
|
|
// Move pointers
|
|
|
// Move pointers
|
|
|
bytes_read += off; |
|
|
bytes_read += off; |
|
|
limit -= off; |
|
|
left -= off; |
|
|
|
|
|
|
|
|
// Found `delim`
|
|
|
// Found `delim`
|
|
|
if (off != avail) { |
|
|
if (off != avail) { |
|
@ -248,9 +254,11 @@ size_t NodeBIO::IndexOf(char delim, size_t limit) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void NodeBIO::Write(const char* data, size_t len) { |
|
|
void NodeBIO::Write(const char* data, size_t size) { |
|
|
while (len > 0) { |
|
|
size_t offset = 0; |
|
|
size_t to_write = len; |
|
|
size_t left = size; |
|
|
|
|
|
while (left > 0) { |
|
|
|
|
|
size_t to_write = left; |
|
|
assert(write_head_->write_pos_ <= kBufferLength); |
|
|
assert(write_head_->write_pos_ <= kBufferLength); |
|
|
size_t avail = kBufferLength - write_head_->write_pos_; |
|
|
size_t avail = kBufferLength - write_head_->write_pos_; |
|
|
|
|
|
|
|
@ -258,28 +266,28 @@ void NodeBIO::Write(const char* data, size_t len) { |
|
|
to_write = avail; |
|
|
to_write = avail; |
|
|
|
|
|
|
|
|
// Copy data
|
|
|
// Copy data
|
|
|
memcpy(write_head_->data_ + write_head_->write_pos_, data, to_write); |
|
|
memcpy(write_head_->data_ + write_head_->write_pos_, |
|
|
write_head_->write_pos_ += to_write; |
|
|
data + offset, |
|
|
assert(write_head_->write_pos_ <= kBufferLength); |
|
|
to_write); |
|
|
|
|
|
|
|
|
// Move pointers
|
|
|
// Move pointers
|
|
|
len -= to_write; |
|
|
left -= to_write; |
|
|
data += to_write; |
|
|
offset += to_write; |
|
|
length_ += to_write; |
|
|
length_ += to_write; |
|
|
|
|
|
write_head_->write_pos_ += to_write; |
|
|
|
|
|
assert(write_head_->write_pos_ <= kBufferLength); |
|
|
|
|
|
|
|
|
// Still have some bytes left:
|
|
|
// Go to next buffer if there still are some bytes to write
|
|
|
// 1. Go to next buffer
|
|
|
if (left != 0) { |
|
|
// 2. Allocate new if next is already full or is partially read
|
|
|
if (write_head_->next_->write_pos_ == kBufferLength) { |
|
|
// (is read head)
|
|
|
Buffer* next = new Buffer(); |
|
|
if (write_head_->next_->write_pos_ == kBufferLength || |
|
|
next->next_ = write_head_->next_; |
|
|
write_head_->next_->read_pos_ != 0) { |
|
|
write_head_->next_ = next; |
|
|
Buffer* next = new Buffer(); |
|
|
} |
|
|
next->next_ = write_head_->next_; |
|
|
write_head_ = write_head_->next_; |
|
|
write_head_->next_ = next; |
|
|
|
|
|
} |
|
|
} |
|
|
write_head_ = write_head_->next_; |
|
|
|
|
|
} |
|
|
} |
|
|
assert(len == 0); |
|
|
assert(left == 0); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|