| 806 | // Parse string and generate String event. Different code paths for kParseInsituFlag. |
| 807 | template<unsigned parseFlags, typename InputStream, typename Handler> |
| 808 | void ParseString(InputStream& is, Handler& handler, bool isKey = false) { |
| 809 | internal::StreamLocalCopy<InputStream> copy(is); |
| 810 | InputStream& s(copy.s); |
| 811 | |
| 812 | RAPIDJSON_ASSERT(s.Peek() == '\"'); |
| 813 | s.Take(); // Skip '\"' |
| 814 | |
| 815 | bool success = false; |
| 816 | if (parseFlags & kParseInsituFlag) { |
| 817 | typename InputStream::Ch *head = s.PutBegin(); |
| 818 | ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s); |
| 819 | RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; |
| 820 | size_t length = s.PutEnd(head) - 1; |
| 821 | RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); |
| 822 | const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head); |
| 823 | success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); |
| 824 | } |
| 825 | else { |
| 826 | StackStream<typename TargetEncoding::Ch> stackStream(stack_); |
| 827 | ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream); |
| 828 | RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; |
| 829 | SizeType length = static_cast<SizeType>(stackStream.Length()) - 1; |
| 830 | const typename TargetEncoding::Ch* const str = stackStream.Pop(); |
| 831 | success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); |
| 832 | } |
| 833 | if (RAPIDJSON_UNLIKELY(!success)) |
| 834 | RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); |
| 835 | } |
| 836 | |
| 837 | // Parse string to an output is |
| 838 | // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. |