/* Fmemopen implementation.
   Copyright (C) 2000, 2002, 2005, 2006, 2008, 2009
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Hanno Mueller, kontakt@hanno.de, 2000.

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

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/*
 * fmemopen() - "my" version of a string stream
 * Hanno Mueller, kontakt@hanno.de
 *
 *
 * I needed fmemopen() for an application that I currently work on,
 * but couldn't find it in libio. The following snippet of code is an
 * attempt to implement what glibc's documentation describes.
 *
 *
 *
 * I already see some potential problems:
 *
 * - I never used the "original" fmemopen(). I am sure that "my"
 *   fmemopen() behaves differently than the original version.
 *
 * - The documentation doesn't say wether a string stream allows
 *   seeks. I checked the old fmemopen implementation in glibc's stdio
 *   directory, wasn't quite able to see what is going on in that
 *   source, but as far as I understand there was no seek there. For
 *   my application, I needed fseek() and ftell(), so it's here.
 *
 * - "append" mode and fseek(p, SEEK_END) have two different ideas
 *   about the "end" of the stream.
 *
 *   As described in the documentation, when opening the file in
 *   "append" mode, the position pointer will be set to the first null
 *   character of the string buffer (yet the buffer may already
 *   contain more data). For fseek(), the last byte of the buffer is
 *   used as the end of the stream.
 *
 * - It is unclear to me what the documentation tries to say when it
 *   explains what happens when you use fmemopen with a NULL
 *   buffer.
 *
 *   Quote: "fmemopen [then] allocates an array SIZE bytes long. This
 *   is really only useful if you are going to write things to the
 *   buffer and then read them back in again."
 *
 *   What does that mean if the original fmemopen() did not allow
 *   seeking? How do you read what you just wrote without seeking back
 *   to the beginning of the stream?
 *
 * - I think there should be a second version of fmemopen() that does
 *   not add null characters for each write. (At least in my
 *   application, I am not actually using strings but binary data and
 *   so I don't need the stream to add null characters on its own.)
 */

#include <errno.h>
#include <libio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include "libioP.h"


typedef struct fmemopen_cookie_struct fmemopen_cookie_t;
struct fmemopen_cookie_struct
{
  char *buffer;
  int mybuffer;
  int binmode;
  size_t size;
  _IO_off64_t pos;
  size_t maxpos;
};


static ssize_t
fmemopen_read (void *cookie, char *b, size_t s)
{
  fmemopen_cookie_t *c;

  c = (fmemopen_cookie_t *) cookie;

  if (c->pos + s > c->size)
    {
      if ((size_t) c->pos == c->size)
	return 0;
      s = c->size - c->pos;
    }

  memcpy (b, &(c->buffer[c->pos]), s);

  c->pos += s;
  if ((size_t) c->pos > c->maxpos)
    c->maxpos = c->pos;

  return s;
}


static ssize_t
fmemopen_write (void *cookie, const char *b, size_t s)
{
  fmemopen_cookie_t *c;
  int addnullc;

  c = (fmemopen_cookie_t *) cookie;

  addnullc = c->binmode == 0 && (s == 0 || b[s - 1] != '\0');

  if (c->pos + s + addnullc > c->size)
    {
      if ((size_t) (c->pos + addnullc) == c->size)
	{
	  __set_errno (ENOSPC);
	  return 0;
	}
      s = c->size - c->pos - addnullc;
    }

  memcpy (&(c->buffer[c->pos]), b, s);

  c->pos += s;
  if ((size_t) c->pos > c->maxpos)
    {
      c->maxpos = c->pos;
      if (addnullc)
	c->buffer[c->maxpos] = '\0';
    }

  return s;
}


static int
fmemopen_seek (void *cookie, _IO_off64_t *p, int w)
{
  _IO_off64_t np;
  fmemopen_cookie_t *c;

  c = (fmemopen_cookie_t *) cookie;

  switch (w)
    {
    case SEEK_SET:
      np = *p;
      break;

    case SEEK_CUR:
      np = c->pos + *p;
      break;

    case SEEK_END:
      np = (c->binmode ? c->size : c->maxpos) - *p;
      break;

    default:
      return -1;
    }

  if (np < 0 || (size_t) np > c->size)
    return -1;

  *p = c->pos = np;

  return 0;
}


static int
fmemopen_close (void *cookie)
{
  fmemopen_cookie_t *c;

  c = (fmemopen_cookie_t *) cookie;

  if (c->mybuffer)
    free (c->buffer);
  free (c);

  return 0;
}


FILE *
fmemopen (void *buf, size_t len, const char *mode)
{
  cookie_io_functions_t iof;
  fmemopen_cookie_t *c;

  if (__builtin_expect (len == 0, 0))
    {
    einval:
      __set_errno (EINVAL);
      return NULL;
    }

  c = (fmemopen_cookie_t *) malloc (sizeof (fmemopen_cookie_t));
  if (c == NULL)
    return NULL;

  c->mybuffer = (buf == NULL);

  if (c->mybuffer)
    {
      c->buffer = (char *) malloc (len);
      if (c->buffer == NULL)
	{
	  free (c);
	  return NULL;
	}
      c->buffer[0] = '\0';
    }
  else
    {
      if (__builtin_expect ((uintptr_t) len > -(uintptr_t) buf, 0))
	{
	  free (c);
	  goto einval;
	}

      c->buffer = buf;
    }

  c->size = len;

  if (mode[0] == 'w')
    c->buffer[0] = '\0';

  c->maxpos = strlen (c->buffer);

  if (mode[0] == 'a')
    c->pos = c->maxpos;
  else
    c->pos = 0;

  c->binmode = mode[0] != '\0' && mode[1] == 'b';

  iof.read = fmemopen_read;
  iof.write = fmemopen_write;
  iof.seek = fmemopen_seek;
  iof.close = fmemopen_close;

  return _IO_fopencookie (c, mode, iof);
}
libc_hidden_def (fmemopen)
