* Scan the string for old values of SCC_ENCODED and fix it to it's new, value. * Note that at the moment this runs, the string has not been validated yet * because the validation looks for SCC_ENCODED. If there is something invalid, * just bail out and do not continue trying to replace the tokens. * @param str the string to fix. */
| 931 | * @param str the string to fix. |
| 932 | */ |
| 933 | void FixSCCEncoded(std::string &str, bool fix_code) |
| 934 | { |
| 935 | if (str.empty()) return; |
| 936 | |
| 937 | /* We need to convert from old escape-style encoding to record separator encoding. |
| 938 | * Initial `<SCC_ENCODED><STRINGID>` stays the same. |
| 939 | * |
| 940 | * `:<SCC_ENCODED><STRINGID>` becomes `<RS><SCC_ENCODED><STRINGID>` |
| 941 | * `:<HEX>` becomes `<RS><SCC_ENCODED_NUMERIC><HEX>` |
| 942 | * `:"<STRING>"` becomes `<RS><SCC_ENCODED_STRING><STRING>` |
| 943 | */ |
| 944 | std::string result; |
| 945 | StringBuilder builder(result); |
| 946 | |
| 947 | bool is_encoded = false; // Set if we determine by the presence of SCC_ENCODED that the string is an encoded string. |
| 948 | bool in_string = false; // Set if we in a string, between double-quotes. |
| 949 | bool need_type = true; // Set if a parameter type needs to be emitted. |
| 950 | |
| 951 | StringConsumer consumer(str); |
| 952 | while (consumer.AnyBytesLeft()) { |
| 953 | char32_t c; |
| 954 | if (auto r = consumer.TryReadUtf8(); r.has_value()) { |
| 955 | c = *r; |
| 956 | } else { |
| 957 | break; |
| 958 | } |
| 959 | if (c == SCC_ENCODED || (fix_code && (c == 0xE028 || c == 0xE02A))) { |
| 960 | builder.PutUtf8(SCC_ENCODED); |
| 961 | need_type = false; |
| 962 | is_encoded = true; |
| 963 | continue; |
| 964 | } |
| 965 | |
| 966 | /* If the first character is not SCC_ENCODED then we don't have to do any conversion. */ |
| 967 | if (!is_encoded) return; |
| 968 | |
| 969 | if (c == '"') { |
| 970 | in_string = !in_string; |
| 971 | if (in_string && need_type) { |
| 972 | /* Started a new string parameter. */ |
| 973 | builder.PutUtf8(SCC_ENCODED_STRING); |
| 974 | need_type = false; |
| 975 | } |
| 976 | continue; |
| 977 | } |
| 978 | |
| 979 | if (!in_string && c == ':') { |
| 980 | builder.PutUtf8(SCC_RECORD_SEPARATOR); |
| 981 | need_type = true; |
| 982 | continue; |
| 983 | } |
| 984 | if (need_type) { |
| 985 | /* Started a new numeric parameter. */ |
| 986 | builder.PutUtf8(SCC_ENCODED_NUMERIC); |
| 987 | need_type = false; |
| 988 | } |
| 989 | |
| 990 | builder.PutUtf8(c); |