comparison Sources/PythonObject.cpp @ 51:3dc37a5af1b1

new method PythonObject::ConvertToJson()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 09 Dec 2020 16:34:03 +0100
parents fd58eb5749ed
children 23f3099bed47
comparison
equal deleted inserted replaced
50:70abe3ebbbfc 51:3dc37a5af1b1
63 { 63 {
64 return new PythonObject(lock_, PyObject_GetAttrString(GetPyObject(), name.c_str())); 64 return new PythonObject(lock_, PyObject_GetAttrString(GetPyObject(), name.c_str()));
65 } 65 }
66 66
67 67
68 bool PythonObject::ToUtf8String(std::string& target) 68 bool PythonObject::ToUtf8String(std::string& target,
69 { 69 PyObject* value)
70 PyObject* value = GetPyObject(); // Raises an exception if needed 70 {
71 71 if (value == NULL)
72 if (PyUnicode_Check(value)) 72 {
73 ORTHANC_PLUGINS_THROW_EXCEPTION(NullPointer);
74 }
75 else if (PyUnicode_Check(value))
73 { 76 {
74 PythonObject encoded(lock_, PyUnicode_AsEncodedString(value, "utf-8", "replace")); 77 PythonObject encoded(lock_, PyUnicode_AsEncodedString(value, "utf-8", "replace"));
75 if (encoded.IsValid()) 78 if (encoded.IsValid())
76 { 79 {
77 target = PyBytes_AS_STRING(encoded.GetPyObject()); 80 target = PyBytes_AS_STRING(encoded.GetPyObject());
130 OrthancPlugins::LogError("Cannot release a NULL or borrowed reference"); 133 OrthancPlugins::LogError("Cannot release a NULL or borrowed reference");
131 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); 134 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
132 } 135 }
133 } 136 }
134 137
138
139 void PythonObject::ConvertToJson(Json::Value& target,
140 PyObject* source)
141 {
142 // WARNING: The order *is* important!
143 if (source == Py_None)
144 {
145 target = Json::nullValue;
146 }
147 else if (PyBool_Check(source))
148 {
149 target = (PyObject_IsTrue(source) ? true : false);
150 }
151 else if (PyLong_Check(source))
152 {
153 target = static_cast<int32_t>(PyLong_AsLong(source));
154 }
155 else if (PyFloat_Check(source))
156 {
157 target = PyFloat_AsDouble(source);
158 }
159 else if (PyNumber_Check(source))
160 {
161 PythonObject asLong(lock_, PyNumber_Long(source));
162 if (PyLong_Check(asLong.GetPyObject()))
163 {
164 target = static_cast<int32_t>(PyLong_AsLong(asLong.GetPyObject()));
165 }
166 else
167 {
168 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
169 }
170 }
171 else if (PyUnicode_Check(source))
172 {
173 std::string s;
174 if (ToUtf8String(s, source))
175 {
176 target = s;
177 }
178 else
179 {
180 ORTHANC_PLUGINS_THROW_EXCEPTION(NotImplemented);
181 }
182 }
183 #if PY_MAJOR_VERSION == 2
184 else if (PyString_Check(source))
185 {
186 target = PyString_AS_STRING(source);
187 }
188 #endif
189 else if (PySequence_Check(source)) // tuples or lists
190 {
191 Py_ssize_t size = PySequence_Size(source);
192
193 if (size < 0)
194 {
195 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
196 }
197
198 target = Json::arrayValue;
199 for (Py_ssize_t i = 0; i < size; i++)
200 {
201 Json::Value item;
202 ConvertToJson(item, PySequence_GetItem(source, i));
203 target.append(item);
204 }
205 }
206 else if (PyMapping_Check(source)) // dictionaries
207 {
208 PythonObject items(lock_, PyMapping_Items(source));
209
210 Py_ssize_t size = PySequence_Size(items.GetPyObject());
211
212 if (size < 0)
213 {
214 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
215 }
216
217 for (Py_ssize_t i = 0; i < size; i++)
218 {
219 PyObject* pair = PySequence_GetItem(items.GetPyObject(), i);
220
221 std::string key;
222 Json::Value value;
223 if (pair != NULL &&
224 ToUtf8String(key, PySequence_GetItem(pair, 0)))
225 {
226 ConvertToJson(value, PySequence_GetItem(pair, 1));
227 target[key] = value;
228 }
229 else
230 {
231 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
232 }
233 }
234 }
235 else
236 {
237 ORTHANC_PLUGINS_THROW_EXCEPTION(NotImplemented);
238 }
239 }