Thrift: Add writePtr(), wroteBytes() to TMemoryBuffer
Summary: This adds the discussed interface to TMemoryBuffer, as follows:
- writePtr(size) returns a ptr you can write (size) bytes to
- wroteBytes() lets it know you wrote that many bytes
To do this, I refactored an:
- ensureCanWrite(size) private func
Reviewed By: dreiss
Test Plan: works in my test environment
Revert: OK
TracCamp Project: Thrift
DiffCamp Revision: 8739
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665555 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TTransportUtils.cpp b/lib/cpp/src/transport/TTransportUtils.cpp
index cb7ab61..d00025e 100644
--- a/lib/cpp/src/transport/TTransportUtils.cpp
+++ b/lib/cpp/src/transport/TTransportUtils.cpp
@@ -297,30 +297,44 @@
return give;
}
-void TMemoryBuffer::write(const uint8_t* buf, uint32_t len) {
+void TMemoryBuffer::ensureCanWrite(uint32_t len) {
// Check available space
uint32_t avail = bufferSize_ - wPos_;
-
- // Grow the buffer
- if (len > avail) {
- if (!owner_) {
- throw TTransportException("Insufficient space in external MemoryBuffer");
- }
- while (len > avail) {
- bufferSize_ *= 2;
- avail = bufferSize_ - wPos_;
- }
- buffer_ = (uint8_t*)std::realloc(buffer_, bufferSize_);
- if (buffer_ == NULL) {
- throw TTransportException("Out of memory.");
- }
+ if (len <= avail) {
+ return;
}
+ if (!owner_) {
+ throw TTransportException("Insufficient space in external MemoryBuffer");
+ }
+
+ // Grow the buffer as necessary
+ while (len > avail) {
+ bufferSize_ *= 2;
+ avail = bufferSize_ - wPos_;
+ }
+ buffer_ = (uint8_t*)std::realloc(buffer_, bufferSize_);
+ if (buffer_ == NULL) {
+ throw TTransportException("Out of memory.");
+ }
+}
+
+void TMemoryBuffer::write(const uint8_t* buf, uint32_t len) {
+ ensureCanWrite(len);
+
// Copy into the buffer and increment wPos_
memcpy(buffer_ + wPos_, buf, len);
wPos_ += len;
}
+void TMemoryBuffer::wroteBytes(uint32_t len) {
+ uint32_t avail = bufferSize_ - wPos_;
+ if (len > avail) {
+ throw TTransportException("Client wrote more bytes than size of buffer.");
+ }
+ wPos_ += len;
+}
+
const uint8_t* TMemoryBuffer::borrow(uint8_t* buf, uint32_t* len) {
if (wPos_-rPos_ >= *len) {
*len = wPos_-rPos_;
diff --git a/lib/cpp/src/transport/TTransportUtils.h b/lib/cpp/src/transport/TTransportUtils.h
index 59d8fb8..e54c1b8 100644
--- a/lib/cpp/src/transport/TTransportUtils.h
+++ b/lib/cpp/src/transport/TTransportUtils.h
@@ -315,6 +315,9 @@
rPos_ = 0;
}
+ // make sure there's at least 'len' bytes available for writing
+ void ensureCanWrite(uint32_t len);
+
public:
static const uint32_t defaultSize = 1024;
@@ -480,7 +483,7 @@
void write(const uint8_t* buf, uint32_t len);
- uint32_t available() {
+ uint32_t available() const {
return wPos_ - rPos_;
}
@@ -496,6 +499,20 @@
swap(owner_, that.owner_);
}
+ // Returns a pointer to where the client can write data to append to
+ // the TMemoryBuffer, and ensures the buffer is big enough to accomodate a
+ // write of the provided length. The returned pointer is very convenient for
+ // passing to read(), recv(), or similar. You must call wroteBytes() as soon
+ // as data is written or the buffer will not be aware that data has changed.
+ uint8_t* getWritePtr(uint32_t len) {
+ ensureCanWrite(len);
+ return buffer_ + wPos_;
+ }
+
+ // Informs the buffer that the client has written 'len' bytes into storage
+ // that had been provided by getWritePtr().
+ void wroteBytes(uint32_t len);
+
private:
// Data buffer
uint8_t* buffer_;