From db2091dd94d04a2309371a8d80ba9e2584a2370e Mon Sep 17 00:00:00 2001 From: Thad House Date: Sat, 10 Dec 2016 22:40:44 -0800 Subject: [PATCH] Adds safe serial port write methods (#396) The old method had a fairly large risk of undefined behavior, and the way the docs were written could cause users to get confused. Deprecate the old method and add StringRef method as preferred approach. --- wpilibc/athena/include/SerialPort.h | 7 +++++++ wpilibc/athena/src/SerialPort.cpp | 29 +++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/wpilibc/athena/include/SerialPort.h b/wpilibc/athena/include/SerialPort.h index f2e140d455..0de241f4b0 100644 --- a/wpilibc/athena/include/SerialPort.h +++ b/wpilibc/athena/include/SerialPort.h @@ -10,6 +10,8 @@ #include #include "ErrorBase.h" +#include "llvm/StringRef.h" +#include "support/deprecated.h" namespace frc { @@ -60,7 +62,12 @@ class SerialPort : public ErrorBase { void DisableTermination(); int GetBytesReceived(); int Read(char* buffer, int count); + WPI_DEPRECATED( + "Potential for unexpected behavior. Please use StringRef overload for " + "custom length buffers using std::string") int Write(const std::string& buffer, int count); + int Write(const char* buffer, int count); + int Write(llvm::StringRef buffer); void SetTimeout(double timeout); void SetReadBufferSize(int size); void SetWriteBufferSize(int size); diff --git a/wpilibc/athena/src/SerialPort.cpp b/wpilibc/athena/src/SerialPort.cpp index 2b2937eb8a..466e4583c9 100644 --- a/wpilibc/athena/src/SerialPort.cpp +++ b/wpilibc/athena/src/SerialPort.cpp @@ -134,6 +134,21 @@ int SerialPort::Read(char* buffer, int count) { return retVal; } +/** + * Write raw bytes to the buffer. Deprecated, please use StringRef overload. Use + * Write({data, len}) to get a buffer that is shorter then the length of the + * std::string. + * + * @param buffer Pointer to the buffer to read the bytes from. If string.size() + * is less then count, only the length of string.size() will be sent. + * @param count The maximum number of bytes to write. + * @return The number of bytes actually written into the port. + */ +int SerialPort::Write(const std::string& buffer, int count) { + return Write(llvm::StringRef( + buffer.data(), std::min(static_cast(buffer.size()), count))); +} + /** * Write raw bytes to the buffer. * @@ -141,10 +156,20 @@ int SerialPort::Read(char* buffer, int count) { * @param count The maximum number of bytes to write. * @return The number of bytes actually written into the port. */ -int SerialPort::Write(const std::string& buffer, int count) { +int SerialPort::Write(const char* buffer, int count) { + return Write(llvm::StringRef(buffer, static_cast(count))); +} + +/** + * Write raw bytes to the buffer. + * + * @param buffer StringRef to the buffer to read the bytes from. + * @return The number of bytes actually written into the port. + */ +int SerialPort::Write(llvm::StringRef buffer) { int32_t status = 0; int retVal = HAL_WriteSerial(static_cast(m_port), - buffer.c_str(), count, &status); + buffer.data(), buffer.size(), &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); return retVal; }