/* 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_

#include "xdelta3-internal.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;
	XPR(NT "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;
	    XPR(NT "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);
	    XPR(NT "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.  Modifies "hinst", see below.  */
static int
xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
{
  /* This method is reentrant for copy instructions which may return
   * XD3_GETSRCBLK to the caller.  Each time through a copy takes the
   * minimum of inst->size and the available space on whichever block
   * supplies the data */
  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;
	int overlap;

	/* 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.  This
	 * if/else must set "overlap", "src", and "dst". */
	if (inst->addr < stream->dec_cpylen)
	  {
	    /* In both branches we are copying from outside the
	     * current decoder window, the first (VCD_TARGET) is
	     * unimplemented. */
	    overlap = 0;
	    
	    /* This branch sets "src".  As a side-effect, we modify
	     * "inst" so that if we reenter this method after a
	     * XD3_GETSRCBLK response the state is correct.  So if the
	     * instruction can be fulfilled by a contiguous block of
	     * memory then we will set:
	     *
	     *  inst->type = XD3_NOOP;
	     *  inst->size = 0;
	     */
	    if (stream->dec_win_ind & VCD_TARGET)
	      {
		/* TODO: Users have requested long-distance copies of
		 * similar material within a target (e.g., for dup
		 * supression in backups). */
		inst->size = 0;
		inst->type = XD3_NOOP;
		stream->msg = "VCD_TARGET not implemented";
		return XD3_UNIMPLEMENTED;
	      }
	    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 = stream->src;
		xoff_t block = source->cpyoff_blocks;
		usize_t blkoff = source->cpyoff_blkoff;
		const usize_t blksize = source->blksize;
		int ret;

		xd3_blksize_add (&block, &blkoff, source, inst->addr);
		XD3_ASSERT (blkoff < blksize);

		if ((ret = xd3_getblk (stream, block)))
		  {
		    /* could be a XD3_GETSRCBLK failure. */
		    if (ret == XD3_TOOFARBACK)
		      {
			stream->msg = "non-seekable source in decode";
			ret = XD3_INTERNAL;
		      }
		    return ret;
		  }

		src = source->curblk + blkoff;

		/* This block is either full, or a partial block that
		 * must contain enough bytes. */
		if ((source->onblk != blksize) &&
		    (blkoff + take > source->onblk))
		  {
		    IF_DEBUG1 (XPR(NT "[srcfile] short at blkno %"Q"u onblk "
				   "%u blksize %u blkoff %u take %u\n",
				   block,
				   source->onblk,
				   blksize,
				   blkoff,
				   take));
		    stream->msg = "source file too short";
		    return XD3_INVALID_INPUT;
		  }

		XD3_ASSERT (blkoff != blksize);

		/* Check if we have enough data on this block to
		 * finish the instruction. */
		if (blkoff + take <= blksize)
		  {
		    inst->type = XD3_NOOP;
		    inst->size = 0;
		  }
		else
		  {
		    take = blksize - blkoff;
		    inst->size -= take;
		    inst->addr += take;

		    /* because (blkoff + take > blksize), above */
		    XD3_ASSERT (inst->size != 0);
		  }
	      }
	  }
	else
	  {
	    /* TODO: the memcpy/overlap optimization, etc.  Overlap
	     * here could be more specific, it's whether (inst->addr -
	     * srclen) + inst->size > input_pos ?  And is the system
	     * memcpy really any good? */
	    overlap = 1;

	    /* 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;

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

  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. */
  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 dec_current1 */
      while ((stream->dec_current1.type != XD3_NOOP))
	{
	  if ((ret = xd3_decode_output_halfinst (stream, & stream->dec_current1)))
	    {
	      return ret;
	    }
	}
      /* Output dec_current2 */
      while (stream->dec_current2.type != XD3_NOOP)
	{
	  if ((ret = xd3_decode_output_halfinst (stream, & stream->dec_current2)))
	    {
	      return ret;
	    }
	}
    }

  if (stream->avail_out != stream->dec_tgtlen)
    {
      IF_DEBUG2 (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);
	    case VCD_LZMA_ID:
	      LZMA_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;
	    }
	}

      /* xoff_t -> usize_t is safe because this is the first block. */
      stream->dec_hdrsize = (usize_t) 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_DEBUG2 (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);
	  
	  IF_DEBUG1(DP(RINT
		       "decode cpyoff %"Q"u "
		       "cpyblkno %"Q"u "
		       "cpyblkoff %u "
		       "blksize %u\n",
		       stream->dec_cpyoff,
		       src->cpyoff_blocks,
		       src->cpyoff_blkoff,
		       src->blksize));
	}

      /* 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_
