json.serialize throws exception when web::json::value::string has backslash in string

Jun 26, 2013 at 11:41 PM
Edited Jun 27, 2013 at 12:15 AM
When trying to serialize a string with a backslash I get the error "invalid escape character in string literal".
web::json::value json = web::json::value::string(L"c:\\Test.txt"); 
std::wstringstream jsonStringStream;
try
{
    json.serialize(jsonStringStream);
    std::wstring jsonString = jsonStringStream.str(); 
}
catch(const std::exception& e)
{
    std::stringstream exceptionStringStream;
    exceptionStringStream << e.what();
    std::string exceptionString(exceptionStringStream.str());
}
I see in the source there is a escape_string function.
Though it looks like serialize calls format() for the specific web::json::detail which appears to call escape_string, so I don't understand why I'm hitting the unescape_string function unless it is being indirectly called through the parse function. Perhaps I am using this incorrectly? Perhaps there is something I can already re-use?

To allow backwards compatibility, is there any way to overload web::json::value::string constructor to allow us to use escape_string? For example:
web::json::value json = web::json::value::string(L"c:\\Test", true);
Another option would be to put escape_string somewhere in utility.

Thanks
Jun 27, 2013 at 12:30 AM
C-style string literals are wonderful, aren't they? (Sarcasm intended. :-)) C++ 11 raw strings will really make a difference here.

Here's what I think is going on:

Since both C++ and JSON define a need to escape the '\' character in literals, what the C++ compiler will do is treat the \ as a single backslash (per the C++ grammar). Thus, what the JSON parser sees is this:

"c:\Test.txt"

Since \T is not a valid escape sequence in the JSON grammar, the parser flags it as an error.

Therefore, I believe that if you really need to parse JSON from a C++ string literal, you would need to say:
web::json::value json = web::json::value::string(L"c:\\\\Test.txt");
Let me know if that doesn't work.

Niklas
Jun 27, 2013 at 2:57 PM
Edited Jun 27, 2013 at 4:47 PM
Thanks Niklas. You are right.
 L"c:\\\\Test.txt"
does work! Any chance I can convince someone to make the escape_string function in json.cpp part of the utility::details namespace so I can reuse it?

For example:
web::json::value json = web::json::value::string(utility::detail::escape_string(L"c:\\Test.txt"));
Jun 28, 2013 at 3:03 PM
Hmm, maybe...

It wouldn't go in the utility namespace, though, it's pretty JSON-specific.