summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/scripts/Python/python-typemaps.swig20
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp85
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h34
-rw-r--r--lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp14
4 files changed, 147 insertions, 6 deletions
diff --git a/lldb/scripts/Python/python-typemaps.swig b/lldb/scripts/Python/python-typemaps.swig
index a09a0b7083b..566da4d6daf 100644
--- a/lldb/scripts/Python/python-typemaps.swig
+++ b/lldb/scripts/Python/python-typemaps.swig
@@ -113,13 +113,21 @@
// typemap for an outgoing buffer
// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).
%typemap(in) (const char *cstr, uint32_t cstr_len) {
- if (PyString_Check($input)) {
- $1 = (char *) PyString_AsString($input);
- $2 = PyString_Size($input);
+ using namespace lldb_private;
+ if (PythonString::Check($input)) {
+ PythonString str(PyRefType::Borrowed, $input);
+ $1 = (char*)str.GetString().data();
+ $2 = str.GetSize();
}
- else if(PyByteArray_Check($input)) {
- $1 = (char *) PyByteArray_AsString($input);
- $2 = PyByteArray_Size($input);
+ else if(PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (char*)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
+ }
+ else if (PythonBytes::Check($input)) {
+ PythonBytes bytes(PyRefType::Borrowed, $input);
+ $1 = (char*)bytes.GetBytes().data();
+ $2 = bytes.GetSize();
}
else {
PyErr_SetString(PyExc_ValueError, "Expecting a string");
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index f0db8a67ff7..5c7d79e3c6b 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -83,6 +83,8 @@ PythonObject::GetObjectType() const
if (PythonBytes::Check(m_py_obj))
return PyObjectType::Bytes;
#endif
+ if (PythonByteArray::Check(m_py_obj))
+ return PyObjectType::ByteArray;
if (PythonInteger::Check(m_py_obj))
return PyObjectType::Integer;
if (PythonFile::Check(m_py_obj))
@@ -218,6 +220,8 @@ PythonObject::CreateStructuredObject() const
return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
case PyObjectType::Bytes:
return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
+ case PyObjectType::ByteArray:
+ return PythonByteArray(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
case PyObjectType::None:
return StructuredData::ObjectSP();
default:
@@ -323,6 +327,87 @@ PythonBytes::CreateStructuredString() const
return result;
}
+PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes) : PythonByteArray(bytes.data(), bytes.size())
+{
+}
+
+PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length)
+{
+ const char *str = reinterpret_cast<const char *>(bytes);
+ Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
+}
+
+PythonByteArray::PythonByteArray(PyRefType type, PyObject *o)
+{
+ Reset(type, o);
+}
+
+PythonByteArray::PythonByteArray(const PythonBytes &object) : PythonObject(object)
+{
+}
+
+PythonByteArray::~PythonByteArray()
+{
+}
+
+bool
+PythonByteArray::Check(PyObject *py_obj)
+{
+ if (!py_obj)
+ return false;
+ if (PyByteArray_Check(py_obj))
+ return true;
+ return false;
+}
+
+void
+PythonByteArray::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 (!PythonByteArray::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>
+PythonByteArray::GetBytes() const
+{
+ if (!IsValid())
+ return llvm::ArrayRef<uint8_t>();
+
+ char *c = PyByteArray_AsString(m_py_obj);
+ size_t size = GetSize();
+ return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
+}
+
+size_t
+PythonByteArray::GetSize() const
+{
+ if (!IsValid())
+ return 0;
+
+ return PyByteArray_Size(m_py_obj);
+}
+
+StructuredData::StringSP
+PythonByteArray::CreateStructuredString() const
+{
+ StructuredData::StringSP result(new StructuredData::String);
+ llvm::ArrayRef<uint8_t> bytes = GetBytes();
+ const char *str = reinterpret_cast<const char *>(bytes.data());
+ result->SetValue(std::string(str, bytes.size()));
+ return result;
+}
+
//----------------------------------------------------------------------
// PythonString
//----------------------------------------------------------------------
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 6d5a11bd7d9..2bcb967cef6 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -75,6 +75,7 @@ enum class PyObjectType
List,
String,
Bytes,
+ ByteArray,
Module,
Callable,
Tuple,
@@ -293,6 +294,39 @@ public:
CreateStructuredString() const;
};
+class PythonByteArray : public PythonObject
+{
+public:
+ PythonByteArray();
+ explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
+ PythonByteArray(const uint8_t *bytes, size_t length);
+ PythonByteArray(PyRefType type, PyObject *o);
+ PythonByteArray(const PythonBytes &object);
+
+ ~PythonByteArray() 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/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
index 605f0233e87..e2b40d5f602 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -224,6 +224,20 @@ TEST_F(PythonDataObjectsTest, TestPythonBytes)
EXPECT_EQ(0, ::memcmp(bytes.data(), test_bytes, bytes.size()));
}
+TEST_F(PythonDataObjectsTest, TestPythonByteArray)
+{
+ static const char *test_bytes = "PythonDataObjectsTest::TestPythonByteArray";
+ llvm::StringRef orig_bytes(test_bytes);
+ PyObject *py_bytes = PyByteArray_FromStringAndSize(test_bytes, orig_bytes.size());
+ EXPECT_TRUE(PythonByteArray::Check(py_bytes));
+ PythonByteArray python_bytes(PyRefType::Owned, py_bytes);
+ EXPECT_EQ(PyObjectType::ByteArray, python_bytes.GetObjectType());
+
+ llvm::ArrayRef<uint8_t> after_bytes = python_bytes.GetBytes();
+ EXPECT_EQ(after_bytes.size(), orig_bytes.size());
+ EXPECT_EQ(0, ::memcmp(orig_bytes.data(), test_bytes, orig_bytes.size()));
+}
+
TEST_F(PythonDataObjectsTest, TestPythonString)
{
// Test that strings behave correctly when wrapped by a PythonString.
OpenPOWER on IntegriCloud