/* xdelta 3 - delta compression tools and library
 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007.  Joshua P. MacDonald
 *
 *  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 2 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _XDELTA3_DECODE_H_
#define _XDELTA3_DECODE_H_

#define SRCORTGT(x) ((((x) & VCD_SRCORTGT) == VCD_SOURCE) ? \
                     VCD_SOURCE : ((((x) & VCD_SRCORTGT) == \
                                    VCD_TARGET) ? VCD_TARGET : 0))

/* Initialize the decoder for a new window.  The dec_tgtlen value is
 * preserved across successive window decodings, and the update to
 * dec_winstart is delayed until a new window actually starts.  This
 * is to avoid throwing an error due to overflow until the last
 * possible moment.  This makes it possible to encode exactly 4GB
 * through a 32-bit encoder. */
static int
xd3_decode_init_window (xd3_stream *stream)
{
  stream->dec_cpylen = 0;
  stream->dec_cpyoff = 0;
  stream->dec_cksumbytes = 0;

  xd3_init_cache (& stream->acache);

  return 0;
}

/* Allocates buffer space for the target window and possibly the
 * VCD_TARGET copy-window.  Also sets the base of the two copy
 * segments. */
static int
xd3_decode_setup_buffers (xd3_stream *stream)
{
  /* If VCD_TARGET is set then the previous buffer may be reused. */
  if (stream->dec_win_ind & VCD_TARGET)
    {
      /* But this implementation only supports copying from the last
       * target window.  If the offset is outside that range, it can't
       * be done. */
      if (stream->dec_cpyoff < stream->dec_laststart)
	{
	  stream->msg = "unsupported VCD_TARGET offset";
	  return XD3_INVALID_INPUT;
	}

      /* See if the two windows are the same.  This indicates the
       * first time VCD_TARGET is used.  This causes a second buffer
       * to be allocated, after that the two are swapped in the
       * DEC_FINISH case. */
      if (stream->dec_lastwin == stream->next_out)
	{
	  stream->next_out  = NULL;
	  stream->space_out = 0;
	}

      // TODO: VCD_TARGET mode, this is broken
      stream->dec_cpyaddrbase = stream->dec_lastwin +
	(usize_t) (stream->dec_cpyoff - stream->dec_laststart);
    }

  /* See if the current output window is large enough. */
  if (stream->space_out < stream->dec_tgtlen)
    {
      xd3_free (stream, stream->dec_buffer);

      stream->space_out =
	xd3_round_blksize (stream->dec_tgtlen, XD3_ALLOCSIZE);

      if ((stream->dec_buffer =
	   (uint8_t*) xd3_alloc (stream, stream->space_out, 1)) == NULL)
	{
	  return ENOMEM;
	}

      stream->next_out = stream->dec_buffer;
    }

  /* dec_tgtaddrbase refers to an invalid base address, but it is
   * always used with a sufficiently large instruction offset (i.e.,
   * beyond the copy window).  This condition is enforced by
   * xd3_decode_output_halfinst. */
  stream->dec_tgtaddrbase = stream->next_out - stream->dec_cpylen;

  return 0;
}

static int
xd3_decode_allocate (xd3_stream  *stream,
		     usize_t       size,
		     uint8_t    **buf_ptr,
		     usize_t      *buf_alloc)
{
  if (*buf_ptr != NULL && *buf_alloc < size)
    {
      xd3_free (stream, *buf_ptr);
      *buf_ptr = NULL;
    }

  if (*buf_ptr == NULL)
    {
      *buf_alloc = xd3_round_blksize (size, XD3_ALLOCSIZE);

      if ((*buf_ptr = (uint8_t*) xd3_alloc (stream, *buf_alloc, 1)) == NULL)
	{
	  return ENOMEM;
	}
    }

  return 0;
}

static int
xd3_decode_section (xd3_stream *stream,
		    xd3_desect *section,
		    xd3_decode_state nstate,
		    int copy)
{
  XD3_ASSERT (section->pos <= section->size);
  XD3_ASSERT (stream->dec_state != nstate);

  if (section->pos < section->size)
    {
      usize_t sect_take;

      if (stream->avail_in == 0)
	{
	  return XD3_INPUT;
	}

      if ((copy == 0) && (section->pos == 0))
	{
	  /* No allocation/copy needed */
	  section->buf = stream->next_in;
	  sect_take    = section->size;
	}
      else
	{
	  usize_t sect_need = section->size - section->pos;

	  /* Allocate and copy */
	  sect_take = min (sect_need, stream->avail_in);

	  if (section->pos == 0)
	    {
	      int ret;

	      if ((ret = xd3_decode_allocate (stream,
					      section->size,
					      & section->copied1,
					      & section->alloc1)))
		{
		  return ret;
		}

	      section->buf = section->copied1;
	    }

	  memcpy (section->copied1 + section->pos,
		  stream->next_in,
		  sect_take);
	}

      section->pos += sect_take;

      stream->dec_winbytes += sect_take;

      DECODE_INPUT (sect_take);
    }

  if (section->pos < section->size)
    {
      stream->msg = "further input required";
      return XD3_INPUT;
    }

  XD3_ASSERT (section->pos == section->size);

  stream->dec_state = nstate;
  section->buf_max  = section->buf + section->size;
  section->pos      = 0;
  return 0;
}

/* Decode the size and address for half of an instruction (i.e., a
 * single opcode).  This updates the stream->dec_position, which are
 * bytes already output prior to processing this instruction.  Perform
 * bounds checking for sizes and copy addresses, which uses the
 * dec_position (which is why these checks are done here). */
static int
xd3_decode_parse_halfinst (xd3_stream *stream, xd3_hinst *inst)
{
  int ret;

  /* If the size from the instruction table is zero then read a size value. */
  if ((inst->size == 0) &&
      (ret = xd3_read_size (stream,
 			    & stream->inst_sect.buf,
			      stream->inst_sect.buf_max,
			    & inst->size)))
    {
      return XD3_INVALID_INPUT;
    }

  /* For copy instructions, read address. */
  if (inst->type >= XD3_CPY)
    {
      IF_DEBUG2 ({
	static int cnt = 0;
	DP(RINT "DECODE:%u: COPY at %"Q"u (winoffset %u) size %u winaddr %u\n",
		 cnt++,
		 stream->total_out + (stream->dec_position -
				      stream->dec_cpylen),
		 (stream->dec_position - stream->dec_cpylen),
		 inst->size,
		 inst->addr);
      });

      if ((ret = xd3_decode_address (stream,
				     stream->dec_position,
				     inst->type - XD3_CPY,
				     & stream->addr_sect.buf,
				     stream->addr_sect.buf_max,
				     & inst->addr)))
	{
	  return ret;
	}

      /* Cannot copy an address before it is filled-in. */
      if (inst->addr >= stream->dec_position)
	{
	  stream->msg = "address too large";
	  return XD3_INVALID_INPUT;
	}

      /* Check: a VCD_TARGET or VCD_SOURCE copy cannot exceed the remaining
       * buffer space in its own segment. */
      if (inst->addr < stream->dec_cpylen &&
	  inst->addr + inst->size > stream->dec_cpylen)
	{
	  stream->msg = "size too large";
	  return XD3_INVALID_INPUT;
	}
    }
  else
    {
      IF_DEBUG2 ({
	if (inst->type == XD3_ADD)
	  {
	    static int cnt;
	    DP(RINT "DECODE:%d: ADD at %"Q"u (winoffset %u) size %u\n",
	       cnt++,
	       (stream->total_out + stream->dec_position - stream->dec_cpylen),
	       stream->dec_position - stream->dec_cpylen,
	       inst->size);
	  }
	else
	  {
	    static int cnt;
	    XD3_ASSERT (inst->type == XD3_RUN);
	    DP(RINT "DECODE:%d: RUN at %"Q"u (winoffset %u) size %u\n",
	       cnt++,
	       stream->total_out + stream->dec_position - stream->dec_cpylen,
	       stream->dec_position - stream->dec_cpylen,
	       inst->size);
	  }
      });
    }

  /* Check: The instruction will not overflow the output buffer. */
  if (stream->dec_position + inst->size > stream->dec_maxpos)
    {
      stream->msg = "size too large";
      return XD3_INVALID_INPUT;
    }

  stream->dec_position += inst->size;
  return 0;
}

/* Decode a single opcode and then decode the two half-instructions. */
static int
xd3_decode_instruction (xd3_stream *stream)
{
  int ret;
  const xd3_dinst *inst;

  if (stream->inst_sect.buf == stream->inst_sect.buf_max)
    {
      stream->msg = "instruction underflow";
      return XD3_INVALID_INPUT;
    }

  inst = &stream->code_table[*stream->inst_sect.buf++];

  stream->dec_current1.type = inst->type1;
  stream->dec_current2.type = inst->type2;
  stream->dec_current1.size = inst->size1;
  stream->dec_current2.size = inst->size2;

  /* For each instruction with a real operation, decode the
   * corresponding size and addresses if necessary.  Assume a
   * code-table may have NOOP in either position, although this is
   * unlikely. */
  if (inst->type1 != XD3_NOOP &&
      (ret = xd3_decode_parse_halfinst (stream, & stream->dec_current1)))
    {
      return ret;
    }
  if (inst->type2 != XD3_NOOP &&
      (ret = xd3_decode_parse_halfinst (stream, & stream->dec_current2)))
    {
      return ret;
    }
  return 0;
}

/* Output the result of a single half-instruction. OPT: This the
   decoder hotspot. */
static int
xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
{
  /* To make this reentrant, set take = min (inst->size, available
     space)... */
  usize_t take = inst->size;

  XD3_ASSERT (inst->type != XD3_NOOP);

  switch (inst->type)
    {
    case XD3_RUN:
      {
	/* Only require a single data byte. */
	if (stream->data_sect.buf == stream->data_sect.buf_max)
	  {
	    stream->msg = "data underflow";
	    return XD3_INVALID_INPUT;
	  }

	memset (stream->next_out + stream->avail_out,
		stream->data_sect.buf[0],
		take);

	stream->data_sect.buf += 1;
	stream->avail_out += take;
	inst->type = XD3_NOOP;
	break;
      }
    case XD3_ADD:
      {
	/* Require at least TAKE data bytes. */
	if (stream->data_sect.buf + take > stream->data_sect.buf_max)
	  {
	    stream->msg = "data underflow";
	    return XD3_INVALID_INPUT;
	  }

	memcpy (stream->next_out + stream->avail_out,
		stream->data_sect.buf,
		take);

	stream->data_sect.buf += take;
	stream->avail_out += take;
	inst->type = XD3_NOOP;
	break;
      }
    default:
      {
	usize_t i;
	const uint8_t *src;
	uint8_t *dst;

	/* See if it copies from the VCD_TARGET/VCD_SOURCE window or
	 * the target window.  Out-of-bounds checks for the addresses
	 * and sizes are performed in xd3_decode_parse_halfinst. */
	if (inst->addr < stream->dec_cpylen)
	  {
	    if (stream->dec_win_ind & VCD_TARGET)
	      {
		/* For VCD_TARGET we know the entire range is
		 * in-memory, as established by
		 * decode_setup_buffers.
                 *
                 * TODO: this is totally bogus, VCD_TARGET won't work.
                 */
		src = stream->dec_cpyaddrbase + inst->addr;
		inst->type = XD3_NOOP;
		inst->size = 0;
	      }
	    else
	      {
		/* In this case we have to read a source block, which
		 * could return control to the caller.  We need to
		 * know the first block number needed for this
		 * copy. */
		xd3_source *source;
		xoff_t block;
		usize_t blkoff;
		usize_t blksize;
		int ret;

	      more:

		source  = stream->src;
		block   = source->cpyoff_blocks;
		blkoff  = source->cpyoff_blkoff + inst->addr;
		blksize = source->blksize;

 		while (blkoff >= blksize)
		  {
		    block  += 1;
		    blkoff -= blksize;
		  }

		if ((ret = xd3_getblk (stream, block)))
		  {
		    /* could be a XD3_GETSRCBLK failure. */
		    if (ret == XD3_TOOFARBACK)
		      {
			ret = XD3_INTERNAL;
		      }
		    return ret;
		  }

		src = source->curblk + blkoff;

		/* This block either contains enough data or the source file
		 * is short. */
		if ((source->onblk != blksize) &&
		    (blkoff + take > source->onblk))
		  {
		    stream->msg = "source file too short";
		    return XD3_INVALID_INPUT;

		  }

		XD3_ASSERT (blkoff != blksize);

		if (blkoff + take <= blksize)
		  {
		    inst->type = XD3_NOOP;
		    inst->size = 0;
		  }
		else
		  {
		    /* This block doesn't contain all the data, modify
		     * the instruction, do not set to XD3_NOOP. */
		    take = blksize - blkoff;
		    inst->size -= take;
		    inst->addr += take;
		  }
	      }
	  }
	else
	  {
	    /* For a target-window copy, we know the entire range is
	     * in-memory.  The dec_tgtaddrbase is negatively offset by
	     * dec_cpylen because the addresses start beyond that
	     * point. */
	    src = stream->dec_tgtaddrbase + inst->addr;
	    inst->type = XD3_NOOP;
	    inst->size = 0;
	  }

 	dst = stream->next_out + stream->avail_out;

	stream->avail_out += take;

	/* Can't just memcpy here due to possible overlap. */
	for (i = take; i != 0; i -= 1)
	  {
	    *dst++ = *src++;
	  }

	take = inst->size;

	/* If there is more to copy, call getblk again. */
	if (inst->type != XD3_NOOP)
	  {
	    XD3_ASSERT (take > 0);
	    goto more;
	  }
	else
	  {
	    XD3_ASSERT (take == 0);
	  }
      }
    }

  return 0;
}

static int
xd3_decode_finish_window (xd3_stream *stream)
{
  stream->dec_winbytes  = 0;
  stream->dec_state     = DEC_FINISH;

  stream->data_sect.pos = 0;
  stream->inst_sect.pos = 0;
  stream->addr_sect.pos = 0;

  return XD3_OUTPUT;
}

static int
xd3_decode_secondary_sections (xd3_stream *secondary_stream)
{
#if SECONDARY_ANY
  int ret;
#define DECODE_SECONDARY_SECTION(UPPER,LOWER) \
  ((secondary_stream->dec_del_ind & VCD_ ## UPPER ## COMP) && \
   (ret = xd3_decode_secondary (secondary_stream, \
				& secondary_stream-> LOWER ## _sect,	\
				& xd3_sec_ ## LOWER (secondary_stream))))

  if (DECODE_SECONDARY_SECTION (DATA, data) ||
      DECODE_SECONDARY_SECTION (INST, inst) ||
      DECODE_SECONDARY_SECTION (ADDR, addr))
    {
      return ret;
    }
#undef DECODE_SECONDARY_SECTION
#endif
  return 0;
}

static int
xd3_decode_sections (xd3_stream *stream)
{
  usize_t need, more, take;
  int copy, ret;

  if ((stream->flags & XD3_JUST_HDR) != 0)
    {
      /* Nothing left to do. */
      return xd3_decode_finish_window (stream);
    }

  /* To avoid copying, need this much data available */
  need = (stream->inst_sect.size +
	  stream->addr_sect.size +
	  stream->data_sect.size);

  /* The window may be entirely processed. */
  XD3_ASSERT (stream->dec_winbytes <= need);

  /* Compute how much more input is needed. */
  more = (need - stream->dec_winbytes);

  /* How much to consume. */
  take = min (more, stream->avail_in);

  /* See if the input is completely available, to avoid copy. */
  copy = (take != more);

  /* If the window is skipped... */
  if ((stream->flags & XD3_SKIP_WINDOW) != 0)
    {
      /* Skip the available input. */
      DECODE_INPUT (take);

      stream->dec_winbytes += take;

      if (copy)
	{
	  stream->msg = "further input required";
	  return XD3_INPUT;
	}

      return xd3_decode_finish_window (stream);
    }

  /* Process all but the DATA section. */
  switch (stream->dec_state)
    {
    default:
      stream->msg = "internal error";
      return XD3_INVALID_INPUT;

    case DEC_DATA:
      if ((ret = xd3_decode_section (stream, & stream->data_sect,
				     DEC_INST, copy))) { return ret; }
    case DEC_INST:
      if ((ret = xd3_decode_section (stream, & stream->inst_sect,
				     DEC_ADDR, copy))) { return ret; }
    case DEC_ADDR:
      if ((ret = xd3_decode_section (stream, & stream->addr_sect,
				     DEC_EMIT, copy))) { return ret; }
    }

  XD3_ASSERT (stream->dec_winbytes == need);

  if ((ret = xd3_decode_secondary_sections (stream))) { return ret; }

  if (stream->flags & XD3_SKIP_EMIT)
    {
      return xd3_decode_finish_window (stream);
    }

  /* OPT: A possible optimization is to avoid allocating memory in
   * decode_setup_buffers and to avoid a large memcpy when the window
   * consists of a single VCD_SOURCE copy instruction.  The only
   * potential problem is if the following window is a VCD_TARGET,
   * then you need to remember... */
  if ((ret = xd3_decode_setup_buffers (stream))) { return ret; }

  return 0;
}

static int
xd3_decode_emit (xd3_stream *stream)
{
  int ret;

  /* Produce output: originally structured to allow reentrant code
   * that fills as much of the output buffer as possible, but VCDIFF
   * semantics allows to copy from anywhere from the target window, so
   * instead allocate a sufficiently sized buffer after the target
   * window length is decoded.
   *
   * This code still needs to be reentrant to allow XD3_GETSRCBLK to
   * return control.  This is handled by setting the
   * stream->dec_currentN instruction types to XD3_NOOP after they
   * have been processed. */
  XD3_ASSERT (! (stream->flags & XD3_SKIP_EMIT));
  XD3_ASSERT (stream->dec_tgtlen <= stream->space_out);

  while (stream->inst_sect.buf != stream->inst_sect.buf_max ||
	 stream->dec_current1.type != XD3_NOOP ||
	 stream->dec_current2.type != XD3_NOOP)
    {
      /* Decode next instruction pair. */
      if ((stream->dec_current1.type == XD3_NOOP) &&
	  (stream->dec_current2.type == XD3_NOOP) &&
	  (ret = xd3_decode_instruction (stream))) { return ret; }

      /* Output for each instruction. */
      if ((stream->dec_current1.type != XD3_NOOP) &&
	  (ret = xd3_decode_output_halfinst (stream, & stream->dec_current1)))
	{
	  return ret;
	}

      if ((stream->dec_current2.type != XD3_NOOP) &&
	  (ret = xd3_decode_output_halfinst (stream, & stream->dec_current2)))
	{
	  return ret;
	}
    }

  if (stream->avail_out != stream->dec_tgtlen)
    {
      IF_DEBUG1 (DP(RINT "AVAIL_OUT(%d) != DEC_TGTLEN(%d)\n",
		    stream->avail_out, stream->dec_tgtlen));
      stream->msg = "wrong window length";
      return XD3_INVALID_INPUT;
    }

  if (stream->data_sect.buf != stream->data_sect.buf_max)
    {
      stream->msg = "extra data section";
      return XD3_INVALID_INPUT;
    }

  if (stream->addr_sect.buf != stream->addr_sect.buf_max)
    {
      stream->msg = "extra address section";
      return XD3_INVALID_INPUT;
    }

  /* OPT: Should cksum computation be combined with the above loop? */
  if ((stream->dec_win_ind & VCD_ADLER32) != 0 &&
      (stream->flags & XD3_ADLER32_NOVER) == 0)
    {
      uint32_t a32 = adler32 (1L, stream->next_out, stream->avail_out);

      if (a32 != stream->dec_adler32)
	{
	  stream->msg = "target window checksum mismatch";
	  return XD3_INVALID_INPUT;
	}
    }

  /* Finished with a window. */
  return xd3_decode_finish_window (stream);
}

int
xd3_decode_input (xd3_stream *stream)
{
  int ret;

  if (stream->enc_state != 0)
    {
      stream->msg = "encoder/decoder transition";
      return XD3_INVALID_INPUT;
    }

#define BYTE_CASE(expr,x,nstate) \
      do { \
      if ( (expr) && \
           ((ret = xd3_decode_byte (stream, & (x))) != 0) ) { return ret; } \
      stream->dec_state = (nstate); \
      } while (0)

#define OFFSET_CASE(expr,x,nstate) \
      do { \
      if ( (expr) && \
           ((ret = xd3_decode_offset (stream, & (x))) != 0) ) { return ret; } \
      stream->dec_state = (nstate); \
      } while (0)

#define SIZE_CASE(expr,x,nstate) \
      do { \
      if ( (expr) && \
           ((ret = xd3_decode_size (stream, & (x))) != 0) ) { return ret; } \
      stream->dec_state = (nstate); \
      } while (0)

  switch (stream->dec_state)
    {
    case DEC_VCHEAD:
      {
	if ((ret = xd3_decode_bytes (stream, stream->dec_magic,
				     & stream->dec_magicbytes, 4)))
	  {
	    return ret;
	  }

	if (stream->dec_magic[0] != VCDIFF_MAGIC1 ||
	    stream->dec_magic[1] != VCDIFF_MAGIC2 ||
	    stream->dec_magic[2] != VCDIFF_MAGIC3)
	  {
	    stream->msg = "not a VCDIFF input";
	    return XD3_INVALID_INPUT;
	  }

	if (stream->dec_magic[3] != 0)
	  {
	    stream->msg = "VCDIFF input version > 0 is not supported";
	    return XD3_INVALID_INPUT;
	  }

	stream->dec_state = DEC_HDRIND;
      }
    case DEC_HDRIND:
      {
	if ((ret = xd3_decode_byte (stream, & stream->dec_hdr_ind)))
	  {
	    return ret;
	  }

	if ((stream->dec_hdr_ind & VCD_INVHDR) != 0)
	  {
	    stream->msg = "unrecognized header indicator bits set";
	    return XD3_INVALID_INPUT;
	  }

	stream->dec_state = DEC_SECONDID;
      }

    case DEC_SECONDID:
      /* Secondary compressor ID: only if VCD_SECONDARY is set */
      if ((stream->dec_hdr_ind & VCD_SECONDARY) != 0)
	{
	  BYTE_CASE (1, stream->dec_secondid, DEC_TABLEN);

	  switch (stream->dec_secondid)
	    {
	    case VCD_FGK_ID:
	      FGK_CASE (stream);
	    case VCD_DJW_ID:
	      DJW_CASE (stream);
	    default:
	      stream->msg = "unknown secondary compressor ID";
	      return XD3_INVALID_INPUT;
	    }
	}

    case DEC_TABLEN:
      /* Length of code table data: only if VCD_CODETABLE is set */
      SIZE_CASE ((stream->dec_hdr_ind & VCD_CODETABLE) != 0,
		 stream->dec_codetblsz, DEC_NEAR);

      /* The codetblsz counts the two NEAR/SAME bytes */
      if ((stream->dec_hdr_ind & VCD_CODETABLE) != 0) {
	if (stream->dec_codetblsz <= 2) {
	  stream->msg = "invalid code table size";
	  return ENOMEM;
	}
	stream->dec_codetblsz -= 2;
      }
    case DEC_NEAR:
      /* Near modes: only if VCD_CODETABLE is set */
      BYTE_CASE((stream->dec_hdr_ind & VCD_CODETABLE) != 0,
		stream->acache.s_near, DEC_SAME);
    case DEC_SAME:
      /* Same modes: only if VCD_CODETABLE is set */
      BYTE_CASE((stream->dec_hdr_ind & VCD_CODETABLE) != 0,
		stream->acache.s_same, DEC_TABDAT);
    case DEC_TABDAT:
      /* Compressed code table data */

      if ((stream->dec_hdr_ind & VCD_CODETABLE) != 0)
	{
	  /* Get the code table data. */
	  if ((stream->dec_codetbl == NULL) &&
	      (stream->dec_codetbl =
	       (uint8_t*) xd3_alloc (stream,
				     stream->dec_codetblsz, 1)) == NULL)
	    {
	      return ENOMEM;
	    }

	  if ((ret = xd3_decode_bytes (stream, stream->dec_codetbl,
				       & stream->dec_codetblbytes,
				       stream->dec_codetblsz)))
	    {
	      return ret;
	    }

	  if ((ret = xd3_apply_table_encoding (stream, stream->dec_codetbl,
					       stream->dec_codetblbytes)))
	    {
	      return ret;
	    }
	}
      else
	{
	  /* Use the default table. */
	  stream->acache.s_near = __rfc3284_code_table_desc.near_modes;
	  stream->acache.s_same = __rfc3284_code_table_desc.same_modes;
	  stream->code_table    = xd3_rfc3284_code_table ();
	}

      if ((ret = xd3_alloc_cache (stream))) { return ret; }

      stream->dec_state = DEC_APPLEN;

    case DEC_APPLEN:
      /* Length of application data */
      SIZE_CASE((stream->dec_hdr_ind & VCD_APPHEADER) != 0,
		stream->dec_appheadsz, DEC_APPDAT);

    case DEC_APPDAT:
      /* Application data */
      if (stream->dec_hdr_ind & VCD_APPHEADER)
	{
	  /* Note: we add an additional byte for padding, to allow
	     0-termination. */
	  if ((stream->dec_appheader == NULL) &&
	      (stream->dec_appheader =
	       (uint8_t*) xd3_alloc (stream,
				     stream->dec_appheadsz+1, 1)) == NULL)
	    {
	      return ENOMEM;
	    }

	  stream->dec_appheader[stream->dec_appheadsz] = 0;

	  if ((ret = xd3_decode_bytes (stream, stream->dec_appheader,
				       & stream->dec_appheadbytes,
				       stream->dec_appheadsz)))
	    {
	      return ret;
	    }
	}

      stream->dec_hdrsize = stream->total_in;
      stream->dec_state = DEC_WININD;

    case DEC_WININD:
      {
	/* Start of a window: the window indicator */
	if ((ret = xd3_decode_byte (stream, & stream->dec_win_ind)))
	  {
	    return ret;
	  }

	stream->current_window = stream->dec_window_count;

	if (XOFF_T_OVERFLOW (stream->dec_winstart, stream->dec_tgtlen))
	  {
	    stream->msg = "decoder file offset overflow";
	    return XD3_INVALID_INPUT;
	  }

	stream->dec_winstart += stream->dec_tgtlen;

	if ((stream->dec_win_ind & VCD_INVWIN) != 0)
	  {
	    stream->msg = "unrecognized window indicator bits set";
	    return XD3_INVALID_INPUT;
	  }

	if ((ret = xd3_decode_init_window (stream))) { return ret; }

	stream->dec_state = DEC_CPYLEN;

	IF_DEBUG1 (DP(RINT "--------- TARGET WINDOW %"Q"u -----------\n",
		      stream->current_window));
      }

    case DEC_CPYLEN:
      /* Copy window length: only if VCD_SOURCE or VCD_TARGET is set */
      SIZE_CASE(SRCORTGT (stream->dec_win_ind), stream->dec_cpylen,
		DEC_CPYOFF);

      /* Set the initial, logical decoder position (HERE address) in
       * dec_position.  This is set to just after the source/copy
       * window, as we are just about to output the first byte of
       * target window. */
      stream->dec_position = stream->dec_cpylen;

    case DEC_CPYOFF:
      /* Copy window offset: only if VCD_SOURCE or VCD_TARGET is set */
      OFFSET_CASE(SRCORTGT (stream->dec_win_ind), stream->dec_cpyoff,
		  DEC_ENCLEN);

      /* Copy offset and copy length may not overflow. */
      if (XOFF_T_OVERFLOW (stream->dec_cpyoff, stream->dec_cpylen))
	{
	  stream->msg = "decoder copy window overflows a file offset";
	  return XD3_INVALID_INPUT;
	}

      /* Check copy window bounds: VCD_TARGET window may not exceed
	 current position. */
      if ((stream->dec_win_ind & VCD_TARGET) &&
	  (stream->dec_cpyoff + (xoff_t) stream->dec_cpylen >
	   stream->dec_winstart))
	{
	  stream->msg = "VCD_TARGET window out of bounds";
	  return XD3_INVALID_INPUT;
	}

    case DEC_ENCLEN:
      /* Length of the delta encoding */
      SIZE_CASE(1, stream->dec_enclen, DEC_TGTLEN);
    case DEC_TGTLEN:
      /* Length of target window */
      SIZE_CASE(1, stream->dec_tgtlen, DEC_DELIND);

      /* Set the maximum decoder position, beyond which we should not
       * decode any data.  This is the maximum value for dec_position.
       * This may not exceed the size of a usize_t. */
      if (USIZE_T_OVERFLOW (stream->dec_cpylen, stream->dec_tgtlen))
	{
	  stream->msg = "decoder target window overflows a usize_t";
	  return XD3_INVALID_INPUT;
	}

      /* Check for malicious files. */
      if (stream->dec_tgtlen > XD3_HARDMAXWINSIZE)
	{
	  stream->msg = "hard window size exceeded";
	  return XD3_INVALID_INPUT;
	}

      stream->dec_maxpos = stream->dec_cpylen + stream->dec_tgtlen;

    case DEC_DELIND:
      /* Delta indicator */
      BYTE_CASE(1, stream->dec_del_ind, DEC_DATALEN);

      if ((stream->dec_del_ind & VCD_INVDEL) != 0)
	{
	  stream->msg = "unrecognized delta indicator bits set";
	  return XD3_INVALID_INPUT;
	}

      /* Delta indicator is only used with secondary compression. */
      if ((stream->dec_del_ind != 0) && (stream->sec_type == NULL))
	{
	  stream->msg = "invalid delta indicator bits set";
	  return XD3_INVALID_INPUT;
	}

      /* Section lengths */
    case DEC_DATALEN:
      SIZE_CASE(1, stream->data_sect.size, DEC_INSTLEN);
    case DEC_INSTLEN:
      SIZE_CASE(1, stream->inst_sect.size, DEC_ADDRLEN);
    case DEC_ADDRLEN:
      SIZE_CASE(1, stream->addr_sect.size, DEC_CKSUM);

    case DEC_CKSUM:
      /* Window checksum. */
      if ((stream->dec_win_ind & VCD_ADLER32) != 0)
	{
	  int i;

	  if ((ret = xd3_decode_bytes (stream, stream->dec_cksum,
				       & stream->dec_cksumbytes, 4)))
	    {
	      return ret;
	    }

	  for (i = 0; i < 4; i += 1)
	    {
	      stream->dec_adler32 =
		(stream->dec_adler32 << 8) | stream->dec_cksum[i];
	    }
	}

      stream->dec_state = DEC_DATA;

      /* Check dec_enclen for redundency, otherwise it is not really used. */
      {
	usize_t enclen_check =
	  (1 + (xd3_sizeof_size (stream->dec_tgtlen) +
		xd3_sizeof_size (stream->data_sect.size) +
		xd3_sizeof_size (stream->inst_sect.size) +
		xd3_sizeof_size (stream->addr_sect.size)) +
	   stream->data_sect.size +
	   stream->inst_sect.size +
	   stream->addr_sect.size +
	   ((stream->dec_win_ind & VCD_ADLER32) ? 4 : 0));

	if (stream->dec_enclen != enclen_check)
	  {
	    stream->msg = "incorrect encoding length (redundent)";
	    return XD3_INVALID_INPUT;
	  }
      }

      /* Returning here gives the application a chance to inspect the
       * header, skip the window, etc. */
      if (stream->current_window == 0) { return XD3_GOTHEADER; }
      else                             { return XD3_WINSTART; }

    case DEC_DATA:
    case DEC_INST:
    case DEC_ADDR:
      /* Next read the three sections. */
     if ((ret = xd3_decode_sections (stream))) { return ret; }

    case DEC_EMIT:

      /* To speed VCD_SOURCE block-address calculations, the source
       * cpyoff_blocks and cpyoff_blkoff are pre-computed. */
      if (stream->dec_win_ind & VCD_SOURCE)
	{
	  xd3_source *src = stream->src;

	  if (src == NULL)
	    {
	      stream->msg = "source input required";
	      return XD3_INVALID_INPUT;
	    }

	  xd3_blksize_div(stream->dec_cpyoff, src,
			  &src->cpyoff_blocks,
			  &src->cpyoff_blkoff);
	}

      /* xd3_decode_emit returns XD3_OUTPUT on every success. */
      if ((ret = xd3_decode_emit (stream)) == XD3_OUTPUT)
	{
	  stream->total_out += (xoff_t) stream->avail_out;
	}

      return ret;

    case DEC_FINISH:
      {
	if (stream->dec_win_ind & VCD_TARGET)
	  {
	    if (stream->dec_lastwin == NULL)
	      {
		stream->dec_lastwin   = stream->next_out;
		stream->dec_lastspace = stream->space_out;
	      }
	    else
	      {
		xd3_swap_uint8p (& stream->dec_lastwin,
				 & stream->next_out);
		xd3_swap_usize_t (& stream->dec_lastspace,
				  & stream->space_out);
	      }
	  }

	stream->dec_lastlen   = stream->dec_tgtlen;
	stream->dec_laststart = stream->dec_winstart;
	stream->dec_window_count += 1;

	/* Note: the updates to dec_winstart & current_window are
	 * deferred until after the next DEC_WININD byte is read. */
	stream->dec_state = DEC_WININD;
	return XD3_WINFINISH;
      }

    default:
      stream->msg = "invalid state";
      return XD3_INVALID_INPUT;
    }
}

#endif // _XDELTA3_DECODE_H_
