/* Python memory buffer interface for reading inferior memory.

   Copyright (C) 2009-2023 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "python-internal.h"

struct membuf_object
{
  PyObject_HEAD

    /* Pointer to the raw data, and array of gdb_bytes.  */
    void *buffer;

  /* The address from where the data was read, held for mbpy_str.  */
  CORE_ADDR addr;

  /* The number of octets in BUFFER.  */
  CORE_ADDR length;
};

extern PyTypeObject
  membuf_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");

/* Wrap BUFFER, ADDRESS, and LENGTH into a gdb.Membuf object.  ADDRESS is
   the address within the inferior that the contents of BUFFER were read,
   and LENGTH is the number of octets in BUFFER.  */

PyObject *
gdbpy_buffer_to_membuf (gdb::unique_xmalloc_ptr<gdb_byte> buffer,
			CORE_ADDR address, ULONGEST length)
{
  gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object,
						     &membuf_object_type));
  if (membuf_obj == nullptr)
    return nullptr;

  membuf_obj->buffer = buffer.release ();
  membuf_obj->addr = address;
  membuf_obj->length = length;

  return PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
}

/* Destructor for gdb.Membuf objects.  */

static void
mbpy_dealloc (PyObject *self)
{
  xfree (((membuf_object *) self)->buffer);
  Py_TYPE (self)->tp_free (self);
}

/* Return a description of the gdb.Membuf object.  */

static PyObject *
mbpy_str (PyObject *self)
{
  membuf_object *membuf_obj = (membuf_object *) self;

  return PyUnicode_FromFormat (_ ("Memory buffer for address %s, \
which is %s bytes long."),
			       paddress (gdbpy_enter::get_gdbarch (),
					 membuf_obj->addr),
			       pulongest (membuf_obj->length));
}

static int
get_buffer (PyObject *self, Py_buffer *buf, int flags)
{
  membuf_object *membuf_obj = (membuf_object *) self;
  int ret;

  ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer, membuf_obj->length,
			   0, PyBUF_CONTIG);

  /* Despite the documentation saying this field is a "const char *",
     in Python 3.4 at least, it's really a "char *".  */
  buf->format = (char *) "c";

  return ret;
}

/* General Python initialization callback.  */

int
gdbpy_initialize_membuf (void)
{
  membuf_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&membuf_object_type) < 0)
    return -1;

  return gdb_pymodule_addobject (gdb_module, "Membuf",
				 (PyObject *) &membuf_object_type);
}

static PyBufferProcs buffer_procs = { get_buffer };

PyTypeObject membuf_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0) "gdb.Membuf", /*tp_name*/
  sizeof (membuf_object),			   /*tp_basicsize*/
  0,						   /*tp_itemsize*/
  mbpy_dealloc,					   /*tp_dealloc*/
  0,						   /*tp_print*/
  0,						   /*tp_getattr*/
  0,						   /*tp_setattr*/
  0,						   /*tp_compare*/
  0,						   /*tp_repr*/
  0,						   /*tp_as_number*/
  0,						   /*tp_as_sequence*/
  0,						   /*tp_as_mapping*/
  0,						   /*tp_hash */
  0,						   /*tp_call*/
  mbpy_str,					   /*tp_str*/
  0,						   /*tp_getattro*/
  0,						   /*tp_setattro*/
  &buffer_procs,				   /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				   /*tp_flags*/
  "GDB memory buffer object",			   /*tp_doc*/
  0,						   /* tp_traverse */
  0,						   /* tp_clear */
  0,						   /* tp_richcompare */
  0,						   /* tp_weaklistoffset */
  0,						   /* tp_iter */
  0,						   /* tp_iternext */
  0,						   /* tp_methods */
  0,						   /* tp_members */
  0,						   /* tp_getset */
  0,						   /* tp_base */
  0,						   /* tp_dict */
  0,						   /* tp_descr_get */
  0,						   /* tp_descr_set */
  0,						   /* tp_dictoffset */
  0,						   /* tp_init */
  0,						   /* tp_alloc */
};
