12#pragma implementation "jsonwriter.cpp"
18#define wxDEBUG_LEVEL 0
21#include "jsonwriter.h"
23#include <wx/sstream.h>
24#include <wx/mstream.h>
29static const wxChar* writerTraceMask = _T(
"traceWriter");
200 if (m_style == wxJSONWRITER_NONE) {
208#if !defined(wxJSON_USE_UNICODE)
211 if (m_style == wxJSONWRITER_NOUTF8_STREAM) {
262#if !defined(wxJSON_USE_UNICODE)
264 bool noUtf8_bak = m_noUtf8;
268 wxMemoryOutputStream os;
272 wxFileOffset len = os.GetLength();
273 wxStreamBuffer* osBuff = os.GetOutputStreamBuffer();
274 void* buffStart = osBuff->GetBufferStart();
277 str = wxString::From8BitData((
const char*)buffStart, len);
279 str = wxString::FromUTF8((
const char*)buffStart, len);
281#if !defined(wxJSON_USE_UNICODE)
282 m_noUtf8 = noUtf8_bak;
327 const wxString* key,
bool comma) {
331 const wxJSONInternalMap* map = 0;
343 if (value.GetCommentCount() > 0 && (m_style & wxJSONWRITER_WRITE_COMMENTS)) {
344 commentPos = value.GetCommentPos();
345 if ((m_style & wxJSONWRITER_COMMENTS_BEFORE) != 0) {
346 commentPos = wxJSONVALUE_COMMENT_BEFORE;
347 }
else if ((m_style & wxJSONWRITER_COMMENTS_AFTER) != 0) {
348 commentPos = wxJSONVALUE_COMMENT_AFTER;
355 if (commentPos == wxJSONVALUE_COMMENT_BEFORE) {
359 }
else if (lastChar !=
'\n') {
378 wxJSONInternalMap::const_iterator it;
381 wxJSONType t = value.GetType();
383 case wxJSONTYPE_INVALID:
386 _T(
"wxJSONWriter::WriteEmpty() cannot be called (not a valid JSON ")
391 case wxJSONTYPE_SHORT:
392 case wxJSONTYPE_LONG:
393 case wxJSONTYPE_INT64:
397 case wxJSONTYPE_UINT:
398 case wxJSONTYPE_USHORT:
399 case wxJSONTYPE_ULONG:
400 case wxJSONTYPE_UINT64:
404 case wxJSONTYPE_NULL:
407 case wxJSONTYPE_BOOL:
411 case wxJSONTYPE_DOUBLE:
415 case wxJSONTYPE_STRING:
416 case wxJSONTYPE_CSTRING:
420 case wxJSONTYPE_MEMORYBUFF:
424 case wxJSONTYPE_ARRAY:
428 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
434 if (lastChar !=
'\n') {
446 for (
int i = 0; i < size; i++) {
452 lastChar =
DoWrite(os, v, 0, comma);
465 case wxJSONTYPE_OBJECT:
470 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
476 if (lastChar !=
'\n') {
486 for (it = map->begin(); it != map->end(); ++it) {
488 wxString key = it->first;
491 if (count < size - 1) {
494 lastChar =
DoWrite(os, v, &key, comma);
510 wxFAIL_MSG(_T(
"wxJSONWriter::DoWrite() undefined wxJSONType type"));
519 if (commentPos == wxJSONVALUE_COMMENT_INLINE) {
524 }
else if (commentPos == wxJSONVALUE_COMMENT_AFTER) {
531 if (lastChar !=
'\n') {
546 if ((m_style & wxJSONWRITER_WRITE_COMMENTS) == 0) {
550 const wxArrayString cmt = value.GetCommentArray();
551 int cmtSize = cmt.GetCount();
552 for (
int i = 0; i < cmtSize; i++) {
559 lastChar = cmt[i].Last();
560 if (lastChar !=
'\n') {
603 if (!(m_style & wxJSONWRITER_STYLED) ||
604 (m_style & wxJSONWRITER_NO_INDENTATION)) {
608 int numChars = m_indent + (m_step * num);
610 if (m_style & wxJSONWRITER_TAB_INDENT) {
615 for (
int i = 0; i < numChars; i++) {
617 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
647 wxCharBuffer utf8CB = str.ToUTF8();
648#if !defined(wxJSON_USE_UNICODE)
649 wxCharBuffer ansiCB(str.c_str());
651 writeBuff = ansiCB.data();
653 writeBuff = utf8CB.data();
656 writeBuff = utf8CB.data();
661 if (writeBuff == 0) {
663 "<wxJSONWriter::WriteStringValue(): error converting the string to a "
665 os.Write(err, strlen(err));
668 size_t len = strlen(writeBuff);
675 int tempCol = m_colNo;
679 for (i = 0; i < len; i++) {
680 bool shouldEscape =
false;
681 unsigned char ch = *writeBuff;
724 shouldEscape =
false;
730 if (!shouldEscape && ch < 32) {
732 snprintf(b, 8,
"\\u%04X", (
int)ch);
734 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
743 if (shouldEscape && !(m_style & wxJSONWRITER_ESCAPE_SOLIDUS)) {
745 shouldEscape =
false;
748 if (shouldEscape && (m_style & wxJSONWRITER_MULTILINE_STRING)) {
749 if (ch ==
'\n' || ch ==
'\t') {
750 shouldEscape =
false;
758 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
764 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
772 if ((m_style & wxJSONWRITER_STYLED) &&
773 (m_style & wxJSONWRITER_SPLIT_STRING)) {
787 else if ((m_colNo >= wxJSONWRITER_SPLIT_COL) &&
788 (tempCol <= wxJSONWRITER_LAST_COL)) {
790 if (len - i > wxJSONWRITER_MIN_LENGTH) {
815 wxLogTrace(writerTraceMask, _T(
"(%s) string to write=%s"),
816 __PRETTY_FUNCTION__, str.c_str());
822 wxCharBuffer utf8CB = str.ToUTF8();
823#if !defined(wxJSON_USE_UNICODE)
824 wxCharBuffer ansiCB(str.c_str());
827 writeBuff = ansiCB.data();
829 writeBuff = utf8CB.data();
832 writeBuff = utf8CB.data();
837 if (writeBuff == 0) {
839 "<wxJSONWriter::WriteComment(): error converting the string to UTF-8>";
840 os.Write(err, strlen(err));
843 size_t len = strlen(writeBuff);
845 os.Write(writeBuff, len);
846 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
850 wxLogTrace(writerTraceMask, _T(
"(%s) result=%d"), __PRETTY_FUNCTION__,
861 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
882#if defined(wxJSON_64BIT_INT)
883#if wxCHECK_VERSION(2, 9, 0) || !defined(wxJSON_USE_UNICODE)
885 snprintf(buffer, 32,
"%" wxLongLongFmtSpec
"d", data->m_value.m_valInt64);
891 s.Printf(_T(
"%") wxLongLongFmtSpec _T(
"d"), data->m_value.m_valInt64);
892 wxCharBuffer cb = s.ToUTF8();
893 const char* cbData = cb.data();
894 len = strlen(cbData);
896 memcpy(buffer, cbData, len);
900 snprintf(buffer, 32,
"%ld", data->m_value.m_valLong);
902 len = strlen(buffer);
903 os.Write(buffer, len);
904 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
925 if (m_style & wxJSONWRITER_RECOGNIZE_UNSIGNED) {
933#if defined(wxJSON_64BIT_INT)
934#if wxCHECK_VERSION(2, 9, 0) || !defined(wxJSON_USE_UNICODE)
936 snprintf(buffer, 32,
"%" wxLongLongFmtSpec
"u", data->m_value.m_valUInt64);
942 s.Printf(_T(
"%") wxLongLongFmtSpec _T(
"u"), data->m_value.m_valInt64);
943 wxCharBuffer cb = s.ToUTF8();
944 const char* cbData = cb.data();
945 len = strlen(cbData);
947 memcpy(buffer, cbData, len);
951 snprintf(buffer, 32,
"%lu", data->m_value.m_valULong);
953 len = strlen(buffer);
954 os.Write(buffer, len);
955 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
980 snprintf(buffer, 32, m_fmt, data->m_value.m_valDouble);
981 size_t len = strlen(buffer);
982 os.Write(buffer, len);
983 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
998 const char* f =
"false";
999 const char* t =
"true";
1005 if (data->m_value.m_valBool) {
1009 size_t len = strlen(c);
1011 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1019 wxLogTrace(writerTraceMask, _T(
"(%s) key write=%s"), __PRETTY_FUNCTION__,
1045 _T(
"wxJSONWriter::WriteInvalid() cannot be called (not a valid JSON ")
1048 os.Write(
"<invalid JSON value>", 9);
1063 const wxMemoryBuffer& buff) {
1064#define MAX_BYTES_PER_ROW 20
1070 int bytesWritten = 0;
1071 bool splitString =
false;
1072 if ((m_style & wxJSONWRITER_STYLED) &&
1073 (m_style & wxJSONWRITER_SPLIT_STRING)) {
1077 size_t buffLen = buff.GetDataLen();
1078 unsigned char* ptr = (
unsigned char*)buff.GetData();
1080 char openChar =
'\'';
1081 char closeChar =
'\'';
1082 bool asArray =
false;
1084 if ((m_style & wxJSONWRITER_MEMORYBUFF) == 0) {
1093 for (
size_t i = 0; i < buffLen; i++) {
1094 unsigned char c = *ptr;
1098 snprintf(str, 14,
"%d", c);
1099 size_t len = strlen(str);
1104 if (i < buffLen - 1) {
1108 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1125 if (os.GetLastError() != wxSTREAM_NO_ERROR) {
1132 if ((bytesWritten >= MAX_BYTES_PER_ROW) && ((buffLen - i) >= 5)) {
1135 os.Write(
"\'\n", 2);
1163 int lastChar =
'\n';
1164 if ((m_style & wxJSONWRITER_STYLED) &&
1165 !(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.