Files
idapython-src/pywraps/py_idaapi_loader_input.hpp
2025-03-13 16:17:53 +01:00

311 lines
8.1 KiB
C++

#ifndef __PY_IDAAPI_LOADER_INPUT__
#define __PY_IDAAPI_LOADER_INPUT__
//--------------------------------------------------------------------------
//<inline(py_idaapi_loader_input)>
class loader_input_t
{
private:
linput_t *li;
int own;
qstring fn;
enum
{
OWN_NONE = 0, // li not created yet
OWN_CREATE = 1, // Owns li because we created it
OWN_FROM_LI = 2, // No ownership we borrowed the li from another class
OWN_FROM_FP = 3, // We got an li instance from an fp instance, we have to unmake_linput() on Close
};
//--------------------------------------------------------------------------
void _from_capsule(PyObject *pycapsule)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
this->set_linput((linput_t *)PyCapsule_GetPointer(pycapsule, VALID_CAPSULE_NAME));
}
//--------------------------------------------------------------------------
void assign(const loader_input_t &rhs)
{
fn = rhs.fn;
li = rhs.li;
own = OWN_FROM_LI;
}
//--------------------------------------------------------------------------
loader_input_t(const loader_input_t &rhs)
{
assign(rhs);
}
public:
// Special attribute that tells the pyvar_to_idcvar how to convert this
// class from and to IDC. The value of this variable must be set to two
int __idc_cvt_id__;
//--------------------------------------------------------------------------
loader_input_t(PyObject *pycapsule = nullptr): li(nullptr), own(OWN_NONE), __idc_cvt_id__(PY_ICID_OPAQUE)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( pycapsule != nullptr && PyCapsule_IsValid(pycapsule, VALID_CAPSULE_NAME) )
_from_capsule(pycapsule);
}
//--------------------------------------------------------------------------
void close()
{
if ( li == nullptr )
return;
PYW_GIL_GET;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
if ( own == OWN_CREATE )
close_linput(li);
else if ( own == OWN_FROM_FP )
unmake_linput(li);
SWIG_PYTHON_THREAD_END_ALLOW;
li = nullptr;
own = OWN_NONE;
}
//--------------------------------------------------------------------------
~loader_input_t()
{
close();
}
//--------------------------------------------------------------------------
bool open(const char *filename, bool remote)
{
close();
PYW_GIL_GET;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
li = open_linput(filename, remote);
if ( li != nullptr )
{
// Save file name
fn = filename;
own = OWN_CREATE;
}
SWIG_PYTHON_THREAD_END_ALLOW;
return li != nullptr;
}
//--------------------------------------------------------------------------
void set_linput(linput_t *linput)
{
close();
own = OWN_FROM_LI;
li = linput;
fn.sprnt("<linput_t * %p>", linput);
}
//--------------------------------------------------------------------------
static loader_input_t *from_linput(linput_t *linput)
{
loader_input_t *l = new loader_input_t();
l->set_linput(linput);
return l;
}
//--------------------------------------------------------------------------
// This method can be used to pass a linput_t* from C code
static loader_input_t *from_capsule(PyObject *pycapsule)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( !PyCapsule_IsValid(pycapsule, VALID_CAPSULE_NAME) )
return nullptr;
loader_input_t *l = new loader_input_t();
l->_from_capsule(pycapsule);
return l;
}
//--------------------------------------------------------------------------
static loader_input_t *from_fp(FILE *fp)
{
PYW_GIL_GET;
loader_input_t *l = nullptr;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
linput_t *fp_li = make_linput(fp);
if ( fp_li != nullptr )
{
l = new loader_input_t();
l->own = OWN_FROM_FP;
l->fn.sprnt("<FILE * %p>", fp);
l->li = fp_li;
}
SWIG_PYTHON_THREAD_END_ALLOW;
return l;
}
//--------------------------------------------------------------------------
linput_t *get_linput()
{
return li;
}
//--------------------------------------------------------------------------
bool open_memory(ea_t start, int64 size)
{
PYW_GIL_GET;
linput_t *l;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
l = create_memory_linput(start, asize_t(size));
if ( l != nullptr )
{
close();
li = l;
fn = "<memory>";
own = OWN_CREATE;
}
SWIG_PYTHON_THREAD_END_ALLOW;
return l != nullptr;
}
//--------------------------------------------------------------------------
int64 seek(int64 offset, int whence)
{
int64 r;
PYW_GIL_GET;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
r = qlseek(li, offset, whence);
SWIG_PYTHON_THREAD_END_ALLOW;
return r;
}
//--------------------------------------------------------------------------
int64 tell()
{
int64 r;
PYW_GIL_GET;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
r = qltell(li);
SWIG_PYTHON_THREAD_END_ALLOW;
return r;
}
//--------------------------------------------------------------------------
PyObject *getz(size_t size, int64 fpos)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == nullptr )
break;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
qlgetz(li, fpos, buf, size);
SWIG_PYTHON_THREAD_END_ALLOW;
PyObject *ret = PyUnicode_FromString(buf);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *gets(int64 len)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
bytevec_t buf;
buf.resize(len);
bool ok;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
ok = qlgets((char *) buf.begin(), buf.size(), li) != nullptr;
SWIG_PYTHON_THREAD_END_ALLOW;
if ( !ok )
Py_RETURN_NONE;
return PyUnicode_FromString((const char *) buf.begin());
}
//--------------------------------------------------------------------------
PyObject *read(int64 size)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
ssize_t ssize(size);
bytevec_t buf;
if ( ssize < 0 )
ssize = qlsize(li) - qltell(li);
buf.resize(ssize);
ssize_t nread;
nread = qlread(li, (char *) buf.begin(), buf.size());
SWIG_PYTHON_THREAD_END_ALLOW;
if ( nread <= 0 )
{
buf.clear();
nread = 0;
}
return PyBytes_FromStringAndSize((const char *) buf.begin(), nread);
}
//--------------------------------------------------------------------------
bool opened()
{
return li != nullptr;
}
//--------------------------------------------------------------------------
PyObject *readbytes(size_t size, bool big_endian)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == nullptr )
break;
int r;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
r = lreadbytes(li, buf, size, big_endian);
SWIG_PYTHON_THREAD_END_ALLOW;
if ( r == -1 )
r = 0;
PyObject *ret = PyUnicode_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
int file2base(int64 pos, ea_t ea1, ea_t ea2, int patchable)
{
int rc;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
rc = ::file2base(li, pos, ea1, ea2, patchable);
SWIG_PYTHON_THREAD_END_ALLOW;
return rc;
}
//--------------------------------------------------------------------------
int64 size()
{
int64 rc;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
rc = qlsize(li);
SWIG_PYTHON_THREAD_END_ALLOW;
return rc;
}
//--------------------------------------------------------------------------
PyObject *filename()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyUnicode_FromString(fn.c_str());
}
//--------------------------------------------------------------------------
PyObject *get_byte()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int ch;
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
ch = qlgetc(li);
SWIG_PYTHON_THREAD_END_ALLOW;
if ( ch == EOF )
Py_RETURN_NONE;
return Py_BuildValue("i", ch);
}
};
//</inline(py_idaapi_loader_input)>
#endif // __PY_IDAAPI_LOADER_INPUT__