static char rcsver[] = "$Id: convert.c,v 2.2 1999/07/12 23:14:08 gorelick Exp $";
 
/**
 ** $Source: /tes/src/vanilla/RCS/convert.c,v $
 **
 ** $Log: convert.c,v $
 ** Revision 2.2  1999/07/12 23:14:08  gorelick
 ** *** empty log message ***
 **
 ** Revision 2.1  1999/02/10 04:00:50  gorelick
 ** *** empty log message ***
 **
 ** Revision 2.0  1998/12/22 22:47:04  gorelick
 ** release version
 **
 ** Revision 2.0  1998/12/18 01:26:03  gorelick
 ** release version
 **
 ** Revision 1.10  1998/12/18 01:04:48  gorelick
 ** *** empty log message ***
 **
 ** Revision 1.9  1998/12/01 22:42:06  gorelick
 ** *** empty log message ***
 **
 ** Revision 1.8  1998/11/12 22:58:55  gorelick
 ** first release version
 **
 **/

#include "header.h"
#include "proto.h"



/**
 ** Convert an ascii representation of a field into a DATA
 **/

DATA ConvertASCIItoData(char *ascii, int i)
{
    DATA d;
    
    switch (i) {
    case INT:
        d.i = strtol(ascii, NULL, 10);
        break;
    case UINT:
		i = strtol(ascii, NULL, 10);
		if (i < 0) d.ui = 0;
		else d.ui = strtoul(ascii, NULL, 10);
        break;
    case REAL:
        d.r = strtod(ascii, NULL);
        break;
    case STRING:
        d.str = ascii;
        break;
    }
    
    return(d);
}

/**
 ** Convert data at <ptr> into a DATA using types specified by field <f>
 ** (<ptr> is not row pointer)
 **/

DATA ConvertFieldData(PTR ptr, FIELD *f)
{
	/* debug */
	if (f == NULL){ fprintf(stderr, "FIELD: NULL  PTR: %X\n", ptr); }
	if (!((long)ptr & 0xffff0000)){
		fprintf(stderr, "PTR: %X  FIELD: %s\n", ptr, f->name);
	}

	return(ConvertData(ptr + f->start, f));
}

DATA ConvertData(PTR ptr, FIELD *f)
{
    DATA d;
    char buf[16];

    switch (f->eformat) {
    case MSB_INTEGER: 
		{
			memcpy(buf, ptr, f->size);
			switch (f->size) {
			case 1:	d.i = ((char *)      buf)[0]; break;
			case 2: d.i = ((short *)MSB2(buf))[0]; break;
			case 4:	d.i = ((int *)  MSB4(buf))[0]; break;
			}
			break;
		}

    case MSB_UNSIGNED_INTEGER: 
		{
			memcpy(buf, ptr, f->size);
			switch (f->size) {
			case 1:	d.ui = ((uchar *)      buf)[0]; break;
			case 2: d.ui = ((ushort *)MSB2(buf))[0]; break;
			case 4:	d.ui = ((uint *)  MSB4(buf))[0]; break;
			}
			break;
		}

    case IEEE_REAL: 
		{
			memcpy(buf, ptr, f->size);
			switch (f->size) {
			case 4:	d.r = ((float *) MSB4(buf))[0]; break;
			case 8:	d.r = ((double *)MSB8(buf))[0]; break;
			}
			break;
		}

    case ASCII_INTEGER: 
		{
			memcpy(buf, ptr, f->size);
			buf[f->size] = '\0';
			d.i = atoi(buf);
			break;
		}

    case ASCII_REAL: 
		{
			memcpy(buf, ptr, f->size);
			buf[f->size] = '\0';
			d.r = atof(buf);
			break;
		}

    case CHARACTER: 
		{
			d.str = (char *)ptr;
			break;
		}
    }
	return(d);
}

/**
 ** Convert data at <ptr> to DATA using types specified by <v>
 **/

DATA ConvertVarData(PTR ptr, VARDATA *v)
{
  DATA d;
  char buf[16];

  switch (v->eformat) {
  case MSB_INTEGER: {
    memcpy(buf, ptr, v->size);
    switch (v->size) {
    case 1:	d.i = ((char *)buf)[0];  break;
    case 2: d.i = ((short *)MSB2(buf))[0]; break;
    case 4:	d.i = ((int *)  MSB4(buf))[0];   break;
    }
  }
  break;

  case MSB_UNSIGNED_INTEGER: {
    memcpy(buf, ptr, v->size);
    switch (v->size) {
    case 1:	d.ui = ((uchar *)buf)[0];  break;
    case 2: d.ui = ((ushort *)MSB2(buf))[0]; break;
    case 4:	d.ui = ((uint *)  MSB4(buf))[0];   break;
    }
  }
  break;

  case IEEE_REAL: {
    memcpy(buf, ptr, v->size);
    switch (v->size) {
    case 4:	d.r = ((float *) MSB4(buf))[0];  break;
    case 8:	d.r = ((double *)MSB8(buf))[0]; break;
    }
  }
  break;

  case ASCII_INTEGER: {
    memcpy(buf, ptr, v->size);
    buf[v->size] = '\0';
    d.i = atoi(buf);
  }
  break;

  case ASCII_REAL: {
    memcpy(buf, ptr, v->size);
    buf[v->size] = '\0';
    d.r = atof(buf);
  }
  break;

  case CHARACTER: {
    d.str = ptr;
  }
  break;
  }
  return(d);
}

int
EquivalentData(DATA d1, DATA d2, FIELD *f)
{
  switch (f->iformat) {
  case INT:
    return (d1.i == d2.i);
  case UINT:
    return (d1.ui == d2.ui);
  case REAL:
    return (d1.r == d2.r);
  case STRING:
    return (strncmp(d1.str, d2.str, f->size));
  }
    
}

int
CompareData(DATA d1, DATA d2, FIELD *f)
{
  DATA d;
    
  switch (f->iformat) {
  case INT:
    return ((d1.i < d2.i) ? -1 : ((d1.i == d2.i) ? 0 : 1));
  case UINT:
    return ((d1.ui < d2.ui) ? -1 : ((d1.ui == d2.ui) ? 0 : 1));
  case REAL:
    return ((d1.r < d2.r) ? -1 : ((d1.r == d2.r) ? 0 : 1));
  case STRING:
    return (strncmp(d1.str, d2.str, f->size));
  }
}