Strings

Like the repeated fields, String fields are of fixed length in Embedded Proto. You specify the size using a template parameter when creating the message object or using a custom option and have it set to the given value.

The custom option works the same as for repeated fields detailed here. In the following paragraphs, we take a look at a simple example using templates:

message text
{
  string txt = 1;
}

The code generated holds a field object with the type FieldString, which has a template parameter to specify the maximum length of the string. In the FieldString object, an array is specified of characters. This is done to be able to work without dynamically allocated memory. This in contrast to std::string which does use dynamic allocation.

template<uint32_t txt_LENGTH>
class text final: public ::EmbeddedProto::MessageInterface
{
  private:
    ::EmbeddedProto::FieldString<txt_LENGTH> txt_;
}

As of version 4.0.0 you can define NULL_TERMINATED_STRINGS when building. Every string field then reserves one extra character behind its maximum length, which always holds a null terminator. The character array returned by get_const() is a valid C string, also when the string is completely full. It costs one byte of RAM per string field and changes nothing on the wire. Bytes fields are unaffected. The default is not to reserve it, which keeps the memory layout of earlier versions.

The functions to access and manipulate the FieldString contains functions to obtain the character array and set the string.

FieldString<MAX_LENGTH>& operator=(const char* const &&rhs)
Error set(const DATA_TYPE* data, const uint32_t length)
const DATA_TYPE& operator[](uint32_t index) const

A working example could look like this:

// Define the message object specifying the maximum number 
// of chars in the array. Ten in this case.
text<10> msg;

// Set the string by means of assignment.
msg.mutable_txt() = "Foo Bar";

// Change the capitals to lower case by means of indeces.
msg.mutable_txt()[0] = 'f';
msg.mutable_txt()[4] = 'b';

// Acces the char array.
const char* text = msg.get_txt().get_const();

// Obtain the current number of chars in the string
const uint32_t N_chars = msg.get_txt().get_length();

// It is also possible to obtain the maximum number of chars 
// this string can hold. This would always return the value 
// you have set as the template parameter.
const uint32_t max_N_chars = msg.get_txt().get_max_length();

// You can clear the whole string with the clear function
msg.mutable_txt().clear();

// As of version 4.0.0 you can compare with a C string, and ask
// beforehand whether a C string fits in the field.
const bool same = (msg.get_txt() == "Foo Bar");
const bool fits = ::EmbeddedProto::FieldString<10>::fits("A longer text");