1*2c1f46dcSZachary Turner //===-- PythonDataObjects.cpp ------------------------------------*- C++ -*-===//
2*2c1f46dcSZachary Turner //
3*2c1f46dcSZachary Turner //                     The LLVM Compiler Infrastructure
4*2c1f46dcSZachary Turner //
5*2c1f46dcSZachary Turner // This file is distributed under the University of Illinois Open Source
6*2c1f46dcSZachary Turner // License. See LICENSE.TXT for details.
7*2c1f46dcSZachary Turner //
8*2c1f46dcSZachary Turner //===----------------------------------------------------------------------===//
9*2c1f46dcSZachary Turner 
10*2c1f46dcSZachary Turner #ifdef LLDB_DISABLE_PYTHON
11*2c1f46dcSZachary Turner 
12*2c1f46dcSZachary Turner // Python is disabled in this build
13*2c1f46dcSZachary Turner 
14*2c1f46dcSZachary Turner #else
15*2c1f46dcSZachary Turner 
16*2c1f46dcSZachary Turner #include "lldb-python.h"
17*2c1f46dcSZachary Turner #include "PythonDataObjects.h"
18*2c1f46dcSZachary Turner #include "ScriptInterpreterPython.h"
19*2c1f46dcSZachary Turner 
20*2c1f46dcSZachary Turner #include "lldb/Core/Stream.h"
21*2c1f46dcSZachary Turner #include "lldb/Host/File.h"
22*2c1f46dcSZachary Turner #include "lldb/Interpreter/ScriptInterpreter.h"
23*2c1f46dcSZachary Turner 
24*2c1f46dcSZachary Turner #include <stdio.h>
25*2c1f46dcSZachary Turner 
26*2c1f46dcSZachary Turner using namespace lldb_private;
27*2c1f46dcSZachary Turner using namespace lldb;
28*2c1f46dcSZachary Turner 
29*2c1f46dcSZachary Turner void
30*2c1f46dcSZachary Turner StructuredPythonObject::Dump(Stream &s) const
31*2c1f46dcSZachary Turner {
32*2c1f46dcSZachary Turner     s << "Python Obj: 0x" << GetValue();
33*2c1f46dcSZachary Turner }
34*2c1f46dcSZachary Turner 
35*2c1f46dcSZachary Turner //----------------------------------------------------------------------
36*2c1f46dcSZachary Turner // PythonObject
37*2c1f46dcSZachary Turner //----------------------------------------------------------------------
38*2c1f46dcSZachary Turner 
39*2c1f46dcSZachary Turner void
40*2c1f46dcSZachary Turner PythonObject::Dump (Stream &strm) const
41*2c1f46dcSZachary Turner {
42*2c1f46dcSZachary Turner     if (m_py_obj)
43*2c1f46dcSZachary Turner     {
44*2c1f46dcSZachary Turner         FILE *file = ::tmpfile();
45*2c1f46dcSZachary Turner         if (file)
46*2c1f46dcSZachary Turner         {
47*2c1f46dcSZachary Turner             ::PyObject_Print (m_py_obj, file, 0);
48*2c1f46dcSZachary Turner             const long length = ftell (file);
49*2c1f46dcSZachary Turner             if (length)
50*2c1f46dcSZachary Turner             {
51*2c1f46dcSZachary Turner                 ::rewind(file);
52*2c1f46dcSZachary Turner                 std::vector<char> file_contents (length,'\0');
53*2c1f46dcSZachary Turner                 const size_t length_read = ::fread (file_contents.data(), 1, file_contents.size(), file);
54*2c1f46dcSZachary Turner                 if (length_read > 0)
55*2c1f46dcSZachary Turner                     strm.Write (file_contents.data(), length_read);
56*2c1f46dcSZachary Turner             }
57*2c1f46dcSZachary Turner             ::fclose (file);
58*2c1f46dcSZachary Turner         }
59*2c1f46dcSZachary Turner     }
60*2c1f46dcSZachary Turner     else
61*2c1f46dcSZachary Turner         strm.PutCString ("NULL");
62*2c1f46dcSZachary Turner }
63*2c1f46dcSZachary Turner 
64*2c1f46dcSZachary Turner PyObjectType
65*2c1f46dcSZachary Turner PythonObject::GetObjectType() const
66*2c1f46dcSZachary Turner {
67*2c1f46dcSZachary Turner     if (IsNULLOrNone())
68*2c1f46dcSZachary Turner         return PyObjectType::None;
69*2c1f46dcSZachary Turner 
70*2c1f46dcSZachary Turner     if (PyList_Check(m_py_obj))
71*2c1f46dcSZachary Turner         return PyObjectType::List;
72*2c1f46dcSZachary Turner     if (PyDict_Check(m_py_obj))
73*2c1f46dcSZachary Turner         return PyObjectType::Dictionary;
74*2c1f46dcSZachary Turner     if (PyString_Check(m_py_obj))
75*2c1f46dcSZachary Turner         return PyObjectType::String;
76*2c1f46dcSZachary Turner     if (PyInt_Check(m_py_obj) || PyLong_Check(m_py_obj))
77*2c1f46dcSZachary Turner         return PyObjectType::Integer;
78*2c1f46dcSZachary Turner     return PyObjectType::Unknown;
79*2c1f46dcSZachary Turner }
80*2c1f46dcSZachary Turner 
81*2c1f46dcSZachary Turner PythonString
82*2c1f46dcSZachary Turner PythonObject::Repr ()
83*2c1f46dcSZachary Turner {
84*2c1f46dcSZachary Turner     if (!m_py_obj)
85*2c1f46dcSZachary Turner         return PythonString ();
86*2c1f46dcSZachary Turner     PyObject *repr = PyObject_Repr(m_py_obj);
87*2c1f46dcSZachary Turner     if (!repr)
88*2c1f46dcSZachary Turner         return PythonString ();
89*2c1f46dcSZachary Turner     return PythonString(repr);
90*2c1f46dcSZachary Turner }
91*2c1f46dcSZachary Turner 
92*2c1f46dcSZachary Turner PythonString
93*2c1f46dcSZachary Turner PythonObject::Str ()
94*2c1f46dcSZachary Turner {
95*2c1f46dcSZachary Turner     if (!m_py_obj)
96*2c1f46dcSZachary Turner         return PythonString ();
97*2c1f46dcSZachary Turner     PyObject *str = PyObject_Str(m_py_obj);
98*2c1f46dcSZachary Turner     if (!str)
99*2c1f46dcSZachary Turner         return PythonString ();
100*2c1f46dcSZachary Turner     return PythonString(str);
101*2c1f46dcSZachary Turner }
102*2c1f46dcSZachary Turner 
103*2c1f46dcSZachary Turner bool
104*2c1f46dcSZachary Turner PythonObject::IsNULLOrNone () const
105*2c1f46dcSZachary Turner {
106*2c1f46dcSZachary Turner     return ((m_py_obj == nullptr) || (m_py_obj == Py_None));
107*2c1f46dcSZachary Turner }
108*2c1f46dcSZachary Turner 
109*2c1f46dcSZachary Turner StructuredData::ObjectSP
110*2c1f46dcSZachary Turner PythonObject::CreateStructuredObject() const
111*2c1f46dcSZachary Turner {
112*2c1f46dcSZachary Turner     switch (GetObjectType())
113*2c1f46dcSZachary Turner     {
114*2c1f46dcSZachary Turner         case PyObjectType::Dictionary:
115*2c1f46dcSZachary Turner             return PythonDictionary(m_py_obj).CreateStructuredDictionary();
116*2c1f46dcSZachary Turner         case PyObjectType::Integer:
117*2c1f46dcSZachary Turner             return PythonInteger(m_py_obj).CreateStructuredInteger();
118*2c1f46dcSZachary Turner         case PyObjectType::List:
119*2c1f46dcSZachary Turner             return PythonList(m_py_obj).CreateStructuredArray();
120*2c1f46dcSZachary Turner         case PyObjectType::String:
121*2c1f46dcSZachary Turner             return PythonString(m_py_obj).CreateStructuredString();
122*2c1f46dcSZachary Turner         case PyObjectType::None:
123*2c1f46dcSZachary Turner             return StructuredData::ObjectSP();
124*2c1f46dcSZachary Turner         default:
125*2c1f46dcSZachary Turner             return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
126*2c1f46dcSZachary Turner     }
127*2c1f46dcSZachary Turner }
128*2c1f46dcSZachary Turner 
129*2c1f46dcSZachary Turner //----------------------------------------------------------------------
130*2c1f46dcSZachary Turner // PythonString
131*2c1f46dcSZachary Turner //----------------------------------------------------------------------
132*2c1f46dcSZachary Turner 
133*2c1f46dcSZachary Turner PythonString::PythonString (PyObject *py_obj) :
134*2c1f46dcSZachary Turner     PythonObject()
135*2c1f46dcSZachary Turner {
136*2c1f46dcSZachary Turner     Reset(py_obj); // Use "Reset()" to ensure that py_obj is a string
137*2c1f46dcSZachary Turner }
138*2c1f46dcSZachary Turner 
139*2c1f46dcSZachary Turner PythonString::PythonString (const PythonObject &object) :
140*2c1f46dcSZachary Turner     PythonObject()
141*2c1f46dcSZachary Turner {
142*2c1f46dcSZachary Turner     Reset(object.get()); // Use "Reset()" to ensure that py_obj is a string
143*2c1f46dcSZachary Turner }
144*2c1f46dcSZachary Turner 
145*2c1f46dcSZachary Turner PythonString::PythonString (llvm::StringRef string) :
146*2c1f46dcSZachary Turner     PythonObject(PyString_FromStringAndSize(string.data(), string.size()))
147*2c1f46dcSZachary Turner {
148*2c1f46dcSZachary Turner }
149*2c1f46dcSZachary Turner 
150*2c1f46dcSZachary Turner PythonString::PythonString(const char *string) :
151*2c1f46dcSZachary Turner     PythonObject(PyString_FromString(string))
152*2c1f46dcSZachary Turner {
153*2c1f46dcSZachary Turner }
154*2c1f46dcSZachary Turner 
155*2c1f46dcSZachary Turner PythonString::PythonString () :
156*2c1f46dcSZachary Turner     PythonObject()
157*2c1f46dcSZachary Turner {
158*2c1f46dcSZachary Turner }
159*2c1f46dcSZachary Turner 
160*2c1f46dcSZachary Turner PythonString::~PythonString ()
161*2c1f46dcSZachary Turner {
162*2c1f46dcSZachary Turner }
163*2c1f46dcSZachary Turner 
164*2c1f46dcSZachary Turner bool
165*2c1f46dcSZachary Turner PythonString::Reset (PyObject *py_obj)
166*2c1f46dcSZachary Turner {
167*2c1f46dcSZachary Turner     if (py_obj && PyString_Check(py_obj))
168*2c1f46dcSZachary Turner         return PythonObject::Reset(py_obj);
169*2c1f46dcSZachary Turner 
170*2c1f46dcSZachary Turner     PythonObject::Reset(nullptr);
171*2c1f46dcSZachary Turner     return py_obj == nullptr;
172*2c1f46dcSZachary Turner }
173*2c1f46dcSZachary Turner 
174*2c1f46dcSZachary Turner llvm::StringRef
175*2c1f46dcSZachary Turner PythonString::GetString() const
176*2c1f46dcSZachary Turner {
177*2c1f46dcSZachary Turner     if (m_py_obj)
178*2c1f46dcSZachary Turner         return llvm::StringRef(PyString_AsString(m_py_obj), GetSize());
179*2c1f46dcSZachary Turner     return llvm::StringRef();
180*2c1f46dcSZachary Turner }
181*2c1f46dcSZachary Turner 
182*2c1f46dcSZachary Turner size_t
183*2c1f46dcSZachary Turner PythonString::GetSize() const
184*2c1f46dcSZachary Turner {
185*2c1f46dcSZachary Turner     if (m_py_obj)
186*2c1f46dcSZachary Turner         return PyString_Size(m_py_obj);
187*2c1f46dcSZachary Turner     return 0;
188*2c1f46dcSZachary Turner }
189*2c1f46dcSZachary Turner 
190*2c1f46dcSZachary Turner void
191*2c1f46dcSZachary Turner PythonString::SetString (llvm::StringRef string)
192*2c1f46dcSZachary Turner {
193*2c1f46dcSZachary Turner     PythonObject::Reset(PyString_FromStringAndSize(string.data(), string.size()));
194*2c1f46dcSZachary Turner }
195*2c1f46dcSZachary Turner 
196*2c1f46dcSZachary Turner StructuredData::StringSP
197*2c1f46dcSZachary Turner PythonString::CreateStructuredString() const
198*2c1f46dcSZachary Turner {
199*2c1f46dcSZachary Turner     StructuredData::StringSP result(new StructuredData::String);
200*2c1f46dcSZachary Turner     result->SetValue(GetString());
201*2c1f46dcSZachary Turner     return result;
202*2c1f46dcSZachary Turner }
203*2c1f46dcSZachary Turner 
204*2c1f46dcSZachary Turner //----------------------------------------------------------------------
205*2c1f46dcSZachary Turner // PythonInteger
206*2c1f46dcSZachary Turner //----------------------------------------------------------------------
207*2c1f46dcSZachary Turner 
208*2c1f46dcSZachary Turner PythonInteger::PythonInteger (PyObject *py_obj) :
209*2c1f46dcSZachary Turner     PythonObject()
210*2c1f46dcSZachary Turner {
211*2c1f46dcSZachary Turner     Reset(py_obj); // Use "Reset()" to ensure that py_obj is a integer type
212*2c1f46dcSZachary Turner }
213*2c1f46dcSZachary Turner 
214*2c1f46dcSZachary Turner PythonInteger::PythonInteger (const PythonObject &object) :
215*2c1f46dcSZachary Turner     PythonObject()
216*2c1f46dcSZachary Turner {
217*2c1f46dcSZachary Turner     Reset(object.get()); // Use "Reset()" to ensure that py_obj is a integer type
218*2c1f46dcSZachary Turner }
219*2c1f46dcSZachary Turner 
220*2c1f46dcSZachary Turner PythonInteger::PythonInteger (int64_t value) :
221*2c1f46dcSZachary Turner     PythonObject()
222*2c1f46dcSZachary Turner {
223*2c1f46dcSZachary Turner     SetInteger (value);
224*2c1f46dcSZachary Turner }
225*2c1f46dcSZachary Turner 
226*2c1f46dcSZachary Turner 
227*2c1f46dcSZachary Turner PythonInteger::~PythonInteger ()
228*2c1f46dcSZachary Turner {
229*2c1f46dcSZachary Turner }
230*2c1f46dcSZachary Turner 
231*2c1f46dcSZachary Turner bool
232*2c1f46dcSZachary Turner PythonInteger::Reset (PyObject *py_obj)
233*2c1f46dcSZachary Turner {
234*2c1f46dcSZachary Turner     if (py_obj)
235*2c1f46dcSZachary Turner     {
236*2c1f46dcSZachary Turner         if (PyInt_Check (py_obj) || PyLong_Check(py_obj))
237*2c1f46dcSZachary Turner             return PythonObject::Reset(py_obj);
238*2c1f46dcSZachary Turner     }
239*2c1f46dcSZachary Turner 
240*2c1f46dcSZachary Turner     PythonObject::Reset(nullptr);
241*2c1f46dcSZachary Turner     return py_obj == nullptr;
242*2c1f46dcSZachary Turner }
243*2c1f46dcSZachary Turner 
244*2c1f46dcSZachary Turner int64_t
245*2c1f46dcSZachary Turner PythonInteger::GetInteger() const
246*2c1f46dcSZachary Turner {
247*2c1f46dcSZachary Turner     if (m_py_obj)
248*2c1f46dcSZachary Turner     {
249*2c1f46dcSZachary Turner         if (PyInt_Check(m_py_obj))
250*2c1f46dcSZachary Turner             return PyInt_AsLong(m_py_obj);
251*2c1f46dcSZachary Turner         else if (PyLong_Check(m_py_obj))
252*2c1f46dcSZachary Turner             return PyLong_AsLongLong(m_py_obj);
253*2c1f46dcSZachary Turner     }
254*2c1f46dcSZachary Turner     return UINT64_MAX;
255*2c1f46dcSZachary Turner }
256*2c1f46dcSZachary Turner 
257*2c1f46dcSZachary Turner void
258*2c1f46dcSZachary Turner PythonInteger::SetInteger (int64_t value)
259*2c1f46dcSZachary Turner {
260*2c1f46dcSZachary Turner     PythonObject::Reset(PyLong_FromLongLong(value));
261*2c1f46dcSZachary Turner }
262*2c1f46dcSZachary Turner 
263*2c1f46dcSZachary Turner StructuredData::IntegerSP
264*2c1f46dcSZachary Turner PythonInteger::CreateStructuredInteger() const
265*2c1f46dcSZachary Turner {
266*2c1f46dcSZachary Turner     StructuredData::IntegerSP result(new StructuredData::Integer);
267*2c1f46dcSZachary Turner     result->SetValue(GetInteger());
268*2c1f46dcSZachary Turner     return result;
269*2c1f46dcSZachary Turner }
270*2c1f46dcSZachary Turner 
271*2c1f46dcSZachary Turner //----------------------------------------------------------------------
272*2c1f46dcSZachary Turner // PythonList
273*2c1f46dcSZachary Turner //----------------------------------------------------------------------
274*2c1f46dcSZachary Turner 
275*2c1f46dcSZachary Turner PythonList::PythonList (bool create_empty) :
276*2c1f46dcSZachary Turner     PythonObject(create_empty ? PyList_New(0) : nullptr)
277*2c1f46dcSZachary Turner {
278*2c1f46dcSZachary Turner }
279*2c1f46dcSZachary Turner 
280*2c1f46dcSZachary Turner PythonList::PythonList (uint32_t count) :
281*2c1f46dcSZachary Turner     PythonObject(PyList_New(count))
282*2c1f46dcSZachary Turner {
283*2c1f46dcSZachary Turner }
284*2c1f46dcSZachary Turner 
285*2c1f46dcSZachary Turner PythonList::PythonList (PyObject *py_obj) :
286*2c1f46dcSZachary Turner     PythonObject()
287*2c1f46dcSZachary Turner {
288*2c1f46dcSZachary Turner     Reset(py_obj); // Use "Reset()" to ensure that py_obj is a list
289*2c1f46dcSZachary Turner }
290*2c1f46dcSZachary Turner 
291*2c1f46dcSZachary Turner 
292*2c1f46dcSZachary Turner PythonList::PythonList (const PythonObject &object) :
293*2c1f46dcSZachary Turner     PythonObject()
294*2c1f46dcSZachary Turner {
295*2c1f46dcSZachary Turner     Reset(object.get()); // Use "Reset()" to ensure that py_obj is a list
296*2c1f46dcSZachary Turner }
297*2c1f46dcSZachary Turner 
298*2c1f46dcSZachary Turner PythonList::~PythonList ()
299*2c1f46dcSZachary Turner {
300*2c1f46dcSZachary Turner }
301*2c1f46dcSZachary Turner 
302*2c1f46dcSZachary Turner bool
303*2c1f46dcSZachary Turner PythonList::Reset (PyObject *py_obj)
304*2c1f46dcSZachary Turner {
305*2c1f46dcSZachary Turner     if (py_obj && PyList_Check(py_obj))
306*2c1f46dcSZachary Turner         return PythonObject::Reset(py_obj);
307*2c1f46dcSZachary Turner 
308*2c1f46dcSZachary Turner     PythonObject::Reset(nullptr);
309*2c1f46dcSZachary Turner     return py_obj == nullptr;
310*2c1f46dcSZachary Turner }
311*2c1f46dcSZachary Turner 
312*2c1f46dcSZachary Turner uint32_t
313*2c1f46dcSZachary Turner PythonList::GetSize() const
314*2c1f46dcSZachary Turner {
315*2c1f46dcSZachary Turner     if (m_py_obj)
316*2c1f46dcSZachary Turner         return PyList_GET_SIZE(m_py_obj);
317*2c1f46dcSZachary Turner     return 0;
318*2c1f46dcSZachary Turner }
319*2c1f46dcSZachary Turner 
320*2c1f46dcSZachary Turner PythonObject
321*2c1f46dcSZachary Turner PythonList::GetItemAtIndex(uint32_t index) const
322*2c1f46dcSZachary Turner {
323*2c1f46dcSZachary Turner     if (m_py_obj)
324*2c1f46dcSZachary Turner         return PythonObject(PyList_GetItem(m_py_obj, index));
325*2c1f46dcSZachary Turner     return PythonObject();
326*2c1f46dcSZachary Turner }
327*2c1f46dcSZachary Turner 
328*2c1f46dcSZachary Turner void
329*2c1f46dcSZachary Turner PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object)
330*2c1f46dcSZachary Turner {
331*2c1f46dcSZachary Turner     if (m_py_obj && object)
332*2c1f46dcSZachary Turner         PyList_SetItem(m_py_obj, index, object.get());
333*2c1f46dcSZachary Turner }
334*2c1f46dcSZachary Turner 
335*2c1f46dcSZachary Turner void
336*2c1f46dcSZachary Turner PythonList::AppendItem (const PythonObject &object)
337*2c1f46dcSZachary Turner {
338*2c1f46dcSZachary Turner     if (m_py_obj && object)
339*2c1f46dcSZachary Turner         PyList_Append(m_py_obj, object.get());
340*2c1f46dcSZachary Turner }
341*2c1f46dcSZachary Turner 
342*2c1f46dcSZachary Turner StructuredData::ArraySP
343*2c1f46dcSZachary Turner PythonList::CreateStructuredArray() const
344*2c1f46dcSZachary Turner {
345*2c1f46dcSZachary Turner     StructuredData::ArraySP result(new StructuredData::Array);
346*2c1f46dcSZachary Turner     uint32_t count = GetSize();
347*2c1f46dcSZachary Turner     for (uint32_t i = 0; i < count; ++i)
348*2c1f46dcSZachary Turner     {
349*2c1f46dcSZachary Turner         PythonObject obj = GetItemAtIndex(i);
350*2c1f46dcSZachary Turner         result->AddItem(obj.CreateStructuredObject());
351*2c1f46dcSZachary Turner     }
352*2c1f46dcSZachary Turner     return result;
353*2c1f46dcSZachary Turner }
354*2c1f46dcSZachary Turner 
355*2c1f46dcSZachary Turner //----------------------------------------------------------------------
356*2c1f46dcSZachary Turner // PythonDictionary
357*2c1f46dcSZachary Turner //----------------------------------------------------------------------
358*2c1f46dcSZachary Turner 
359*2c1f46dcSZachary Turner PythonDictionary::PythonDictionary (bool create_empty) :
360*2c1f46dcSZachary Turner PythonObject(create_empty ? PyDict_New() : nullptr)
361*2c1f46dcSZachary Turner {
362*2c1f46dcSZachary Turner }
363*2c1f46dcSZachary Turner 
364*2c1f46dcSZachary Turner PythonDictionary::PythonDictionary (PyObject *py_obj) :
365*2c1f46dcSZachary Turner     PythonObject(py_obj)
366*2c1f46dcSZachary Turner {
367*2c1f46dcSZachary Turner     Reset(py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
368*2c1f46dcSZachary Turner }
369*2c1f46dcSZachary Turner 
370*2c1f46dcSZachary Turner 
371*2c1f46dcSZachary Turner PythonDictionary::PythonDictionary (const PythonObject &object) :
372*2c1f46dcSZachary Turner     PythonObject()
373*2c1f46dcSZachary Turner {
374*2c1f46dcSZachary Turner     Reset(object.get()); // Use "Reset()" to ensure that py_obj is a dictionary
375*2c1f46dcSZachary Turner }
376*2c1f46dcSZachary Turner 
377*2c1f46dcSZachary Turner PythonDictionary::~PythonDictionary ()
378*2c1f46dcSZachary Turner {
379*2c1f46dcSZachary Turner }
380*2c1f46dcSZachary Turner 
381*2c1f46dcSZachary Turner bool
382*2c1f46dcSZachary Turner PythonDictionary::Reset (PyObject *py_obj)
383*2c1f46dcSZachary Turner {
384*2c1f46dcSZachary Turner     if (py_obj && PyDict_Check(py_obj))
385*2c1f46dcSZachary Turner         return PythonObject::Reset(py_obj);
386*2c1f46dcSZachary Turner 
387*2c1f46dcSZachary Turner     PythonObject::Reset(nullptr);
388*2c1f46dcSZachary Turner     return py_obj == nullptr;
389*2c1f46dcSZachary Turner }
390*2c1f46dcSZachary Turner 
391*2c1f46dcSZachary Turner uint32_t
392*2c1f46dcSZachary Turner PythonDictionary::GetSize() const
393*2c1f46dcSZachary Turner {
394*2c1f46dcSZachary Turner     if (m_py_obj)
395*2c1f46dcSZachary Turner         return PyDict_Size(m_py_obj);
396*2c1f46dcSZachary Turner     return 0;
397*2c1f46dcSZachary Turner }
398*2c1f46dcSZachary Turner 
399*2c1f46dcSZachary Turner PythonObject
400*2c1f46dcSZachary Turner PythonDictionary::GetItemForKey (const char *key) const
401*2c1f46dcSZachary Turner {
402*2c1f46dcSZachary Turner     if (key && key[0])
403*2c1f46dcSZachary Turner     {
404*2c1f46dcSZachary Turner         PythonString python_key(key);
405*2c1f46dcSZachary Turner         return GetItemForKey(python_key);
406*2c1f46dcSZachary Turner     }
407*2c1f46dcSZachary Turner     return PythonObject();
408*2c1f46dcSZachary Turner }
409*2c1f46dcSZachary Turner 
410*2c1f46dcSZachary Turner 
411*2c1f46dcSZachary Turner PythonObject
412*2c1f46dcSZachary Turner PythonDictionary::GetItemForKey (const PythonString &key) const
413*2c1f46dcSZachary Turner {
414*2c1f46dcSZachary Turner     if (m_py_obj && key)
415*2c1f46dcSZachary Turner         return PythonObject(PyDict_GetItem(m_py_obj, key.get()));
416*2c1f46dcSZachary Turner     return PythonObject();
417*2c1f46dcSZachary Turner }
418*2c1f46dcSZachary Turner 
419*2c1f46dcSZachary Turner 
420*2c1f46dcSZachary Turner const char *
421*2c1f46dcSZachary Turner PythonDictionary::GetItemForKeyAsString (const PythonString &key, const char *fail_value) const
422*2c1f46dcSZachary Turner {
423*2c1f46dcSZachary Turner     if (m_py_obj && key)
424*2c1f46dcSZachary Turner     {
425*2c1f46dcSZachary Turner         PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get());
426*2c1f46dcSZachary Turner         if (py_obj && PyString_Check(py_obj))
427*2c1f46dcSZachary Turner             return PyString_AsString(py_obj);
428*2c1f46dcSZachary Turner     }
429*2c1f46dcSZachary Turner     return fail_value;
430*2c1f46dcSZachary Turner }
431*2c1f46dcSZachary Turner 
432*2c1f46dcSZachary Turner int64_t
433*2c1f46dcSZachary Turner PythonDictionary::GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value) const
434*2c1f46dcSZachary Turner {
435*2c1f46dcSZachary Turner     if (m_py_obj && key)
436*2c1f46dcSZachary Turner     {
437*2c1f46dcSZachary Turner         PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get());
438*2c1f46dcSZachary Turner         if (py_obj)
439*2c1f46dcSZachary Turner         {
440*2c1f46dcSZachary Turner             if (PyInt_Check(py_obj))
441*2c1f46dcSZachary Turner                 return PyInt_AsLong(py_obj);
442*2c1f46dcSZachary Turner 
443*2c1f46dcSZachary Turner             if (PyLong_Check(py_obj))
444*2c1f46dcSZachary Turner                 return PyLong_AsLong(py_obj);
445*2c1f46dcSZachary Turner         }
446*2c1f46dcSZachary Turner     }
447*2c1f46dcSZachary Turner     return fail_value;
448*2c1f46dcSZachary Turner }
449*2c1f46dcSZachary Turner 
450*2c1f46dcSZachary Turner PythonList
451*2c1f46dcSZachary Turner PythonDictionary::GetKeys () const
452*2c1f46dcSZachary Turner {
453*2c1f46dcSZachary Turner     if (m_py_obj)
454*2c1f46dcSZachary Turner         return PythonList(PyDict_Keys(m_py_obj));
455*2c1f46dcSZachary Turner     return PythonList(true);
456*2c1f46dcSZachary Turner }
457*2c1f46dcSZachary Turner 
458*2c1f46dcSZachary Turner PythonString
459*2c1f46dcSZachary Turner PythonDictionary::GetKeyAtPosition (uint32_t pos) const
460*2c1f46dcSZachary Turner {
461*2c1f46dcSZachary Turner     PyObject *key, *value;
462*2c1f46dcSZachary Turner     Py_ssize_t pos_iter = 0;
463*2c1f46dcSZachary Turner 
464*2c1f46dcSZachary Turner     if (m_py_obj)
465*2c1f46dcSZachary Turner     {
466*2c1f46dcSZachary Turner         while (PyDict_Next(m_py_obj, &pos_iter, &key, &value))
467*2c1f46dcSZachary Turner         {
468*2c1f46dcSZachary Turner             if (pos-- == 0)
469*2c1f46dcSZachary Turner                 return PythonString(key);
470*2c1f46dcSZachary Turner         }
471*2c1f46dcSZachary Turner     }
472*2c1f46dcSZachary Turner     return PythonString();
473*2c1f46dcSZachary Turner }
474*2c1f46dcSZachary Turner 
475*2c1f46dcSZachary Turner PythonObject
476*2c1f46dcSZachary Turner PythonDictionary::GetValueAtPosition (uint32_t pos) const
477*2c1f46dcSZachary Turner {
478*2c1f46dcSZachary Turner     PyObject *key, *value;
479*2c1f46dcSZachary Turner     Py_ssize_t pos_iter = 0;
480*2c1f46dcSZachary Turner 
481*2c1f46dcSZachary Turner     if (!m_py_obj)
482*2c1f46dcSZachary Turner         return PythonObject();
483*2c1f46dcSZachary Turner 
484*2c1f46dcSZachary Turner     while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) {
485*2c1f46dcSZachary Turner         if (pos-- == 0)
486*2c1f46dcSZachary Turner             return PythonObject(value);
487*2c1f46dcSZachary Turner     }
488*2c1f46dcSZachary Turner     return PythonObject();
489*2c1f46dcSZachary Turner }
490*2c1f46dcSZachary Turner 
491*2c1f46dcSZachary Turner void
492*2c1f46dcSZachary Turner PythonDictionary::SetItemForKey (const PythonString &key, PyObject *value)
493*2c1f46dcSZachary Turner {
494*2c1f46dcSZachary Turner     if (m_py_obj && key && value)
495*2c1f46dcSZachary Turner         PyDict_SetItem(m_py_obj, key.get(), value);
496*2c1f46dcSZachary Turner }
497*2c1f46dcSZachary Turner 
498*2c1f46dcSZachary Turner void
499*2c1f46dcSZachary Turner PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value)
500*2c1f46dcSZachary Turner {
501*2c1f46dcSZachary Turner     if (m_py_obj && key && value)
502*2c1f46dcSZachary Turner         PyDict_SetItem(m_py_obj, key.get(), value.get());
503*2c1f46dcSZachary Turner }
504*2c1f46dcSZachary Turner 
505*2c1f46dcSZachary Turner StructuredData::DictionarySP
506*2c1f46dcSZachary Turner PythonDictionary::CreateStructuredDictionary() const
507*2c1f46dcSZachary Turner {
508*2c1f46dcSZachary Turner     StructuredData::DictionarySP result(new StructuredData::Dictionary);
509*2c1f46dcSZachary Turner     PythonList keys(GetKeys());
510*2c1f46dcSZachary Turner     uint32_t num_keys = keys.GetSize();
511*2c1f46dcSZachary Turner     for (uint32_t i = 0; i < num_keys; ++i)
512*2c1f46dcSZachary Turner     {
513*2c1f46dcSZachary Turner         PythonObject key = keys.GetItemAtIndex(i);
514*2c1f46dcSZachary Turner         PythonString key_str = key.Str();
515*2c1f46dcSZachary Turner         PythonObject value = GetItemForKey(key);
516*2c1f46dcSZachary Turner         StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
517*2c1f46dcSZachary Turner         result->AddItem(key_str.GetString(), structured_value);
518*2c1f46dcSZachary Turner     }
519*2c1f46dcSZachary Turner     return result;
520*2c1f46dcSZachary Turner }
521*2c1f46dcSZachary Turner 
522*2c1f46dcSZachary Turner #endif
523