| 3882 | return NULL; |
| 3883 | } |
| 3884 | static std::string valueToQuotedStringN(const char* value, unsigned length) { |
| 3885 | if (value == NULL) |
| 3886 | return ""; |
| 3887 | // Not sure how to handle unicode... |
| 3888 | if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL && |
| 3889 | !containsControlCharacter0(value, length)) |
| 3890 | return std::string("\"") + value + "\""; |
| 3891 | // We have to walk value and escape any special characters. |
| 3892 | // Appending to std::string is not efficient, but this should be rare. |
| 3893 | // (Note: forward slashes are *not* rare, but I am not escaping them.) |
| 3894 | std::string::size_type maxsize = |
| 3895 | length * 2 + 3; // allescaped+quotes+NULL |
| 3896 | std::string result; |
| 3897 | result.reserve(maxsize); // to avoid lots of mallocs |
| 3898 | result += "\""; |
| 3899 | char const* end = value + length; |
| 3900 | for (const char* c = value; c != end; ++c) { |
| 3901 | switch (*c) { |
| 3902 | case '\"': |
| 3903 | result += "\\\""; |
| 3904 | break; |
| 3905 | case '\\': |
| 3906 | result += "\\\\"; |
| 3907 | break; |
| 3908 | case '\b': |
| 3909 | result += "\\b"; |
| 3910 | break; |
| 3911 | case '\f': |
| 3912 | result += "\\f"; |
| 3913 | break; |
| 3914 | case '\n': |
| 3915 | result += "\\n"; |
| 3916 | break; |
| 3917 | case '\r': |
| 3918 | result += "\\r"; |
| 3919 | break; |
| 3920 | case '\t': |
| 3921 | result += "\\t"; |
| 3922 | break; |
| 3923 | // case '/': |
| 3924 | // Even though \/ is considered a legal escape in JSON, a bare |
| 3925 | // slash is also legal, so I see no reason to escape it. |
| 3926 | // (I hope I am not misunderstanding something.) |
| 3927 | // blep notes: actually escaping \/ may be useful in javascript to avoid </ |
| 3928 | // sequence. |
| 3929 | // Should add a flag to allow this compatibility mode and prevent this |
| 3930 | // sequence from occurring. |
| 3931 | default: |
| 3932 | if ((isControlCharacter(*c)) || (*c == 0)) { |
| 3933 | std::ostringstream oss; |
| 3934 | oss << "\\u" << std::hex << std::uppercase << std::setfill('0') |
| 3935 | << std::setw(4) << static_cast<int>(*c); |
| 3936 | result += oss.str(); |
| 3937 | } else { |
| 3938 | result += *c; |
| 3939 | } |
| 3940 | break; |
| 3941 | } |
no test coverage detected