@@ -79,6 +79,25 @@ static void loadPython()
7979}
8080#endif
8181
82+ namespace
83+ {
84+
85+ std::string readPythonString (PyObject* dict, const std::string& key)
86+ {
87+ std::string s;
88+
89+ PyObject* o = PyDict_GetItemString (dict, key.c_str ());
90+ if (o)
91+ {
92+ PyObject* r = PyObject_Str (o);
93+ if (r)
94+ s = PyUnicode_AsUTF8AndSize (r, NULL );
95+ }
96+ return s;
97+ }
98+
99+ } // unnamed namespace
100+
82101// http://www.linuxjournal.com/article/3641
83102// http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I
84103// http://stackoverflow.com/questions/6596016/python-threads-in-c
@@ -199,9 +218,9 @@ std::string getTraceback()
199218 PyObject* r = PyObject_Repr (l);
200219 if (!r)
201220 throw pdal::pdal_error (" unable to get repr in getTraceback" );
202- Py_ssize_t size ;
203- const char *d = PyUnicode_AsUTF8AndSize (r, &size);
204- mssg << d;
221+ const char *d = PyUnicode_AsUTF8AndSize (r, NULL ) ;
222+ if (d)
223+ mssg << d;
205224 }
206225
207226 // clean up
@@ -213,9 +232,9 @@ std::string getTraceback()
213232 PyObject* r = PyObject_Repr (value);
214233 if (!r)
215234 throw pdal::pdal_error (" couldn't make string representation of traceback value" );
216- Py_ssize_t size ;
217- const char *d = PyUnicode_AsUTF8AndSize (r, &size);
218- mssg << d;
235+ const char *d = PyUnicode_AsUTF8AndSize (r, NULL ) ;
236+ if (d)
237+ mssg << d;
219238 }
220239 else
221240 mssg << " unknown error that we are unable to get a traceback for."
@@ -231,21 +250,6 @@ std::string getTraceback()
231250// Returns a new reference.
232251PyObject *fromMetadata (MetadataNode m)
233252{
234- std::string name = m.name ();
235- std::string value = m.value ();
236- std::string type = m.type ();
237- std::string description = m.description ();
238-
239- MetadataNodeList children = m.children ();
240- PyObject *submeta (0 );
241- if (children.size ())
242- {
243- submeta = PyList_New (0 );
244- for (MetadataNode& child : children)
245- PyList_Append (submeta, fromMetadata (child));
246- }
247- PyObject *data = PyDict_New ();
248-
249253 auto getString = [](const std::string& s)
250254 {
251255 PyObject *o = PyUnicode_FromString (s.data ());
@@ -254,68 +258,59 @@ PyObject *fromMetadata(MetadataNode m)
254258 return o;
255259 };
256260
257- PyDict_SetItemString (data, " name" , getString (name));
258- PyDict_SetItemString (data, " value" , getString (value));
259- PyDict_SetItemString (data, " type" , getString (value));
260- PyDict_SetItemString (data, " description" , getString (description));
261+ PyObject *data = PyDict_New ();
262+
263+ PyDict_SetItemString (data, " name" , getString (m.name ()));
264+ PyDict_SetItemString (data, " value" , getString (m.value ()));
265+ PyDict_SetItemString (data, " type" , getString (m.type ()));
266+ PyDict_SetItemString (data, " description" , getString (m.description ()));
261267
268+ MetadataNodeList children = m.children ();
262269 if (children.size ())
270+ {
271+ PyObject *submeta = PyList_New (0 );
272+ for (MetadataNode& child : children)
273+ PyList_Append (submeta, fromMetadata (child));
263274 PyDict_SetItemString (data, " children" , submeta);
275+ }
276+
264277 return data;
265278}
266279
267- std::string readPythonString (PyObject* dict, const std::string& key)
268- {
269- std::stringstream ss;
270280
271- PyObject* o = PyDict_GetItemString (dict, key.c_str ());
272- if (!o)
273- {
274- std::stringstream oss;
275- oss << " Unable to get dictionary item '" << key << " '" ;
276- throw pdal_error (oss.str ());
277- }
278-
279- PyObject* r = PyObject_Str (o);
280- if (!r)
281- throw pdal::pdal_error (" unable to get repr in readPythonString" );
282- Py_ssize_t size;
283- const char *d = PyUnicode_AsUTF8AndSize (r, &size);
284- ss << d;
285-
286- return ss.str ();
287- }
288281void addMetadata (PyObject *dict, MetadataNode m)
289282{
290283 if (!dict)
291- {
292284 return ;
293- }
294285
295286 if (!PyDict_Check (dict))
296- throw pdal::pdal_error (" ' metadata' member must be a dictionary! " );
287+ throw pdal::pdal_error (" Output metadata must be in a dictionary. " );
297288
298289 std::string name = readPythonString (dict, " name" );
299290 std::string value = readPythonString (dict, " value" );
300-
301291 std::string type = readPythonString (dict, " type" );
292+ std::string description = readPythonString (dict, " description" );
293+ if (name.empty ())
294+ return ;
302295 if (type.empty ())
303296 type = Metadata::inferType (value);
304297
305- std::string description = readPythonString (dict, " description" );
306-
298+ m.addWithType (name, value, type, description);
307299 PyObject *submeta = PyDict_GetItemString (dict, " children" );
308300 if (submeta)
309301 {
310302 if (!PyList_Check (submeta))
311- throw pdal::pdal_error (" 'children' metadata member must be a list! " );
312-
313- for (Py_ssize_t i = 0 ; i < PyList_Size (submeta); ++i )
303+ throw pdal::pdal_error (" Ouput metadata 'children' must be a list. " );
304+ Py_ssize_t size = PyList_Size (submeta);
305+ if (size )
314306 {
315- PyObject* p = PyList_GetItem (submeta, i);
316- addMetadata (p, m);
307+ m = m.add (" children" );
308+ for (Py_ssize_t i = 0 ; i < PyList_Size (submeta); ++i)
309+ {
310+ PyObject* p = PyList_GetItem (submeta, i);
311+ addMetadata (p, m);
312+ }
317313 }
318- MetadataNode child = m.addWithType (name, value, type, description);
319314 }
320315}
321316
0 commit comments