#ifndef __PY_IDAAPI_LOADER_INPUT__ #define __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); } //-------------------------------------------------------------------------- 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("", 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 = ""; 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); } }; // #endif // __PY_IDAAPI_LOADER_INPUT__