/* resres.c: read_res_file and write_res_file implementation for windres.

   Copyright 1998, 1999 Free Software Foundation, Inc.
   Written by Anders Norlander <anorland@hem2.passagen.se>.

   This file is part of GNU Binutils.

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

#include "bfd.h"
#include "bucomm.h"
#include "libiberty.h"
#include "windres.h"

#include <assert.h>
#include <time.h>

struct res_hdr
  {
    unsigned long data_size;
    unsigned long header_size;
  };

static void write_res_directory
  PARAMS ((const struct res_directory *,
	   const struct res_id *, const struct res_id *,
	   int *, int));
static void write_res_resource
  PARAMS ((const struct res_id *, const struct res_id *,
	   const struct res_resource *, int *));
static void write_res_bin
  PARAMS ((const struct res_resource *, const struct res_id *,
	   const struct res_id *, const struct res_res_info *));

static void write_res_id PARAMS ((const struct res_id *));
static void write_res_info PARAMS ((const struct res_res_info *));
static void write_res_data PARAMS ((const void *, size_t, int));
static void write_res_header
  PARAMS ((unsigned long, const struct res_id *, const struct res_id *,
	   const struct res_res_info *));

static int read_resource_entry PARAMS ((void));
static void read_res_data PARAMS ((void *, size_t, int));
static void read_res_id PARAMS ((struct res_id *));
static unichar *read_unistring PARAMS ((int *));
static void skip_null_resource PARAMS ((void));

static unsigned long get_id_size PARAMS ((const struct res_id *));
static void res_align_file PARAMS ((void));

static void
  res_add_resource
  PARAMS ((struct res_resource *, const struct res_id *,
	   const struct res_id *, int, int));

void
  res_append_resource
  PARAMS ((struct res_directory **, struct res_resource *,
	   int, const struct res_id *, int));

static struct res_directory *resources = NULL;

static FILE *fres;
static const char *filename;

extern char *program_name;

/* Read resource file */
struct res_directory *
read_res_file (fn)
     const char *fn;
{
  filename = fn;
  fres = fopen (filename, "rb");
  if (fres == NULL)
    fatal ("can't open `%s' for output: %s", filename, strerror (errno));

  skip_null_resource ();

  while (read_resource_entry ())
    ;

  fclose (fres);

  return resources;
}

/* Write resource file */
void
write_res_file (fn, resdir)
     const char *fn;
     const struct res_directory *resdir;
{
  int language;
  static const unsigned char sign[] =
  {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  long fpos;

  filename = fn;

  fres = fopen (filename, "wb");
  if (fres == NULL)
    fatal ("can't open `%s' for output: %s", filename, strerror (errno));

  /* Write 32 bit resource signature */
  write_res_data (sign, sizeof (sign), 1);

  /* write resources */

  language = -1;
  write_res_directory (resdir, (const struct res_id *) NULL,
		       (const struct res_id *) NULL, &language, 1);

  /* end file on DWORD boundary */
  fpos = ftell (fres);
  if (fpos % 4)
    write_res_data (sign, fpos % 4, 1);

  fclose (fres);
}

/* Read a resource entry, returns 0 when all resources are read */
static int
read_resource_entry (void)
{
  struct res_id type;
  struct res_id name;
  struct res_res_info resinfo;
  struct res_hdr reshdr;
  long version;
  void *buff;

  struct res_resource *r;

  res_align_file ();

  /* Read header */
  if (fread (&reshdr, sizeof (reshdr), 1, fres) != 1)
    return 0;

  /* read resource type */
  read_res_id (&type);
  /* read resource id */
  read_res_id (&name);

  res_align_file ();

  /* Read additional resource header */
  read_res_data (&resinfo.version, sizeof (resinfo.version), 1);
  read_res_data (&resinfo.memflags, sizeof (resinfo.memflags), 1);
  read_res_data (&resinfo.language, sizeof (resinfo.language), 1);
  read_res_data (&version, sizeof (version), 1);
  read_res_data (&resinfo.characteristics, sizeof (resinfo.characteristics), 1);

  res_align_file ();

  /* Allocate buffer for data */
  buff = res_alloc (reshdr.data_size);
  /* Read data */
  read_res_data (buff, reshdr.data_size, 1);
  /* Convert binary data to resource */
  r = bin_to_res (type, buff, reshdr.data_size, 0);
  r->res_info = resinfo;
  /* Add resource to resource directory */
  res_add_resource (r, &type, &name, resinfo.language, 0);

  return 1;
}

/* write resource directory to binary resource file */
static void
write_res_directory (rd, type, name, language, level)
     const struct res_directory *rd;
     const struct res_id *type;
     const struct res_id *name;
     int *language;
     int level;
{
  const struct res_entry *re;

  for (re = rd->entries; re != NULL; re = re->next)
    {
      switch (level)
	{
	case 1:
	  /* If we're at level 1, the key of this resource is the
	     type.  This normally duplicates the information we have
	     stored with the resource itself, but we need to remember
	     the type if this is a user define resource type.  */
	  type = &re->id;
	  break;

	case 2:
	  /* If we're at level 2, the key of this resource is the name
	     we are going to use in the rc printout. */
	  name = &re->id;
	  break;

	case 3:
	  /* If we're at level 3, then this key represents a language.
	     Use it to update the current language.  */
	  if (!re->id.named
	      && re->id.u.id != *language
	      && (re->id.u.id & 0xffff) == re->id.u.id)
	    {
	      *language = re->id.u.id;
	    }
	  break;

	default:
	  break;
	}

      if (re->subdir)
	write_res_directory (re->u.dir, type, name, language, level + 1);
      else
	{
	  if (level == 3)
	    {
	      /* This is the normal case: the three levels are
	         TYPE/NAME/LANGUAGE.  NAME will have been set at level
	         2, and represents the name to use.  We probably just
	         set LANGUAGE, and it will probably match what the
	         resource itself records if anything.  */
	      write_res_resource (type, name, re->u.res, language);
	    }
	  else
	    {
	      fprintf (stderr, "// Resource at unexpected level %d\n", level);
	      write_res_resource (type, (struct res_id *) NULL, re->u.res,
				  language);
	    }
	}
    }

}

static void
write_res_resource (type, name, res, language)
     const struct res_id *type;
     const struct res_id *name;
     const struct res_resource *res;
     int *language;
{
  int rt;

  switch (res->type)
    {
    default:
      abort ();

    case RES_TYPE_ACCELERATOR:
      rt = RT_ACCELERATOR;
      break;

    case RES_TYPE_BITMAP:
      rt = RT_BITMAP;
      break;

    case RES_TYPE_CURSOR:
      rt = RT_CURSOR;
      break;

    case RES_TYPE_GROUP_CURSOR:
      rt = RT_GROUP_CURSOR;
      break;

    case RES_TYPE_DIALOG:
      rt = RT_DIALOG;
      break;

    case RES_TYPE_FONT:
      rt = RT_FONT;
      break;

    case RES_TYPE_FONTDIR:
      rt = RT_FONTDIR;
      break;

    case RES_TYPE_ICON:
      rt = RT_ICON;
      break;

    case RES_TYPE_GROUP_ICON:
      rt = RT_GROUP_ICON;
      break;

    case RES_TYPE_MENU:
      rt = RT_MENU;
      break;

    case RES_TYPE_MESSAGETABLE:
      rt = RT_MESSAGETABLE;
      break;

    case RES_TYPE_RCDATA:
      rt = RT_RCDATA;
      break;

    case RES_TYPE_STRINGTABLE:
      rt = RT_STRING;
      break;

    case RES_TYPE_USERDATA:
      rt = 0;
      break;

    case RES_TYPE_VERSIONINFO:
      rt = RT_VERSION;
      break;
    }

  if (rt != 0
      && type != NULL
      && (type->named || type->u.id != rt))
    {
      fprintf (stderr, "// Unexpected resource type mismatch: ");
      res_id_print (stderr, *type, 1);
      fprintf (stderr, " != %d", rt);
      abort ();
    }

  write_res_bin (res, type, name, &res->res_info);
  return;
}

/* Write a resource in binary resource format */
static void
write_res_bin (res, type, name, resinfo)
     const struct res_resource *res;
     const struct res_id *type;
     const struct res_id *name;
     const struct res_res_info *resinfo;
{
  unsigned long datasize = 0;
  const struct bindata *bin_rep, *data;

  bin_rep = res_to_bin (res, 0);
  for (data = bin_rep; data != NULL; data = data->next)
    datasize += data->length;

  write_res_header (datasize, type, name, resinfo);

  for (data = bin_rep; data != NULL; data = data->next)
    write_res_data (data->data, data->length, 1);
}

/* Get number of bytes needed to store an id in binary format */
static unsigned long
get_id_size (id)
     const struct res_id *id;
{
  if (id->named)
    return sizeof (unichar) * (id->u.n.length + 1);
  else
    return sizeof (unichar) * 2;
}

/* Write a resource header */
static void
write_res_header (datasize, type, name, resinfo)
     unsigned long datasize;
     const struct res_id *type;
     const struct res_id *name;
     const struct res_res_info *resinfo;
{
  struct res_hdr reshdr;
  reshdr.data_size = datasize;
  reshdr.header_size = 24 + get_id_size (type) + get_id_size (name);

  res_align_file ();
  write_res_data (&reshdr, sizeof (reshdr), 1);
  write_res_id (type);
  write_res_id (name);

  res_align_file ();

  write_res_info (resinfo);
  res_align_file ();
}


/* Write data to file, abort on failure */
static void
write_res_data (data, size, count)
     const void *data;
     size_t size;
     int count;
{
  if (fwrite (data, size, count, fres) != count)
    fatal ("%s: %s: could not write to file", program_name, filename);
}

/* Read data from file, abort on failure */
static void
read_res_data (data, size, count)
     void *data;
     size_t size;
     int count;
{
  if (fread (data, size, count, fres) != count)
    fatal ("%s: %s: unexpected end of file", program_name, filename);
}

/* Write a resource id */
static void
write_res_id (id)
     const struct res_id *id;
{
  if (id->named)
    {
      unsigned long len = id->u.n.length;
      unichar null_term = 0;
      write_res_data (id->u.n.name, len * sizeof (unichar), 1);
      write_res_data (&null_term, sizeof (null_term), 1);
    }
  else
    {
      unsigned short i = 0xFFFF;
      write_res_data (&i, sizeof (i), 1);
      i = id->u.id;
      write_res_data (&i, sizeof (i), 1);
    }
}

/* Write resource info */
static void
write_res_info (info)
     const struct res_res_info *info;
{
  write_res_data (&info->version, sizeof (info->version), 1);
  write_res_data (&info->memflags, sizeof (info->memflags), 1);
  write_res_data (&info->language, sizeof (info->language), 1);
  write_res_data (&info->version, sizeof (info->version), 1);
  write_res_data (&info->characteristics, sizeof (info->characteristics), 1);
}

/* read a resource identifier */
void 
read_res_id (id)
     struct res_id *id;
{
  unsigned short ord;
  unichar *id_s = NULL;
  int len;

  read_res_data (&ord, sizeof (ord), 1);
  if (ord == 0xFFFF)		/* an ordinal id */
    {
      read_res_data (&ord, sizeof (ord), 1);
      id->named = 0;
      id->u.id = ord;
    }
  else
    /* named id */
    {
      if (fseek (fres, -sizeof (ord), SEEK_CUR) != 0)
	fatal ("%s: %s: could not seek in file", program_name, filename);
      id_s = read_unistring (&len);
      id->named = 1;
      id->u.n.length = len;
      id->u.n.name = id_s;
    }
}

/* Read a null terminated UNICODE string */
static unichar *
read_unistring (len)
     int *len;
{
  unichar *s;
  unichar c;
  unichar *p;
  int l;

  *len = 0;
  l = 0;

  /* there are hardly any names longer than 256 characters */
  p = s = (unichar *) xmalloc (sizeof (unichar) * 256);
  do
    {
      read_res_data (&c, sizeof (c), 1);
      *p++ = c;
      if (c != 0)
	l++;
    }
  while (c != 0);
  *len = l;
  return s;
}

/* align file on DWORD boundary */
static void
res_align_file (void)
{
  if (fseek (fres, ftell (fres) % 4, SEEK_CUR) != 0)
    fatal ("%s: %s: unable to align file", program_name, filename);
}

/* Check if file is a win32 binary resource file, if so
   skip past the null resource. Returns 0 if successful, -1 on
   error.
 */
static void
skip_null_resource (void)
{
  struct res_hdr reshdr =
  {0, 0};
  read_res_data (&reshdr, sizeof (reshdr), 1);
  if ((reshdr.data_size != 0) || (reshdr.header_size != 0x20))
    goto skip_err;

  /* Subtract size of HeaderSize and DataSize */
  if (fseek (fres, reshdr.header_size - 8, SEEK_CUR) != 0)
    goto skip_err;

  return;

skip_err:
  fprintf (stderr, "%s: %s: Not a valid WIN32 resource file\n", program_name,
	   filename);
  xexit (1);
}

/* Add a resource to resource directory */
void
res_add_resource (r, type, id, language, dupok)
     struct res_resource *r;
     const struct res_id *type;
     const struct res_id *id;
     int language;
     int dupok;
{
  struct res_id a[3];

  a[0] = *type;
  a[1] = *id;
  a[2].named = 0;
  a[2].u.id = language;
  res_append_resource (&resources, r, 3, a, dupok);
}

/* Append a resource to resource directory.
   This is just copied from define_resource
   and modified to add an existing resource.
 */
void
res_append_resource (resources, resource, cids, ids, dupok)
     struct res_directory **resources;
     struct res_resource *resource;
     int cids;
     const struct res_id *ids;
     int dupok;
{
  struct res_entry *re = NULL;
  int i;

  assert (cids > 0);
  for (i = 0; i < cids; i++)
    {
      struct res_entry **pp;

      if (*resources == NULL)
	{
	  static unsigned long timeval;

	  /* Use the same timestamp for every resource created in a
	     single run.  */
	  if (timeval == 0)
	    timeval = time (NULL);

	  *resources = ((struct res_directory *)
			res_alloc (sizeof **resources));
	  (*resources)->characteristics = 0;
	  (*resources)->time = timeval;
	  (*resources)->major = 0;
	  (*resources)->minor = 0;
	  (*resources)->entries = NULL;
	}

      for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
	if (res_id_cmp ((*pp)->id, ids[i]) == 0)
	  break;

      if (*pp != NULL)
	re = *pp;
      else
	{
	  re = (struct res_entry *) res_alloc (sizeof *re);
	  re->next = NULL;
	  re->id = ids[i];
	  if ((i + 1) < cids)
	    {
	      re->subdir = 1;
	      re->u.dir = NULL;
	    }
	  else
	    {
	      re->subdir = 0;
	      re->u.res = NULL;
	    }

	  *pp = re;
	}

      if ((i + 1) < cids)
	{
	  if (!re->subdir)
	    {
	      fprintf (stderr, "%s: ", program_name);
	      res_ids_print (stderr, i, ids);
	      fprintf (stderr, ": expected to be a directory\n");
	      xexit (1);
	    }

	  resources = &re->u.dir;
	}
    }

  if (re->subdir)
    {
      fprintf (stderr, "%s: ", program_name);
      res_ids_print (stderr, cids, ids);
      fprintf (stderr, ": expected to be a leaf\n");
      xexit (1);
    }

  if (re->u.res != NULL)
    {
      if (dupok)
	return;

      fprintf (stderr, "%s: warning: ", program_name);
      res_ids_print (stderr, cids, ids);
      fprintf (stderr, ": duplicate value\n");
    }

  re->u.res = resource;
}
