*Note: That we never stored a `mana` value, so it will return the default.*
+The following attributes are supported:
+
+- `shared` (on a field): For string fields, this enables the usage of string
+ pooling (i.e. `CreateSharedString`) as default serialization behavior.
+
+ Specifically, `CreateXxxDirect` functions and `Pack` functions for object
+ based API (see below) will use `CreateSharedString` to create strings.
+
## Object based API. {#flatbuffers_cpp_object_based_api}
FlatBuffers is all about memory efficiency, which is why its base API is written
: deprecated(false),
required(false),
key(false),
+ shared(false),
native_inline(false),
flexbuffer(false),
nested_flatbuffer(NULL),
// written in new data nor accessed in new code.
bool required; // Field must always be present.
bool key; // Field functions as a key for creating sorted vectors.
+ bool shared; // Field will be using string pooling (i.e. CreateSharedString)
+ // as default serialization behavior if field is a string.
bool native_inline; // Field will be defined inline (instead of as a pointer)
// for native tables if field is a struct.
bool flexbuffer; // This field contains FlexBuffer data.
known_attributes_["deprecated"] = true;
known_attributes_["required"] = true;
known_attributes_["key"] = true;
+ known_attributes_["shared"] = true;
known_attributes_["hash"] = true;
known_attributes_["id"] = true;
known_attributes_["force_align"] = true;
if (!field.deprecated) {
code_.SetValue("FIELD_NAME", Name(field));
if (field.value.type.base_type == BASE_TYPE_STRING) {
+ if (!field.shared) {
+ code_.SetValue("CREATE_STRING", "CreateString");
+ } else {
+ code_.SetValue("CREATE_STRING", "CreateSharedString");
+ }
code_ +=
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
- "_fbb.CreateString({{FIELD_NAME}}) : 0;";
+ "_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : 0;";
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code_ += " auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? \\";
const auto vtype = field.value.type.VectorType();
switch (field.value.type.base_type) {
// String fields are of the form:
// _fbb.CreateString(_o->field)
+ // or
+ // _fbb.CreateSharedString(_o->field)
case BASE_TYPE_STRING: {
- code += "_fbb.CreateString(" + value + ")";
+ if (!field.shared) {
+ code += "_fbb.CreateString(";
+ } else {
+ code += "_fbb.CreateSharedString(";
+ }
+ code += value;
+ code.push_back(')');
// For optional fields, check to see if there actually is any data
// in _o->field before attempting to access it. If there isn't,
return Error("'key' field must be string or scalar type");
}
}
+ field->shared = field->attributes.Lookup("shared") != nullptr;
+ if (field->shared && field->value.type.base_type != BASE_TYPE_STRING)
+ return Error("shared can only be defined on strings");
auto field_native_custom_alloc =
field->attributes.Lookup("native_custom_alloc");
field->native_inline = field->attributes.Lookup("native_inline") != nullptr;
if (field->native_inline && !IsStruct(field->value.type))
- return Error("native_inline can only be defined on structs'");
+ return Error("native_inline can only be defined on structs");
auto nested = field->attributes.Lookup("nested_flatbuffer");
if (nested) {