/* This is part of libio/iostream, providing -*- C++ -*- input/output.
Copyright (C) 1993 Free Software Foundation

This file is part of the GNU IO Library.  This library 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 2, or (at your option)
any later version.

This 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this library; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

As a special exception, if you link this library with files
compiled with a GNU compiler to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License.

Written by Per Bothner (bothner@cygnus.com). */

#ifdef __GNUG__
#pragma implementation
#endif
#include "libioP.h"
#include "editbuf.h"
#include <stddef.h>
#include <stdlib.h>

/* NOTE: Some of the code here is taken from GNU emacs */
/* Hence this file falls under the GNU License! */

// Invariants for edit_streambuf:
// An edit_streambuf is associated with a specific edit_string,
// which again is a sub-string of a specific edit_buffer.
// An edit_streambuf is always in either get mode or put mode, never both.
// In get mode, gptr() is the current position,
// and pbase(), pptr(), and epptr() are all NULL.
// In put mode, pptr() is the current position,
// and eback(), gptr(), and egptr() are all NULL.
// Any edit_streambuf that is actively doing insertion (as opposed to
// replacing) // must have its pptr() pointing to the start of the gap.
// Only one edit_streambuf can be actively inserting into a specific
// edit_buffer; the edit_buffer's _writer field points to that edit_streambuf.
// That edit_streambuf "owns" the gap, and the actual start of the
// gap is the pptr() of the edit_streambuf; the edit_buffer::_gap_start pointer
// will only be updated on an edit_streambuf::overflow().

int edit_streambuf::truncate()
{
    str->buffer->delete_range(str->buffer->tell((buf_char*)pptr()),
			      str->buffer->tell(str->end));
    return 0;
}

#ifdef OLD_STDIO
inline void  disconnect_gap_from_file(edit_buffer* buffer, FILE* fp)
{
    if (buffer->gap_start_ptr != &fp->__bufp)
	return;
    buffer->gap_start_normal = fp->__bufp;
    buffer->gap_start_ptr = &buffer->gap_start_normal;
}
#endif

void edit_streambuf::flush_to_buffer(edit_buffer* buffer)
{
    if (pptr() > buffer->_gap_start && pptr() < buffer->gap_end())
	buffer->_gap_start = pptr();
}

void edit_streambuf::disconnect_gap_from_file(edit_buffer* buffer)
{
    if (buffer->_writer != this) return;
    flush_to_buffer(buffer);
    setp(pptr(),pptr());
    buffer->_writer = NULL;    
}

buf_index edit_buffer::tell(buf_char *ptr)
{
    if (ptr <= gap_start())
	return ptr - data;
    else
	return ptr - gap_end() + size1();
}

#if 0
buf_index buf_cookie::tell()
{
    return str->buffer->tell(file->__bufp);
}
#endif

buf_index edit_buffer::tell(edit_mark*mark)
{
    return tell(data + mark->index_in_buffer(this));
}

// adjust the position of the gap

void edit_buffer::move_gap(buf_offset pos)
{
  if (pos < size1())
    gap_left (pos);
  else if (pos > size1())
    gap_right (pos);
}

void edit_buffer::gap_left (int pos)
{
  register buf_char *to, *from;
  register int i;
  int new_s1;

  i = size1();
  from = gap_start();
  to = from + gap_size();
  new_s1 = size1();

  /* Now copy the characters.  To move the gap down,
     copy characters up.  */

  for (;;)
    {
      /* I gets number of characters left to copy.  */
      i = new_s1 - pos;
      if (i == 0)
	break;
#if 0
      /* If a quit is requested, stop copying now.
	 Change POS to be where we have actually moved the gap to.  */
      if (QUITP)
	{
	  pos = new_s1;
	  break;
	}
#endif
      /* Move at most 32000 chars before checking again for a quit.  */
      if (i > 32000)
	i = 32000;
      new_s1 -= i;
      while (--i >= 0)
	*--to = *--from;
    }

  /* Adjust markers, and buffer data structure, to put the gap at POS.
     POS is where the loop above stopped, which may be what was specified
     or may be where a quit was detected.  */
  adjust_markers (pos << 1, size1() << 1, gap_size(), data);
#ifndef OLD_STDIO
  _gap_start = data + pos;
#else
  if (gap_start_ptr == &gap_start_normal)
	gap_start_normal = data + pos;
#endif
  __gap_end_pos = to - data;
/*  QUIT;*/
}

void edit_buffer::gap_right (int pos)
{
  register buf_char *to, *from;
  register int i;
  int new_s1;

  i = size1();
  to = gap_start();
  from = i + gap_end();
  new_s1 = i;

  /* Now copy the characters.  To move the gap up,
     copy characters down.  */

  while (1)
    {
      /* I gets number of characters left to copy.  */
      i = pos - new_s1;
      if (i == 0)
	break;
#if 0
      /* If a quit is requested, stop copying now.
	 Change POS to be where we have actually moved the gap to.  */
      if (QUITP)
	{
	  pos = new_s1;
	  break;
	}
#endif
      /* Move at most 32000 chars before checking again for a quit.  */
      if (i > 32000)
	i = 32000;
      new_s1 += i;
      while (--i >= 0)
	*to++ = *from++;
    }

  adjust_markers ((size1() + gap_size()) << 1, (pos + gap_size()) << 1,
	- gap_size(), data);
#ifndef OLD_STDIO
  _gap_start = data+pos;
#else
  if (gap_start_ptr == &gap_start_normal)
	gap_start_normal = data + pos;
#endif
  __gap_end_pos = from - data;
/*  QUIT;*/
}

/* make sure that the gap in the current buffer is at least k
   characters wide */

void edit_buffer::make_gap(buf_offset k)
{
  register buf_char *p1, *p2, *lim;
  buf_char *old_data = data;
  int s1 = size1();

  if (gap_size() >= k)
    return;

  /* Get more than just enough */
  if (buf_size > 1000) k += 2000;
  else k += /*200;*/ 20; // for testing!

  p1 = (buf_char *) realloc (data, s1 + size2() + k);
  if (p1 == 0)
    abort(); /*memory_full ();*/

  k -= gap_size();			/* Amount of increase.  */

  /* Record new location of text */
  data = p1;

  /* Transfer the new free space from the end to the gap
     by shifting the second segment upward */
  p2 = data + buf_size;
  p1 = p2 + k;
  lim = p2 - size2();
  while (lim < p2)
    *--p1 = *--p2;

  /* Finish updating text location data */
  __gap_end_pos += k;

#ifndef OLD_STDIO
  _gap_start = data + s1;
#else
  if (gap_start_ptr == &gap_start_normal)
	gap_start_normal = data + s1;
#endif

  /* adjust markers */
  adjust_markers (s1 << 1, (buf_size << 1) + 1, k, old_data);
  buf_size += k;
}

/* Add `amount' to the position of every marker in the current buffer
   whose current position is between `from' (exclusive) and `to' (inclusive).
   Also, any markers past the outside of that interval, in the direction
   of adjustment, are first moved back to the near end of the interval
   and then adjusted by `amount'.  */

void edit_buffer::adjust_markers(register mark_pointer low,
				 register mark_pointer high,
				 int amount, buf_char *old_data)
{
  register struct edit_mark *m;
  register mark_pointer mpos;
  /* convert to mark_pointer */
  amount <<= 1;

  if (_writer)
      _writer->disconnect_gap_from_file(this);

  for (m = mark_list(); m != NULL; m = m->chain)
    {
      mpos = m->_pos;
      if (amount > 0)
	{
	  if (mpos > high && mpos < high + amount)
	    mpos = high + amount;
	}
      else
	{
	  if (mpos > low + amount && mpos <= low)
	    mpos = low + amount;
	}
      if (mpos > low && mpos <= high)
	mpos += amount;
      m->_pos = mpos;
    }

    // Now adjust files
    edit_streambuf *file;

    for (file = files; file != NULL; file = file->next) {
	mpos = file->current() - old_data;
	if (amount > 0)
	{
	  if (mpos > high && mpos < high + amount)
	    mpos = high + amount;
	}
	else
	{
	  if (mpos > low + amount && mpos <= low)
	    mpos = low + amount;
	}
	if (mpos > low && mpos <= high)
	    mpos += amount;
	char* new_pos = data + mpos;
	file->set_current(new_pos, file->is_reading());
    }
}

#if 0
stdio_
   __off == index at start of buffer (need only be valid after seek ? )
   __buf ==

if read/read_delete/overwrite mode:
     __endp <= min(*gap_start_ptr, edit_string->end->ptr(buffer))

if inserting:
     must have *gap_start_ptr == __bufp && *gap_start_ptr+gap == __endp
     file->edit_string->end->ptr(buffer) == *gap_start_ptr+end
if write_mode:
     if before gap
#endif

int edit_streambuf::underflow()
{
    if (!(_mode & ios::in))
	return EOF;
    struct edit_buffer *buffer = str->buffer;
    if (!is_reading()) { // Must switch from put to get mode.
	disconnect_gap_from_file(buffer);
	set_current(pptr(), 1);
    }
    buf_char *str_end = str->end->ptr(buffer);
  retry:
    if (gptr() < egptr()) {
	return *gptr();
    }
    if ((buf_char*)gptr() == str_end)
	return EOF;
    if (str_end <= buffer->gap_start()) {
	setg(eback(), gptr(), str_end);
	goto retry;
    }
    if (gptr() < buffer->gap_start()) {
	setg(eback(), gptr(), buffer->gap_start());
	goto retry;
    }
    if (gptr() == buffer->gap_start()) {
	disconnect_gap_from_file(buffer);
//	fp->__offset += fp->__bufp - fp->__buffer;
	setg(buffer->gap_end(), buffer->gap_end(), str_end);
    }
    else
	setg(eback(), gptr(), str_end);
    goto retry;
}

int edit_streambuf::overflow(int ch)
{
    if (_mode == ios::in)
	return EOF;
    struct edit_buffer *buffer = str->buffer;
    flush_to_buffer(buffer);
    if (ch == EOF)
	return 0;
    if (is_reading()) { // Must switch from get to put mode.
	set_current(gptr(), 0);
    }
    buf_char *str_end = str->end->ptr(buffer);
  retry:
    if (pptr() < epptr()) {
	*pptr() = ch;
	pbump(1);
	return (unsigned char)ch;
    }
    if ((buf_char*)pptr() == str_end || inserting()) {
	/* insert instead */
	if (buffer->_writer)
	    buffer->_writer->flush_to_buffer(); // Redundant?
	buffer->_writer = NULL;
	if  (pptr() >= buffer->gap_end())
	    buffer->move_gap(pptr() - buffer->gap_size());
	else
	    buffer->move_gap(pptr());
	buffer->make_gap(1);
	setp(buffer->gap_start(), buffer->gap_end());
	buffer->_writer = this;
	*pptr() = ch;
	pbump(1);
	return (unsigned char)ch;
    }
    if (str_end <= buffer->gap_start()) {
	// Entire string is left of gap.
	setp(pptr(), str_end);
    }
    else if (pptr() < buffer->gap_start()) {
	// Current pos is left of gap.
	setp(pptr(), buffer->gap_start());
	goto retry;
    }
    else if (pptr() == buffer->gap_start()) {
	// Current pos is at start of gap; move to end of gap.
//	disconnect_gap_from_file(buffer);
	setp(buffer->gap_end(), str_end);
//	__offset += __bufp - __buffer;
    }
    else {
	// Otherwise, current pos is right of gap.
	setp(pptr(), str_end);
    }
    goto retry;
}

void edit_streambuf::set_current(char *new_pos, int reading)
{
    if (reading) {
	setg(new_pos, new_pos, new_pos);
	setp(NULL, NULL);
    }
    else {
	setg(NULL, NULL, NULL);
	setp(new_pos, new_pos);
    }
}

// Called by fseek(fp, pos, whence) if fp is bound to a edit_buffer.

streampos edit_streambuf::seekoff(streamoff offset, _seek_dir dir,
				  int /* =ios::in|ios::out*/)
{
    struct edit_buffer *buffer = str->buffer;
    disconnect_gap_from_file(buffer);
    buf_index cur_pos = buffer->tell((buf_char*)current());;
    buf_index start_pos = buffer->tell(str->start);
    buf_index end_pos = buffer->tell(str->end);
    switch (dir) {
      case ios::beg:
	offset += start_pos;
	break;
      case ios::cur:
	offset += cur_pos;
	break;
      case ios::end:
	offset += end_pos;
	break;
    }
    if (offset < start_pos || offset > end_pos)
	return EOF;
    buf_char *new_pos = buffer->data + offset;
    buf_char* gap_start = buffer->gap_start();
    if (new_pos > gap_start) {
	buf_char* gap_end = buffer->gap_end();
	new_pos += gap_end - gap_start;
	if (new_pos >= buffer->data + buffer->buf_size) abort(); // Paranoia.
    }
    set_current(new_pos, is_reading());
    return EOF;
}

#if 0
int buf_seek(void *arg_cookie, fpos_t * pos, int whence)
{
    struct buf_cookie *cookie = arg_cookie;
    FILE *file = cookie->file;
    struct edit_buffer *buffer = cookie->str->buffer;
    buf_char *str_start = cookie->str->start->ptr(buffer);
    disconnect_gap_from_file(buffer, cookie->file);
    fpos_t cur_pos, new_pos;
    if (file->__bufp <= *buffer->gap_start_ptr
	|| str_start >= buffer->__gap_end)
	cur_pos = str_start - file->__bufp;
    else
	cur_pos =
	    (*buffer->gap_start_ptr - str_start) + (file->__bufp - __gap_end);
    end_pos = ...;
    switch (whence) {
      case SEEK_SET:
	new_pos = *pos;
	break;
      case SEEK_CUR:
	new_pos = cur_pos + *pos;
	break;
      case SEEK_END:
	new_pos = end_pos + *pos;
	break;
    }
    if (new_pos > end_pos) {
	seek to end_pos;
	insert_nulls(new_pos - end_pos);
	return;
    }
    if (str_start + new_pos <= *gap_start_ptr &* *gap_start_ptr < end) {
	__buffer = str_start;
        __off = 0;
	__bufp = str_start + new_pos;
	file->__get_limit =
	    *buffer->gap_start_ptr; /* what if gap_start_ptr == &bufp ??? */
    } else if () {
	
    }
    *pos = new_pos;
}
#endif

/* Delete characters from `from' up to (but not incl) `to' */

void edit_buffer::delete_range (buf_index from, buf_index to)
{
  register int numdel;

  if ((numdel = to - from) <= 0)
    return;

  /* Make sure the gap is somewhere in or next to what we are deleting */
  if (from > size1())
    gap_right (from);
  if (to < size1())
    gap_left (to);

  /* Relocate all markers pointing into the new, larger gap
     to point at the end of the text before the gap.  */
  adjust_markers ((to + gap_size()) << 1, (to + gap_size()) << 1,
	- numdel - gap_size(), data);

   __gap_end_pos = to + gap_size();
  _gap_start = data + from;
}

void edit_buffer::delete_range(struct edit_mark *start, struct edit_mark *end)
{
    delete_range(tell(start), tell(end));
}

void buf_delete_chars(struct edit_buffer *, struct edit_mark *, size_t)
{
 abort();
}

edit_streambuf::edit_streambuf(edit_string* bstr, int mode)
{
    _mode = mode;
    str = bstr;
    edit_buffer* buffer = bstr->buffer;
    next = buffer->files;
    buffer->files = this;
    char* buf_ptr = bstr->start->ptr(buffer);
    _inserting = 0;
//    setb(buf_ptr, buf_ptr, 0);
    set_current(buf_ptr, !(mode & ios::out+ios::trunc+ios::app));
    if (_mode & ios::trunc)
	truncate();
    if (_mode & ios::ate)
	seekoff(0, ios::end);
}

// Called by fclose(fp) if fp is bound to a edit_buffer.

#if 0
static int buf_close(void *arg)
{
    register struct buf_cookie *cookie = arg;
    struct edit_buffer *buffer = cookie->str->buffer;
    struct buf_cookie **ptr;
    for (ptr = &buffer->files; *ptr != cookie; ptr = &(*ptr)->next) ;
    *ptr = cookie->next;
    disconnect_gap_from_file(buffer, cookie->file);
    free (cookie);
    return 0;
}
#endif

edit_streambuf::~edit_streambuf()
{
    if (_mode == ios::out)
	truncate();
    // Unlink this from list of files associated with bstr->buffer.
    edit_streambuf **ptr = &str->buffer->files;
    for (; *ptr != this; ptr = &(*ptr)->next) { }
    *ptr = next;

    disconnect_gap_from_file(str->buffer);
}

edit_buffer::edit_buffer()
{
    buf_size = /*200;*/ 15; /* for testing! */
    data = (buf_char*)malloc(buf_size);
    files = NULL;
#ifndef OLD_STDIO
    _gap_start = data;
    _writer = NULL;
#else
    gap_start_normal = data;
    gap_start_ptr = &gap_start_normal;
#endif
    __gap_end_pos = buf_size;
    start_mark.chain = &end_mark;
    start_mark._pos = 0;
    end_mark.chain = NULL;
    end_mark._pos = 2 * buf_size + 1;
}

// Allocate a new mark, which is adjusted by 'delta' bytes from 'this'.
// Restrict new mark to lie within 'str'.

edit_mark::edit_mark(struct edit_string *str, long delta)
{
    struct edit_buffer *buf = str->buffer;
    chain = buf->start_mark.chain;
    buf->start_mark.chain = this;
    mark_pointer size1 = buf->size1() << 1;
    int gap_size = buf->gap_size() << 1;
    delta <<= 1;

    // check if new and old marks are opposite sides of gap
    if (_pos <= size1 && _pos + delta > size1)
	delta += gap_size;
    else if (_pos >= size1 + gap_size && _pos + delta < size1 + gap_size)
	delta -= gap_size;

    _pos = _pos + delta;
    if (_pos < str->start->_pos & ~1)
	_pos = (str->start->_pos & ~ 1) + (_pos & 1);
    else if (_pos >= str->end->_pos)
	_pos = (str->end->_pos & ~ 1) + (_pos & 1);
}

// A (slow) way to find the buffer a mark belongs to.

edit_buffer * edit_mark::buffer()
{
    struct edit_mark *mark;
    for (mark = this; mark->chain != NULL; mark = mark->chain) ;
    // Assume that the last mark on the chain is the end_mark.
    return (edit_buffer *)((char*)mark - offsetof(edit_buffer, end_mark));
}

edit_mark::~edit_mark()
{
    // Must unlink mark from chain of owning buffer
    struct edit_buffer *buf = buffer();
    if (this == &buf->start_mark || this == &buf->end_mark) abort();
    edit_mark **ptr;
    for (ptr = &buf->start_mark.chain; *ptr != this; ptr = &(*ptr)->chain) ;
    *ptr = this->chain;
}

int edit_string::length() const
{
    ptrdiff_t delta = end->ptr(buffer) - start->ptr(buffer);
    if (end->ptr(buffer) <= buffer->gap_start() ||
	start->ptr(buffer) >= buffer->gap_end())
	return delta;
    return delta - buffer->gap_size();
}

buf_char * edit_string::copy_bytes(int *lenp) const
{
    char *new_str;
    int len1, len2;
    buf_char *start1, *start2;
    start1 = start->ptr(buffer);
    if (end->ptr(buffer) <= buffer->gap_start()
	|| start->ptr(buffer) >= buffer->gap_end()) {
	len1 = end->ptr(buffer) - start1;
	len2 = 0;
	start2 = NULL; // To avoid a warning from g++.
    }
    else {
	len1 = buffer->gap_start() - start1;
	start2 = buffer->gap_end();
	len2 = end->ptr(buffer) - start2;
    }
    new_str = (char*)malloc(len1 + len2 + 1);
    memcpy(new_str, start1, len1);
    if (len2 > 0) memcpy(new_str + len1, start2, len2);
    new_str[len1+len2] = '\0';
    *lenp = len1+len2;
    return new_str;
}

// Replace the buf_chars in 'this' with ones from 'src'.
// Equivalent to deleting this, then inserting src, except tries
// to leave marks in place: Marks whose offset from the start
// of 'this' is less than 'src->length()' will still have the
// same offset in 'this' when done.

void edit_string::assign(struct edit_string *src)
{
    edit_streambuf dst_file(this, ios::out);
    if (buffer == src->buffer /*&& ???*/) { /* overly conservative */
	int src_len;
	buf_char *new_str;
	new_str = src->copy_bytes(&src_len);
	dst_file.sputn(new_str, src_len);
	free (new_str);
    } else {
	edit_streambuf src_file(src, ios::in);
	for ( ; ; ) {
	    int ch = src_file.sbumpc();
	    if (ch == EOF) break;
	    dst_file.sputc(ch);
	}
    }
}
