20#define wxDEBUG_LEVEL 0
23#include <wx/sstream.h>
24#include <wx/mstream.h>
28#include "jsonwriter.h"
31static const wxChar* writerTraceMask =
"traceWriter";
202 if (m_style == wxJSONWRITER_NONE) {
210#if !defined(wxJSON_USE_UNICODE)
213 if (m_style == wxJSONWRITER_NOUTF8_STREAM) {
264#if !defined(wxJSON_USE_UNICODE)
266 bool noUtf8_bak = m_noUtf8;
270 wxMemoryOutputStream os;
274 wxFileOffset len = os.GetLength();
275 wxStreamBuffer* osBuff = os.GetOutputStreamBuffer();
276 void* buffStart = osBuff->GetBufferStart();
279 str = wxString::From8BitData((
const char*)buffStart, len);
281 str = wxString::FromUTF8((
const char*)buffStart, len);
283#if !defined(wxJSON_USE_UNICODE)
284 m_noUtf8 = noUtf8_bak;
329 const wxString* key,
bool comma) {
333 const wxJSONInternalMap* map =
nullptr;
345 if (value.GetCommentCount() > 0 && (m_style & wxJSONWRITER_WRITE_COMMENTS)) {
346 commentPos = value.GetCommentPos();
347 if ((m_style & wxJSONWRITER_COMMENTS_BEFORE) != 0) {
348 commentPos = wxJSONVALUE_COMMENT_BEFORE;
349 }
else if ((m_style & wxJSONWRITER_COMMENTS_AFTER) != 0) {
350 commentPos = wxJSONVALUE_COMMENT_AFTER;
357 if (commentPos == wxJSONVALUE_COMMENT_BEFORE) {
361 }
else if (lastChar !=
'\n') {
380 wxJSONInternalMap::const_iterator it;
383 wxJSONType t = value.GetType();
385 case wxJSONTYPE_INVALID:
388 "wxJSONWriter::WriteEmpty() cannot be called (not a valid JSON "
393 case wxJSONTYPE_SHORT:
394 case wxJSONTYPE_LONG:
395 case wxJSONTYPE_INT64:
399 case wxJSONTYPE_UINT:
400 case wxJSONTYPE_USHORT:
401 case wxJSONTYPE_ULONG:
402 case wxJSONTYPE_UINT64:
406 case wxJSONTYPE_NULL:
409 case wxJSONTYPE_BOOL:
413 case wxJSONTYPE_DOUBLE:
417 case wxJSONTYPE_STRING:
418 case wxJSONTYPE_CSTRING:
422 case wxJSONTYPE_MEMORYBUFF:
426 case wxJSONTYPE_ARRAY:
430 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
436 if (lastChar !=
'\n') {
448 for (
int i = 0; i < size; i++) {
454 lastChar =
DoWrite(os, v, 0, comma);
467 case wxJSONTYPE_OBJECT:
472 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
478 if (lastChar !=
'\n') {
488 for (it = map->begin(); it != map->end(); ++it) {
490 wxString key = it->first;
493 if (count < size - 1) {
496 lastChar =
DoWrite(os, v, &key, comma);
512 wxFAIL_MSG(
"wxJSONWriter::DoWrite() undefined wxJSONType type");
521 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
526 }
else if (commentPos == wxJSONVALUE_COMMENT_AFTER) {
533 if (lastChar !=
'\n') {
548 if ((m_style & wxJSONWRITER_WRITE_COMMENTS) == 0) {
552 const wxArrayString cmt = value.GetCommentArray();
553 int cmtSize = cmt.GetCount();
554 for (
int i = 0; i < cmtSize; i++) {
561 lastChar = cmt[i].Last();
562 if (lastChar !=
'\n') {
605 if (!(m_style & wxJSONWRITER_STYLED) ||
606 (m_style & wxJSONWRITER_NO_INDENTATION)) {
610 int numChars = m_indent + (m_step * num);
612 if (m_style & wxJSONWRITER_TAB_INDENT) {
617 for (
int i = 0; i < numChars; i++) {
619 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
649 wxCharBuffer utf8CB = str.ToUTF8();
650#if !defined(wxJSON_USE_UNICODE)
651 wxCharBuffer ansiCB(str.c_str());
653 writeBuff = ansiCB.data();
655 writeBuff = utf8CB.data();
658 writeBuff = utf8CB.data();
663 if (writeBuff ==
nullptr) {
665 "<wxJSONWriter::WriteStringValue(): error converting the string to a "
667 os.Write(err, strlen(err));
670 size_t len = strlen(writeBuff);
677 int tempCol = m_colNo;
681 for (i = 0; i < len; i++) {
682 bool shouldEscape =
false;
683 unsigned char ch = *writeBuff;
726 shouldEscape =
false;
732 if (!shouldEscape && ch < 32) {
734 snprintf(b, 8,
"\\u%04X", (
int)ch);
736 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
745 if (shouldEscape && !(m_style & wxJSONWRITER_ESCAPE_SOLIDUS)) {
747 shouldEscape =
false;
750 if (shouldEscape && (m_style & wxJSONWRITER_MULTILINE_STRING)) {
751 if (ch ==
'\n' || ch ==
'\t') {
752 shouldEscape =
false;
760 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
766 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
774 if ((m_style & wxJSONWRITER_STYLED) &&
775 (m_style & wxJSONWRITER_SPLIT_STRING)) {
789 else if ((m_colNo >= wxJSONWRITER_SPLIT_COL) &&
790 (tempCol <= wxJSONWRITER_LAST_COL)) {
792 if (len - i > wxJSONWRITER_MIN_LENGTH) {
817 wxLogTrace(writerTraceMask,
"(%s) string to write=%s", __PRETTY_FUNCTION__,
820 char* writeBuff =
nullptr;
824 wxCharBuffer utf8CB = str.ToUTF8();
825#if !defined(wxJSON_USE_UNICODE)
826 wxCharBuffer ansiCB(str.c_str());
829 writeBuff = ansiCB.data();
831 writeBuff = utf8CB.data();
834 writeBuff = utf8CB.data();
839 if (writeBuff ==
nullptr) {
841 "<wxJSONWriter::WriteComment(): error converting the string to UTF-8>";
842 os.Write(err, strlen(err));
845 size_t len = strlen(writeBuff);
847 os.Write(writeBuff, len);
848 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
852 wxLogTrace(writerTraceMask,
"(%s) result=%d", __PRETTY_FUNCTION__, lastChar);
862 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
883#if defined(wxJSON_64BIT_INT)
884#if wxCHECK_VERSION(2, 9, 0) || !defined(wxJSON_USE_UNICODE)
886 snprintf(buffer, 32,
"%" wxLongLongFmtSpec
"d", data->m_value.m_valInt64);
892 s.Printf(
"%" wxLongLongFmtSpec
"d", data->m_value.m_valInt64);
893 wxCharBuffer cb = s.ToUTF8();
894 const char* cbData = cb.data();
895 len = strlen(cbData);
897 memcpy(buffer, cbData, len);
901 snprintf(buffer, 32,
"%ld", data->m_value.m_valLong);
903 len = strlen(buffer);
904 os.Write(buffer, len);
905 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
926 if (m_style & wxJSONWRITER_RECOGNIZE_UNSIGNED) {
934#if defined(wxJSON_64BIT_INT)
935#if wxCHECK_VERSION(2, 9, 0) || !defined(wxJSON_USE_UNICODE)
937 snprintf(buffer, 32,
"%" wxLongLongFmtSpec
"u", data->m_value.m_valUInt64);
943 s.Printf(
"%" wxLongLongFmtSpec
"u", data->m_value.m_valInt64);
944 wxCharBuffer cb = s.ToUTF8();
945 const char* cbData = cb.data();
946 len = strlen(cbData);
948 memcpy(buffer, cbData, len);
952 snprintf(buffer, 32,
"%lu", data->m_value.m_valULong);
954 len = strlen(buffer);
955 os.Write(buffer, len);
956 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
981 snprintf(buffer, 32, m_fmt, data->m_value.m_valDouble);
982 size_t len = strlen(buffer);
983 os.Write(buffer, len);
984 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
999 const char* f =
"false";
1000 const char* t =
"true";
1006 if (data->m_value.m_valBool) {
1010 size_t len = strlen(c);
1012 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1020 wxLogTrace(writerTraceMask,
"(%s) key write=%s", __PRETTY_FUNCTION__,
1046 "wxJSONWriter::WriteInvalid() cannot be called (not a valid JSON "
1049 os.Write(
"<invalid JSON value>", 9);
1064 const wxMemoryBuffer& buff) {
1065#define MAX_BYTES_PER_ROW 20
1071 int bytesWritten = 0;
1072 bool splitString =
false;
1073 if ((m_style & wxJSONWRITER_STYLED) &&
1074 (m_style & wxJSONWRITER_SPLIT_STRING)) {
1078 size_t buffLen = buff.GetDataLen();
1079 unsigned char* ptr = (
unsigned char*)buff.GetData();
1081 char openChar =
'\'';
1082 char closeChar =
'\'';
1083 bool asArray =
false;
1085 if ((m_style & wxJSONWRITER_MEMORYBUFF) == 0) {
1094 for (
size_t i = 0; i < buffLen; i++) {
1095 unsigned char c = *ptr;
1099 snprintf(str, 14,
"%d", c);
1100 size_t len = strlen(str);
1105 if (i < buffLen - 1) {
1109 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1126 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1133 if ((bytesWritten >= MAX_BYTES_PER_ROW) && ((buffLen - i) >= 5)) {
1136 os.Write(
"\'\n", 2);
1164 int lastChar =
'\n';
1165 if ((m_style & wxJSONWRITER_STYLED) &&
1166 !(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.