1818
1919#include " TIVarTypes.h"
2020#include " TypeHandlers/TypeHandlers.h"
21+ #include " json.hpp"
2122#include " tivarslib_utils.h"
2223
24+ using json = nlohmann::ordered_json;
25+
2326namespace tivars ::EvoFormat
2427{
2528 namespace
@@ -113,6 +116,27 @@ namespace tivars::EvoFormat
113116 codepoint = static_cast <uint16_t >(value);
114117 return true ;
115118 }
119+
120+ data_t hex_string_to_bytes (const std::string& hex, const char * fieldName)
121+ {
122+ if ((hex.size () % 2 ) != 0 )
123+ {
124+ throw std::invalid_argument (std::string (fieldName) + " must contain an even number of hex digits" );
125+ }
126+
127+ data_t out;
128+ out.reserve (hex.size () / 2 );
129+ for (size_t i = 0 ; i < hex.size (); i += 2 )
130+ {
131+ if (!std::isxdigit (static_cast <unsigned char >(hex[i])) ||
132+ !std::isxdigit (static_cast <unsigned char >(hex[i + 1 ])))
133+ {
134+ throw std::invalid_argument (std::string (fieldName) + " must be valid hexadecimal" );
135+ }
136+ out.push_back (hexdec (hex.substr (i, 2 )));
137+ }
138+ return out;
139+ }
116140 }
117141
118142uint16_t evo_checksum (const data_t & body)
@@ -804,10 +828,32 @@ data_t tokenize_evo_token_words(const std::string& source, const options_t& opti
804828 const bool deindent = options.contains (" deindent" ) && options.at (" deindent" ) == 1 ;
805829 const bool detectStrings = !options.contains (" detect_strings" ) || options.at (" detect_strings" ) != 0 ;
806830
831+ std::string sourceText = source;
832+ const std::string trimmed = trim (sourceText);
833+ if (!trimmed.empty () && trimmed.front () == ' {' )
834+ {
835+ try
836+ {
837+ const json j = json::parse (trimmed);
838+ if (j.contains (" rawDataHex" ))
839+ {
840+ return hex_string_to_bytes (j.at (" rawDataHex" ).get <std::string>(), " rawDataHex" );
841+ }
842+ if (j.contains (" code" ))
843+ {
844+ sourceText = j.at (" code" ).get <std::string>();
845+ }
846+ }
847+ catch (const json::exception&)
848+ {
849+ // Ignore non-JSON input and fall back to regular Evo tokenized parsing.
850+ }
851+ }
852+
807853 std::string normalizedSource;
808854 if (deindent)
809855 {
810- std::istringstream lines{source };
856+ std::istringstream lines{sourceText };
811857 std::string line;
812858 while (std::getline (lines, line))
813859 {
@@ -820,7 +866,7 @@ data_t tokenize_evo_token_words(const std::string& source, const options_t& opti
820866 }
821867 else
822868 {
823- normalizedSource = source ;
869+ normalizedSource = sourceText ;
824870 }
825871
826872 static constexpr uint16_t legacyQuote = 0x2A ;
0 commit comments