2323
2424namespace ember ::protogen {
2525
26+ enum class Dir {
27+ Read,
28+ Write,
29+ Both
30+ };
31+
2632struct WalkState {
2733 std::vector<std::string> members;
2834 std::set<std::string> includes;
@@ -141,7 +147,7 @@ std::string cpp_type_name(const std::string& type, const TypeRegistry& reg) {
141147 return leaf;
142148}
143149
144- std::string string_adaptor_expr (const jsoncons::json& type_def, std::string_view expr) {
150+ std::string string_adaptor_expr (const jsoncons::json& type_def, std::string_view expr, Dir dir ) {
145151 const auto encoding = type_def[" encoding" ].as <std::string>();
146152
147153 if (encoding == " null_terminated" ) {
@@ -150,13 +156,14 @@ std::string string_adaptor_expr(const jsoncons::json& type_def, std::string_view
150156
151157 const auto length_type = type_def[" length_type" ].as <std::string>();
152158 const auto length_cpp = cpp_type_for_primitive (length_type);
159+ std::string_view qualifier = (dir == Dir::Write)? " const " : " " ;
153160
154161 if (encoding == " prefixed" ) {
155- return std::format (" spark::io::prefixed<std::string, {}>({})" , length_cpp, expr);
162+ return std::format (" spark::io::prefixed<{} std::string, {}>({})" , qualifier , length_cpp, expr);
156163 }
157164
158165 if (encoding == " prefixed_null_terminated" ) {
159- return std::format (" spark::io::prefixed_null_terminated<std::string, {}>({})" , length_cpp, expr);
166+ return std::format (" spark::io::prefixed_null_terminated<{} std::string, {}>({})" , qualifier , length_cpp, expr);
160167 }
161168
162169 throw std::runtime_error (
@@ -262,8 +269,6 @@ std::string cpp_element_type(const std::string& type, const TypeRegistry& reg) {
262269 return cpp_type_name (type, reg);
263270}
264271
265- enum class Dir { Read, Write, Both };
266-
267272// Emits stream ops for a single scalar value. `dir` controls which of
268273// `read_ops` / `write_ops` are appended to — helpers that build their own
269274// loops (e.g. until_end, which has asymmetric read vs write) use Read /
@@ -370,13 +375,16 @@ void emit_scalar_stream_op(const std::string& name, const std::string& type,
370375 }
371376
372377 if (kind == " string" ) {
373- const auto adaptor = string_adaptor_expr (*def, qualified);
374378 if (do_read) {
379+ const auto adaptor = string_adaptor_expr (*def, qualified, Dir::Read);
375380 state.read_ops .emplace_back (std::format (" {}stream >> {};" , indent (state.read_tab ), adaptor));
376381 }
382+
377383 if (do_write) {
384+ const auto adaptor = string_adaptor_expr (*def, qualified, Dir::Write);
378385 state.write_ops .emplace_back (std::format (" {}stream << {};" , indent (state.write_tab ), adaptor));
379386 }
387+
380388 state.includes .insert (" spark/buffers/StringAdaptors.h" );
381389 return ;
382390 }
0 commit comments