

#if defined(HAVE_MAC_DIRS) || defined(__MWERKS__)
#include <LiDIA:gf2n.h>
#include <LiDIA:gf2nIO.h>
#else
#include <LiDIA/gf2n.h>
#include <LiDIA/gf2nIO.h>
#endif

#include <string.h>


void decin(gf2n & a, char* input_str);
void hexin(gf2n & a, char* input_str);

/* ================================================================ */

istream & operator >> (istream & in_strm, gf2n & a)
{
  char line[1000], c, *str;
  int i, length = 0;

#ifdef __GNUG__
  if (!in_strm.ipfx0())
#else
    if (!in_strm.ipfx(0))
#endif
      return in_strm;

  str = line;
  c = in_strm.get();

  if (c == EOF)
    {
      in_strm.setf(ios::failbit|ios::eofbit); 
      return in_strm;
    }
  
  while (isalpha(c)|| isdigit(c) || c == ':')
    {
      length++;
      if (isalpha(c))
	*str++ = toupper(c);
      else
	*str++ = c;
      c = in_strm.get();
      if (c == EOF)
	*str = '\0';
    }
  line[length] = '\0';

  i = 0;
  while(line[i] != ':' && i < length)
    i++;

  if (i == length)   /* no format given, take decimal input */
    {
      decin(a, line);
      return (in_strm);
    }
  else
    {
      str = line+i+1;
      line[i] = (char) NULL;

      if (strcmp(line, "HEX") == 0)
	{
	  hexin(a, str);
	  return (in_strm);
	}
      
      if (strcmp(line, "DEC") == 0)
	{
	  decin(a, str);
	  return (in_strm);
	}
      
      lidia_error_handler ("gf2n",">>(...)::wrong base");
    }
  return (in_strm);
}



/* ================================================================ */
/* Function hexin                                                   */
/* ================================================================ */

void hexin(gf2n & a, char* input_str)
{
  unsigned int i;
  int j;
  bigint h(0);
  char c;

  for (i=0; i< strlen(input_str); i++)
    {
      c = input_str[i];
   
      multiply(h, h, 16);
      j = c - '0';
      if (j >= 0 && j < 10)
	{
	  add(h, h, j);
	  continue;
	}
      c = toupper(c);
 
      j = c - 'A';
      if (j>=0 && j < 6)
	{
	  add(h, h, j+10);
	  continue;
	}
      else
	lidia_error_handler("gf2n","hexin::wrong input character ");
    }

  a.assign(h);
}
/* ================================================================ */
/* Function decin                                                   */
/* ================================================================ */
  
void decin(gf2n & a, char* input_str)
{
  bigint h(0);
  char c;
  unsigned int i;
  int  j;

  for (i=0; i < strlen(input_str); i++)
    {
      c = input_str[i];
      if (c == ' ')
	continue;
      
      multiply(h, h, 10);
      j = c - '0';
      if (j >= 0 && j < 10)
	{
	  add(h, h, j);
	  continue;
	}
      else
	lidia_error_handler("gf2n","decin()::wrong input character ");
    }
  
  a.assign(h);
}
	  
      
      
      






