1 
2 /*
3 A* -------------------------------------------------------------------
4 B* This file contains source code for the PyMOL computer program
5 C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
6 D* -------------------------------------------------------------------
7 E* It is unlawful to modify or remove this copyright notice.
8 F* -------------------------------------------------------------------
9 G* Please see the accompanying LICENSE file for further information.
10 H* -------------------------------------------------------------------
11 I* Additional authors of this source file include:
12 -*
13 -*
14 -*
15 Z* -------------------------------------------------------------------
16 */
17 #include"os_python.h"
18 
19 #include"os_predef.h"
20 #include"os_python.h"
21 
22 #include"os_std.h"
23 
24 #include"Err.h"
25 #include"MemoryDebug.h"
26 #include"Base.h"
27 #include"PConv.h"
28 #include"P.h"
29 #include"Util.h"
30 
31 #include <vector>
32 
33 #if PY_MAJOR_VERSION >= 3
34 #define pickle_mod_name "pickle"
35 #else
36 #define pickle_mod_name "cPickle"
37 // support loading Python 3 pickles with Python 2
38 #define PyString_Check(o) (PyBytes_CheckExact(o) || PyUnicode_Check(o))
39 #endif
40 
41 /* Return value: New reference.
42  * Load a pickle from the given string
43  */
PConvPickleLoads(PyObject * str)44 PyObject *PConvPickleLoads(PyObject * str)
45 {
46   PyObject *picklemod = NULL, *obj = NULL;
47   ok_assert(1, picklemod = PyImport_ImportModule(pickle_mod_name));
48   obj = PYOBJECT_CALLMETHOD(picklemod, "loads", "O", str);
49 ok_except1:
50   Py_XDECREF(picklemod);
51   return obj;
52 }
53 
54 /* Return value: New reference.
55  * Return a string containing an object in pickle format.
56  */
PConvPickleDumps(PyObject * obj)57 PyObject *PConvPickleDumps(PyObject * obj)
58 {
59   PyObject *picklemod = NULL, *str = NULL;
60   ok_assert(1, picklemod = PyImport_ImportModule(pickle_mod_name));
61   str = PYOBJECT_CALLMETHOD(picklemod, "dumps", "Oi", obj, 1);
62 ok_except1:
63   Py_XDECREF(picklemod);
64   return str;
65 }
66 
PConvAutoNone(PyObject * result)67 PyObject *PConvAutoNone(PyObject * result)
68 {                               /* automatically own Py_None */
69   if(result == Py_None)
70     Py_INCREF(result);
71   else if(result == NULL) {
72     result = Py_None;
73     Py_INCREF(result);
74   }
75   return (result);
76 }
77 
78 
79 /* Error-checked utility routines */
80 
PConvPyListToBitmask(PyObject * obj,int * bitmask,ov_size ll)81 int PConvPyListToBitmask(PyObject * obj, int *bitmask, ov_size ll)
82 {
83   std::vector<signed char> visRepArr(ll, 0);
84 
85   if (ll > 0)
86     ok_assert(1, PConvPyListToSCharArrayInPlaceAutoZero(obj, &visRepArr[0], ll));
87 
88   *bitmask = 0;
89   for(int i = 0; i < ll; i++)
90     if(visRepArr[i])
91       SET_BIT(*bitmask, i);
92 
93   return true;
94 ok_except1:
95   return false;
96 }
97 
PConvPyListToExtent(PyObject * obj,float * mn,float * mx)98 int PConvPyListToExtent(PyObject * obj, float *mn, float *mx)
99 {                               /* [[min_x,min_y,min_z],
100                                    [max_x,max_y,max_z]] */
101   int ok = false;
102   PyObject *t1, *t2;
103   if(!obj) {
104     ok = false;
105   } else if(PyList_Check(obj))
106     if(PyList_Size(obj) == 2) {
107       t1 = PyList_GetItem(obj, 0);
108       t2 = PyList_GetItem(obj, 1);
109       if(PConvPyListToFloatArrayInPlace(t1, mn, 3) &&
110          PConvPyListToFloatArrayInPlace(t2, mx, 3))
111         ok = true;
112     }
113   return (ok);
114 }
115 
PConvPyListToStrVLAList(PyObject * obj,char ** vla,int * n_str)116 int PConvPyListToStrVLAList(PyObject * obj, char **vla, int *n_str)
117 {
118   int ok = false;
119   PyObject *t;
120   int n_st = 0, n_ch = 0, nn_ch, l, i;
121   if(!*vla)
122     *vla = VLAlloc(char, 10);
123   if((!obj) || (!*vla)) {
124     ok = false;
125   } else if(PyList_Check(obj)) {
126     n_st = PyList_Size(obj);
127     ok = true;
128     for(i = 0; i < n_st; i++) {
129       t = PyList_GetItem(obj, i);
130       if(PyString_Check(t)) {
131         l = PyString_Size(t);
132         nn_ch = n_ch + l + 1;
133         VLACheck(*vla, char, nn_ch);
134         auto strval = PyString_AsSomeString(t);
135         UtilNCopy((*vla) + n_ch, strval.c_str(), l + 1);
136         n_ch = nn_ch;
137       } else {
138         VLACheck(*vla, char, n_ch + 1);
139         (*vla)[n_ch] = 0;
140         n_ch++;
141       }
142     }
143   }
144   *n_str = n_st;
145   return (ok);
146 }
147 
PConvAttrToIntArrayInPlace(PyObject * obj,const char * attr,int * f,ov_size ll)148 int PConvAttrToIntArrayInPlace(PyObject * obj, const char *attr, int *f, ov_size ll)
149 {
150   int ok = true;
151   PyObject *tmp;
152   if(!obj) {
153     ok = false;
154   } else if(PyObject_HasAttrString(obj, attr)) {
155     tmp = PyObject_GetAttrString(obj, attr);
156     ok = PConvPyListToIntArrayInPlace(tmp, f, ll);
157     Py_DECREF(tmp);
158   } else {
159     ok = false;
160   }
161   return (ok);
162 }
163 
PConvAttrToFloatArrayInPlace(PyObject * obj,const char * attr,float * f,ov_size ll)164 int PConvAttrToFloatArrayInPlace(PyObject * obj, const char *attr, float *f, ov_size ll)
165 {
166   int ok = true;
167   PyObject *tmp;
168   if(!obj) {
169     ok = false;
170   } else if(PyObject_HasAttrString(obj, attr)) {
171     tmp = PyObject_GetAttrString(obj, attr);
172     ok = PConvPyListToFloatArrayInPlace(tmp, f, ll);
173     Py_DECREF(tmp);
174   } else {
175     ok = false;
176   }
177   return (ok);
178 }
179 
PConvAttrToStrMaxLen(PyObject * obj,const char * attr,char * str,ov_size ll)180 int PConvAttrToStrMaxLen(PyObject * obj, const char *attr, char *str, ov_size ll)
181 {
182   int ok = true;
183   PyObject *tmp;
184   if(!obj) {
185     ok = false;
186   } else if(PyObject_HasAttrString(obj, attr)) {
187     tmp = PyObject_GetAttrString(obj, attr);
188     ok = PConvPyObjectToStrMaxLen(tmp, str, ll);
189     Py_DECREF(tmp);
190   } else {
191     ok = false;
192   }
193   return (ok);
194 }
195 
PConvAttrToPtr(PyObject * obj,const char * attr,void ** cobj)196 int PConvAttrToPtr(PyObject * obj, const char *attr, void **cobj)
197 {
198   PyObject *tmp;
199   int ok = true;
200   if(!obj) {
201     ok = false;
202   } else if(PyObject_HasAttrString(obj, attr)) {
203     tmp = PyObject_GetAttrString(obj, attr);
204     ok = PConvCObjectToPtr(tmp, cobj);
205     Py_DECREF(tmp);
206   } else {
207     ok = false;
208   }
209   return (ok);
210 }
211 
PConvCObjectToPtr(PyObject * obj,void ** ptr)212 int PConvCObjectToPtr(PyObject * obj, void **ptr)
213 {
214   int ok = true;
215   if(!obj) {
216     ok = false;
217   } else if(!PyCObject_Check(obj))
218     ok = false;
219   else
220     (*ptr) = PyCObject_AsVoidPtr(obj);
221   return (ok);
222 }
223 
PConvPyStrToLexRef(PyObject * obj,OVLexicon * lex,int * lex_ref)224 int PConvPyStrToLexRef(PyObject * obj, OVLexicon * lex, int *lex_ref)
225 {
226   int ok = true;
227   if(!obj) {
228     ok = false;
229   } else if(!PyString_Check(obj)) {
230     ok = false;
231   } else {
232     auto strval = PyString_AsSomeString(obj);
233     if(!strval.c_str()) {
234       ok = false;
235     } else {
236       OVreturn_word result = OVLexicon_GetFromCString(lex, strval.c_str());
237       if(OVreturn_IS_OK(result)) {
238         *lex_ref = result.word;
239       } else {
240         ok = false;
241       }
242     }
243   }
244   return ok;
245 }
246 
247 #ifndef _PYMOL_NOPY
PConvPyStrToStrPtr(PyObject * obj,const char ** ptr)248 int PConvPyStrToStrPtr(PyObject * obj, const char **ptr)
249 {
250   int ok = true;
251   if(!obj) {
252     ok = false;
253   } else if(!PyString_Check(obj)) {
254     ok = false;
255   }
256   if(ok)
257     *ptr = PyString_AsString(obj);
258   return (ok);
259 }
260 #endif
261 
PConvPyStrToStr(PyObject * obj,char * ptr,int size)262 int PConvPyStrToStr(PyObject * obj, char *ptr, int size)
263 {
264   int ok = true;
265   if(!obj) {
266     ok = false;
267 #if PY_MAJOR_VERSION >= 3
268   } else if(PyBytes_Check(obj)) {
269     auto strval = PyBytes_AsSomeString(obj);
270     UtilNCopy(ptr, strval.c_str(), size);
271 #endif
272   } else if(!PyString_Check(obj)) {
273     ok = false;
274     if(size)
275       *ptr = 0;
276   } else {
277     auto strval = PyString_AsSomeString(obj);
278     UtilNCopy(ptr, strval.c_str(), size);
279   }
280   return (ok);
281 }
282 
PConvPyIntToInt(PyObject * obj,int * ptr)283 int PConvPyIntToInt(PyObject * obj, int *ptr)
284 {
285   int ok = true;
286   if(!obj) {
287     ok = false;
288   } else if(PyLong_Check(obj)) {
289     *ptr = (int) PyLong_AsLongLong(obj);
290   } else if(PyInt_Check(obj)) {
291     *ptr = PyInt_AsLong(obj);
292   } else {
293     ok = false;
294   }
295   return (ok);
296 }
297 
PConvPyFloatToFloat(PyObject * obj,float * ptr)298 int PConvPyFloatToFloat(PyObject * obj, float *ptr)
299 {
300   int ok = true;
301   if(!obj) {
302     ok = false;
303   } else if(!PyFloat_Check(obj)) {
304     ok = false;
305   } else {
306     *ptr = (float) PyFloat_AsDouble(obj);
307   }
308   return (ok);
309 }
310 
PConvPyIntToChar(PyObject * obj,char * ptr)311 int PConvPyIntToChar(PyObject * obj, char *ptr)
312 {
313   int ok = true;
314   if(!obj) {
315     ok = false;
316   } else if(!PyInt_Check(obj)) {
317     if(!PyLong_Check(obj)) {
318       ok = false;
319     } else {
320       *ptr = (char) PyLong_AsLongLong(obj);
321     }
322   } else {
323     *ptr = (char) PyInt_AsLong(obj);
324   }
325   return (ok);
326 }
327 
328 
329 /* == end == */
330 
PConvPyObjectToFloat(PyObject * object,float * value)331 int PConvPyObjectToFloat(PyObject * object, float *value)
332 {
333   int result = true;
334   PyObject *tmp;
335   if(!object)
336     result = false;
337   else if(PyFloat_Check(object)) {
338     (*value) = (float) PyFloat_AsDouble(object);
339   } else if(PyLong_Check(object)) {
340     (*value) = (float) PyLong_AsLongLong(object);
341   } else if(PyInt_Check(object)) {
342     (*value) = (float) PyInt_AsLong(object);
343   } else {
344     tmp = PyNumber_Float(object);
345     if(tmp) {
346       (*value) = (float) PyFloat_AsDouble(tmp);
347       Py_DECREF(tmp);
348     } else
349       result = false;
350   }
351   return (result);
352 }
353 
PConvPyObjectToInt(PyObject * object,int * value)354 int PConvPyObjectToInt(PyObject * object, int *value)
355 {
356   int result = true;
357   PyObject *tmp;
358   if(!object) {
359     result = false;
360   } else if(PyLong_Check(object)) {
361     (*value) = (int) PyLong_AsLongLong(object);
362   } else if(PyInt_Check(object)) {
363     (*value) = (int) PyInt_AsLong(object);
364   } else {
365     tmp = PyNumber_Int(object);
366     if(tmp) {
367       (*value) = (int) PyInt_AsLong(tmp);
368       Py_DECREF(tmp);
369     } else
370       result = false;
371   }
372   return (result);
373 }
374 
PConvPyObjectToChar(PyObject * object,char * value)375 int PConvPyObjectToChar(PyObject * object, char *value)
376 {
377   int result = true;
378   PyObject *tmp;
379   if(!object)
380     result = false;
381   else if(PyInt_Check(object)) {
382     (*value) = (char) PyInt_AsLong(object);
383   } else if(PyLong_Check(object)) {
384     (*value) = (char) PyLong_AsLongLong(object);
385   } else {
386     tmp = PyNumber_Int(object);
387     if(tmp) {
388       (*value) = (char) PyInt_AsLong(tmp);
389       Py_DECREF(tmp);
390     } else
391       result = false;
392   }
393   return (result);
394 }
395 
PConvPyObjectToStrMaxLen(PyObject * object,char * value,int ln)396 int PConvPyObjectToStrMaxLen(PyObject * object, char *value, int ln)
397 {
398   PyObject *tmp;
399   int result = true;
400   if(!object) {
401     result = false;
402 #if PY_MAJOR_VERSION >= 3
403   } else if(PyBytes_Check(object)) {
404     auto strval = PyBytes_AsSomeString(object);
405     strncpy(value, strval.c_str(), ln);
406 #endif
407   } else if(PyString_Check(object)) {
408     auto strval = PyString_AsSomeString(object);
409     strncpy(value, strval.c_str(), ln);
410   } else {
411     tmp = PyObject_Str(object);
412     if(tmp) {
413       auto strval = PyString_AsSomeString(tmp);
414       strncpy(value, strval.c_str(), ln);
415       Py_DECREF(tmp);
416     } else
417       result = 0;
418   }
419   if(ln > 0)
420     value[ln] = 0;
421   else
422     value[0] = 0;
423   return (result);
424 }
425 
PConvPyObjectToStrMaxClean(PyObject * object,char * value,int ln)426 int PConvPyObjectToStrMaxClean(PyObject * object, char *value, int ln)
427 {
428   PyObject *tmp;
429   int result = true;
430   if(!object)
431     result = false;
432   else if(PyString_Check(object)) {
433     auto strval = PyString_AsSomeString(object);
434     strncpy(value, strval.c_str(), ln);
435   } else {
436     tmp = PyObject_Str(object);
437     if(tmp) {
438       auto strval = PyString_AsSomeString(tmp);
439       strncpy(value, strval.c_str(), ln);
440       Py_DECREF(tmp);
441     } else
442       result = 0;
443   }
444   if(ln > 0)
445     value[ln] = 0;
446   else
447     value[0] = 0;
448   UtilCleanStr(value);
449   return (result);
450 }
451 
PConvFloatToPyDictItem(PyObject * dict,const char * key,float f)452 PyObject *PConvFloatToPyDictItem(PyObject * dict, const char *key, float f)
453 {
454   PyObject *tmp;
455   tmp = PyFloat_FromDouble((double) f);
456   PyDict_SetItemString(dict, key, tmp);
457   Py_XDECREF(tmp);
458   return (tmp);
459 }
460 
PConvIntToPyDictItem(PyObject * dict,const char * key,int i)461 PyObject *PConvIntToPyDictItem(PyObject * dict, const char *key, int i)
462 {
463   PyObject *tmp;
464   tmp = PyInt_FromLong(i);
465   PyDict_SetItemString(dict, key, tmp);
466   Py_XDECREF(tmp);
467   return (tmp);
468 }
469 
PConvFloat3ToPyObjAttr(PyObject * obj,const char * attr,const float * v)470 void PConvFloat3ToPyObjAttr(PyObject * obj, const char *attr, const float *v)
471 {
472   PyObject *t1, *t2, *t3, *tmp;
473 
474   t1 = PyFloat_FromDouble((double) v[0]);
475   t2 = PyFloat_FromDouble((double) v[1]);
476   t3 = PyFloat_FromDouble((double) v[2]);
477   tmp = PyList_New(3);
478   if(t1 && t2 && t3 && tmp) {
479     PyList_SetItem(tmp, 0, t1); /* steals reference */
480     PyList_SetItem(tmp, 1, t2); /* steals reference */
481     PyList_SetItem(tmp, 2, t3); /* steals reference */
482     PyObject_SetAttrString(obj, attr, tmp);
483   }
484   Py_XDECREF(tmp);
485 }
486 
PConvInt2ToPyObjAttr(PyObject * obj,const char * attr,const int * v)487 void PConvInt2ToPyObjAttr(PyObject * obj, const char *attr, const int *v)
488 {
489   PyObject *t1, *t2, *tmp;
490 
491   t1 = PyInt_FromLong((long) v[0]);
492   t2 = PyInt_FromLong((long) v[1]);
493   tmp = PyList_New(2);
494   if(t1 && t2 && tmp) {
495     PyList_SetItem(tmp, 0, t1); /* steals reference */
496     PyList_SetItem(tmp, 1, t2); /* steals reference */
497     PyObject_SetAttrString(obj, attr, tmp);
498   }
499   Py_XDECREF(tmp);
500 }
501 
PConvFloatToPyObjAttr(PyObject * obj,const char * attr,float f)502 void PConvFloatToPyObjAttr(PyObject * obj, const char *attr, float f)
503 {
504   PyObject *tmp;
505   tmp = PyFloat_FromDouble((double) f);
506   PyObject_SetAttrString(obj, attr, tmp);
507   Py_DECREF(tmp);
508 }
509 
PConvIntToPyObjAttr(PyObject * obj,const char * attr,int i)510 void PConvIntToPyObjAttr(PyObject * obj, const char *attr, int i)
511 {
512   PyObject *tmp;
513   tmp = PyInt_FromLong(i);
514   PyObject_SetAttrString(obj, attr, tmp);
515   Py_DECREF(tmp);
516 }
517 
PConvStringToPyObjAttr(PyObject * obj,const char * attr,const char * f)518 void PConvStringToPyObjAttr(PyObject * obj, const char *attr, const char *f)
519 {
520   PyObject *tmp;
521   tmp = PyString_FromString(f);
522   PyObject_SetAttrString(obj, attr, tmp);
523   Py_DECREF(tmp);
524 }
525 
PConvPyListToFloatArrayImpl(PyObject * obj,float ** f,bool as_vla)526 int PConvPyListToFloatArrayImpl(PyObject * obj, float **f, bool as_vla)
527 {
528   int a, l;
529   int ok = true;
530   float *ff;
531   if(!obj) {
532     *f = NULL;
533     ok = false;
534   } else if (PyBytes_Check(obj)){
535     // binary_dump
536     int slen = PyBytes_Size(obj);
537     l = slen / sizeof(float);
538 
539     if (as_vla) {
540       (*f) = VLAlloc(float, l);
541     } else {
542       (*f) = pymol::malloc<float>(l);
543     }
544 
545     auto strval = PyBytes_AsSomeString(obj);
546     memcpy(*f, strval.data(), slen);
547   } else if(!PyList_Check(obj)) {
548     *f = NULL;
549     ok = false;
550   } else {
551     l = (int) PyList_Size(obj);
552     if(!l)
553       ok = -1;
554     else
555       ok = l;
556 
557     if (as_vla) {
558       (*f) = VLAlloc(float, l);
559     } else {
560       (*f) = pymol::malloc<float>(l);
561     }
562 
563     ff = (*f);
564     for(a = 0; a < l; a++)
565       *(ff++) = (float) PyFloat_AsDouble(PyList_GetItem(obj, a));
566 
567   }
568   return (ok);
569 }
570 
PConvPyListToFloatVLANoneOkay(PyObject * obj,float ** f)571 int PConvPyListToFloatVLANoneOkay(PyObject * obj, float **f)
572 {
573   int a, l;
574   float *ff;
575   int ok = true;
576   if(!obj) {
577     *f = NULL;
578     ok = false;
579   } else if(obj == Py_None) {
580     *f = NULL;
581     ok = true;
582   } else if(!PyList_Check(obj)) {
583     *f = NULL;
584     ok = false;
585   } else {
586     l = PyList_Size(obj);
587     if(!l)
588       ok = -1;
589     else
590       ok = l;
591     (*f) = VLAlloc(float, l);
592     ff = (*f);
593     for(a = 0; a < l; a++)
594       *(ff++) = (float) PyFloat_AsDouble(PyList_GetItem(obj, a));
595     VLASize((*f), float, l);
596   }
597   return (ok);
598 
599 }
600 
PConvPyList3ToFloatVLA(PyObject * obj,float ** f)601 int PConvPyList3ToFloatVLA(PyObject * obj, float **f)
602 {
603   int a, b, l;
604   float *ff;
605   PyObject *triple;
606   int ok = true;
607   if(!obj) {
608     *f = NULL;
609     ok = false;
610   } else if(!PyList_Check(obj)) {
611     *f = NULL;
612     ok = false;
613   } else {
614     l = PyList_Size(obj);
615     if(!l)
616       ok = -1;
617     else
618       ok = l;
619     (*f) = VLAlloc(float, l * 3);
620     ff = (*f);
621     for(a = 0; a < l; a++) {
622       triple = PyList_GetItem(obj, a);
623       ok = PyList_Check(triple);
624       if(ok)
625         ok = (PyList_Size(triple) == 3);
626       if(ok) {
627         for(b = 0; b < 3; b++)
628           *(ff++) = (float) PyFloat_AsDouble(PyList_GetItem(triple, b));
629       } else {
630         ok = false;
631         break;
632       }
633     }
634     VLASize((*f), float, l * 3);
635   }
636   return (ok);
637 }
638 
PConvPyListToDoubleArray(PyObject * obj,double ** f)639 int PConvPyListToDoubleArray(PyObject * obj, double **f)
640 {
641   int a, l;
642   double *ff;
643   int ok = true;
644   if(!obj) {
645     *f = NULL;
646     l = 0;
647   } else if(!PyList_Check(obj)) {
648     *f = NULL;
649     ok = false;
650   } else {
651     l = PyList_Size(obj);
652     if(!l)
653       ok = -1;
654     else
655       ok = l;
656     (*f) = pymol::malloc<double>(l);
657     ff = (*f);
658     for(a = 0; a < l; a++)
659       *(ff++) = PyFloat_AsDouble(PyList_GetItem(obj, a));
660   }
661   return (ok);
662 }
663 
PConvPyListToIntArrayImpl(PyObject * obj,int ** f,bool as_vla)664 int PConvPyListToIntArrayImpl(PyObject * obj, int **f, bool as_vla)
665 {
666   int a, l;
667   int *ff;
668   int ok = true;
669   if(!obj) {
670     *f = NULL;
671     ok = false;
672   } else if (PyBytes_Check(obj)){
673     // binary_dump
674     int slen = PyBytes_Size(obj);
675     l = slen / sizeof(int);
676 
677     if (as_vla) {
678       (*f) = VLAlloc(int, l);
679     } else {
680       (*f) = pymol::malloc<int>(l);
681     }
682 
683     auto strval = PyBytes_AsSomeString(obj);
684     memcpy(*f, strval.data(), slen);
685   } else if(!PyList_Check(obj)) {
686     *f = NULL;
687     ok = false;
688   } else {
689     l = PyList_Size(obj);
690     if(!l)
691       ok = -1;
692     else
693       ok = l;
694 
695     if (as_vla) {
696       (*f) = VLAlloc(int, l);
697     } else {
698       (*f) = pymol::malloc<int>(l);
699     }
700 
701     ff = (*f);
702     for(a = 0; a < l; a++)
703       *(ff++) = PyInt_AsLong(PyList_GetItem(obj, a));
704   }
705   return (ok);
706 }
707 
PConvPyTupleToIntVLA(int ** result,PyObject * tuple)708 ov_status PConvPyTupleToIntVLA(int **result, PyObject * tuple)
709 {
710   ov_status status = OV_STATUS_FAILURE;
711   if(!(tuple && PyTuple_Check(tuple))) {
712     *result = NULL;
713   } else {
714     int *vla = NULL;
715     ov_size size = PyTuple_Size(tuple);
716     vla = VLAlloc(int, size);
717     if(vla) {
718       ov_size i;
719       int *ptr = vla;
720       status = OV_STATUS_SUCCESS;
721       for(i = 0; i < size; i++)
722         *(ptr++) = PyInt_AsLong(PyTuple_GetItem(tuple, i));
723     }
724     *result = vla;
725   }
726   return status;
727 }
728 
PConvPyTupleToFloatVLA(float ** result,PyObject * tuple)729 ov_status PConvPyTupleToFloatVLA(float **result, PyObject * tuple)
730 {
731   ov_status status = OV_STATUS_FAILURE;
732   if(!(tuple && PyTuple_Check(tuple))) {
733     *result = NULL;
734   } else {
735     float *vla = NULL;
736     ov_size size = PyTuple_Size(tuple);
737     vla = VLAlloc(float, size);
738     if(vla) {
739       ov_size i;
740       float *ptr = vla;
741       status = OV_STATUS_SUCCESS;
742       for(i = 0; i < size; i++)
743         *(ptr++) = (float) PyFloat_AsDouble(PyTuple_GetItem(tuple, i));
744     }
745     *result = vla;
746   }
747   return status;
748 }
749 
PConvPyListToDoubleArrayInPlace(PyObject * obj,double * ff,ov_size ll)750 int PConvPyListToDoubleArrayInPlace(PyObject * obj, double *ff, ov_size ll)
751 {
752   int ok = true;
753   ov_size a, l;
754   if(!obj) {
755     ok = false;
756   } else if(!PyList_Check(obj)) {
757     ok = false;
758   } else {
759     l = PyList_Size(obj);
760     if(l != ll)
761       ok = false;
762     else {
763       if(!l)
764         ok = -1;
765       else
766         ok = l;
767       for(a = 0; a < l; a++)
768         *(ff++) = PyFloat_AsDouble(PyList_GetItem(obj, a));
769     }
770     /* NOTE ASSUMPTION! */
771   }
772   return (ok);
773 }
774 
PConvPyListToFloatArrayInPlace(PyObject * obj,float * ff,ov_size ll)775 int PConvPyListToFloatArrayInPlace(PyObject * obj, float *ff, ov_size ll)
776 {
777   int ok = true;
778   ov_size a, l;
779   if(!obj) {
780     ok = false;
781   } else if(!PyList_Check(obj)) {
782     ok = false;
783   } else {
784     l = PyList_Size(obj);
785     if(ll > 0 && l != ll)
786       ok = false;
787     else {
788       if(!l)
789         ok = -1;
790       else
791         ok = l;
792       for(a = 0; a < l; a++)
793         *(ff++) = (float) PyFloat_AsDouble(PyList_GetItem(obj, a));
794     }
795     /* NOTE ASSUMPTION! */
796   }
797   return (ok);
798 }
799 
PConvPyListOrTupleToFloatArrayInPlace(PyObject * obj,float * ff,ov_size ll)800 int PConvPyListOrTupleToFloatArrayInPlace(PyObject * obj, float *ff, ov_size ll)
801 {
802   int ok = true, isTuple = false;
803   ov_size a, l;
804   if(!obj) {
805     ok = false;
806   } else if(!PyList_Check(obj) && !(isTuple=PyTuple_Check(obj))) {
807     ok = false;
808   } else {
809     if (isTuple)
810       l = PyTuple_Size(obj);
811     else
812       l = PyList_Size(obj);
813     if(l != ll)
814       ok = false;
815     else {
816       if(!l)
817         ok = -1;
818       else
819         ok = l;
820       if (isTuple)
821 	for(a = 0; a < l; a++){
822 	  *(ff++) = (float) PyFloat_AsDouble(PyTuple_GetItem(obj, a));
823 	}
824       else
825 	for(a = 0; a < l; a++){
826 	  *(ff++) = (float) PyFloat_AsDouble(PyList_GetItem(obj, a));
827 	}
828     }
829     /* NOTE ASSUMPTION! */
830   }
831   return (ok);
832 }
833 
PConvPyListToIntArrayInPlace(PyObject * obj,int * ii,ov_size ll)834 int PConvPyListToIntArrayInPlace(PyObject * obj, int *ii, ov_size ll)
835 {
836   int ok = true;
837   ov_size a, l;
838   if(!obj)
839     ok = false;
840   else if(!PyList_Check(obj))
841     ok = false;
842   else {
843     l = PyList_Size(obj);
844     if(!l)
845       ok = -1;
846     else
847       ok = l;
848     if(l != ll)
849       ok = false;
850     else
851       for(a = 0; a < l; a++)
852         *(ii++) = PyInt_AsLong(PyList_GetItem(obj, a));
853     /* NOTE ASSUMPTION! */
854   }
855   return (ok);
856 }
857 
PConvPyListToIntArrayInPlaceAutoZero(PyObject * obj,int * ii,ov_size ll)858 int PConvPyListToIntArrayInPlaceAutoZero(PyObject * obj, int *ii, ov_size ll)
859 {
860   int ok = true;
861   ov_size a, l;
862   if(!obj)
863     ok = false;
864   else if(!PyList_Check(obj))
865     ok = false;
866   else {
867     l = PyList_Size(obj);
868     if(!l)
869       ok = -1;
870     else
871       ok = l;
872     for(a = 0; (a < l) && (a < ll); a++)
873       *(ii++) = PyInt_AsLong(PyList_GetItem(obj, a));
874     while(l < ll) {
875       *(ii++) = 0;
876       l++;
877     }
878   }
879   return (ok);
880 }
881 
PConvPyListToSIntArrayInPlaceAutoZero(PyObject * obj,short int * ii,ov_size ll)882 int PConvPyListToSIntArrayInPlaceAutoZero(PyObject * obj, short int *ii, ov_size ll)
883 {
884   int ok = true;
885   ov_size a, l;
886   if(!obj)
887     ok = false;
888   else if(!PyList_Check(obj))
889     ok = false;
890   else {
891     l = PyList_Size(obj);
892     if(!l)
893       ok = -1;
894     else
895       ok = l;
896     for(a = 0; (a < l) && (a < ll); a++)
897       *(ii++) = (short int) PyInt_AsLong(PyList_GetItem(obj, a));
898     while(l < ll) {
899       *(ii++) = 0;
900       l++;
901     }
902   }
903   return (ok);
904 }
905 
PConvPyListToSCharArrayInPlaceAutoZero(PyObject * obj,signed char * ii,ov_size ll)906 int PConvPyListToSCharArrayInPlaceAutoZero(PyObject * obj, signed char *ii, ov_size ll)
907 {
908   int ok = true;
909   ov_size a, l;
910   if(!obj)
911     ok = false;
912   else if(!PyList_Check(obj))
913     ok = false;
914   else {
915     l = PyList_Size(obj);
916     if(!l)
917       ok = -1;
918     else
919       ok = l;
920     for(a = 0; (a < l) && (a < ll); a++)
921       *(ii++) = (signed char) PyInt_AsLong(PyList_GetItem(obj, a));
922     while(l < ll) {
923       *(ii++) = 0;
924       l++;
925     }
926   }
927   return (ok);
928 }
929 
PConvPyListToFloatArrayInPlaceAutoZero(PyObject * obj,float * ii,ov_size ll)930 int PConvPyListToFloatArrayInPlaceAutoZero(PyObject * obj, float *ii, ov_size ll)
931 {
932   int ok = true;
933   ov_size a, l;
934   if(!obj)
935     ok = false;
936   else if(!PyList_Check(obj))
937     ok = false;
938   else {
939     l = PyList_Size(obj);
940     if(!l)
941       ok = -1;
942     else
943       ok = l;
944     for(a = 0; (a < l) && (a < ll); a++)
945       *(ii++) = (float) PyFloat_AsDouble(PyList_GetItem(obj, a));
946     while(l < ll) {
947       *(ii++) = 0.0f;
948       l++;
949     }
950   }
951   return (ok);
952 }
953 
PConvFloatArrayToPyList(const float * f,int l,bool dump_binary)954 PyObject *PConvFloatArrayToPyList(const float *f, int l, bool dump_binary)
955 {
956 #ifndef PICKLETOOLS
957   if (dump_binary){
958     return PyBytes_FromStringAndSize(reinterpret_cast<const char*>(f), l * sizeof(float));
959   }
960 #endif
961   int a;
962   PyObject *result = PyList_New(l);
963   for(a = 0; a < l; a++)
964     PyList_SetItem(result, a, PyFloat_FromDouble((double) *(f++)));
965   return (PConvAutoNone(result));
966 }
967 
PConvFloatArrayToPyListNullOkay(const float * f,int l)968 PyObject *PConvFloatArrayToPyListNullOkay(const float *f, int l)
969 {
970   int a;
971   PyObject *result = NULL;
972   if(f) {
973     result = PyList_New(l);
974     for(a = 0; a < l; a++)
975       PyList_SetItem(result, a, PyFloat_FromDouble((double) *(f++)));
976   }
977   return (PConvAutoNone(result));
978 }
979 
PConvDoubleArrayToPyList(const double * f,int l)980 PyObject *PConvDoubleArrayToPyList(const double *f, int l)
981 {
982   int a;
983   PyObject *result = PyList_New(l);
984   for(a = 0; a < l; a++)
985     PyList_SetItem(result, a, PyFloat_FromDouble(*(f++)));
986   return (PConvAutoNone(result));
987 }
988 
PConvFloatVLAToPyList(const float * f)989 PyObject *PConvFloatVLAToPyList(const float *f)
990 {
991   int a, l;
992   PyObject *result = NULL;
993   l = VLAGetSize(f);
994   result = PyList_New(l);
995   for(a = 0; a < l; a++) {
996     PyList_SetItem(result, a, PyFloat_FromDouble((double) *(f++)));     /* set item steals ref */
997   }
998   return (PConvAutoNone(result));
999 }
1000 
PConvFloatVLAToPyTuple(float * vla)1001 PyObject *PConvFloatVLAToPyTuple(float *vla)
1002 {
1003   PyObject *result = NULL;
1004   if(vla) {
1005     ov_size size = VLAGetSize(vla);
1006     result = PyTuple_New(size);
1007     if(result) {
1008       ov_size i;
1009       for(i = 0; i < size; i++) {
1010         PyTuple_SetItem(result, i, PyFloat_FromDouble((double) *(vla++)));      /* set item steals ref */
1011       }
1012     }
1013   }
1014   return (PConvAutoNone(result));
1015 }
1016 
PConvIntVLAToPyList(const int * f)1017 PyObject *PConvIntVLAToPyList(const int *f)
1018 {
1019   int a, l;
1020   PyObject *result = NULL;
1021   l = VLAGetSize(f);
1022   result = PyList_New(l);
1023   for(a = 0; a < l; a++)
1024     PyList_SetItem(result, a, PyInt_FromLong(*(f++)));
1025   return (PConvAutoNone(result));
1026 }
1027 
PConvIntVLAToPyTuple(int * vla)1028 PyObject *PConvIntVLAToPyTuple(int *vla)
1029 {
1030   PyObject *result = NULL;
1031   if(vla) {
1032     ov_size size = VLAGetSize(vla);
1033     result = PyTuple_New(size);
1034     if(result) {
1035       ov_size i;
1036       for(i = 0; i < size; i++) {
1037         PyTuple_SetItem(result, i, PyInt_FromLong(*(vla++)));   /* set item steals ref */
1038       }
1039     }
1040   }
1041   return (PConvAutoNone(result));
1042 }
1043 
PConvIntArrayToPyList(const int * f,int l,bool dump_binary)1044 PyObject *PConvIntArrayToPyList(const int *f, int l, bool dump_binary)
1045 {
1046 #ifndef PICKLETOOLS
1047   if (dump_binary){
1048     return PyBytes_FromStringAndSize(reinterpret_cast<const char*>(f), l * sizeof(int));
1049   }
1050 #endif
1051   int a;
1052   PyObject *result = PyList_New(l);
1053   for(a = 0; a < l; a++)
1054     PyList_SetItem(result, a, PyInt_FromLong(*(f++)));
1055   return (PConvAutoNone(result));
1056 }
1057 
PConvSIntArrayToPyList(const short int * f,int l)1058 PyObject *PConvSIntArrayToPyList(const short int *f, int l)
1059 {
1060   int a;
1061   PyObject *result = PyList_New(l);
1062   for(a = 0; a < l; a++)
1063     PyList_SetItem(result, a, PyInt_FromLong(*(f++)));
1064   return (PConvAutoNone(result));
1065 }
1066 
PConvSCharArrayToPyList(const signed char * f,int l)1067 PyObject *PConvSCharArrayToPyList(const signed char *f, int l)
1068 {
1069   int a;
1070   PyObject *result = PyList_New(l);
1071   for(a = 0; a < l; a++)
1072     PyList_SetItem(result, a, PyInt_FromLong(*(f++)));
1073   return (PConvAutoNone(result));
1074 }
1075 
PConv3DIntArrayTo3DPyList(int *** array,int * dim)1076 PyObject *PConv3DIntArrayTo3DPyList(int ***array, int *dim)
1077 {
1078   int a, b, c;
1079   PyObject *result, *pyB, *pyC;
1080   result = PyList_New(dim[0]);
1081   for(a = 0; a < dim[0]; a++) {
1082     pyB = PyList_New(dim[1]);
1083     PyList_SetItem(result, a, pyB);
1084     for(b = 0; b < dim[1]; b++) {
1085       pyC = PyList_New(dim[2]);
1086       PyList_SetItem(pyB, b, pyC);
1087       for(c = 0; c < dim[2]; c++) {
1088         PyList_SetItem(pyC, c, PyInt_FromLong(array[a][b][c]));
1089       }
1090     }
1091   }
1092   return (PConvAutoNone(result));
1093 }
1094 
PConvStringListToPyList(int l,const char * const * str)1095 PyObject *PConvStringListToPyList(int l, const char * const *str)
1096 {
1097   int a;
1098   PyObject *result = PyList_New(l);
1099   for(a = 0; a < l; a++) {
1100     PyList_SetItem(result, a, PyString_FromString(str[a]));
1101   }
1102   return (PConvAutoNone(result));
1103 }
1104 
1105 /**
1106  * Converts concatenated null-terminated strings to a list of strings.
1107  */
PConvStringVLAToPyList(const char * vla)1108 PyObject *PConvStringVLAToPyList(const char *vla)
1109 {
1110   int a, c, n = 0;
1111   const char *p;
1112   PyObject *result = NULL;
1113   p = vla;
1114   c = VLAGetSize(vla);
1115   while(c--) {                  /* count strings */
1116     if(!*(p++))
1117       n++;
1118   }
1119 
1120   result = PyList_New(n);
1121   p = vla;
1122   for(a = 0; a < n; a++) {
1123     PyList_SetItem(result, a, PyString_FromString(p));
1124     while(*(p++));
1125   }
1126   return (PConvAutoNone(result));
1127 }
1128 
1129 /**
1130  * Concatenates a list of null-terminated strings (the null-terminator serves as
1131  * the delimiter).
1132  */
PConvPyListToStringVLA(PyObject * obj,char ** vla_ptr)1133 int PConvPyListToStringVLA(PyObject * obj, char **vla_ptr)
1134 {
1135   int a, l, ll;
1136   char *vla = NULL, *q;
1137   PyObject *i;
1138   if(obj)
1139     if(PyList_Check(obj)) {
1140       l = PyList_Size(obj);
1141       ll = 0;
1142       for(a = 0; a < l; a++) {
1143         i = PyList_GetItem(obj, a);
1144         if(PyString_Check(i)) {
1145           ll += PyString_Size(i) + 1;
1146         }
1147       }
1148       vla = VLAlloc(char, ll);
1149       VLASize(vla, char, ll);
1150       q = vla;
1151       for(a = 0; a < l; a++) {
1152         i = PyList_GetItem(obj, a);
1153         if(PyString_Check(i)) {
1154           auto strval = PyString_AsSomeString(i);
1155           auto p = strval.c_str();
1156           while(*p)
1157             *(q++) = *(p++);
1158           *(q++) = 0;
1159         }
1160       }
1161     }
1162   (*vla_ptr) = vla;
1163   return (vla && 1);
1164 }
1165 
PConvPyListToLabPosVLA(PyObject * obj,LabPosType ** vla_ptr)1166 int PConvPyListToLabPosVLA(PyObject * obj, LabPosType ** vla_ptr)
1167 {
1168   int a, l;
1169   int ok = true;
1170   LabPosType *vla = NULL, *q;
1171   PyObject *i;
1172   if(obj)
1173     if(PyList_Check(obj)) {
1174       l = PyList_Size(obj);
1175       vla = VLACalloc(LabPosType, l);
1176       q = vla;
1177       for(a = 0; a < l; a++) {
1178         i = PyList_GetItem(obj, a);
1179         if(PyList_Check(i) && (PyList_Size(i) == 7)) {
1180           ok = ok && PConvPyIntToInt(PyList_GetItem(i, 0), &q->mode) &&
1181             PConvPyFloatToFloat(PyList_GetItem(i, 1), q->pos) &&
1182             PConvPyFloatToFloat(PyList_GetItem(i, 2), q->pos + 1) &&
1183             PConvPyFloatToFloat(PyList_GetItem(i, 3), q->pos + 2) &&
1184             PConvPyFloatToFloat(PyList_GetItem(i, 4), q->offset) &&
1185             PConvPyFloatToFloat(PyList_GetItem(i, 5), q->offset + 1) &&
1186             PConvPyFloatToFloat(PyList_GetItem(i, 6), q->offset + 2);
1187         } else {
1188           VLAFreeP(vla);        /* just in case... */
1189           vla = NULL;
1190           break;
1191         }
1192         q++;
1193       }
1194     }
1195   if(!ok && (!vla)) {
1196     VLAFreeP(vla);
1197   }
1198   (*vla_ptr) = vla;
1199   return (ok);
1200 }
1201 
PConvLabPosVLAToPyList(const LabPosType * vla,int l)1202 PyObject *PConvLabPosVLAToPyList(const LabPosType * vla, int l)
1203 {                               /* TO DO error handling */
1204   int a;
1205   const LabPosType *p = vla;
1206   PyObject *result = NULL;
1207   if(p) {
1208     PyObject *item;
1209     result = PyList_New(l);
1210     for(a = 0; a < l; a++) {
1211       item = PyList_New(7);
1212         PyList_SetItem(item, 0, PyInt_FromLong(p->mode));
1213         PyList_SetItem(item, 1, PyFloat_FromDouble((double) p->pos[0]));
1214         PyList_SetItem(item, 2, PyFloat_FromDouble((double) p->pos[1]));
1215         PyList_SetItem(item, 3, PyFloat_FromDouble((double) p->pos[2]));
1216         PyList_SetItem(item, 4, PyFloat_FromDouble((double) p->offset[0]));
1217         PyList_SetItem(item, 5, PyFloat_FromDouble((double) p->offset[1]));
1218         PyList_SetItem(item, 6, PyFloat_FromDouble((double) p->offset[2]));
1219         PyList_SetItem(result, a, item);
1220       p++;
1221     }
1222   }
1223   return (PConvAutoNone(result));
1224 }
1225 
PConv44PyListTo44f(PyObject * src,float * dest)1226 void PConv44PyListTo44f(PyObject * src, float *dest)
1227 {                               /* note lost of precision */
1228   PyObject *row;
1229   if(src && dest && PyList_Check(src)) {
1230     row = PyList_GetItem(src, 0);
1231     if(row && PyList_Check(row)) {
1232       dest[0] = (float) PyFloat_AsDouble(PyList_GetItem(row, 0));
1233       dest[1] = (float) PyFloat_AsDouble(PyList_GetItem(row, 1));
1234       dest[2] = (float) PyFloat_AsDouble(PyList_GetItem(row, 2));
1235       dest[3] = (float) PyFloat_AsDouble(PyList_GetItem(row, 3));
1236     }
1237     row = PyList_GetItem(src, 1);
1238     if(row && PyList_Check(row)) {
1239       dest[4] = (float) PyFloat_AsDouble(PyList_GetItem(row, 0));
1240       dest[5] = (float) PyFloat_AsDouble(PyList_GetItem(row, 1));
1241       dest[6] = (float) PyFloat_AsDouble(PyList_GetItem(row, 2));
1242       dest[7] = (float) PyFloat_AsDouble(PyList_GetItem(row, 3));
1243     }
1244     row = PyList_GetItem(src, 2);
1245     if(row && PyList_Check(row)) {
1246       dest[8] = (float) PyFloat_AsDouble(PyList_GetItem(row, 0));
1247       dest[9] = (float) PyFloat_AsDouble(PyList_GetItem(row, 1));
1248       dest[10] = (float) PyFloat_AsDouble(PyList_GetItem(row, 2));
1249       dest[11] = (float) PyFloat_AsDouble(PyList_GetItem(row, 3));
1250     }
1251     row = PyList_GetItem(src, 3);
1252     if(row && PyList_Check(row)) {
1253       dest[12] = (float) PyFloat_AsDouble(PyList_GetItem(row, 0));
1254       dest[13] = (float) PyFloat_AsDouble(PyList_GetItem(row, 1));
1255       dest[14] = (float) PyFloat_AsDouble(PyList_GetItem(row, 2));
1256       dest[15] = (float) PyFloat_AsDouble(PyList_GetItem(row, 3));
1257     }
1258   }
1259 }
1260