17#define wxDEBUG_LEVEL 0
20#include <wx/jsonwriter.h>
22#include <wx/sstream.h>
23#include <wx/mstream.h>
28static const wxChar* writerTraceMask =
"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 "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(
"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,
"(%s) string to write=%s", __PRETTY_FUNCTION__,
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,
"(%s) result=%d", __PRETTY_FUNCTION__, lastChar);
859 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
880#if defined(wxJSON_64BIT_INT)
881#if wxCHECK_VERSION(2, 9, 0) || !defined(wxJSON_USE_UNICODE)
883 snprintf(buffer, 32,
"%" wxLongLongFmtSpec
"d", data->m_value.m_valInt64);
889 s.Printf(
"%" wxLongLongFmtSpec
"d", data->m_value.m_valInt64);
890 wxCharBuffer cb = s.ToUTF8();
891 const char* cbData = cb.data();
892 len = strlen(cbData);
894 memcpy(buffer, cbData, len);
898 snprintf(buffer, 32,
"%ld", data->m_value.m_valLong);
900 len = strlen(buffer);
901 os.Write(buffer, len);
902 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
923 if (m_style & wxJSONWRITER_RECOGNIZE_UNSIGNED) {
931#if defined(wxJSON_64BIT_INT)
932#if wxCHECK_VERSION(2, 9, 0) || !defined(wxJSON_USE_UNICODE)
934 snprintf(buffer, 32,
"%" wxLongLongFmtSpec
"u", data->m_value.m_valUInt64);
940 s.Printf(
"%" wxLongLongFmtSpec
"u", data->m_value.m_valInt64);
941 wxCharBuffer cb = s.ToUTF8();
942 const char* cbData = cb.data();
943 len = strlen(cbData);
945 memcpy(buffer, cbData, len);
949 snprintf(buffer, 32,
"%lu", data->m_value.m_valULong);
951 len = strlen(buffer);
952 os.Write(buffer, len);
953 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
978 snprintf(buffer, 32, m_fmt, data->m_value.m_valDouble);
979 size_t len = strlen(buffer);
980 os.Write(buffer, len);
981 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
996 const char* f =
"false";
997 const char* t =
"true";
1003 if (data->m_value.m_valBool) {
1007 size_t len = strlen(c);
1009 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1017 wxLogTrace(writerTraceMask,
"(%s) key write=%s", __PRETTY_FUNCTION__,
1043 "wxJSONWriter::WriteInvalid() cannot be called (not a valid JSON "
1046 os.Write(
"<invalid JSON value>", 9);
1061 const wxMemoryBuffer& buff) {
1062#define MAX_BYTES_PER_ROW 20
1068 int bytesWritten = 0;
1069 bool splitString =
false;
1070 if ((m_style & wxJSONWRITER_STYLED) &&
1071 (m_style & wxJSONWRITER_SPLIT_STRING)) {
1075 size_t buffLen = buff.GetDataLen();
1076 unsigned char* ptr = (
unsigned char*)buff.GetData();
1078 char openChar =
'\'';
1079 char closeChar =
'\'';
1080 bool asArray =
false;
1082 if ((m_style & wxJSONWRITER_MEMORYBUFF) == 0) {
1091 for (
size_t i = 0; i < buffLen; i++) {
1092 unsigned char c = *ptr;
1096 snprintf(str, 14,
"%d", c);
1097 size_t len = strlen(str);
1102 if (i < buffLen - 1) {
1106 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1123 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1130 if ((bytesWritten >= MAX_BYTES_PER_ROW) && ((buffLen - i) >= 5)) {
1133 os.Write(
"\'\n", 2);
1161 int lastChar =
'\n';
1162 if ((m_style & wxJSONWRITER_STYLED) &&
1163 !(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.