void jsonValueToRapidJSON(JSONValue* value, rapidjson::Value& rapidValue, rapidjson::Document& document) { JSONNull* nullValue = dynamic_cast<JSONNull*>(value); if (nullValue) { rapidValue.SetNull(); return; } JSONNumber* numberValue = dynamic_cast<JSONNumber*>(value); if (numberValue) { if (numberValue->canBeUInt64()) { rapidValue.SetUint64(numberValue->getUInt64Value()); } else if (numberValue->canBeInt64()) { rapidValue.SetInt64(numberValue->getInt64Value()); } else { rapidValue.SetDouble(numberValue->getDoubleValue()); } return; } JSONString* stringValue = dynamic_cast<JSONString*>(value); if (stringValue) { rapidValue.SetString(stringValue->getValue().c_str(), stringValue->getValue().size(), document.GetAllocator()); return; } JSONBool* boolValue = dynamic_cast<JSONBool*>(value); if (boolValue) { rapidValue.SetBool(boolValue->getValue()); return; } JSONArray* arrayValue = dynamic_cast<JSONArray*>(value); if (arrayValue) { rapidValue.SetArray(); std::vector<JSONValue::ref> values = arrayValue->getValues(); for (auto & value : values) { rapidjson::Value obj; jsonValueToRapidJSON(value.get(), obj, document); rapidValue.PushBack(obj, document.GetAllocator()); } return; } JSONObject* objectValue = dynamic_cast<JSONObject*>(value); if (objectValue) { rapidValue.SetObject(); typedef std::map<std::string, JSONValue::ref> ValuesMap; ValuesMap values = objectValue->getValues(); for (auto & value : values) { rapidjson::Value obj; jsonValueToRapidJSON(value.second.get(), obj, document); rapidjson::Value key; key.SetString(value.first.c_str(), value.first.size(), document.GetAllocator()); rapidValue.AddMember(key, obj, document.GetAllocator()); } return; } assert(false); }
static bool pyobj2doc(PyObject *object, rapidjson::Value& doc, rapidjson::Document& root) { if (PyBool_Check(object)) { if (Py_True == object) { doc.SetBool(true); } else { doc.SetBool(false); } } else if (Py_None == object) { doc.SetNull(); } else if (PyFloat_Check(object)) { doc.SetDouble(PyFloat_AsDouble(object)); } else if (PyInt_Check(object)) { doc.SetInt64(PyLong_AsLong(object)); } else if (PyString_Check(object)) { doc.SetString(PyString_AsString(object), PyString_GET_SIZE(object)); } else if (PyUnicode_Check(object)) { PyObject *utf8_item = PyUnicode_AsUTF8String(object); if (!utf8_item) { PyErr_SetString(PyExc_RuntimeError, "codec error."); return false; } #ifdef PY3 doc.SetString(PyBytes_AsString(utf8_item), PyBytes_GET_SIZE(utf8_item), root.GetAllocator()); #else doc.SetString(PyString_AsString(utf8_item), PyString_GET_SIZE(utf8_item), root.GetAllocator()); #endif Py_XDECREF(utf8_item); } else if (PyTuple_Check(object)) { int len = PyTuple_Size(object), i; doc.SetArray(); rapidjson::Value _v; for (i = 0; i < len; ++i) { PyObject *elm = PyTuple_GetItem(object, i); if (false == pyobj2doc(elm, _v, root)) { return false; } doc.PushBack(_v, root.GetAllocator()); } } else if (PyList_Check(object)) { int len = PyList_Size(object), i; doc.SetArray(); rapidjson::Value _v; for (i = 0; i < len; ++i) { PyObject *elm = PyList_GetItem(object, i); if (false == pyobj2doc(elm, _v, root)) { return false; } doc.PushBack(_v, root.GetAllocator()); } } else if (PyDict_Check(object)) { doc.SetObject(); PyObject *key, *value; Py_ssize_t pos = 0; while (PyDict_Next(object, &pos, &key, &value)) { if (false == pyobj2doc_pair(key, value, doc, root)) { return false; } } } else { PyErr_SetString(PyExc_RuntimeError, "invalid python object"); return false; } return true; }
void tvalue2json(rapidjson::Value & output, const QVariant & input, rapidjson::Value::AllocatorType & allocator) { switch(input.type()) { case QVariant::Invalid: { output.SetNull(); break; } case QVariant::Bool: { output.SetBool(input.toBool()); break; } case QVariant::Int: { output.SetInt64(input.toInt()); break; } case QVariant::LongLong: { output.SetInt64(input.toLongLong()); break; } case QVariant::Double: { output.SetDouble(input.toDouble()); break; } case QVariant::String: { QByteArray str = input.toString().toUtf8(); output.SetString(str.data(), str.size(), allocator); break; } case QVariant::StringList: { QStringList list = input.toStringList(); output.SetArray(); output.Reserve(list.size(), allocator); rapidjson::Value temp; for(QStringList::const_iterator it = list.begin(); it != list.end(); ++it) { QByteArray str = it->toUtf8(); temp.SetString(str.data(), str.size(), allocator); output.PushBack(temp, allocator); } break; } case QVariant::List: { QList<QVariant> list = input.toList(); output.SetArray(); output.Reserve(list.size(), allocator); rapidjson::Value temp; for(QList<QVariant>::const_iterator it = list.begin(); it != list.end(); ++it) { tvalue2json(temp, *it, allocator); output.PushBack(temp, allocator); } break; } case QVariant::Map: { output.SetObject(); rapidjson::Value tempK, tempV; QMap<QString, QVariant> qmap = input.toMap(); for(QMap<QString, QVariant>::const_iterator it = qmap.begin(); it != qmap.end(); ++it) { tvalue2json(tempK, it.key(), allocator); tvalue2json(tempV, it.value(), allocator); output.AddMember(tempK, tempV, allocator); } break; } case QVariant::Point: { QPoint pt = input.toPoint(); output.SetArray(); output.Reserve(2, allocator); output.PushBack(pt.x(), allocator); output.PushBack(pt.y(), allocator); break; } case QVariant::PointF: { QPointF pt = input.toPointF(); output.SetArray(); output.Reserve(2, allocator); output.PushBack(pt.x(), allocator); output.PushBack(pt.y(), allocator); break; } case QVariant::Size: { QSize pt = input.toSize(); output.SetArray(); output.Reserve(2, allocator); output.PushBack(pt.width(), allocator); output.PushBack(pt.height(), allocator); break; } case QVariant::SizeF: { QSizeF pt = input.toSizeF(); output.SetArray(); output.Reserve(2, allocator); output.PushBack(pt.width(), allocator); output.PushBack(pt.height(), allocator); break; } case QVariant::Rect: { QRect pt = input.toRect(); output.SetArray(); output.Reserve(4, allocator); output.PushBack(pt.x(), allocator); output.PushBack(pt.y(), allocator); output.PushBack(pt.width(), allocator); output.PushBack(pt.height(), allocator); break; } case QVariant::RectF: { QRectF pt = input.toRectF(); output.SetArray(); output.Reserve(4, allocator); output.PushBack(pt.x(), allocator); output.PushBack(pt.y(), allocator); output.PushBack(pt.width(), allocator); output.PushBack(pt.height(), allocator); break; } case QVariant::Vector2D: { QVector2D pt = input.value<QVector2D>(); output.SetArray(); output.Reserve(2, allocator); output.PushBack(pt.x(), allocator); output.PushBack(pt.y(), allocator); break; } case QVariant::Vector3D: { QVector3D pt = input.value<QVector3D>(); output.SetArray(); output.Reserve(3, allocator); output.PushBack(pt.x(), allocator); output.PushBack(pt.y(), allocator); output.PushBack(pt.z(), allocator); break; } case QVariant::Vector4D: { QVector4D pt = input.value<QVector4D>(); output.SetArray(); output.Reserve(4, allocator); output.PushBack(pt.x(), allocator); output.PushBack(pt.y(), allocator); output.PushBack(pt.z(), allocator); output.PushBack(pt.w(), allocator); break; } case QVariant::Color: { QColor pt = input.value<QColor>(); output.SetArray(); output.Reserve(4, allocator); output.PushBack(pt.red(), allocator); output.PushBack(pt.green(), allocator); output.PushBack(pt.blue(), allocator); output.PushBack(pt.alpha(), allocator); break; } default: { output.SetNull(); assert(false && "shuldn't execute to here."); } } }