| 117 | */ |
| 118 | template <class Builder> |
| 119 | static void StrMakeValid(Builder &builder, StringConsumer &consumer, StringValidationSettings settings) |
| 120 | { |
| 121 | /* Assume the ABSOLUTE WORST to be in str as it comes from the outside. */ |
| 122 | while (consumer.AnyBytesLeft()) { |
| 123 | auto c = consumer.TryReadUtf8(); |
| 124 | if (!c.has_value()) { |
| 125 | /* Maybe the next byte is still a valid character? */ |
| 126 | consumer.Skip(1); |
| 127 | continue; |
| 128 | } |
| 129 | if (*c == 0) break; |
| 130 | |
| 131 | if ((IsPrintable(*c) && (*c < SCC_SPRITE_START || *c > SCC_SPRITE_END)) || |
| 132 | (settings.Test(StringValidationSetting::AllowControlCode) && IsSccEncodedCode(*c)) || |
| 133 | (settings.Test(StringValidationSetting::AllowNewline) && *c == '\n')) { |
| 134 | builder.PutUtf8(*c); |
| 135 | } else if (settings.Test(StringValidationSetting::AllowNewline) && *c == '\r' && consumer.PeekCharIf('\n')) { |
| 136 | /* Skip \r, if followed by \n */ |
| 137 | /* continue */ |
| 138 | } else if (settings.Test(StringValidationSetting::ReplaceTabCrNlWithSpace) && (*c == '\r' || *c == '\n' || *c == '\t')) { |
| 139 | /* Replace the tab, carriage return or newline with a space. */ |
| 140 | builder.PutChar(' '); |
| 141 | } else if (settings.Test(StringValidationSetting::ReplaceWithQuestionMark)) { |
| 142 | /* Replace the undesirable character with a question mark */ |
| 143 | builder.PutChar('?'); |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | /* String termination, if needed, is left to the caller of this function. */ |
| 148 | } |
| 149 | |
| 150 | /** |
| 151 | * Scans the string for invalid characters and replaces them with a |
no test coverage detected