17#define wxDEBUG_LEVEL 0
20#include <wx/jsonwriter.h>
22#include <wx/sstream.h>
23#include <wx/mstream.h>
28static const wxChar* writerTraceMask = _T(
"traceWriter");
199 if (m_style == wxJSONWRITER_NONE) {
207#if !defined(wxJSON_USE_UNICODE)
210 if (m_style == wxJSONWRITER_NOUTF8_STREAM) {
261#if !defined(wxJSON_USE_UNICODE)
263 bool noUtf8_bak = m_noUtf8;
267 wxMemoryOutputStream os;
271 wxFileOffset len = os.GetLength();
272 wxStreamBuffer* osBuff = os.GetOutputStreamBuffer();
273 void* buffStart = osBuff->GetBufferStart();
276 str = wxString::From8BitData((
const char*)buffStart, len);
278 str = wxString::FromUTF8((
const char*)buffStart, len);
280#if !defined(wxJSON_USE_UNICODE)
281 m_noUtf8 = noUtf8_bak;
326 const wxString* key,
bool comma) {
330 const wxJSONInternalMap* map =
nullptr;
342 if (value.GetCommentCount() > 0 && (m_style & wxJSONWRITER_WRITE_COMMENTS)) {
343 commentPos = value.GetCommentPos();
344 if ((m_style & wxJSONWRITER_COMMENTS_BEFORE) != 0) {
345 commentPos = wxJSONVALUE_COMMENT_BEFORE;
346 }
else if ((m_style & wxJSONWRITER_COMMENTS_AFTER) != 0) {
347 commentPos = wxJSONVALUE_COMMENT_AFTER;
354 if (commentPos == wxJSONVALUE_COMMENT_BEFORE) {
358 }
else if (lastChar !=
'\n') {
377 wxJSONInternalMap::const_iterator it;
380 wxJSONType t = value.GetType();
382 case wxJSONTYPE_INVALID:
385 _T(
"wxJSONWriter::WriteEmpty() cannot be called (not a valid JSON ")
390 case wxJSONTYPE_SHORT:
391 case wxJSONTYPE_LONG:
392 case wxJSONTYPE_INT64:
396 case wxJSONTYPE_UINT:
397 case wxJSONTYPE_USHORT:
398 case wxJSONTYPE_ULONG:
399 case wxJSONTYPE_UINT64:
403 case wxJSONTYPE_NULL:
406 case wxJSONTYPE_BOOL:
410 case wxJSONTYPE_DOUBLE:
414 case wxJSONTYPE_STRING:
415 case wxJSONTYPE_CSTRING:
419 case wxJSONTYPE_MEMORYBUFF:
423 case wxJSONTYPE_ARRAY:
427 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
433 if (lastChar !=
'\n') {
445 for (
int i = 0; i < size; i++) {
451 lastChar =
DoWrite(os, v, 0, comma);
464 case wxJSONTYPE_OBJECT:
469 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
475 if (lastChar !=
'\n') {
485 for (it = map->begin(); it != map->end(); ++it) {
487 wxString key = it->first;
490 if (count < size - 1) {
493 lastChar =
DoWrite(os, v, &key, comma);
509 wxFAIL_MSG(_T(
"wxJSONWriter::DoWrite() undefined wxJSONType type"));
518 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
523 }
else if (commentPos == wxJSONVALUE_COMMENT_AFTER) {
530 if (lastChar !=
'\n') {
545 if ((m_style & wxJSONWRITER_WRITE_COMMENTS) == 0) {
549 const wxArrayString cmt = value.GetCommentArray();
550 int cmtSize = cmt.GetCount();
551 for (
int i = 0; i < cmtSize; i++) {
558 lastChar = cmt[i].Last();
559 if (lastChar !=
'\n') {
602 if (!(m_style & wxJSONWRITER_STYLED) ||
603 (m_style & wxJSONWRITER_NO_INDENTATION)) {
607 int numChars = m_indent + (m_step * num);
609 if (m_style & wxJSONWRITER_TAB_INDENT) {
614 for (
int i = 0; i < numChars; i++) {
616 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
646 wxCharBuffer utf8CB = str.ToUTF8();
647#if !defined(wxJSON_USE_UNICODE)
648 wxCharBuffer ansiCB(str.c_str());
650 writeBuff = ansiCB.data();
652 writeBuff = utf8CB.data();
655 writeBuff = utf8CB.data();
660 if (writeBuff ==
nullptr) {
662 "<wxJSONWriter::WriteStringValue(): error converting the string to a "
664 os.Write(err, strlen(err));
667 size_t len = strlen(writeBuff);
674 int tempCol = m_colNo;
678 for (i = 0; i < len; i++) {
679 bool shouldEscape =
false;
680 unsigned char ch = *writeBuff;
723 shouldEscape =
false;
729 if (!shouldEscape && ch < 32) {
731 snprintf(b, 8,
"\\u%04X", (
int)ch);
733 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
742 if (shouldEscape && !(m_style & wxJSONWRITER_ESCAPE_SOLIDUS)) {
744 shouldEscape =
false;
747 if (shouldEscape && (m_style & wxJSONWRITER_MULTILINE_STRING)) {
748 if (ch ==
'\n' || ch ==
'\t') {
749 shouldEscape =
false;
757 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
763 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
771 if ((m_style & wxJSONWRITER_STYLED) &&
772 (m_style & wxJSONWRITER_SPLIT_STRING)) {
786 else if ((m_colNo >= wxJSONWRITER_SPLIT_COL) &&
787 (tempCol <= wxJSONWRITER_LAST_COL)) {
789 if (len - i > wxJSONWRITER_MIN_LENGTH) {
814 wxLogTrace(writerTraceMask, _T(
"(%s) string to write=%s"),
815 __PRETTY_FUNCTION__, str.c_str());
817 char* writeBuff =
nullptr;
821 wxCharBuffer utf8CB = str.ToUTF8();
822#if !defined(wxJSON_USE_UNICODE)
823 wxCharBuffer ansiCB(str.c_str());
826 writeBuff = ansiCB.data();
828 writeBuff = utf8CB.data();
831 writeBuff = utf8CB.data();
836 if (writeBuff ==
nullptr) {
838 "<wxJSONWriter::WriteComment(): error converting the string to UTF-8>";
839 os.Write(err, strlen(err));
842 size_t len = strlen(writeBuff);
844 os.Write(writeBuff, len);
845 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
849 wxLogTrace(writerTraceMask, _T(
"(%s) result=%d"), __PRETTY_FUNCTION__,
860 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
881#if defined(wxJSON_64BIT_INT)
882#if wxCHECK_VERSION(2, 9, 0) || !defined(wxJSON_USE_UNICODE)
884 snprintf(buffer, 32,
"%" wxLongLongFmtSpec
"d", data->m_value.m_valInt64);
890 s.Printf(_T(
"%") wxLongLongFmtSpec _T(
"d"), data->m_value.m_valInt64);
891 wxCharBuffer cb = s.ToUTF8();
892 const char* cbData = cb.data();
893 len = strlen(cbData);
895 memcpy(buffer, cbData, len);
899 snprintf(buffer, 32,
"%ld", data->m_value.m_valLong);
901 len = strlen(buffer);
902 os.Write(buffer, len);
903 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
924 if (m_style & wxJSONWRITER_RECOGNIZE_UNSIGNED) {
932#if defined(wxJSON_64BIT_INT)
933#if wxCHECK_VERSION(2, 9, 0) || !defined(wxJSON_USE_UNICODE)
935 snprintf(buffer, 32,
"%" wxLongLongFmtSpec
"u", data->m_value.m_valUInt64);
941 s.Printf(_T(
"%") wxLongLongFmtSpec _T(
"u"), data->m_value.m_valInt64);
942 wxCharBuffer cb = s.ToUTF8();
943 const char* cbData = cb.data();
944 len = strlen(cbData);
946 memcpy(buffer, cbData, len);
950 snprintf(buffer, 32,
"%lu", data->m_value.m_valULong);
952 len = strlen(buffer);
953 os.Write(buffer, len);
954 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
979 snprintf(buffer, 32, m_fmt, data->m_value.m_valDouble);
980 size_t len = strlen(buffer);
981 os.Write(buffer, len);
982 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
997 const char* f =
"false";
998 const char* t =
"true";
1004 if (data->m_value.m_valBool) {
1008 size_t len = strlen(c);
1010 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1018 wxLogTrace(writerTraceMask, _T(
"(%s) key write=%s"), __PRETTY_FUNCTION__,
1044 _T(
"wxJSONWriter::WriteInvalid() cannot be called (not a valid JSON ")
1047 os.Write(
"<invalid JSON value>", 9);
1062 const wxMemoryBuffer& buff) {
1063#define MAX_BYTES_PER_ROW 20
1069 int bytesWritten = 0;
1070 bool splitString =
false;
1071 if ((m_style & wxJSONWRITER_STYLED) &&
1072 (m_style & wxJSONWRITER_SPLIT_STRING)) {
1076 size_t buffLen = buff.GetDataLen();
1077 unsigned char* ptr = (
unsigned char*)buff.GetData();
1079 char openChar =
'\'';
1080 char closeChar =
'\'';
1081 bool asArray =
false;
1083 if ((m_style & wxJSONWRITER_MEMORYBUFF) == 0) {
1092 for (
size_t i = 0; i < buffLen; i++) {
1093 unsigned char c = *ptr;
1097 snprintf(str, 14,
"%d", c);
1098 size_t len = strlen(str);
1103 if (i < buffLen - 1) {
1107 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1124 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1131 if ((bytesWritten >= MAX_BYTES_PER_ROW) && ((buffLen - i) >= 5)) {
1134 os.Write(
"\'\n", 2);
1162 int lastChar =
'\n';
1163 if ((m_style & wxJSONWRITER_STYLED) &&
1164 !(m_style & wxJSONWRITER_NO_LINEFEEDS)) {
The reference counted JSON value data (internal use).
The JSON value class implementation.
wxJSONValue ItemAt(unsigned index) const
Return the item at the specified index.
int WriteComment(wxOutputStream &os, const wxJSONValue &value, bool indent)
Write the comment strings, if any.
int WriteInvalid(wxOutputStream &os)
Write the invalid JSON value to the output stream.
int WriteUIntValue(wxOutputStream &os, const wxJSONValue &v)
Writes a value of type UNSIGNED INT.
bool IsPunctuation(wxChar ch)
Returns TRUE if the character if a puctuation character.
~wxJSONWriter()
Dtor - does nothing.
void Write(const wxJSONValue &value, wxString &str)
Write the JSONvalue object to a JSON text.
void SetDoubleFmtString(const char *fmt)
Set the format string for double values.
int WriteIntValue(wxOutputStream &os, const wxJSONValue &v)
Writes a value of type INT.
int WriteKey(wxOutputStream &os, const wxString &key)
Write the key of a key/value element to the output stream.
int WriteIndent(wxOutputStream &os)
Writes the indentation to the JSON text.
int WriteBoolValue(wxOutputStream &os, const wxJSONValue &v)
Writes a value of type BOOL.
bool IsSpace(wxChar ch)
Returns TRUE if the character is a space character.
int WriteNullValue(wxOutputStream &os)
Write the nullptr JSON value to the output stream.
int WriteStringValue(wxOutputStream &os, const wxString &str)
Write the provided string to the output object.
int WriteString(wxOutputStream &os, const wxString &str)
Write a generic string.
int WriteMemoryBuff(wxOutputStream &os, const wxMemoryBuffer &buff)
Write a JSON value of type memory buffer.
wxJSONWriter(int style=wxJSONWRITER_STYLED, int indent=0, int step=3)
Ctor.
int WriteDoubleValue(wxOutputStream &os, const wxJSONValue &v)
Writes a value of type DOUBLE.
int DoWrite(wxOutputStream &os, const wxJSONValue &value, const wxString *key, bool comma)
Perform the real write operation.
int WriteSeparator(wxOutputStream &os)
Writes the separator between values.