diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/cpp/CppGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/cpp/CppGenerator.java index 6541d41163..ec1b200d3d 100755 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/cpp/CppGenerator.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/cpp/CppGenerator.java @@ -531,9 +531,12 @@ private void generateVarData( indent + " %3$s lengthFieldValue = %4$s(length);\n" + indent + " sbePosition(lengthPosition + lengthOfLengthField);\n" + indent + " std::memcpy(m_buffer + lengthPosition, &lengthFieldValue, sizeof(%3$s));\n" + - indent + " std::uint64_t pos = sbePosition();\n" + - indent + " sbePosition(pos + length);\n" + - indent + " std::memcpy(m_buffer + pos, src, length);\n" + + indent + " if (length != %3$s(0))" + + indent + " {" + + indent + " std::uint64_t pos = sbePosition();\n" + + indent + " sbePosition(pos + length);\n" + + indent + " std::memcpy(m_buffer + pos, src, length);\n" + + indent + " }" + indent + " return *this;\n" + indent + " }\n", propertyName, @@ -591,25 +594,31 @@ private void generateVarData( new Formatter(sb).format("\n" + indent + " %1$s &put%2$s(const std::string& str)\n" + indent + " {\n" + - indent + " if (str.length() > %6$d)\n" + + indent + " if (str.length() > %4$d)\n" + indent + " {\n" + indent + " throw std::runtime_error(\"std::string too long for length type [E109]\");\n" + indent + " }\n" + - indent + " std::uint64_t lengthOfLengthField = %3$d;\n" + - indent + " std::uint64_t lengthPosition = sbePosition();\n" + - indent + " %4$s lengthFieldValue = %5$s(static_cast<%4$s>(str.length()));\n" + - indent + " sbePosition(lengthPosition + lengthOfLengthField);\n" + - indent + " std::memcpy(m_buffer + lengthPosition, &lengthFieldValue, sizeof(%4$s));\n" + - indent + " std::uint64_t pos = sbePosition();\n" + - indent + " sbePosition(pos + str.length());\n" + - indent + " std::memcpy(m_buffer + pos, str.c_str(), str.length());\n" + - indent + " return *this;\n" + + indent + " return put%2$s(str.data(), static_cast<%3$s>(str.length()));" + indent + " }\n", className, propertyName, - lengthOfLengthField, lengthCppType, - lengthByteOrderStr, + lengthToken.encoding().applicableMaxValue().longValue()); + + new Formatter(sb).format("\n" + + indent + " #if __cplusplus >= 201703L\n" + + indent + " %1$s &put%2$s(const std::string_view str)\n" + + indent + " {\n" + + indent + " if (str.length() > %4$d)\n" + + indent + " {\n" + + indent + " throw std::runtime_error(\"std::string too long for length type [E109]\");\n" + + indent + " }\n" + + indent + " return put%2$s(str.data(), static_cast<%3$s>(str.length()));" + + indent + " }\n" + + indent + " #endif\n", + className, + propertyName, + lengthCppType, lengthToken.encoding().applicableMaxValue().longValue()); i += token.componentTokenCount();