/* String reading

   Copyright (C) 2022 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 "gdbsupport/common-defs.h"
#include "target/target.h"

/* Read LEN bytes of target memory at address MEMADDR, placing the
   results in GDB's memory at MYADDR.  Returns a count of the bytes
   actually read, and optionally a target_xfer_status value in the
   location pointed to by ERRPTR if ERRPTR is non-null.  */

static int
partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
		     int len, int *errptr)
{
  int nread;			/* Number of bytes actually read.  */
  int errcode;			/* Error from last read.  */

  /* First try a complete read.  */
  errcode = target_read_memory (memaddr, myaddr, len);
  if (errcode == 0)
    {
      /* Got it all.  */
      nread = len;
    }
  else
    {
      /* Loop, reading one byte at a time until we get as much as we can.  */
      for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--)
	{
	  errcode = target_read_memory (memaddr++, myaddr++, 1);
	}
      /* If an error, the last read was unsuccessful, so adjust count.  */
      if (errcode != 0)
	{
	  nread--;
	}
    }
  if (errptr != NULL)
    {
      *errptr = errcode;
    }
  return (nread);
}

/* See target/target.h.  */

int
target_read_string (CORE_ADDR addr, int len, int width,
		    unsigned int fetchlimit,
		    gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
		    int *bytes_read)
{
  int errcode;			/* Errno returned from bad reads.  */
  unsigned int nfetch;		/* Chars to fetch / chars fetched.  */
  gdb_byte *bufptr;		/* Pointer to next available byte in
				   buffer.  */

  /* Loop until we either have all the characters, or we encounter
     some error, such as bumping into the end of the address space.  */

  buffer->reset (nullptr);

  if (len > 0)
    {
      /* We want fetchlimit chars, so we might as well read them all in
	 one operation.  */
      unsigned int fetchlen = std::min ((unsigned) len, fetchlimit);

      buffer->reset ((gdb_byte *) xmalloc (fetchlen * width));
      bufptr = buffer->get ();

      nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode)
	/ width;
      addr += nfetch * width;
      bufptr += nfetch * width;
    }
  else if (len == -1)
    {
      unsigned long bufsize = 0;
      unsigned int chunksize;	/* Size of each fetch, in chars.  */
      int found_nul;		/* Non-zero if we found the nul char.  */
      gdb_byte *limit;		/* First location past end of fetch buffer.  */

      found_nul = 0;
      /* We are looking for a NUL terminator to end the fetching, so we
	 might as well read in blocks that are large enough to be efficient,
	 but not so large as to be slow if fetchlimit happens to be large.
	 So we choose the minimum of 8 and fetchlimit.  We used to use 200
	 instead of 8 but 200 is way too big for remote debugging over a
	  serial line.  */
      chunksize = std::min (8u, fetchlimit);

      do
	{
	  nfetch = std::min ((unsigned long) chunksize, fetchlimit - bufsize);

	  if (*buffer == NULL)
	    buffer->reset ((gdb_byte *) xmalloc (nfetch * width));
	  else
	    buffer->reset ((gdb_byte *) xrealloc (buffer->release (),
						  (nfetch + bufsize) * width));

	  bufptr = buffer->get () + bufsize * width;
	  bufsize += nfetch;

	  /* Read as much as we can.  */
	  nfetch = partial_memory_read (addr, bufptr, nfetch * width, &errcode)
		    / width;

	  /* Scan this chunk for the null character that terminates the string
	     to print.  If found, we don't need to fetch any more.  Note
	     that bufptr is explicitly left pointing at the next character
	     after the null character, or at the next character after the end
	     of the buffer.  */

	  limit = bufptr + nfetch * width;
	  while (bufptr < limit)
	    {
	      bool found_nonzero = false;

	      for (int i = 0; !found_nonzero && i < width; ++i)
		if (bufptr[i] != 0)
		  found_nonzero = true;

	      addr += width;
	      bufptr += width;
	      if (!found_nonzero)
		{
		  /* We don't care about any error which happened after
		     the NUL terminator.  */
		  errcode = 0;
		  found_nul = 1;
		  break;
		}
	    }
	}
      while (errcode == 0	/* no error */
	     && bufptr - buffer->get () < fetchlimit * width	/* no overrun */
	     && !found_nul);	/* haven't found NUL yet */
    }
  else
    {				/* Length of string is really 0!  */
      /* We always allocate *buffer.  */
      buffer->reset ((gdb_byte *) xmalloc (1));
      bufptr = buffer->get ();
      errcode = 0;
    }

  /* bufptr and addr now point immediately beyond the last byte which we
     consider part of the string (including a '\0' which ends the string).  */
  *bytes_read = bufptr - buffer->get ();

  return errcode;
}

/* See target/target.h.  */

gdb::unique_xmalloc_ptr<char>
target_read_string (CORE_ADDR memaddr, int len, int *bytes_read)
{
  gdb::unique_xmalloc_ptr<gdb_byte> buffer;

  int ignore;
  if (bytes_read == nullptr)
    bytes_read = &ignore;

  /* Note that the endian-ness does not matter here.  */
  int errcode = target_read_string (memaddr, -1, 1, len, &buffer, bytes_read);
  if (errcode != 0)
    return {};

  return gdb::unique_xmalloc_ptr<char> ((char *) buffer.release ());
}
