pykd/pykd/pydataaccess.h
2017-11-16 17:33:14 +04:00

315 lines
9.0 KiB
C++

#pragma once
#include "boost/python/object.hpp"
#include "boost/python/wrapper.hpp"
#include "kdlib/dataaccessor.h"
#include "kdlib/exceptions.h"
#include "pythreadstate.h"
namespace python = boost::python;
namespace pykd {
///////////////////////////////////////////////////////////////////////////////
using kdlib::ImplementException;
///////////////////////////////////////////////////////////////////////////////
class PythonObjectAccessor : public kdlib::DataAccessor
{
public:
PythonObjectAccessor(python::object& obj, size_t pos = 0) : m_object(obj)
{
m_pystate = PyThreadState_Get();
m_startPos = pos;
}
public:
virtual size_t getLength() const {
AutoSavePythonState pystate(&m_pystate);
return python::len(m_object);
}
virtual unsigned char readByte(size_t pos=0) const {
return readValue<unsigned char>(pos);
}
virtual void writeByte(unsigned char value, size_t pos=0) {
writeValue(value,pos);
}
virtual char readSignByte(size_t pos=0) const {
return readValue<char>(pos);
}
virtual void writeSignByte(char value, size_t pos=0) {
writeValue(value,pos);
}
virtual unsigned short readWord(size_t pos=0) const {
return readValue<unsigned short>(pos);
}
virtual void writeWord(unsigned short value, size_t pos=0) {
writeValue(value,pos);
}
virtual short readSignWord(size_t pos=0) const {
return readValue<short>(pos);
}
virtual void writeSignWord(short value, size_t pos=0) {
writeValue(value,pos);
}
virtual unsigned long readDWord(size_t pos=0) const {
return readValue<unsigned long>(pos);
}
virtual void writeDWord(unsigned long value, size_t pos=0) {
writeValue(value,pos);
}
virtual long readSignDWord(size_t pos=0) const {
return readValue<long>(pos);
}
virtual void writeSignDWord(long value, size_t pos=0) {
writeValue(value,pos);
}
virtual unsigned long long readQWord(size_t pos=0) const {
return readValue<unsigned long long>(pos);
}
virtual void writeQWord(unsigned long long value, size_t pos=0) {
writeValue(value,pos);
}
virtual long long readSignQWord(size_t pos=0) const {
return readValue<long long>(pos);
}
virtual void writeSignQWord(long long value, size_t pos=0) {
writeValue(value,pos);
}
virtual float readFloat(size_t pos=0) const {
return readValue<float>(pos);
}
virtual void writeFloat(float value, size_t pos=0) {
writeValue(value,pos);
}
virtual double readDouble(size_t pos=0) const {
return readValue<double>(pos);
}
virtual void writeDouble(double value, size_t pos=0) {
writeValue(value,pos);
}
virtual void readBytes( std::vector<unsigned char>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeBytes( const std::vector<unsigned char>& dataRange, size_t pos=0) {
writeValues(dataRange,pos);
}
void readWords( std::vector<unsigned short>& dataRange, size_t count, size_t pos) const {
readValues(dataRange, count, pos);
}
virtual void writeWords( const std::vector<unsigned short>& dataRange, size_t pos=0) {
writeValues(dataRange,pos);
}
virtual void readDWords( std::vector<unsigned long>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeDWords( const std::vector<unsigned long>& dataRange, size_t pos=0) {
writeValues(dataRange,pos);
}
virtual void readQWords( std::vector<unsigned long long>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeQWords( const std::vector<unsigned long long>& dataRange, size_t pos=0) {
writeValues(dataRange,pos);
}
virtual void readSignBytes( std::vector<char>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeSignBytes( const std::vector<char>& dataRange, size_t pos=0) {
writeValues(dataRange,pos);
}
virtual void readSignWords( std::vector<short>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeSignWords( const std::vector<short>& dataRange, size_t pos=0) {
writeValues(dataRange,pos);
}
virtual void readSignDWords( std::vector<long>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeSignDWords( const std::vector<long>& dataRange, size_t pos=0) {
writeValues(dataRange, pos);
}
virtual void readSignQWords( std::vector<long long>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeSignQWords( const std::vector<long long>& dataRange, size_t pos=0) {
writeValues(dataRange,pos);
}
virtual void readFloats( std::vector<float>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeFloats( const std::vector<float>& dataRange, size_t pos=0) {
writeValues(dataRange, pos);
}
virtual void readDoubles( std::vector<double>& dataRange, size_t count, size_t pos=0) const {
readValues(dataRange, count, pos);
}
virtual void writeDoubles( const std::vector<double>& dataRange, size_t pos=0) {
writeValues(dataRange, pos);
}
virtual kdlib::DataAccessorPtr copy( size_t startOffset = 0, size_t length = 0 ) {
AutoSavePythonState pystate(&m_pystate);
return kdlib::DataAccessorPtr( new PythonObjectAccessor(m_object, startOffset) );
}
virtual std::wstring getLocationAsStr() const {
return L"python byte sequance";
}
virtual kdlib::MEMOFFSET_64 getAddress() const {
throw kdlib::DbgException("python accessor error");
}
virtual kdlib::VarStorage getStorageType() const {
throw kdlib::DbgException("python accessor error");
}
virtual std::wstring getRegisterName() const {
throw kdlib::DbgException("python accessor error");
}
private:
python::object m_object;
mutable PyThreadState* m_pystate;
size_t m_startPos;
template<typename T>
T readValue(size_t pos) const
{
AutoSavePythonState pystate(&m_pystate);
try
{
return readValueUnsafe<T>(pos);
}
catch( python::error_already_set const & )
{}
throw kdlib::DbgException("python accessor error");
}
template<typename T>
T readValueUnsafe(size_t pos) const
{
unsigned long long value = 0;
for ( size_t i = sizeof(T); i > 0; --i)
value = ( value << 8 ) + python::extract<unsigned char>(m_object[m_startPos + pos*sizeof(T) + i - 1])();
return *reinterpret_cast<T*>(&value);
}
template<typename T>
void writeValue(T value, size_t pos)
{
AutoSavePythonState pystate(&m_pystate);
try
{
writeValueUnsafe(value,pos);
return;
}
catch( python::error_already_set const & )
{}
throw kdlib::DbgException("python accessor error");
}
template<typename T>
void writeValueUnsafe(T value, size_t pos)
{
unsigned long long val = *reinterpret_cast<unsigned long long*>(&value);
for ( size_t i = 0; i < sizeof(T); ++i )
m_object[m_startPos + pos*sizeof(T) + i] = static_cast<unsigned char>( ( val >> (8*i)) & 0xFF );
}
template<typename T>
void readValues( std::vector<T>& dataRange, size_t count, size_t pos) const
{
AutoSavePythonState pystate(&m_pystate);
try
{
dataRange.resize(count);
for ( size_t i = 0; i < count; ++i )
dataRange[i] = readValueUnsafe<T>(pos + i);
return;
}
catch( python::error_already_set const & )
{}
throw kdlib::DbgException("python accessor error");
}
template<typename T>
void writeValues( const std::vector<T>& dataRange, size_t pos)
{
AutoSavePythonState pystate(&m_pystate);
try
{
for ( size_t i = 0; i < dataRange.size(); ++i )
writeValueUnsafe(dataRange[i], pos + i );
return;
}
catch( python::error_already_set const & )
{}
throw kdlib::DbgException("python accessor error");
}
};
///////////////////////////////////////////////////////////////////////////////
}