Add function to reliably acquire message body length (#349)

* Add function to reliably acquire message body length; Fix a few typo and grammar error
Co-authored-by: Li Zhanhui <shutian.lzh@alibaba-inc.com>
diff --git a/.gitignore b/.gitignore
index 0640d20..013ac4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@
 tmp_*
 Testing
 .vscode
+.cache
+compile_commands.json
diff --git a/build.sh b/build.sh
index 8a424bb..ca49088 100755
--- a/build.sh
+++ b/build.sh
@@ -157,7 +157,7 @@
 
 Prepare() {
   if [ -e ${down_dir} ]; then
-    echo "${down_dir} is exist"
+    echo "${down_dir} exists"
     #cd ${down_dir}
     #ls |grep -v ${fname_libevent} |grep -v ${fname_jsoncpp} | grep -v ${fname_boost} |xargs rm -rf
   else
@@ -182,21 +182,21 @@
   fi
 
   if [ -e ${build_dir} ]; then
-    echo "${build_dir} is exist"
+    echo "${build_dir} exists"
     #rm -rf ${build_dir}/*
   else
     mkdir -p ${build_dir}
   fi
 
   if [ -e ${packet_dir} ]; then
-    echo "${packet_dir} is exist"
+    echo "${packet_dir} exists"
     #rm -rf ${packet_dir}/*
   else
     mkdir -p ${packet_dir}
   fi
 
   if [ -e ${install_lib_dir} ]; then
-    echo "${install_lib_dir} is exist"
+    echo "${install_lib_dir} exists"
   else
     mkdir -p ${install_lib_dir}
   fi
@@ -210,7 +210,7 @@
 
   cd ${down_dir}
   if [ -e ${fname_openssl} ]; then
-    echo "${fname_openssl} is exist"
+    echo "${fname_openssl} exists"
   else
     wget https://www.openssl.org/source/old/1.1.1/${fname_openssl_down} -O ${fname_openssl_down}
   fi
@@ -256,7 +256,7 @@
 
   cd ${down_dir}
   if [ -e ${fname_libevent} ]; then
-    echo "${fname_libevent} is exist"
+    echo "${fname_libevent} exists"
   else
     wget https://github.com/libevent/libevent/archive/${fname_libevent_down} -O libevent-${fname_libevent_down}
   fi
@@ -305,7 +305,7 @@
   cd ${down_dir}
 
   if [ -e ${fname_jsoncpp} ]; then
-    echo "${fname_jsoncpp} is exist"
+    echo "${fname_jsoncpp} exists"
   else
     wget https://github.com/open-source-parsers/jsoncpp/archive/${fname_jsoncpp_down} -O jsoncpp-${fname_jsoncpp_down}
   fi
@@ -354,7 +354,7 @@
 
   cd ${down_dir}
   if [ -e ${fname_boost} ]; then
-    echo "${fname_boost} is exist"
+    echo "${fname_boost} exists"
   else
     wget http://sourceforge.net/projects/boost/files/boost/${fname_boost_down}
   fi
@@ -430,12 +430,12 @@
     return 0
   fi
   if [ -f ./bin/lib/libgtest.a ]; then
-    echo "libgteest already exist no need build test"
+    echo "GTest already exists, no need build"
     return 0
   fi
   cd ${down_dir}
   if [ -e release-1.8.1.tar.gz ]; then
-    echo "${fname_boost} is exist"
+    echo "${fname_boost} exists"
   else
     wget https://github.com/abseil/googletest/archive/release-1.8.1.tar.gz
   fi
diff --git a/include/CMessage.h b/include/CMessage.h
index be46435..a02305d 100644
--- a/include/CMessage.h
+++ b/include/CMessage.h
@@ -39,6 +39,7 @@
 ROCKETMQCLIENT_API const char* GetOriginMessageTags(CMessage* msg);
 ROCKETMQCLIENT_API const char* GetOriginMessageKeys(CMessage* msg);
 ROCKETMQCLIENT_API const char* GetOriginMessageBody(CMessage* msg);
+ROCKETMQCLIENT_API int GetOriginMessageBodyLength(CMessage* msg);
 ROCKETMQCLIENT_API const char* GetOriginMessageProperty(CMessage* msg, const char* key);
 ROCKETMQCLIENT_API int GetOriginDelayTimeLevel(CMessage* msg);
 
diff --git a/include/CMessageExt.h b/include/CMessageExt.h
index 42d35de..ae216e0 100644
--- a/include/CMessageExt.h
+++ b/include/CMessageExt.h
@@ -31,6 +31,7 @@
 ROCKETMQCLIENT_API const char* GetMessageTags(CMessageExt* msgExt);
 ROCKETMQCLIENT_API const char* GetMessageKeys(CMessageExt* msgExt);
 ROCKETMQCLIENT_API const char* GetMessageBody(CMessageExt* msgExt);
+ROCKETMQCLIENT_API int GetMessageBodyLength(CMessageExt* msgExt);
 ROCKETMQCLIENT_API const char* GetMessageProperty(CMessageExt* msgExt, const char* key);
 ROCKETMQCLIENT_API const char* GetMessageId(CMessageExt* msgExt);
 ROCKETMQCLIENT_API int GetMessageDelayTimeLevel(CMessageExt* msgExt);
diff --git a/src/extern/CMessage.cpp b/src/extern/CMessage.cpp
index ea3e4f6..d55b391 100644
--- a/src/extern/CMessage.cpp
+++ b/src/extern/CMessage.cpp
@@ -60,6 +60,10 @@
   ((MQMessage*)msg)->setKeys(keys);
   return OK;
 }
+
+/**
+ * DO NOT USE THIS FUNCTION, IT IS ERROR-PRONE.
+ */
 int SetMessageBody(CMessage* msg, const char* body) {
   if (msg == NULL) {
     return NULL_POINTER;
@@ -112,6 +116,12 @@
   }
   return ((MQMessage*)msg)->getBody().c_str();
 }
+int GetOriginMessageBodyLength(CMessage* msg) {
+  if (NULL == msg) {
+    return 0;
+  }
+  return reinterpret_cast<MQMessage*>(msg)->getBody().length();
+}
 const char* GetOriginMessageProperty(CMessage* msg, const char* key) {
   if (msg == NULL) {
     return NULL;
diff --git a/src/extern/CMessageExt.cpp b/src/extern/CMessageExt.cpp
index a013b84..45da289 100644
--- a/src/extern/CMessageExt.cpp
+++ b/src/extern/CMessageExt.cpp
@@ -47,6 +47,14 @@
   }
   return ((MQMessageExt*)msg)->getBody().c_str();
 }
+
+int GetMessageBodyLength(CMessageExt* msgExt) {
+  if (NULL == msgExt) {
+    return 0;
+  }
+  return reinterpret_cast<MQMessageExt*>(msgExt)->getBody().length();
+}
+
 const char* GetMessageProperty(CMessageExt* msg, const char* key) {
   if (msg == NULL) {
     return NULL;
diff --git a/test/src/extern/CMessageExtTest.cpp b/test/src/extern/CMessageExtTest.cpp
index 8752d5c..386054a 100644
--- a/test/src/extern/CMessageExtTest.cpp
+++ b/test/src/extern/CMessageExtTest.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#include <string>
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -41,8 +42,11 @@
   mqMessageExt->setKeys("testKeys");
   EXPECT_EQ(GetMessageKeys(messageExt), mqMessageExt->getKeys());
 
-  mqMessageExt->setBody("testBody");
-  EXPECT_EQ(GetMessageBody(messageExt), mqMessageExt->getBody());
+  std::string body("testBody");
+  body.append(3, '\0');
+  mqMessageExt->setBody(body.c_str(), body.length());
+  std::string retrieved_body(GetMessageBody(messageExt), GetMessageBodyLength(messageExt));
+  EXPECT_TRUE(body == retrieved_body);
 
   mqMessageExt->setProperty("testKey", "testValues");
   EXPECT_EQ(GetMessageProperty(messageExt, "testKey"), mqMessageExt->getProperty("testKey"));
diff --git a/test/src/extern/CMessageTest.cpp b/test/src/extern/CMessageTest.cpp
index 19d78c2..4ac24f1 100644
--- a/test/src/extern/CMessageTest.cpp
+++ b/test/src/extern/CMessageTest.cpp
@@ -14,6 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#include <cstring>
+#include <string>
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -40,8 +43,11 @@
   SetMessageKeys(message, "testKeys");
   EXPECT_STREQ(GetOriginMessageKeys(message), "testKeys");
 
-  SetMessageBody(message, "testBody");
-  EXPECT_STREQ(GetOriginMessageBody(message), "testBody");
+  std::string body("test_body");
+  body.append(3, '\0');
+  SetByteMessageBody(message, body.c_str(), body.length());
+  std::string retrieved_body(GetOriginMessageBody(message), GetOriginMessageBodyLength(message));
+  EXPECT_TRUE(body == retrieved_body);
 
   SetMessageProperty(message, "testKey", "testValue");
   EXPECT_STREQ(GetOriginMessageProperty(message, "testKey"), "testValue");