UTF8 Latin1 tildes problem generating JSON


#1

Hi,

I'm trying to create a Json formated String with accents.  Simplifying a bit the process is something like:

 

var dataJson (dataObj);

String dataString = JSON::toString(dataJson);

Logger::writeToLog(dataString);

 

My expected output in the attributes with accents is:

"value": "Hello world! é",

but I get:

"value": "Hello world! \u00e1",

 

I really dont't know where to look to solve this issue. The value is printed fine before calling JSON::toString and everywhere else in the aplication. Can give me some clues?

 

Thanks in advance,

 

 

 


#2

There's nothing actually wrong with that - it's perfectly valid JSON. Any JSON parser should read it correctly.

It's safer to use the escape sequence than outputing raw UTF8 characters because it avoids confusion over the codepage if it ends up in a text editor.


#3

Hi Jules,

Ok I understand. Thanks for the info. The problem is the server I'm sending the info to is not propertly parsing that  escaped characters, and I can not modify the parsing code. So I finally I will have to replace all the special characters after calling JSON::toString(dataJson); Something like

dataString = dataString.replace("\\u00e9", "é"); ...

I cannot figure a better way.


#4

ok, but you should at least un-escape it properly rather than hacking it for that specific character. Have a look at JSONParser::parseString for inspiration.


#5

Thanks for the help Jules.

As I have control over the client I ended URI encoding Strings before creating the JSON and decoding them back in the client. I found this more clean to understand and works fine with the server.

 

String UriEncodeString(const String &stringToEncode)

{

    std::string sSrc = stringToEncode.toStdString();

    const char DEC2HEX[16 + 1] = "0123456789ABCDEF";

    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();

    const int SRC_LEN = sSrc.length();

    unsigned char * const pStart = new unsigned char[SRC_LEN * 3];

    unsigned char * pEnd = pStart;

    const unsigned char * const SRC_END = pSrc + SRC_LEN;

    for (; pSrc < SRC_END; ++pSrc)

    {

        if (isalnum(*pSrc) || *pSrc == '-' || *pSrc == '_' || *pSrc == '.' || *pSrc == '~')

            *pEnd++ = *pSrc;

        else

        {

            *pEnd++ = '%';

            *pEnd++ = DEC2HEX[*pSrc >> 4];

            *pEnd++ = DEC2HEX[*pSrc & 0x0F];

        }

    }

    std::string sResult((char *)pStart, (char *)pEnd);

    delete [] pStart;

    return String(sResult);

}