diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:06:56 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:06:56 +0000 | 
| commit | 7fed546d1996271dabc7cf71d4d033125c4da4ee (patch) | |
| tree | 2b6dc7dcb4a6380cb331aded15f5a81c0038e194 /source/Plugins/ScriptInterpreter/Python | |
| parent | 9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (diff) | |
Notes
Diffstat (limited to 'source/Plugins/ScriptInterpreter/Python')
3 files changed, 144 insertions, 3 deletions
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index 3107677ee948..23bacc932c03 100644 --- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -77,6 +77,10 @@ PythonObject::GetObjectType() const          return PyObjectType::Dictionary;      if (PythonString::Check(m_py_obj))          return PyObjectType::String; +#if PY_MAJOR_VERSION >= 3 +    if (PythonBytes::Check(m_py_obj)) +        return PyObjectType::Bytes; +#endif      if (PythonInteger::Check(m_py_obj))          return PyObjectType::Integer;      if (PythonFile::Check(m_py_obj)) @@ -210,6 +214,8 @@ PythonObject::CreateStructuredObject() const              return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();          case PyObjectType::String:              return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); +        case PyObjectType::Bytes: +            return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();          case PyObjectType::None:              return StructuredData::ObjectSP();          default: @@ -220,6 +226,104 @@ PythonObject::CreateStructuredObject() const  //----------------------------------------------------------------------  // PythonString  //---------------------------------------------------------------------- +PythonBytes::PythonBytes() : PythonObject() +{ +} + +PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() +{ +    SetBytes(bytes); +} + +PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() +{ +    SetBytes(llvm::ArrayRef<uint8_t>(bytes, length)); +} + +PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() +{ +    Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string +} + +PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object) +{ +} + +PythonBytes::~PythonBytes() +{ +} + +bool +PythonBytes::Check(PyObject *py_obj) +{ +    if (!py_obj) +        return false; +    if (PyBytes_Check(py_obj)) +        return true; +    return false; +} + +void +PythonBytes::Reset(PyRefType type, PyObject *py_obj) +{ +    // Grab the desired reference type so that if we end up rejecting +    // `py_obj` it still gets decremented if necessary. +    PythonObject result(type, py_obj); + +    if (!PythonBytes::Check(py_obj)) +    { +        PythonObject::Reset(); +        return; +    } + +    // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls +    // back into the virtual implementation. +    PythonObject::Reset(PyRefType::Borrowed, result.get()); +} + +llvm::ArrayRef<uint8_t> +PythonBytes::GetBytes() const +{ +    if (!IsValid()) +        return llvm::ArrayRef<uint8_t>(); + +    Py_ssize_t size; +    char *c; + +    PyBytes_AsStringAndSize(m_py_obj, &c, &size); +    return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size); +} + +size_t +PythonBytes::GetSize() const +{ +    if (!IsValid()) +        return 0; +    return PyBytes_Size(m_py_obj); +} + +void +PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) +{ +    const char *data = reinterpret_cast<const char *>(bytes.data()); +    PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size()); +    PythonObject::Reset(PyRefType::Owned, py_bytes); +} + +StructuredData::StringSP +PythonBytes::CreateStructuredString() const +{ +    StructuredData::StringSP result(new StructuredData::String); +    Py_ssize_t size; +    char *c; +    PyBytes_AsStringAndSize(m_py_obj, &c, &size); +    result->SetValue(std::string(c, size)); +    return result; +} + +//---------------------------------------------------------------------- +// PythonString +//----------------------------------------------------------------------  PythonString::PythonString(PyRefType type, PyObject *py_obj)      : PythonObject() diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index c9d17c0f0fad..06264b66c283 100644 --- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -23,8 +23,11 @@  #include "lldb/Host/File.h"  #include "lldb/Interpreter/OptionValue.h" +#include "llvm/ADT/ArrayRef.h" +  namespace lldb_private { +class PythonBytes;  class PythonString;  class PythonList;  class PythonDictionary; @@ -71,6 +74,7 @@ enum class PyObjectType      Dictionary,      List,      String, +    Bytes,      Module,      Callable,      Tuple, @@ -256,6 +260,39 @@ protected:      PyObject* m_py_obj;  }; +class PythonBytes : public PythonObject +{ +public: +    PythonBytes(); +    explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); +    PythonBytes(const uint8_t *bytes, size_t length); +    PythonBytes(PyRefType type, PyObject *o); +    PythonBytes(const PythonBytes &object); + +    ~PythonBytes() override; + +    static bool +    Check(PyObject *py_obj); + +    // Bring in the no-argument base class version +    using PythonObject::Reset; + +    void +    Reset(PyRefType type, PyObject *py_obj) override; + +    llvm::ArrayRef<uint8_t> +    GetBytes() const; + +    size_t +    GetSize() const; + +    void +    SetBytes(llvm::ArrayRef<uint8_t> stringbytes); + +    StructuredData::StringSP +    CreateStructuredString() const; +}; +  class PythonString : public PythonObject  {  public: diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index b1dd34b46f69..19ad86db240a 100644 --- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1692,10 +1692,10 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData(StructuredData::ObjectSP o          PyErr_Clear();      } -    assert(PythonString::Check(py_return.get()) && "get_register_data returned unknown object type!"); +    assert(PythonBytes::Check(py_return.get()) && "get_register_data returned unknown object type!"); -    PythonString result_string(PyRefType::Borrowed, py_return.get()); -    return result_string.CreateStructuredString(); +    PythonBytes result(PyRefType::Borrowed, py_return.get()); +    return result.CreateStructuredString();  }  StructuredData::DictionarySP  | 
