Parse the encoding of a previously encoded string. If parse succeeds, return true, consume encoding from "*src", and if result != NULL append the decoded string to "*result". Otherwise, return false and leave both undefined.
| 213 | // "*src", and if result != NULL append the decoded string to "*result". |
| 214 | // Otherwise, return false and leave both undefined. |
| 215 | inline static bool ReadStringInternal(StringPiece* src, string* result) { |
| 216 | const char* start = src->data(); |
| 217 | const char* string_limit = src->data() + src->size(); |
| 218 | |
| 219 | // We only scan up to "limit-2" since a valid string must end with |
| 220 | // a two character terminator: 'kEscape1 kSeparator' |
| 221 | const char* limit = string_limit - 1; |
| 222 | const char* copy_start = start; |
| 223 | while (true) { |
| 224 | start = SkipToNextSpecialByte(start, limit); |
| 225 | if (start >= limit) break; // No terminator sequence found |
| 226 | const char c = *(start++); |
| 227 | // If inversion is required, instead of inverting 'c', we invert the |
| 228 | // character constants to which 'c' is compared. We get the same |
| 229 | // behavior but save the runtime cost of inverting 'c'. |
| 230 | DCHECK(IsSpecialByte(c)); |
| 231 | if (c == kEscape1) { |
| 232 | if (result) { |
| 233 | AppendBytes(result, copy_start, start - copy_start - 1); |
| 234 | } |
| 235 | // kEscape1 kSeparator ends component |
| 236 | // kEscape1 kNullCharacter represents '\0' |
| 237 | const char next = *(start++); |
| 238 | if (next == kSeparator) { |
| 239 | src->remove_prefix(start - src->data()); |
| 240 | return true; |
| 241 | } else if (next == kNullCharacter) { |
| 242 | if (result) { |
| 243 | *result += '\0'; |
| 244 | } |
| 245 | } else { |
| 246 | return false; |
| 247 | } |
| 248 | copy_start = start; |
| 249 | } else { |
| 250 | assert(c == kEscape2); |
| 251 | if (result) { |
| 252 | AppendBytes(result, copy_start, start - copy_start - 1); |
| 253 | } |
| 254 | // kEscape2 kFFCharacter represents '\xff' |
| 255 | // kEscape2 kInfinity is an error |
| 256 | const char next = *(start++); |
| 257 | if (next == kFFCharacter) { |
| 258 | if (result) { |
| 259 | *result += '\xff'; |
| 260 | } |
| 261 | } else { |
| 262 | return false; |
| 263 | } |
| 264 | copy_start = start; |
| 265 | } |
| 266 | } |
| 267 | return false; |
| 268 | } |
| 269 | |
| 270 | bool OrderedCode::ReadString(StringPiece* src, string* result) { |
| 271 | return ReadStringInternal(src, result); |
no test coverage detected