 /* GNU Objective C Runtime archiving
   Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004, 2009,
   2010 Free Software Foundation, Inc.
   Contributed by Kresten Krab Thorup

This file is part of GCC.

GCC 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 3, or (at your option) any later version.

GCC 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.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

/* This file is entirely deprecated and will be removed.  */

#include "objc-private/common.h"
#include "objc-private/error.h"
#include "tconfig.h"
#include "objc/objc-api.h"
#include "objc/hash.h"
#include "objc/objc-list.h" 
#include "objc-private/runtime.h"
#include "objc/typedstream.h"
#include "objc/encoding.h"
#include <stdlib.h>

extern int fflush (FILE *);

#define ROUND(V, A) \
  ({ typeof (V) __v = (V); typeof (A) __a = (A);  \
     __a * ((__v + __a - 1)/__a); })

#define PTR2LONG(P) (((char *) (P))-(char *) 0)
#define LONG2PTR(L) (((char *) 0) + (L))

/* Declare some functions... */

static int
objc_read_class (struct objc_typed_stream *stream, Class *class);

int objc_sizeof_type (const char *type);

static int
objc_write_use_common (struct objc_typed_stream *stream, unsigned long key);

static int
objc_write_register_common (struct objc_typed_stream *stream,
			    unsigned long key);

static int 
objc_write_class (struct objc_typed_stream *stream,
			 struct objc_class *class);

const char *objc_skip_type (const char *type);

static void __objc_finish_write_root_object (struct objc_typed_stream *);
static void __objc_finish_read_root_object (struct objc_typed_stream *);

static inline int
__objc_code_unsigned_char (unsigned char *buf, unsigned char val)
{
  if ((val&_B_VALUE) == val)
    {
      buf[0] = val|_B_SINT;
      return 1;
    }
  else
    {
      buf[0] = _B_NINT|0x01;
      buf[1] = val;
      return 2;
    }
}

int
objc_write_unsigned_char (struct objc_typed_stream *stream,
			  unsigned char value)
{
  unsigned char buf[sizeof (unsigned char) + 1];
  int len = __objc_code_unsigned_char (buf, value);
  return (*stream->write) (stream->physical, (char*)buf, len);
}

static inline int
__objc_code_char (unsigned char *buf, signed char val)
{
  if (val >= 0)
    return __objc_code_unsigned_char (buf, val);
  else
    {
      buf[0] = _B_NINT|_B_SIGN|0x01;
      buf[1] = -val;
      return 2;
    }
}

int
objc_write_char (struct objc_typed_stream *stream, signed char value)
{
  unsigned char buf[sizeof (char) + 1];
  int len = __objc_code_char (buf, value);
  return (*stream->write) (stream->physical, (char*)buf, len);
}

static inline int
__objc_code_unsigned_short (unsigned char *buf, unsigned short val)
{
  if ((val&_B_VALUE) == val)
    {
      buf[0] = val|_B_SINT;
      return 1;
    }
  else 
    {
      int c, b;

      buf[0] = _B_NINT;

      for (c = sizeof (short); c != 0; c -= 1)
	if (((val >> (8*(c - 1)))%0x100) != 0)
	  break;

      buf[0] |= c;

      for (b = 1; c != 0; c--, b++)
	{
	  buf[b] = (val >> (8*(c - 1)))%0x100;
	}

      return b;
    }
}

int
objc_write_unsigned_short (struct objc_typed_stream *stream, 
			   unsigned short value)
{
  unsigned char buf[sizeof (unsigned short) + 1];
  int len = __objc_code_unsigned_short (buf, value);
  return (*stream->write) (stream->physical, (char*)buf, len);
}
      
static inline int
__objc_code_short (unsigned char *buf, short val)
{
  int sign = (val < 0);
  int size = __objc_code_unsigned_short (buf, sign ? -val : val);
  if (sign)
    buf[0] |= _B_SIGN;
  return size;
}

int
objc_write_short (struct objc_typed_stream *stream, short value)
{
  unsigned char buf[sizeof (short) + 1];
  int len = __objc_code_short (buf, value);
  return (*stream->write) (stream->physical, (char*)buf, len);
}
      

static inline int
__objc_code_unsigned_int (unsigned char *buf, unsigned int val)
{
  if ((val&_B_VALUE) == val)
    {
      buf[0] = val|_B_SINT;
      return 1;
    }
  else 
    {
      int c, b;

      buf[0] = _B_NINT;

      for (c = sizeof (int); c != 0; c -= 1)
	if (((val >> (8*(c - 1)))%0x100) != 0)
	  break;

      buf[0] |= c;

      for (b = 1; c != 0; c--, b++)
	{
	  buf[b] = (val >> (8*(c-1)))%0x100;
	}

      return b;
    }
}

int
objc_write_unsigned_int (struct objc_typed_stream *stream, unsigned int value)
{
  unsigned char buf[sizeof (unsigned int) + 1];
  int len = __objc_code_unsigned_int (buf, value);
  return (*stream->write) (stream->physical, (char*)buf, len);
}

static inline int
__objc_code_int (unsigned char *buf, int val)
{
  int sign = (val < 0);
  int size = __objc_code_unsigned_int (buf, sign ? -val : val);
  if (sign)
    buf[0] |= _B_SIGN;
  return size;
}

int
objc_write_int (struct objc_typed_stream *stream, int value)
{
  unsigned char buf[sizeof (int) + 1];
  int len = __objc_code_int (buf, value);
  return (*stream->write) (stream->physical, (char*)buf, len);
}

static inline int
__objc_code_unsigned_long (unsigned char *buf, unsigned long val)
{
  if ((val&_B_VALUE) == val)
    {
      buf[0] = val|_B_SINT;
      return 1;
    }
  else 
    {
      int c, b;

      buf[0] = _B_NINT;

      for (c = sizeof (long); c != 0; c -= 1)
	if (((val >> (8*(c - 1)))%0x100) != 0)
	  break;

      buf[0] |= c;

      for (b = 1; c != 0; c--, b++)
	{
	  buf[b] = (val >> (8*(c - 1)))%0x100;
	}

      return b;
    }
}

int
objc_write_unsigned_long (struct objc_typed_stream *stream, 
			  unsigned long value)
{
  unsigned char buf[sizeof (unsigned long) + 1];
  int len = __objc_code_unsigned_long (buf, value);
  return (*stream->write) (stream->physical, (char*)buf, len);
}

static inline int
__objc_code_long (unsigned char *buf, long val)
{
  int sign = (val < 0);
  int size = __objc_code_unsigned_long (buf, sign ? -val : val);
  if (sign)
    buf[0] |= _B_SIGN;
  return size;
}

int
objc_write_long (struct objc_typed_stream *stream, long value)
{
  unsigned char buf[sizeof (long) + 1];
  int len = __objc_code_long (buf, value);
  return (*stream->write) (stream->physical, (char*)buf, len);
}


int
objc_write_string (struct objc_typed_stream *stream,
		   const unsigned char *string, unsigned int nbytes)
{
  unsigned char buf[sizeof (unsigned int) + 1];
  int len = __objc_code_unsigned_int (buf, nbytes);
  
  if ((buf[0]&_B_CODE) == _B_SINT)
    buf[0] = (buf[0]&_B_VALUE)|_B_SSTR;

  else /* _B_NINT */
    buf[0] = (buf[0]&_B_VALUE)|_B_NSTR;

  if ((*stream->write) (stream->physical, (char*)buf, len) != 0)
    return (*stream->write) (stream->physical, (char*)string, nbytes);
  else
    return 0;
}

int
objc_write_string_atomic (struct objc_typed_stream *stream,
			  unsigned char *string, unsigned int nbytes)
{
  unsigned long key;
  if ((key = PTR2LONG(objc_hash_value_for_key (stream->stream_table, string))))
    return objc_write_use_common (stream, key);
  else
    {
      int length;
      objc_hash_add (&stream->stream_table,
		     LONG2PTR(key=PTR2LONG(string)), string);
      if ((length = objc_write_register_common (stream, key)))
	return objc_write_string (stream, string, nbytes);
      return length;
    }
}

static int
objc_write_register_common (struct objc_typed_stream *stream, 
			    unsigned long key)
{
  unsigned char buf[sizeof (unsigned long)+2];
  int len = __objc_code_unsigned_long (buf + 1, key);
  if (len == 1)
    {
      buf[0] = _B_RCOMM|0x01;
      buf[1] &= _B_VALUE;
      return (*stream->write) (stream->physical, (char*)buf, len + 1);
    }
  else
    {
      buf[1] = (buf[1]&_B_VALUE)|_B_RCOMM;
      return (*stream->write) (stream->physical, (char*)buf + 1, len);
    }
}

static int
objc_write_use_common (struct objc_typed_stream *stream, unsigned long key)
{
  unsigned char buf[sizeof (unsigned long)+2];
  int len = __objc_code_unsigned_long (buf + 1, key);
  if (len == 1)
    {
      buf[0] = _B_UCOMM|0x01;
      buf[1] &= _B_VALUE;
      return (*stream->write) (stream->physical, (char*)buf, 2);
    }
  else
    {
      buf[1] = (buf[1]&_B_VALUE)|_B_UCOMM;
      return (*stream->write) (stream->physical, (char*)buf + 1, len);
    }
}

static inline int
__objc_write_extension (struct objc_typed_stream *stream, unsigned char code)
{
  if (code <= _B_VALUE)
    {
      unsigned char buf = code|_B_EXT;
      return (*stream->write) (stream->physical, (char*)&buf, 1);
    }
  else 
    {
      _objc_abort ("__objc_write_extension: bad opcode %c\n", code);
      return -1;
    }
}

int
__objc_write_object (struct objc_typed_stream *stream, id object)
{
  unsigned char buf = '\0';
  SEL write_sel = sel_get_any_uid ("write:");
  if (object)
    {
      __objc_write_extension (stream, _BX_OBJECT);
      objc_write_class (stream, object->class_pointer);
      (*objc_msg_lookup (object, write_sel)) (object, write_sel, stream);
      return (*stream->write) (stream->physical, (char*)&buf, 1);
    }
  else
    return objc_write_use_common (stream, 0);
}

int 
objc_write_object_reference (struct objc_typed_stream *stream, id object)
{
  unsigned long key;
  if ((key = PTR2LONG(objc_hash_value_for_key (stream->object_table, object))))
    return objc_write_use_common (stream, key);

  __objc_write_extension (stream, _BX_OBJREF);
  return objc_write_unsigned_long (stream, PTR2LONG (object));
}

int 
objc_write_root_object (struct objc_typed_stream *stream, id object)
{
  int len = 0;
  if (stream->writing_root_p)
    _objc_abort ("objc_write_root_object called recursively");
  else
    {
      stream->writing_root_p = 1;
      __objc_write_extension (stream, _BX_OBJROOT);
      if ((len = objc_write_object (stream, object)))
	__objc_finish_write_root_object (stream);
      stream->writing_root_p = 0;
    }
  return len;
}

int 
objc_write_object (struct objc_typed_stream *stream, id object)
{
  unsigned long key;
  if ((key = PTR2LONG(objc_hash_value_for_key (stream->object_table, object))))
    return objc_write_use_common (stream, key);

  else if (object == nil)
    return objc_write_use_common (stream, 0);

  else
    {
      int length;
      objc_hash_add (&stream->object_table,
		     LONG2PTR(key=PTR2LONG(object)), object);
      if ((length = objc_write_register_common (stream, key)))
	return __objc_write_object (stream, object);
      return length;
    }
}

int
__objc_write_class (struct objc_typed_stream *stream, struct objc_class *class)
{
  __objc_write_extension (stream, _BX_CLASS);
  objc_write_string_atomic (stream, (unsigned char *) class->name,
			   strlen ((char *) class->name));
  return objc_write_unsigned_long (stream, class->version);
}


static int 
objc_write_class (struct objc_typed_stream *stream,
			 struct objc_class *class)
{
  unsigned long key;
  if ((key = PTR2LONG(objc_hash_value_for_key (stream->stream_table, class))))
    return objc_write_use_common (stream, key);
  else
    {
      int length;
      objc_hash_add (&stream->stream_table,
		     LONG2PTR(key = PTR2LONG(class)), class);
      if ((length = objc_write_register_common (stream, key)))
	return __objc_write_class (stream, class);
      return length;
    }
}


int 
__objc_write_selector (struct objc_typed_stream *stream, SEL selector)
{
  const char *sel_name;
  __objc_write_extension (stream, _BX_SEL);
  /* to handle NULL selectors */
  if ((SEL)0 == selector)
    return objc_write_string (stream, (unsigned char*)"", 0);
  sel_name = sel_get_name (selector);
  return objc_write_string (stream, (unsigned char*)sel_name, strlen ((char*)sel_name));
}

int 
objc_write_selector (struct objc_typed_stream *stream, SEL selector)
{
  const char *sel_name;
  unsigned long key;

  /* to handle NULL selectors */
  if ((SEL)0 == selector)
    return __objc_write_selector (stream, selector);

  sel_name = sel_get_name (selector);
  if ((key = PTR2LONG(objc_hash_value_for_key (stream->stream_table,
					       sel_name))))
    return objc_write_use_common (stream, key);
  else
    {
      int length;
      objc_hash_add (&stream->stream_table, 
		LONG2PTR(key = PTR2LONG(sel_name)), (char *) sel_name);
      if ((length = objc_write_register_common (stream, key)))
	return __objc_write_selector (stream, selector);
      return length;
    }
}



/*
** Read operations 
*/

int
objc_read_char (struct objc_typed_stream *stream, char *val)
{
  unsigned char buf;
  int len;
  len = (*stream->read) (stream->physical, (char*)&buf, 1);
  if (len != 0)
    {
      if ((buf & _B_CODE) == _B_SINT)
	(*val) = (buf & _B_VALUE);

      else if ((buf & _B_NUMBER) == 1)
	{
	  len = (*stream->read) (stream->physical, val, 1);
	  if (buf&_B_SIGN)
	    (*val) = -1 * (*val);
	}

      else
	_objc_abort ("expected 8bit signed int, got %dbit int",
		     (int) (buf&_B_NUMBER)*8);
    }
  return len;
}


int
objc_read_unsigned_char (struct objc_typed_stream *stream, unsigned char *val)
{
  unsigned char buf;
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)&buf, 1)))
    {
      if ((buf & _B_CODE) == _B_SINT)
	(*val) = (buf & _B_VALUE);

      else if ((buf & _B_NUMBER) == 1)
	len = (*stream->read) (stream->physical, (char*)val, 1);

      else
	_objc_abort ("expected 8bit unsigned int, got %dbit int",
		     (int) (buf&_B_NUMBER)*8);
    }
  return len;
}

int
objc_read_short (struct objc_typed_stream *stream, short *value)
{
  unsigned char buf[sizeof (short) + 1];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      if ((buf[0] & _B_CODE) == _B_SINT)
	(*value) = (buf[0] & _B_VALUE);

      else
	{
	  int pos = 1;
	  int nbytes = buf[0] & _B_NUMBER;
	  if (nbytes > (int) sizeof (short))
	    _objc_abort ("expected short, got bigger (%dbits)", nbytes*8);
	  len = (*stream->read) (stream->physical, (char*)buf + 1, nbytes);
	  (*value) = 0;
	  while (pos <= nbytes)
	    (*value) = ((*value)*0x100) + buf[pos++];
	  if (buf[0] & _B_SIGN)
	    (*value) = -(*value);
	}
    }
  return len;
}

int
objc_read_unsigned_short (struct objc_typed_stream *stream,
			  unsigned short *value)
{
  unsigned char buf[sizeof (unsigned short) + 1];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      if ((buf[0] & _B_CODE) == _B_SINT)
	(*value) = (buf[0] & _B_VALUE);

      else
	{
	  int pos = 1;
	  int nbytes = buf[0] & _B_NUMBER;
	  if (nbytes > (int) sizeof (short))
	    _objc_abort ("expected short, got int or bigger");
	  len = (*stream->read) (stream->physical, (char*)buf + 1, nbytes);
	  (*value) = 0;
	  while (pos <= nbytes)
	    (*value) = ((*value)*0x100) + buf[pos++];
	}
    }
  return len;
}


int
objc_read_int (struct objc_typed_stream *stream, int *value)
{
  unsigned char buf[sizeof (int) + 1];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      if ((buf[0] & _B_CODE) == _B_SINT)
	(*value) = (buf[0] & _B_VALUE);

      else
	{
	  int pos = 1;
	  int nbytes = buf[0] & _B_NUMBER;
	  if (nbytes > (int) sizeof (int))
	    _objc_abort ("expected int, got bigger");
	  len = (*stream->read) (stream->physical, (char*)buf + 1, nbytes);
	  (*value) = 0;
	  while (pos <= nbytes)
	    (*value) = ((*value)*0x100) + buf[pos++];
	  if (buf[0] & _B_SIGN)
	    (*value) = -(*value);
	}
    }
  return len;
}

int
objc_read_long (struct objc_typed_stream *stream, long *value)
{
  unsigned char buf[sizeof (long) + 1];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      if ((buf[0] & _B_CODE) == _B_SINT)
	(*value) = (buf[0] & _B_VALUE);

      else
	{
	  int pos = 1;
	  int nbytes = buf[0] & _B_NUMBER;
	  if (nbytes > (int) sizeof (long))
	    _objc_abort ("expected long, got bigger");
	  len = (*stream->read) (stream->physical, (char*)buf + 1, nbytes);
	  (*value) = 0;
	  while (pos <= nbytes)
	    (*value) = ((*value)*0x100) + buf[pos++];
	  if (buf[0] & _B_SIGN)
	    (*value) = -(*value);
	}
    }
  return len;
}

int
__objc_read_nbyte_uint (struct objc_typed_stream *stream,
			unsigned int nbytes, unsigned int *val)
{
  int len;
  unsigned int pos = 0;
  unsigned char buf[sizeof (unsigned int) + 1];

  if (nbytes > sizeof (int))
    _objc_abort ("expected int, got bigger");

  len = (*stream->read) (stream->physical, (char*)buf, nbytes);
  (*val) = 0;
  while (pos < nbytes)
    (*val) = ((*val)*0x100) + buf[pos++];
  return len;
}
  

int
objc_read_unsigned_int (struct objc_typed_stream *stream,
			unsigned int *value)
{
  unsigned char buf[sizeof (unsigned int) + 1];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      if ((buf[0] & _B_CODE) == _B_SINT)
	(*value) = (buf[0] & _B_VALUE);

      else
	len = __objc_read_nbyte_uint (stream, (buf[0] & _B_VALUE), value);

    }
  return len;
}

int
__objc_read_nbyte_ulong (struct objc_typed_stream *stream,
		       unsigned int nbytes, unsigned long *val)
{
  int len;
  unsigned int pos = 0;
  unsigned char buf[sizeof (unsigned long) + 1];

  if (nbytes > sizeof (long))
    _objc_abort ("expected long, got bigger");

  len = (*stream->read) (stream->physical, (char*)buf, nbytes);
  (*val) = 0;
  while (pos < nbytes)
    (*val) = ((*val)*0x100) + buf[pos++];
  return len;
}
  

int
objc_read_unsigned_long (struct objc_typed_stream *stream,
			 unsigned long *value)
{
  unsigned char buf[sizeof (unsigned long) + 1];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      if ((buf[0] & _B_CODE) == _B_SINT)
	(*value) = (buf[0] & _B_VALUE);

      else
	len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), value);

    }
  return len;
}

int
objc_read_string (struct objc_typed_stream *stream,
		  char **string)
{
  unsigned char buf[sizeof (unsigned int) + 1];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      unsigned long key = 0;

      if ((buf[0]&_B_CODE) == _B_RCOMM)	/* register following */
	{
	  len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key);
	  len = (*stream->read) (stream->physical, (char*)buf, 1);
	}

      switch (buf[0]&_B_CODE) {
      case _B_SSTR:
	{
	  int length = buf[0]&_B_VALUE;
	  (*string) = (char*)objc_malloc (length + 1);
	  if (key)
	    objc_hash_add (&stream->stream_table, LONG2PTR(key), *string);
	  len = (*stream->read) (stream->physical, *string, length);
	  (*string)[length] = '\0';
	}
	break;

      case _B_UCOMM:
	{
	  char *tmp;
	  len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key);
	  tmp = objc_hash_value_for_key (stream->stream_table, LONG2PTR (key));
	  *string = objc_malloc (strlen (tmp) + 1);
	  strcpy (*string, tmp);
	}
	break;

      case _B_NSTR:
	{
	  unsigned int nbytes = buf[0]&_B_VALUE;
	  len = __objc_read_nbyte_uint (stream, nbytes, &nbytes);
	  if (len) {
	    (*string) = (char*)objc_malloc (nbytes + 1);
	    if (key)
	      objc_hash_add (&stream->stream_table, LONG2PTR(key), *string);
	    len = (*stream->read) (stream->physical, *string, nbytes);
	    (*string)[nbytes] = '\0';
	  }
	}
	break;
	
      default:
	_objc_abort ("expected string, got opcode %c\n", (buf[0]&_B_CODE));
      }
    }

  return len;
}


int
objc_read_object (struct objc_typed_stream *stream, id *object)
{
  unsigned char buf[sizeof (unsigned int)];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      SEL read_sel = sel_get_any_uid ("read:");
      unsigned long key = 0;

      if ((buf[0]&_B_CODE) == _B_RCOMM)	/* register common */
	{
	  len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key);
	  len = (*stream->read) (stream->physical, (char*)buf, 1);
	}

      if (buf[0] == (_B_EXT | _BX_OBJECT))
	{
	  Class class;

	  /* get class */
	  len = objc_read_class (stream, &class);

	  /* create instance */
	  (*object) = class_create_instance (class);

	  /* register? */
	  if (key)
	    objc_hash_add (&stream->object_table, LONG2PTR(key), *object);

	  /* send -read: */
	  if (__objc_responds_to (*object, read_sel))
	    (*get_imp (class, read_sel)) (*object, read_sel, stream);

	  /* check null-byte */
	  len = (*stream->read) (stream->physical, (char*)buf, 1);
	  if (buf[0] != '\0')
	    _objc_abort ("expected null-byte, got opcode %c", buf[0]);
	}

      else if ((buf[0]&_B_CODE) == _B_UCOMM)
	{
	  if (key)
	    _objc_abort ("cannot register use upcode...");
	  len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key);
	  (*object) = objc_hash_value_for_key (stream->object_table,
					       LONG2PTR(key));
	}

      else if (buf[0] == (_B_EXT | _BX_OBJREF))	/* a forward reference */
	{
	  struct objc_list *other;
	  len = objc_read_unsigned_long (stream, &key);
	  other 
	    = (struct objc_list *) objc_hash_value_for_key (stream->object_refs, 
							   LONG2PTR(key));
	  objc_hash_add (&stream->object_refs, LONG2PTR(key), 
			 (void *)list_cons (object, other));
	}

      else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */
	{
	  if (key)
	    _objc_abort ("cannot register root object...");
	  len = objc_read_object (stream, object);
	  __objc_finish_read_root_object (stream);
	}

      else
	_objc_abort ("expected object, got opcode %c", buf[0]);
    }
  return len;
}

static int
objc_read_class (struct objc_typed_stream *stream, Class *class)
{
  unsigned char buf[sizeof (unsigned int)];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      unsigned long key = 0;

      if ((buf[0]&_B_CODE) == _B_RCOMM)	/* register following */
	{
	  len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key);
	  len = (*stream->read) (stream->physical, (char*)buf, 1);
	}

      if (buf[0] == (_B_EXT | _BX_CLASS))
	{
	  char temp[1] = "";
	  char *class_name = temp;
	  unsigned long version;

	  /* get class */
	  len = objc_read_string (stream, &class_name);
	  (*class) = objc_get_class (class_name);
	  objc_free (class_name);

	  /* register */
	  if (key)
	    objc_hash_add (&stream->stream_table, LONG2PTR(key), *class);

	  objc_read_unsigned_long (stream, &version);
	  objc_hash_add (&stream->class_table,
			 (*class)->name, (void *) ((size_t) version));
	}

      else if ((buf[0]&_B_CODE) == _B_UCOMM)
	{
	  if (key)
	    _objc_abort ("cannot register use upcode...");
	  len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key);
	  *class = objc_hash_value_for_key (stream->stream_table,
					    LONG2PTR(key));
	  if (! *class)
	    _objc_abort ("cannot find class for key %lu", key);
	}

      else
	_objc_abort ("expected class, got opcode %c", buf[0]);
    }
  return len;
}

int
objc_read_selector (struct objc_typed_stream *stream, SEL* selector)
{
  unsigned char buf[sizeof (unsigned int)];
  int len;
  if ((len = (*stream->read) (stream->physical, (char*)buf, 1)))
    {
      unsigned long key = 0;

      if ((buf[0]&_B_CODE) == _B_RCOMM)	/* register following */
	{
	  len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key);
	  len = (*stream->read) (stream->physical, (char*)buf, 1);
	}

      if (buf[0] == (_B_EXT|_BX_SEL)) /* selector! */
	{
	  char temp[1] = "";
	  char *selector_name = temp;

	  /* get selector */
	  len = objc_read_string (stream, &selector_name);
	  /* To handle NULL selectors */
	  if (0 == strlen (selector_name))
	    {
	      (*selector) = (SEL)0;
	      return 0;
	    }
	  else 
	    (*selector) = sel_get_any_uid (selector_name);
	  objc_free (selector_name);

	  /* register */
	  if (key)
	    objc_hash_add (&stream->stream_table,
			   LONG2PTR(key), (void *) *selector);
	}

      else if ((buf[0]&_B_CODE) == _B_UCOMM)
	{
	  if (key)
	    _objc_abort ("cannot register use upcode...");
	  len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key);
	  (*selector) = objc_hash_value_for_key (stream->stream_table, 
						 LONG2PTR(key));
	}

      else
	_objc_abort ("expected selector, got opcode %c", buf[0]);
    }
  return len;
}

/*
** USER LEVEL FUNCTIONS
*/

/*
** Write one object, encoded in TYPE and pointed to by DATA to the
** typed stream STREAM.  
*/

int
objc_write_type (TypedStream *stream, const char *type, const void *data)
{
  switch (*type) {
  case _C_ID:
    return objc_write_object (stream, *(id *) data);
    break;

  case _C_CLASS:
    return objc_write_class (stream, *(Class *) data);
    break;

  case _C_SEL:
    return objc_write_selector (stream, *(SEL *) data);
    break;

  case _C_CHR:
    return objc_write_char (stream, *(signed char *) data);
    break;
    
  case _C_UCHR:
    return objc_write_unsigned_char (stream, *(unsigned char *) data);
    break;

  case _C_SHT:
    return objc_write_short (stream, *(short *) data);
    break;

  case _C_USHT:
    return objc_write_unsigned_short (stream, *(unsigned short *) data);
    break;

  case _C_INT:
    return objc_write_int (stream, *(int *) data);
    break;

  case _C_UINT:
    return objc_write_unsigned_int (stream, *(unsigned int *) data);
    break;

  case _C_LNG:
    return objc_write_long (stream, *(long *) data);
    break;

  case _C_ULNG:
    return objc_write_unsigned_long (stream, *(unsigned long *) data);
    break;

  case _C_CHARPTR:
    return objc_write_string (stream,
			      *(unsigned char **) data, strlen (*(char **) data));
    break;

  case _C_ATOM:
    return objc_write_string_atomic (stream, *(unsigned char **) data, 
				     strlen (*(char **) data));
    break;

  case _C_ARY_B:
    {
      int len = atoi (type + 1);
      while (isdigit ((unsigned char) *++type))
	;
      return objc_write_array (stream, type, len, data);
    }
    break; 

  case _C_STRUCT_B:
    {
      int acc_size = 0;
      int align;
      while (*type != _C_STRUCT_E && *type++ != '=')
	; /* skip "<name>=" */
      while (*type != _C_STRUCT_E)
	{
	  align = objc_alignof_type (type);       /* padd to alignment */
	  acc_size = ROUND (acc_size, align);
	  objc_write_type (stream, type, ((char *) data) + acc_size);
	  acc_size += objc_sizeof_type (type);   /* add component size */
	  type = objc_skip_typespec (type);	 /* skip component */
	}
      return 1;
    }

  default:
    {
      _objc_abort ("objc_write_type: cannot parse typespec: %s\n", type);
      return 0;
    }
  }
}

/*
** Read one object, encoded in TYPE and pointed to by DATA to the
** typed stream STREAM.  DATA specifies the address of the types to
** read.  Expected type is checked against the type actually present
** on the stream. 
*/

int
objc_read_type(TypedStream *stream, const char *type, void *data)
{
  char c;
  switch (c = *type) {
  case _C_ID:
    return objc_read_object (stream, (id*)data);
    break;

  case _C_CLASS:
    return objc_read_class (stream, (Class*)data);
    break;

  case _C_SEL:
    return objc_read_selector (stream, (SEL*)data);
    break;

  case _C_CHR:
    return objc_read_char (stream, (char*)data);
    break;
    
  case _C_UCHR:
    return objc_read_unsigned_char (stream, (unsigned char*)data);
    break;

  case _C_SHT:
    return objc_read_short (stream, (short*)data);
    break;

  case _C_USHT:
    return objc_read_unsigned_short (stream, (unsigned short*)data);
    break;

  case _C_INT:
    return objc_read_int (stream, (int*)data);
    break;

  case _C_UINT:
    return objc_read_unsigned_int (stream, (unsigned int*)data);
    break;

  case _C_LNG:
    return objc_read_long (stream, (long*)data);
    break;

  case _C_ULNG:
    return objc_read_unsigned_long (stream, (unsigned long*)data);
    break;

  case _C_CHARPTR:
  case _C_ATOM:
    return objc_read_string (stream, (char**)data);
    break;

  case _C_ARY_B:
    {
      int len = atoi (type + 1);
      while (isdigit ((unsigned char) *++type))
	;
      return objc_read_array (stream, type, len, data);
    }
    break; 

  case _C_STRUCT_B:
    {
      int acc_size = 0;
      int align;
      while (*type != _C_STRUCT_E && *type++ != '=')
	; /* skip "<name>=" */
      while (*type != _C_STRUCT_E)
	{
	  align = objc_alignof_type (type);       /* padd to alignment */
	  acc_size = ROUND (acc_size, align);
	  objc_read_type (stream, type, ((char*)data)+acc_size);
	  acc_size += objc_sizeof_type (type);   /* add component size */
	  type = objc_skip_typespec (type);	 /* skip component */
	}
      return 1;
    }

  default:
    {
      _objc_abort ("objc_read_type: cannot parse typespec: %s\n", type);
      return 0;
    }
  }
}

/*
** Write the object specified by the template TYPE to STREAM.  Last
** arguments specify addresses of values to be written.  It might 
** seem surprising to specify values by address, but this is extremely
** convenient for copy-paste with objc_read_types calls.  A more
** down-to-the-earth cause for this passing of addresses is that values
** of arbitrary size is not well supported in ANSI C for functions with
** variable number of arguments.
*/

int 
objc_write_types (TypedStream *stream, const char *type, ...)
{
  va_list args;
  const char *c;
  int res = 0;

  va_start(args, type);

  for (c = type; *c; c = objc_skip_typespec (c))
    {
      switch (*c) {
      case _C_ID:
	res = objc_write_object (stream, *va_arg (args, id*));
	break;

      case _C_CLASS:
	res = objc_write_class (stream, *va_arg (args, Class*));
	break;

      case _C_SEL:
	res = objc_write_selector (stream, *va_arg (args, SEL*));
	break;
	
      case _C_CHR:
	res = objc_write_char (stream, *va_arg (args, char*));
	break;
	
      case _C_UCHR:
	res = objc_write_unsigned_char (stream,
					*va_arg (args, unsigned char*));
	break;
	
      case _C_SHT:
	res = objc_write_short (stream, *va_arg (args, short*));
	break;

      case _C_USHT:
	res = objc_write_unsigned_short (stream,
					 *va_arg (args, unsigned short*));
	break;

      case _C_INT:
	res = objc_write_int(stream, *va_arg (args, int*));
	break;
	
      case _C_UINT:
	res = objc_write_unsigned_int(stream, *va_arg (args, unsigned int*));
	break;

      case _C_LNG:
	res = objc_write_long(stream, *va_arg (args, long*));
	break;
	
      case _C_ULNG:
	res = objc_write_unsigned_long(stream, *va_arg (args, unsigned long*));
	break;

      case _C_CHARPTR:
	{
	  unsigned char **str = va_arg (args, unsigned char **);
	  res = objc_write_string (stream, *str, strlen ((char*)*str));
	}
	break;

      case _C_ATOM:
	{
	  unsigned char **str = va_arg (args, unsigned char **);
	  res = objc_write_string_atomic (stream, *str, strlen ((char*)*str));
	}
	break;

      case _C_ARY_B:
	{
	  int len = atoi (c + 1);
	  const char *t = c;
	  while (isdigit ((unsigned char) *++t))
	    ;
	  res = objc_write_array (stream, t, len, va_arg (args, void *));
	  t = objc_skip_typespec (t);
	  if (*t != _C_ARY_E)
	    _objc_abort ("expected `]', got: %s", t);
	}
	break; 
	
      default:
	_objc_abort ("objc_write_types: cannot parse typespec: %s\n", type);
      }
    }
  va_end(args);
  return res;
}


/* 
** Last arguments specify addresses of values to be read.  Expected
** type is checked against the type actually present on the stream. 
*/

int 
objc_read_types(TypedStream *stream, const char *type, ...)
{
  va_list args;
  const char *c;
  int res = 0;

  va_start (args, type);

  for (c = type; *c; c = objc_skip_typespec(c))
    {
      switch (*c) {
      case _C_ID:
	res = objc_read_object(stream, va_arg (args, id*));
	break;

      case _C_CLASS:
	res = objc_read_class(stream, va_arg (args, Class*));
	break;

      case _C_SEL:
	res = objc_read_selector(stream, va_arg (args, SEL*));
	break;
	
      case _C_CHR:
	res = objc_read_char(stream, va_arg (args, char*));
	break;
	
      case _C_UCHR:
	res = objc_read_unsigned_char(stream, va_arg (args, unsigned char*));
	break;
	
      case _C_SHT:
	res = objc_read_short(stream, va_arg (args, short*));
	break;

      case _C_USHT:
	res = objc_read_unsigned_short(stream, va_arg (args, unsigned short*));
	break;

      case _C_INT:
	res = objc_read_int(stream, va_arg (args, int*));
	break;
	
      case _C_UINT:
	res = objc_read_unsigned_int(stream, va_arg (args, unsigned int*));
	break;

      case _C_LNG:
	res = objc_read_long(stream, va_arg (args, long*));
	break;
	
      case _C_ULNG:
	res = objc_read_unsigned_long(stream, va_arg (args, unsigned long*));
	break;

      case _C_CHARPTR:
      case _C_ATOM:
	{
	  char **str = va_arg (args, char **);
	  res = objc_read_string (stream, str);
	}
	break;

      case _C_ARY_B:
	{
	  int len = atoi (c + 1);
	  const char *t = c;
	  while (isdigit ((unsigned char) *++t))
	    ;
	  res = objc_read_array (stream, t, len, va_arg (args, void *));
	  t = objc_skip_typespec (t);
	  if (*t != _C_ARY_E)
	    _objc_abort ("expected `]', got: %s", t);
	}
	break; 
	
      default:
	_objc_abort ("objc_read_types: cannot parse typespec: %s\n", type);
      }
    }
  va_end (args);
  return res;
}

/*
** Write an array of COUNT elements of TYPE from the memory address DATA.
** This is equivalent of objc_write_type (stream, "[N<type>]", data)
*/

int
objc_write_array (TypedStream *stream, const char *type,
		  int count, const void *data)
{
  int off = objc_sizeof_type(type);
  const char *where = data;

  while (count-- > 0)
    {
      objc_write_type(stream, type, where);
      where += off;
    }
  return 1;
}

/*
** Read an array of COUNT elements of TYPE into the memory address
** DATA.  The memory pointed to by data is supposed to be allocated
** by the callee.  This is equivalent of 
**   objc_read_type (stream, "[N<type>]", data)
*/

int
objc_read_array (TypedStream *stream, const char *type,
		 int count, void *data)
{
  int off = objc_sizeof_type(type);
  char *where = (char*)data;

  while (count-- > 0)
    {
      objc_read_type(stream, type, where);
      where += off;
    }
  return 1;
}

static int 
__objc_fread (FILE *file, char *data, int len)
{
  return fread(data, len, 1, file);
}

static int 
__objc_fwrite (FILE *file, char *data, int len)
{
  return fwrite(data, len, 1, file);
}

static int
__objc_feof (FILE *file)
{
  return feof(file);
}

static int 
__objc_no_write (FILE *file __attribute__ ((__unused__)),
		 const char *data __attribute__ ((__unused__)),
		 int len __attribute__ ((__unused__)))
{
  _objc_abort ("TypedStream not open for writing");
  return 0;
}

static int 
__objc_no_read (FILE *file __attribute__ ((__unused__)),
		const char *data __attribute__ ((__unused__)),
		int len __attribute__ ((__unused__)))
{
  _objc_abort ("TypedStream not open for reading");
  return 0;
}

static int
__objc_read_typed_stream_signature (TypedStream *stream)
{
  char buffer[80];
  int pos = 0;
  do
    (*stream->read) (stream->physical, buffer+pos, 1);
  while (buffer[pos++] != '\0')
    ;
  sscanf (buffer, "GNU TypedStream %d", &stream->version);
  if (stream->version != OBJC_TYPED_STREAM_VERSION)
    _objc_abort ("cannot handle TypedStream version %d", stream->version);
  return 1;
}

static int
__objc_write_typed_stream_signature (TypedStream *stream)
{
  char buffer[80];
  sprintf(buffer, "GNU TypedStream %d", OBJC_TYPED_STREAM_VERSION);
  stream->version = OBJC_TYPED_STREAM_VERSION;
  (*stream->write) (stream->physical, buffer, strlen (buffer) + 1);
  return 1;
}

static void __objc_finish_write_root_object(struct objc_typed_stream *stream)
{
  objc_hash_delete (stream->object_table);
  stream->object_table = objc_hash_new (64,
					(hash_func_type) objc_hash_ptr,
					(compare_func_type) objc_compare_ptrs);
}

static void __objc_finish_read_root_object(struct objc_typed_stream *stream)
{
  node_ptr node;
  SEL awake_sel = sel_get_any_uid ("awake");
  cache_ptr free_list = objc_hash_new (64,
				       (hash_func_type) objc_hash_ptr,
				       (compare_func_type) objc_compare_ptrs);

  /* resolve object forward references */
  for (node = objc_hash_next (stream->object_refs, NULL); node;
       node = objc_hash_next (stream->object_refs, node))
    {
      struct objc_list *reflist = node->value;
      const void *key = node->key;
      id object = objc_hash_value_for_key (stream->object_table, key);
      while (reflist)
	{
	  *((id*) reflist->head) = object;
	  if (objc_hash_value_for_key (free_list,reflist) == NULL)
	    objc_hash_add (&free_list,reflist,reflist);

	  reflist = reflist->tail;
	}
    }
    
  /* apply __objc_free to all objects stored in free_list */
  for (node = objc_hash_next (free_list, NULL); node;
       node = objc_hash_next (free_list, node))
    objc_free ((void *) node->key);

  objc_hash_delete (free_list);

  /* empty object reference table */
  objc_hash_delete (stream->object_refs);
  stream->object_refs = objc_hash_new (8, (hash_func_type) objc_hash_ptr,
				       (compare_func_type) objc_compare_ptrs);
  
  /* call -awake for all objects read  */
  if (awake_sel)
    {
      for (node = objc_hash_next (stream->object_table, NULL); node;
	   node = objc_hash_next (stream->object_table, node))
	{
	  id object = node->value;
	  if (__objc_responds_to (object, awake_sel))
	    (*objc_msg_lookup (object, awake_sel)) (object, awake_sel);
	}
    }

  /* empty object table */
  objc_hash_delete (stream->object_table);
  stream->object_table = objc_hash_new(64,
				       (hash_func_type)objc_hash_ptr,
				       (compare_func_type)objc_compare_ptrs);
}

/*
** Open the stream PHYSICAL in MODE
*/

TypedStream *
objc_open_typed_stream (FILE *physical, int mode)
{
  TypedStream *s = (TypedStream *) objc_malloc (sizeof (TypedStream));

  s->mode = mode;
  s->physical = physical;
  s->stream_table = objc_hash_new (64,
				   (hash_func_type) objc_hash_ptr,
				   (compare_func_type) objc_compare_ptrs);
  s->object_table = objc_hash_new (64,
				   (hash_func_type) objc_hash_ptr,
				   (compare_func_type) objc_compare_ptrs);
  s->eof = (objc_typed_eof_func) __objc_feof;
  s->flush = (objc_typed_flush_func) fflush;
  s->writing_root_p = 0;
  if (mode == OBJC_READONLY)
    {
      s->class_table 
	= objc_hash_new (8, (hash_func_type) objc_hash_string,
			 (compare_func_type) objc_compare_strings);
      s->object_refs = objc_hash_new (8, (hash_func_type) objc_hash_ptr,
				      (compare_func_type) objc_compare_ptrs);
      s->read = (objc_typed_read_func) __objc_fread;
      s->write = (objc_typed_write_func) __objc_no_write;
      __objc_read_typed_stream_signature (s);
    }
  else if (mode == OBJC_WRITEONLY)
    {
      s->class_table = 0;
      s->object_refs = 0;
      s->read = (objc_typed_read_func) __objc_no_read;
      s->write = (objc_typed_write_func) __objc_fwrite;
      __objc_write_typed_stream_signature (s);
    }      
  else
    {
      objc_close_typed_stream (s);
      return NULL;
    }
  s->type = OBJC_FILE_STREAM;
  return s;
}

/*
** Open the file named by FILE_NAME in MODE
*/

TypedStream*
objc_open_typed_stream_for_file (const char *file_name, int mode)
{
  FILE *file = NULL;
  TypedStream *s;

  if (mode == OBJC_READONLY)
    file = fopen (file_name, "r");
  else
    file = fopen (file_name, "w");

  if (file)
    {
      s = objc_open_typed_stream (file, mode);
      if (s)
	s->type |= OBJC_MANAGED_STREAM;
      return s;
    }
  else
    return NULL;
}

/*
** Close STREAM freeing the structure it self.  If it was opened with 
** objc_open_typed_stream_for_file, the file will also be closed.
*/

void
objc_close_typed_stream (TypedStream *stream)
{
  if (stream->mode == OBJC_READONLY)
    {
      __objc_finish_read_root_object (stream); /* Just in case... */
      objc_hash_delete (stream->class_table);
      objc_hash_delete (stream->object_refs);
    }

  objc_hash_delete (stream->stream_table);
  objc_hash_delete (stream->object_table);

  if (stream->type == (OBJC_MANAGED_STREAM | OBJC_FILE_STREAM))
    fclose ((FILE *)stream->physical);

  objc_free(stream);
}

BOOL
objc_end_of_typed_stream (TypedStream *stream)
{
  return (*stream->eof) (stream->physical);
}

void
objc_flush_typed_stream (TypedStream *stream)
{
  (*stream->flush) (stream->physical);
}

long
objc_get_stream_class_version (TypedStream *stream, Class class)
{
  if (stream->class_table)
    return PTR2LONG(objc_hash_value_for_key (stream->class_table,
					     class->name));
  else
    return class_get_version (class);
}

