11#include < jse/jse.h>
22
33#include < cctype>
4+ #include < cstddef>
45#include < cstdlib>
56#include < filesystem>
67#include < fstream>
@@ -142,16 +143,13 @@ namespace
142143 return engine.inject_include (rules);
143144 }
144145
145- std::string raw_string_literal (const std::string & value)
146+ std::string byte_literal (const unsigned char value)
146147 {
147- for (int i = 0 ; i < 10000 ; ++i)
148- {
149- const std::string delimiter = i == 0 ? " JSE_JSON" : " JSE_JSON_" + std::to_string (i);
150- if (value.find (" )" + delimiter + " \" " ) == std::string::npos)
151- return " R\" " + delimiter + " (" + value + " )" + delimiter + " \" " ;
152- }
153-
154- throw std::runtime_error (" Failed to find a valid raw string delimiter." );
148+ constexpr char hex[] = " 0123456789ABCDEF" ;
149+ std::string result = " 0x" ;
150+ result += hex[value >> 4 ];
151+ result += hex[value & 0x0F ];
152+ return result;
155153 }
156154
157155 std::vector<std::string> split_string (const std::string &value, const std::size_t chunk_size)
@@ -165,6 +163,28 @@ namespace
165163 return chunks;
166164 }
167165
166+ void write_byte_array_chunk (std::ostream &os, const std::string &chunk, const std::size_t index)
167+ {
168+ const std::string name = " chunk_" + std::to_string (index);
169+
170+ os << " static constexpr unsigned char " << name << " [] = {\n " ;
171+ for (std::size_t i = 0 ; i < chunk.size (); ++i)
172+ {
173+ if (i % 16 == 0 )
174+ os << " " ;
175+
176+ os << byte_literal (static_cast <unsigned char >(chunk[i]));
177+
178+ if (i + 1 != chunk.size ())
179+ os << " , " ;
180+
181+ if (i % 16 == 15 || i + 1 == chunk.size ())
182+ os << " \n " ;
183+ }
184+ os << " };\n " ;
185+ os << " text.append(reinterpret_cast<const char *>(" << name << " ), sizeof(" << name << " ));\n " ;
186+ }
187+
168188 void ensure_parent_directory (const std::filesystem::path &path)
169189 {
170190 const auto parent = path.parent_path ();
@@ -217,12 +237,12 @@ namespace
217237
218238 std::string source_content (const Options &options, const jse::json &rules)
219239 {
220- constexpr std::size_t max_string_literal_chunk_size = 8000 ;
240+ constexpr std::size_t max_byte_array_chunk_size = 4096 ;
221241
222242 const auto namespaces = split_namespace (options.namespace_name );
223243 const auto header_name = options.output_header .filename ().string ();
224244 const std::string rules_text = " \n " + rules.dump (4 , ' ' , true ) + " \n " ;
225- const auto rules_text_chunks = split_string (rules_text, max_string_literal_chunk_size );
245+ const auto rules_text_chunks = split_string (rules_text, max_byte_array_chunk_size );
226246
227247 std::ostringstream os;
228248 os << " #include \" " << header_name << " \"\n\n " ;
@@ -233,8 +253,8 @@ namespace
233253 os << " static const nlohmann::json value = []() {\n " ;
234254 os << " std::string text;\n " ;
235255 os << " text.reserve(" << rules_text.size () << " );\n " ;
236- for (const auto &chunk : rules_text_chunks)
237- os << " text += " << raw_string_literal (chunk) << " ; \n " ;
256+ for (std:: size_t i = 0 ; i < rules_text_chunks. size (); ++i )
257+ write_byte_array_chunk (os, rules_text_chunks[i], i) ;
238258 os << " return nlohmann::json::parse(text);\n " ;
239259 os << " }();\n " ;
240260 os << " return value;\n " ;
0 commit comments