Mercurial > pytave
diff oct-py-types.cc @ 325:fd5881d48238
Overhaul Python string creation and extraction
* oct-py-types.cc, oct-py-types.h (pytave::extract_py_str, pytave::make_py_str):
New functions to create a Python string and extract string value from Python.
(pytave::make_py_dict): Use make_py_str.
* octave_to_python.cc (pytave::octvalue_to_pyobj): Use make_py_str.
(pytave::octstring_to_pyobject): Delete.
* python_to_octave.cc (pytave::pyobj_to_octvalue): Use extract_py_str.
(pytave::pyunicode_to_utf8): Delete.
author | Mike Miller <mtmiller@octave.org> |
---|---|
date | Sat, 13 Aug 2016 19:29:47 -0700 |
parents | c2aa34730dc9 |
children | 5782d7932529 |
line wrap: on
line diff
--- a/oct-py-types.cc Fri Aug 12 00:57:46 2016 -0700 +++ b/oct-py-types.cc Sat Aug 13 19:29:47 2016 -0700 @@ -27,6 +27,7 @@ #include <octave/oct-map.h> #include <octave/quit.h> +#include "exceptions.h" #include "oct-py-types.h" // FIXME: only here to bootstrap nested conversions needed in this file @@ -54,7 +55,10 @@ for (auto p = map.begin (); p != map.end (); ++p) { - PyObject *key = wrap_octvalue_to_pyobj (map.key (p)); + PyObject *key = make_py_str (map.key (p)); + if (! key) + octave_throw_bad_alloc (); + PyObject *item = wrap_octvalue_to_pyobj (map.contents (p)); if (PyDict_SetItem (dict, key, item) < 0) @@ -64,4 +68,47 @@ return dict; } +std::string +extract_py_str (PyObject *obj) +{ + std::string retval; + + if (! obj) + throw object_convert_exception ("failed to extract string: null object"); + if (PyBytes_Check (obj)) + { + retval.assign (PyBytes_AsString (obj), PyBytes_Size (obj)); + } + else if (PyUnicode_Check (obj)) + { + bool ok = false; + PyObject *enc = PyUnicode_AsUTF8String (obj); + if (enc) + { + if (PyBytes_Check (enc)) + { + ok = true; + retval.assign (PyBytes_AsString (enc), PyBytes_Size (enc)); + } + Py_DECREF (enc); + } + if (! ok) + throw object_convert_exception ("failed to extract string: UTF-8 error"); + } + else + throw object_convert_exception ("failed to extract string: wrong type"); + + return retval; } + +PyObject * +make_py_str (const std::string& str) +{ +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_FromStringAndSize (str.data (), str.size ()); +#else + return PyString_FromStringAndSize (str.data (), str.size ()); +#endif +} + +}