12c1f46dcSZachary Turner //===-- PythonDataObjects.cpp ------------------------------------*- C++ -*-===// 22c1f46dcSZachary Turner // 32c1f46dcSZachary Turner // The LLVM Compiler Infrastructure 42c1f46dcSZachary Turner // 52c1f46dcSZachary Turner // This file is distributed under the University of Illinois Open Source 62c1f46dcSZachary Turner // License. See LICENSE.TXT for details. 72c1f46dcSZachary Turner // 82c1f46dcSZachary Turner //===----------------------------------------------------------------------===// 92c1f46dcSZachary Turner 102c1f46dcSZachary Turner #ifdef LLDB_DISABLE_PYTHON 112c1f46dcSZachary Turner 122c1f46dcSZachary Turner // Python is disabled in this build 132c1f46dcSZachary Turner 142c1f46dcSZachary Turner #else 152c1f46dcSZachary Turner 162c1f46dcSZachary Turner #include "lldb-python.h" 172c1f46dcSZachary Turner #include "PythonDataObjects.h" 182c1f46dcSZachary Turner #include "ScriptInterpreterPython.h" 192c1f46dcSZachary Turner 202c1f46dcSZachary Turner #include "lldb/Core/Stream.h" 212c1f46dcSZachary Turner #include "lldb/Host/File.h" 222c1f46dcSZachary Turner #include "lldb/Interpreter/ScriptInterpreter.h" 232c1f46dcSZachary Turner 242c1f46dcSZachary Turner #include <stdio.h> 252c1f46dcSZachary Turner 262c1f46dcSZachary Turner using namespace lldb_private; 272c1f46dcSZachary Turner using namespace lldb; 282c1f46dcSZachary Turner 292c1f46dcSZachary Turner void 302c1f46dcSZachary Turner StructuredPythonObject::Dump(Stream &s) const 312c1f46dcSZachary Turner { 322c1f46dcSZachary Turner s << "Python Obj: 0x" << GetValue(); 332c1f46dcSZachary Turner } 342c1f46dcSZachary Turner 352c1f46dcSZachary Turner //---------------------------------------------------------------------- 362c1f46dcSZachary Turner // PythonObject 372c1f46dcSZachary Turner //---------------------------------------------------------------------- 382c1f46dcSZachary Turner 392c1f46dcSZachary Turner void 402c1f46dcSZachary Turner PythonObject::Dump (Stream &strm) const 412c1f46dcSZachary Turner { 422c1f46dcSZachary Turner if (m_py_obj) 432c1f46dcSZachary Turner { 442c1f46dcSZachary Turner FILE *file = ::tmpfile(); 452c1f46dcSZachary Turner if (file) 462c1f46dcSZachary Turner { 472c1f46dcSZachary Turner ::PyObject_Print (m_py_obj, file, 0); 482c1f46dcSZachary Turner const long length = ftell (file); 492c1f46dcSZachary Turner if (length) 502c1f46dcSZachary Turner { 512c1f46dcSZachary Turner ::rewind(file); 522c1f46dcSZachary Turner std::vector<char> file_contents (length,'\0'); 532c1f46dcSZachary Turner const size_t length_read = ::fread (file_contents.data(), 1, file_contents.size(), file); 542c1f46dcSZachary Turner if (length_read > 0) 552c1f46dcSZachary Turner strm.Write (file_contents.data(), length_read); 562c1f46dcSZachary Turner } 572c1f46dcSZachary Turner ::fclose (file); 582c1f46dcSZachary Turner } 592c1f46dcSZachary Turner } 602c1f46dcSZachary Turner else 612c1f46dcSZachary Turner strm.PutCString ("NULL"); 622c1f46dcSZachary Turner } 632c1f46dcSZachary Turner 642c1f46dcSZachary Turner PyObjectType 652c1f46dcSZachary Turner PythonObject::GetObjectType() const 662c1f46dcSZachary Turner { 672c1f46dcSZachary Turner if (IsNULLOrNone()) 682c1f46dcSZachary Turner return PyObjectType::None; 692c1f46dcSZachary Turner 702c1f46dcSZachary Turner if (PyList_Check(m_py_obj)) 712c1f46dcSZachary Turner return PyObjectType::List; 722c1f46dcSZachary Turner if (PyDict_Check(m_py_obj)) 732c1f46dcSZachary Turner return PyObjectType::Dictionary; 74*22c8efcdSZachary Turner if (PyUnicode_Check(m_py_obj)) 75*22c8efcdSZachary Turner return PyObjectType::String; 76*22c8efcdSZachary Turner if (PyLong_Check(m_py_obj)) 77*22c8efcdSZachary Turner return PyObjectType::Integer; 78*22c8efcdSZachary Turner #if PY_MAJOR_VERSION < 3 79*22c8efcdSZachary Turner // These functions don't exist in Python 3.x. PyString is PyUnicode 80*22c8efcdSZachary Turner // and PyInt is PyLong. 812c1f46dcSZachary Turner if (PyString_Check(m_py_obj)) 822c1f46dcSZachary Turner return PyObjectType::String; 83*22c8efcdSZachary Turner if (PyInt_Check(m_py_obj)) 842c1f46dcSZachary Turner return PyObjectType::Integer; 85*22c8efcdSZachary Turner #endif 862c1f46dcSZachary Turner return PyObjectType::Unknown; 872c1f46dcSZachary Turner } 882c1f46dcSZachary Turner 892c1f46dcSZachary Turner PythonString 902c1f46dcSZachary Turner PythonObject::Repr () 912c1f46dcSZachary Turner { 922c1f46dcSZachary Turner if (!m_py_obj) 932c1f46dcSZachary Turner return PythonString (); 942c1f46dcSZachary Turner PyObject *repr = PyObject_Repr(m_py_obj); 952c1f46dcSZachary Turner if (!repr) 962c1f46dcSZachary Turner return PythonString (); 972c1f46dcSZachary Turner return PythonString(repr); 982c1f46dcSZachary Turner } 992c1f46dcSZachary Turner 1002c1f46dcSZachary Turner PythonString 1012c1f46dcSZachary Turner PythonObject::Str () 1022c1f46dcSZachary Turner { 1032c1f46dcSZachary Turner if (!m_py_obj) 1042c1f46dcSZachary Turner return PythonString (); 1052c1f46dcSZachary Turner PyObject *str = PyObject_Str(m_py_obj); 1062c1f46dcSZachary Turner if (!str) 1072c1f46dcSZachary Turner return PythonString (); 1082c1f46dcSZachary Turner return PythonString(str); 1092c1f46dcSZachary Turner } 1102c1f46dcSZachary Turner 1112c1f46dcSZachary Turner bool 1122c1f46dcSZachary Turner PythonObject::IsNULLOrNone () const 1132c1f46dcSZachary Turner { 1142c1f46dcSZachary Turner return ((m_py_obj == nullptr) || (m_py_obj == Py_None)); 1152c1f46dcSZachary Turner } 1162c1f46dcSZachary Turner 1172c1f46dcSZachary Turner StructuredData::ObjectSP 1182c1f46dcSZachary Turner PythonObject::CreateStructuredObject() const 1192c1f46dcSZachary Turner { 1202c1f46dcSZachary Turner switch (GetObjectType()) 1212c1f46dcSZachary Turner { 1222c1f46dcSZachary Turner case PyObjectType::Dictionary: 1232c1f46dcSZachary Turner return PythonDictionary(m_py_obj).CreateStructuredDictionary(); 1242c1f46dcSZachary Turner case PyObjectType::Integer: 1252c1f46dcSZachary Turner return PythonInteger(m_py_obj).CreateStructuredInteger(); 1262c1f46dcSZachary Turner case PyObjectType::List: 1272c1f46dcSZachary Turner return PythonList(m_py_obj).CreateStructuredArray(); 1282c1f46dcSZachary Turner case PyObjectType::String: 1292c1f46dcSZachary Turner return PythonString(m_py_obj).CreateStructuredString(); 1302c1f46dcSZachary Turner case PyObjectType::None: 1312c1f46dcSZachary Turner return StructuredData::ObjectSP(); 1322c1f46dcSZachary Turner default: 1332c1f46dcSZachary Turner return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj)); 1342c1f46dcSZachary Turner } 1352c1f46dcSZachary Turner } 1362c1f46dcSZachary Turner 1372c1f46dcSZachary Turner //---------------------------------------------------------------------- 1382c1f46dcSZachary Turner // PythonString 1392c1f46dcSZachary Turner //---------------------------------------------------------------------- 1402c1f46dcSZachary Turner 1412c1f46dcSZachary Turner PythonString::PythonString (PyObject *py_obj) : 1422c1f46dcSZachary Turner PythonObject() 1432c1f46dcSZachary Turner { 1442c1f46dcSZachary Turner Reset(py_obj); // Use "Reset()" to ensure that py_obj is a string 1452c1f46dcSZachary Turner } 1462c1f46dcSZachary Turner 1472c1f46dcSZachary Turner PythonString::PythonString (const PythonObject &object) : 1482c1f46dcSZachary Turner PythonObject() 1492c1f46dcSZachary Turner { 1502c1f46dcSZachary Turner Reset(object.get()); // Use "Reset()" to ensure that py_obj is a string 1512c1f46dcSZachary Turner } 1522c1f46dcSZachary Turner 153*22c8efcdSZachary Turner PythonString::PythonString(llvm::StringRef string) 154*22c8efcdSZachary Turner : PythonObject() 1552c1f46dcSZachary Turner { 156*22c8efcdSZachary Turner SetString(string); 1572c1f46dcSZachary Turner } 1582c1f46dcSZachary Turner 159*22c8efcdSZachary Turner PythonString::PythonString(const char *string) 160*22c8efcdSZachary Turner : PythonObject() 1612c1f46dcSZachary Turner { 162*22c8efcdSZachary Turner SetString(llvm::StringRef(string)); 1632c1f46dcSZachary Turner } 1642c1f46dcSZachary Turner 1652c1f46dcSZachary Turner PythonString::PythonString () : 1662c1f46dcSZachary Turner PythonObject() 1672c1f46dcSZachary Turner { 1682c1f46dcSZachary Turner } 1692c1f46dcSZachary Turner 1702c1f46dcSZachary Turner PythonString::~PythonString () 1712c1f46dcSZachary Turner { 1722c1f46dcSZachary Turner } 1732c1f46dcSZachary Turner 1742c1f46dcSZachary Turner bool 175*22c8efcdSZachary Turner PythonString::Check(PyObject *py_obj) 176*22c8efcdSZachary Turner { 177*22c8efcdSZachary Turner if (!py_obj) 178*22c8efcdSZachary Turner return false; 179*22c8efcdSZachary Turner #if PY_MAJOR_VERSION >= 3 180*22c8efcdSZachary Turner // Python 3 does not have PyString objects, only PyUnicode. 181*22c8efcdSZachary Turner return PyUnicode_Check(py_obj); 182*22c8efcdSZachary Turner #else 183*22c8efcdSZachary Turner return PyUnicode_Check(py_obj) || PyString_Check(py_obj); 184*22c8efcdSZachary Turner #endif 185*22c8efcdSZachary Turner } 186*22c8efcdSZachary Turner 187*22c8efcdSZachary Turner bool 1882c1f46dcSZachary Turner PythonString::Reset(PyObject *py_obj) 1892c1f46dcSZachary Turner { 190*22c8efcdSZachary Turner if (!PythonString::Check(py_obj)) 191*22c8efcdSZachary Turner { 1922c1f46dcSZachary Turner PythonObject::Reset(nullptr); 193*22c8efcdSZachary Turner return false; 194*22c8efcdSZachary Turner } 195*22c8efcdSZachary Turner 196*22c8efcdSZachary Turner // Convert this to a PyBytes object, and only store the PyBytes. Note that in 197*22c8efcdSZachary Turner // Python 2.x, PyString and PyUnicode are interchangeable, and PyBytes is an alias 198*22c8efcdSZachary Turner // of PyString. So on 2.x, if we get into this branch, we already have a PyBytes. 199*22c8efcdSZachary Turner //#if PY_MAJOR_VERSION >= 3 200*22c8efcdSZachary Turner if (PyUnicode_Check(py_obj)) 201*22c8efcdSZachary Turner { 202*22c8efcdSZachary Turner PyObject *unicode = py_obj; 203*22c8efcdSZachary Turner py_obj = PyUnicode_AsUTF8String(py_obj); 204*22c8efcdSZachary Turner Py_XDECREF(unicode); 205*22c8efcdSZachary Turner } 206*22c8efcdSZachary Turner //#endif 207*22c8efcdSZachary Turner 208*22c8efcdSZachary Turner assert(PyBytes_Check(py_obj) && "PythonString::Reset received a non-string"); 209*22c8efcdSZachary Turner return PythonObject::Reset(py_obj); 2102c1f46dcSZachary Turner } 2112c1f46dcSZachary Turner 2122c1f46dcSZachary Turner llvm::StringRef 2132c1f46dcSZachary Turner PythonString::GetString() const 2142c1f46dcSZachary Turner { 2152c1f46dcSZachary Turner if (m_py_obj) 216*22c8efcdSZachary Turner { 217*22c8efcdSZachary Turner Py_ssize_t size; 218*22c8efcdSZachary Turner char *c; 219*22c8efcdSZachary Turner PyBytes_AsStringAndSize(m_py_obj, &c, &size); 220*22c8efcdSZachary Turner return llvm::StringRef(c, size); 221*22c8efcdSZachary Turner } 2222c1f46dcSZachary Turner return llvm::StringRef(); 2232c1f46dcSZachary Turner } 2242c1f46dcSZachary Turner 2252c1f46dcSZachary Turner size_t 2262c1f46dcSZachary Turner PythonString::GetSize() const 2272c1f46dcSZachary Turner { 2282c1f46dcSZachary Turner if (m_py_obj) 229*22c8efcdSZachary Turner return PyBytes_Size(m_py_obj); 2302c1f46dcSZachary Turner return 0; 2312c1f46dcSZachary Turner } 2322c1f46dcSZachary Turner 2332c1f46dcSZachary Turner void 2342c1f46dcSZachary Turner PythonString::SetString (llvm::StringRef string) 2352c1f46dcSZachary Turner { 236*22c8efcdSZachary Turner #if PY_MAJOR_VERSION >= 3 237*22c8efcdSZachary Turner PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size()); 238*22c8efcdSZachary Turner PyObject *bytes = PyUnicode_AsUTF8String(unicode); 239*22c8efcdSZachary Turner PythonObject::Reset(bytes); 240*22c8efcdSZachary Turner Py_XDECREF(unicode); 241*22c8efcdSZachary Turner #else 2422c1f46dcSZachary Turner PythonObject::Reset(PyString_FromStringAndSize(string.data(), string.size())); 243*22c8efcdSZachary Turner #endif 2442c1f46dcSZachary Turner } 2452c1f46dcSZachary Turner 2462c1f46dcSZachary Turner StructuredData::StringSP 2472c1f46dcSZachary Turner PythonString::CreateStructuredString() const 2482c1f46dcSZachary Turner { 2492c1f46dcSZachary Turner StructuredData::StringSP result(new StructuredData::String); 2502c1f46dcSZachary Turner result->SetValue(GetString()); 2512c1f46dcSZachary Turner return result; 2522c1f46dcSZachary Turner } 2532c1f46dcSZachary Turner 2542c1f46dcSZachary Turner //---------------------------------------------------------------------- 2552c1f46dcSZachary Turner // PythonInteger 2562c1f46dcSZachary Turner //---------------------------------------------------------------------- 2572c1f46dcSZachary Turner 2582c1f46dcSZachary Turner PythonInteger::PythonInteger (PyObject *py_obj) : 2592c1f46dcSZachary Turner PythonObject() 2602c1f46dcSZachary Turner { 2612c1f46dcSZachary Turner Reset(py_obj); // Use "Reset()" to ensure that py_obj is a integer type 2622c1f46dcSZachary Turner } 2632c1f46dcSZachary Turner 2642c1f46dcSZachary Turner PythonInteger::PythonInteger (const PythonObject &object) : 2652c1f46dcSZachary Turner PythonObject() 2662c1f46dcSZachary Turner { 2672c1f46dcSZachary Turner Reset(object.get()); // Use "Reset()" to ensure that py_obj is a integer type 2682c1f46dcSZachary Turner } 2692c1f46dcSZachary Turner 2702c1f46dcSZachary Turner PythonInteger::PythonInteger (int64_t value) : 2712c1f46dcSZachary Turner PythonObject() 2722c1f46dcSZachary Turner { 2732c1f46dcSZachary Turner SetInteger (value); 2742c1f46dcSZachary Turner } 2752c1f46dcSZachary Turner 2762c1f46dcSZachary Turner 2772c1f46dcSZachary Turner PythonInteger::~PythonInteger () 2782c1f46dcSZachary Turner { 2792c1f46dcSZachary Turner } 2802c1f46dcSZachary Turner 2812c1f46dcSZachary Turner bool 282*22c8efcdSZachary Turner PythonInteger::Check(PyObject *py_obj) 2832c1f46dcSZachary Turner { 284*22c8efcdSZachary Turner if (!py_obj) 285*22c8efcdSZachary Turner return false; 286*22c8efcdSZachary Turner 287*22c8efcdSZachary Turner #if PY_MAJOR_VERSION >= 3 288*22c8efcdSZachary Turner // Python 3 does not have PyInt_Check. There is only one type of 289*22c8efcdSZachary Turner // integral value, long. 290*22c8efcdSZachary Turner return PyLong_Check(py_obj); 291*22c8efcdSZachary Turner #else 292*22c8efcdSZachary Turner return PyLong_Check(py_obj) || PyInt_Check(py_obj); 293*22c8efcdSZachary Turner #endif 2942c1f46dcSZachary Turner } 2952c1f46dcSZachary Turner 296*22c8efcdSZachary Turner bool 297*22c8efcdSZachary Turner PythonInteger::Reset(PyObject *py_obj) 298*22c8efcdSZachary Turner { 299*22c8efcdSZachary Turner if (!PythonInteger::Check(py_obj)) 300*22c8efcdSZachary Turner { 3012c1f46dcSZachary Turner PythonObject::Reset(nullptr); 302*22c8efcdSZachary Turner return false; 303*22c8efcdSZachary Turner } 304*22c8efcdSZachary Turner 305*22c8efcdSZachary Turner #if PY_MAJOR_VERSION < 3 306*22c8efcdSZachary Turner // Always store this as a PyLong, which makes interoperability between 307*22c8efcdSZachary Turner // Python 2.x and Python 3.x easier. This is only necessary in 2.x, 308*22c8efcdSZachary Turner // since 3.x doesn't even have a PyInt. 309*22c8efcdSZachary Turner if (PyInt_Check(py_obj)) 310*22c8efcdSZachary Turner { 311*22c8efcdSZachary Turner PyObject *py_long = PyLong_FromLongLong(PyInt_AsLong(py_obj)); 312*22c8efcdSZachary Turner Py_XDECREF(py_obj); 313*22c8efcdSZachary Turner py_obj = py_long; 314*22c8efcdSZachary Turner } 315*22c8efcdSZachary Turner #endif 316*22c8efcdSZachary Turner 317*22c8efcdSZachary Turner assert(PyLong_Check(py_obj) && "Couldn't get a PyLong from this PyObject"); 318*22c8efcdSZachary Turner 319*22c8efcdSZachary Turner return PythonObject::Reset(py_obj); 3202c1f46dcSZachary Turner } 3212c1f46dcSZachary Turner 3222c1f46dcSZachary Turner int64_t 3232c1f46dcSZachary Turner PythonInteger::GetInteger() const 3242c1f46dcSZachary Turner { 3252c1f46dcSZachary Turner if (m_py_obj) 3262c1f46dcSZachary Turner { 327*22c8efcdSZachary Turner assert(PyLong_Check(m_py_obj) && "PythonInteger::GetInteger has a PyObject that isn't a PyLong"); 328*22c8efcdSZachary Turner 3292c1f46dcSZachary Turner return PyLong_AsLongLong(m_py_obj); 3302c1f46dcSZachary Turner } 3312c1f46dcSZachary Turner return UINT64_MAX; 3322c1f46dcSZachary Turner } 3332c1f46dcSZachary Turner 3342c1f46dcSZachary Turner void 3352c1f46dcSZachary Turner PythonInteger::SetInteger (int64_t value) 3362c1f46dcSZachary Turner { 3372c1f46dcSZachary Turner PythonObject::Reset(PyLong_FromLongLong(value)); 3382c1f46dcSZachary Turner } 3392c1f46dcSZachary Turner 3402c1f46dcSZachary Turner StructuredData::IntegerSP 3412c1f46dcSZachary Turner PythonInteger::CreateStructuredInteger() const 3422c1f46dcSZachary Turner { 3432c1f46dcSZachary Turner StructuredData::IntegerSP result(new StructuredData::Integer); 3442c1f46dcSZachary Turner result->SetValue(GetInteger()); 3452c1f46dcSZachary Turner return result; 3462c1f46dcSZachary Turner } 3472c1f46dcSZachary Turner 3482c1f46dcSZachary Turner //---------------------------------------------------------------------- 3492c1f46dcSZachary Turner // PythonList 3502c1f46dcSZachary Turner //---------------------------------------------------------------------- 3512c1f46dcSZachary Turner 352*22c8efcdSZachary Turner PythonList::PythonList() 353*22c8efcdSZachary Turner : PythonObject(PyList_New(0)) 3542c1f46dcSZachary Turner { 3552c1f46dcSZachary Turner } 3562c1f46dcSZachary Turner 3572c1f46dcSZachary Turner PythonList::PythonList (PyObject *py_obj) : 3582c1f46dcSZachary Turner PythonObject() 3592c1f46dcSZachary Turner { 3602c1f46dcSZachary Turner Reset(py_obj); // Use "Reset()" to ensure that py_obj is a list 3612c1f46dcSZachary Turner } 3622c1f46dcSZachary Turner 3632c1f46dcSZachary Turner 3642c1f46dcSZachary Turner PythonList::PythonList (const PythonObject &object) : 3652c1f46dcSZachary Turner PythonObject() 3662c1f46dcSZachary Turner { 3672c1f46dcSZachary Turner Reset(object.get()); // Use "Reset()" to ensure that py_obj is a list 3682c1f46dcSZachary Turner } 3692c1f46dcSZachary Turner 3702c1f46dcSZachary Turner PythonList::~PythonList () 3712c1f46dcSZachary Turner { 3722c1f46dcSZachary Turner } 3732c1f46dcSZachary Turner 3742c1f46dcSZachary Turner bool 375*22c8efcdSZachary Turner PythonList::Check(PyObject *py_obj) 376*22c8efcdSZachary Turner { 377*22c8efcdSZachary Turner if (!py_obj) 378*22c8efcdSZachary Turner return false; 379*22c8efcdSZachary Turner return PyList_Check(py_obj); 380*22c8efcdSZachary Turner } 381*22c8efcdSZachary Turner 382*22c8efcdSZachary Turner bool 3832c1f46dcSZachary Turner PythonList::Reset(PyObject *py_obj) 3842c1f46dcSZachary Turner { 385*22c8efcdSZachary Turner if (!PythonList::Check(py_obj)) 386*22c8efcdSZachary Turner { 3872c1f46dcSZachary Turner PythonObject::Reset(nullptr); 388*22c8efcdSZachary Turner return false; 389*22c8efcdSZachary Turner } 390*22c8efcdSZachary Turner 391*22c8efcdSZachary Turner return PythonObject::Reset(py_obj); 3922c1f46dcSZachary Turner } 3932c1f46dcSZachary Turner 3942c1f46dcSZachary Turner uint32_t 3952c1f46dcSZachary Turner PythonList::GetSize() const 3962c1f46dcSZachary Turner { 3972c1f46dcSZachary Turner if (m_py_obj) 3982c1f46dcSZachary Turner return PyList_GET_SIZE(m_py_obj); 3992c1f46dcSZachary Turner return 0; 4002c1f46dcSZachary Turner } 4012c1f46dcSZachary Turner 4022c1f46dcSZachary Turner PythonObject 4032c1f46dcSZachary Turner PythonList::GetItemAtIndex(uint32_t index) const 4042c1f46dcSZachary Turner { 4052c1f46dcSZachary Turner if (m_py_obj) 4062c1f46dcSZachary Turner return PythonObject(PyList_GetItem(m_py_obj, index)); 4072c1f46dcSZachary Turner return PythonObject(); 4082c1f46dcSZachary Turner } 4092c1f46dcSZachary Turner 4102c1f46dcSZachary Turner void 4112c1f46dcSZachary Turner PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object) 4122c1f46dcSZachary Turner { 4132c1f46dcSZachary Turner if (m_py_obj && object) 4142c1f46dcSZachary Turner PyList_SetItem(m_py_obj, index, object.get()); 4152c1f46dcSZachary Turner } 4162c1f46dcSZachary Turner 4172c1f46dcSZachary Turner void 4182c1f46dcSZachary Turner PythonList::AppendItem (const PythonObject &object) 4192c1f46dcSZachary Turner { 4202c1f46dcSZachary Turner if (m_py_obj && object) 4212c1f46dcSZachary Turner PyList_Append(m_py_obj, object.get()); 4222c1f46dcSZachary Turner } 4232c1f46dcSZachary Turner 4242c1f46dcSZachary Turner StructuredData::ArraySP 4252c1f46dcSZachary Turner PythonList::CreateStructuredArray() const 4262c1f46dcSZachary Turner { 4272c1f46dcSZachary Turner StructuredData::ArraySP result(new StructuredData::Array); 4282c1f46dcSZachary Turner uint32_t count = GetSize(); 4292c1f46dcSZachary Turner for (uint32_t i = 0; i < count; ++i) 4302c1f46dcSZachary Turner { 4312c1f46dcSZachary Turner PythonObject obj = GetItemAtIndex(i); 4322c1f46dcSZachary Turner result->AddItem(obj.CreateStructuredObject()); 4332c1f46dcSZachary Turner } 4342c1f46dcSZachary Turner return result; 4352c1f46dcSZachary Turner } 4362c1f46dcSZachary Turner 4372c1f46dcSZachary Turner //---------------------------------------------------------------------- 4382c1f46dcSZachary Turner // PythonDictionary 4392c1f46dcSZachary Turner //---------------------------------------------------------------------- 4402c1f46dcSZachary Turner 441*22c8efcdSZachary Turner PythonDictionary::PythonDictionary() 442*22c8efcdSZachary Turner : PythonObject(PyDict_New()) 4432c1f46dcSZachary Turner { 4442c1f46dcSZachary Turner } 4452c1f46dcSZachary Turner 4462c1f46dcSZachary Turner PythonDictionary::PythonDictionary (PyObject *py_obj) : 4472c1f46dcSZachary Turner PythonObject(py_obj) 4482c1f46dcSZachary Turner { 4492c1f46dcSZachary Turner Reset(py_obj); // Use "Reset()" to ensure that py_obj is a dictionary 4502c1f46dcSZachary Turner } 4512c1f46dcSZachary Turner 4522c1f46dcSZachary Turner 4532c1f46dcSZachary Turner PythonDictionary::PythonDictionary (const PythonObject &object) : 4542c1f46dcSZachary Turner PythonObject() 4552c1f46dcSZachary Turner { 4562c1f46dcSZachary Turner Reset(object.get()); // Use "Reset()" to ensure that py_obj is a dictionary 4572c1f46dcSZachary Turner } 4582c1f46dcSZachary Turner 4592c1f46dcSZachary Turner PythonDictionary::~PythonDictionary () 4602c1f46dcSZachary Turner { 4612c1f46dcSZachary Turner } 4622c1f46dcSZachary Turner 4632c1f46dcSZachary Turner bool 464*22c8efcdSZachary Turner PythonDictionary::Check(PyObject *py_obj) 465*22c8efcdSZachary Turner { 466*22c8efcdSZachary Turner if (!py_obj) 467*22c8efcdSZachary Turner return false; 468*22c8efcdSZachary Turner 469*22c8efcdSZachary Turner return PyDict_Check(py_obj); 470*22c8efcdSZachary Turner } 471*22c8efcdSZachary Turner 472*22c8efcdSZachary Turner bool 4732c1f46dcSZachary Turner PythonDictionary::Reset(PyObject *py_obj) 4742c1f46dcSZachary Turner { 475*22c8efcdSZachary Turner if (!PythonDictionary::Check(py_obj)) 476*22c8efcdSZachary Turner { 4772c1f46dcSZachary Turner PythonObject::Reset(nullptr); 478*22c8efcdSZachary Turner return false; 479*22c8efcdSZachary Turner } 480*22c8efcdSZachary Turner 481*22c8efcdSZachary Turner return PythonObject::Reset(py_obj); 4822c1f46dcSZachary Turner } 4832c1f46dcSZachary Turner 4842c1f46dcSZachary Turner uint32_t 4852c1f46dcSZachary Turner PythonDictionary::GetSize() const 4862c1f46dcSZachary Turner { 4872c1f46dcSZachary Turner if (m_py_obj) 4882c1f46dcSZachary Turner return PyDict_Size(m_py_obj); 4892c1f46dcSZachary Turner return 0; 4902c1f46dcSZachary Turner } 4912c1f46dcSZachary Turner 4922c1f46dcSZachary Turner PythonObject 4932c1f46dcSZachary Turner PythonDictionary::GetItemForKey (const char *key) const 4942c1f46dcSZachary Turner { 4952c1f46dcSZachary Turner if (key && key[0]) 4962c1f46dcSZachary Turner { 4972c1f46dcSZachary Turner PythonString python_key(key); 4982c1f46dcSZachary Turner return GetItemForKey(python_key); 4992c1f46dcSZachary Turner } 5002c1f46dcSZachary Turner return PythonObject(); 5012c1f46dcSZachary Turner } 5022c1f46dcSZachary Turner 5032c1f46dcSZachary Turner 5042c1f46dcSZachary Turner PythonObject 5052c1f46dcSZachary Turner PythonDictionary::GetItemForKey (const PythonString &key) const 5062c1f46dcSZachary Turner { 5072c1f46dcSZachary Turner if (m_py_obj && key) 5082c1f46dcSZachary Turner return PythonObject(PyDict_GetItem(m_py_obj, key.get())); 5092c1f46dcSZachary Turner return PythonObject(); 5102c1f46dcSZachary Turner } 5112c1f46dcSZachary Turner 5122c1f46dcSZachary Turner 5132c1f46dcSZachary Turner const char * 5142c1f46dcSZachary Turner PythonDictionary::GetItemForKeyAsString (const PythonString &key, const char *fail_value) const 5152c1f46dcSZachary Turner { 5162c1f46dcSZachary Turner if (m_py_obj && key) 5172c1f46dcSZachary Turner { 5182c1f46dcSZachary Turner PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get()); 519*22c8efcdSZachary Turner if (py_obj && PythonString::Check(py_obj)) 520*22c8efcdSZachary Turner { 521*22c8efcdSZachary Turner PythonString str(py_obj); 522*22c8efcdSZachary Turner return str.GetString().data(); 523*22c8efcdSZachary Turner } 5242c1f46dcSZachary Turner } 5252c1f46dcSZachary Turner return fail_value; 5262c1f46dcSZachary Turner } 5272c1f46dcSZachary Turner 5282c1f46dcSZachary Turner int64_t 5292c1f46dcSZachary Turner PythonDictionary::GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value) const 5302c1f46dcSZachary Turner { 5312c1f46dcSZachary Turner if (m_py_obj && key) 5322c1f46dcSZachary Turner { 5332c1f46dcSZachary Turner PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get()); 534*22c8efcdSZachary Turner if (PythonInteger::Check(py_obj)) 5352c1f46dcSZachary Turner { 536*22c8efcdSZachary Turner PythonInteger int_obj(py_obj); 537*22c8efcdSZachary Turner return int_obj.GetInteger(); 5382c1f46dcSZachary Turner } 5392c1f46dcSZachary Turner } 5402c1f46dcSZachary Turner return fail_value; 5412c1f46dcSZachary Turner } 5422c1f46dcSZachary Turner 5432c1f46dcSZachary Turner PythonList 5442c1f46dcSZachary Turner PythonDictionary::GetKeys () const 5452c1f46dcSZachary Turner { 5462c1f46dcSZachary Turner if (m_py_obj) 5472c1f46dcSZachary Turner return PythonList(PyDict_Keys(m_py_obj)); 548*22c8efcdSZachary Turner return PythonList(); 5492c1f46dcSZachary Turner } 5502c1f46dcSZachary Turner 5512c1f46dcSZachary Turner PythonString 5522c1f46dcSZachary Turner PythonDictionary::GetKeyAtPosition (uint32_t pos) const 5532c1f46dcSZachary Turner { 5542c1f46dcSZachary Turner PyObject *key, *value; 5552c1f46dcSZachary Turner Py_ssize_t pos_iter = 0; 5562c1f46dcSZachary Turner 5572c1f46dcSZachary Turner if (m_py_obj) 5582c1f46dcSZachary Turner { 5592c1f46dcSZachary Turner while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) 5602c1f46dcSZachary Turner { 5612c1f46dcSZachary Turner if (pos-- == 0) 5622c1f46dcSZachary Turner return PythonString(key); 5632c1f46dcSZachary Turner } 5642c1f46dcSZachary Turner } 5652c1f46dcSZachary Turner return PythonString(); 5662c1f46dcSZachary Turner } 5672c1f46dcSZachary Turner 5682c1f46dcSZachary Turner PythonObject 5692c1f46dcSZachary Turner PythonDictionary::GetValueAtPosition (uint32_t pos) const 5702c1f46dcSZachary Turner { 5712c1f46dcSZachary Turner PyObject *key, *value; 5722c1f46dcSZachary Turner Py_ssize_t pos_iter = 0; 5732c1f46dcSZachary Turner 5742c1f46dcSZachary Turner if (!m_py_obj) 5752c1f46dcSZachary Turner return PythonObject(); 5762c1f46dcSZachary Turner 5772c1f46dcSZachary Turner while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) { 5782c1f46dcSZachary Turner if (pos-- == 0) 5792c1f46dcSZachary Turner return PythonObject(value); 5802c1f46dcSZachary Turner } 5812c1f46dcSZachary Turner return PythonObject(); 5822c1f46dcSZachary Turner } 5832c1f46dcSZachary Turner 5842c1f46dcSZachary Turner void 5852c1f46dcSZachary Turner PythonDictionary::SetItemForKey (const PythonString &key, PyObject *value) 5862c1f46dcSZachary Turner { 5872c1f46dcSZachary Turner if (m_py_obj && key && value) 5882c1f46dcSZachary Turner PyDict_SetItem(m_py_obj, key.get(), value); 5892c1f46dcSZachary Turner } 5902c1f46dcSZachary Turner 5912c1f46dcSZachary Turner void 5922c1f46dcSZachary Turner PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value) 5932c1f46dcSZachary Turner { 5942c1f46dcSZachary Turner if (m_py_obj && key && value) 5952c1f46dcSZachary Turner PyDict_SetItem(m_py_obj, key.get(), value.get()); 5962c1f46dcSZachary Turner } 5972c1f46dcSZachary Turner 5982c1f46dcSZachary Turner StructuredData::DictionarySP 5992c1f46dcSZachary Turner PythonDictionary::CreateStructuredDictionary() const 6002c1f46dcSZachary Turner { 6012c1f46dcSZachary Turner StructuredData::DictionarySP result(new StructuredData::Dictionary); 6022c1f46dcSZachary Turner PythonList keys(GetKeys()); 6032c1f46dcSZachary Turner uint32_t num_keys = keys.GetSize(); 6042c1f46dcSZachary Turner for (uint32_t i = 0; i < num_keys; ++i) 6052c1f46dcSZachary Turner { 6062c1f46dcSZachary Turner PythonObject key = keys.GetItemAtIndex(i); 6072c1f46dcSZachary Turner PythonString key_str = key.Str(); 6082c1f46dcSZachary Turner PythonObject value = GetItemForKey(key); 6092c1f46dcSZachary Turner StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); 6102c1f46dcSZachary Turner result->AddItem(key_str.GetString(), structured_value); 6112c1f46dcSZachary Turner } 6122c1f46dcSZachary Turner return result; 6132c1f46dcSZachary Turner } 6142c1f46dcSZachary Turner 6152c1f46dcSZachary Turner #endif 616