/*libintel.c - functions for manipulating numbers in Intel byte-order.
  Copyright (c) 1995 Matthew Belmonte

  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.

  If you find this program useful, please send mail to Matthew Belmonte.
  <mkb4@Cornell.edu>.  If you base a publication on data processed by this
  program, please notify Matthew Belmonte and include the following citation
  in your publication:

	Matthew Belmonte, `A Software System for Analysis of
	Steady-State Evoked Potentials', Association for Computing
	Machinery SIGBIO Newsletter 17:1:9-14 (April 1997).
*/

#include <stdio.h>
/*In the code that follows, floats are passed as doubles, in order to avoid
  confusion caused by default argument promotion.*/

short fetch_Intel_short(block, offset)
char *block;
int offset;
  {
  short result;
  char *x;
#ifdef M_I86
  x = (char *)&result;
  *(x++) = block[offset++];
#else
  x = ((char *)&result)+1;
  *(x--) = block[offset++];
#endif
  *x = block[offset];
  return(result);
  }

void store_Intel_short(block, offset, value)
char *block;
int offset;
short value;
  {
  block[offset++] = value & 0xff;
  block[offset] = (value >> 8) & 0xff;
  }

long fetch_Intel_long(block, offset)
char *block;
int offset;
  {
  long result;
  char *x;
#ifdef M_I86
  x = (char *)&result;
  *(x++) = block[offset++];
  *(x++) = block[offset++];
  *(x++) = block[offset++];
#else
  x = ((char *)&result)+3;
  *(x--) = block[offset++];
  *(x--) = block[offset++];
  *(x--) = block[offset++];
#endif
  *x = block[offset];
  return(result);
  }

void store_Intel_long(block, offset, value)
char *block;
int offset;
long value;
  {
  char *x;
#ifdef M_I86
  x = (char *)&value;
  block[offset++] = *(x++);
  block[offset++] = *(x++);
  block[offset++] = *(x++);
#else
  x = 3+(char *)&value;
  block[offset++] = *(x--);
  block[offset++] = *(x--);
  block[offset++] = *(x--);
#endif
  block[offset] = *x;
  }

double fetch_Intel_float(block, offset)
char *block;
int offset;
  {
  float result;
  char *x;
#ifdef M_I86
  x = (char *)&result;
  *(x++) = block[offset++];
  *(x++) = block[offset++];
  *(x++) = block[offset++];
#else
  x = ((char *)&result)+3;
  *(x--) = block[offset++];
  *(x--) = block[offset++];
  *(x--) = block[offset++];
#endif
  *x = block[offset];
  return((float)result);
  }

void store_Intel_float(block, offset, value)
char *block;
int offset;
double value;
  {
  char *x;
  float v;
  v = value;
#ifdef M_I86
  x = (char *)&v;
  block[offset++] = *(x++);
  block[offset++] = *(x++);
  block[offset++] = *(x++);
#else
  x = ((char *)&v)+3;
  block[offset++] = *(x--);
  block[offset++] = *(x--);
  block[offset++] = *(x--);
#endif
  block[offset] = *x;
  }

short read_Intel_short(fp)
FILE *fp;
  {
  register short result;
  result = getc(fp);
  result |= getc(fp)<<8;
  return(result);
  }

void write_Intel_short(v, fp)
short v;
FILE *fp;
  {
  putc((v & 0xff), fp);
  putc(((v>>8) & 0xff), fp);
  }

long read_Intel_long(fp)
FILE *fp;
  {
  char buf[sizeof(long)];
  fread(buf, 1, sizeof(long), fp);
  return(fetch_Intel_long(buf, 0));
  }

void write_Intel_long(v, fp)
long v;
FILE *fp;
  {
  char buf[sizeof(long)];
  store_Intel_long(buf, 0, v);
  fwrite(buf, 1, sizeof(long), fp);
  }

double read_Intel_float(fp)
FILE *fp;
  {
  float result;
  fread(&result, sizeof(float), 1, fp);
#ifdef M_I86
  return((double)result);
#else
  return(fetch_Intel_float((char *)&result, 0));
#endif
  }

void write_Intel_float(value, fp)
double value;
FILE *fp;
  {
  float v;
#ifdef M_I86
  v = value;
  fwrite(&v, sizeof(float), 1, fp);
#else
  v = value;
  store_Intel_float((char *)&v, 0, v);
  fwrite(&v, sizeof(float), 1, fp);
#endif
  }
