/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
}
-} // anonymous namespace
+} // namespace
namespace folly {
std::min(max, last->tailroom()));
}
-unique_ptr<IOBuf>
-IOBufQueue::split(size_t n) {
+unique_ptr<IOBuf> IOBufQueue::split(size_t n, bool throwOnUnderflow) {
unique_ptr<IOBuf> result;
while (n != 0) {
if (head_ == nullptr) {
- throw std::underflow_error(
- "Attempt to remove more bytes than are present in IOBufQueue");
+ if (throwOnUnderflow) {
+ throw std::underflow_error(
+ "Attempt to remove more bytes than are present in IOBufQueue");
+ } else {
+ break;
+ }
} else if (head_->length() <= n) {
n -= head_->length();
chainLength_ -= head_->length();
break;
}
}
+ if (UNLIKELY(result == nullptr)) {
+ return IOBuf::create(0);
+ }
return result;
}
void IOBufQueue::trimStart(size_t amount) {
+ auto trimmed = trimStartAtMost(amount);
+ if (trimmed != amount) {
+ throw std::underflow_error(
+ "Attempt to trim more bytes than are present in IOBufQueue");
+ }
+}
+
+size_t IOBufQueue::trimStartAtMost(size_t amount) {
+ auto original = amount;
while (amount > 0) {
if (!head_) {
- throw std::underflow_error(
- "Attempt to trim more bytes than are present in IOBufQueue");
+ break;
}
if (head_->length() > amount) {
head_->trimStart(amount);
chainLength_ -= amount;
+ amount = 0;
break;
}
amount -= head_->length();
chainLength_ -= head_->length();
head_ = head_->pop();
}
+ return original - amount;
}
void IOBufQueue::trimEnd(size_t amount) {
+ auto trimmed = trimEndAtMost(amount);
+ if (trimmed != amount) {
+ throw std::underflow_error(
+ "Attempt to trim more bytes than are present in IOBufQueue");
+ }
+}
+
+size_t IOBufQueue::trimEndAtMost(size_t amount) {
+ auto original = amount;
while (amount > 0) {
if (!head_) {
- throw std::underflow_error(
- "Attempt to trim more bytes than are present in IOBufQueue");
+ break;
}
if (head_->prev()->length() > amount) {
head_->prev()->trimEnd(amount);
chainLength_ -= amount;
+ amount = 0;
break;
}
amount -= head_->prev()->length();
head_.reset();
}
}
+ return original - amount;
}
std::unique_ptr<folly::IOBuf> IOBufQueue::pop_front() {
}
}
-} // folly
+void IOBufQueue::gather(uint64_t maxLength) {
+ if (head_ != nullptr) {
+ head_->gather(maxLength);
+ }
+}
+
+} // namespace folly