# include "autocode.h"

int gfits_convert_$STRUCT ($STRUCT *data, int size, int nitems) {

  int i;
  unsigned char *byte, tmp;

  if (size != $SIZE) { 
    fprintf (stderr, "ERROR: mismatch in data types $STRUCT: %d vs %d\n",
	     size, $SIZE);
    exit (1);
  }

  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
  i = tmp = 0;
  byte = NULL;

# ifdef BYTE_SWAP
  byte = (unsigned char *) data;
  for (i = 0; i < nitems; i++, byte += $SIZE) {
    /** BYTE SWAP **/
  }
# endif  

  return (TRUE);
} 

/*** add test of EXTNAME and header-defined columns? ***/
/* return internal structure representation */
$STRUCT *gfits_table_get_$STRUCT (FTable *ftable, int *Ndata, int *swapped) {

  $STRUCT *data;

  *Ndata = ftable[0].header[0].Naxis[1];
  data = ($STRUCT *) ftable[0].buffer;
  if ((swapped == NULL) || (*swapped == FALSE)) {
    gfits_convert_$STRUCT (data, sizeof ($STRUCT), *Ndata);
    gfits_table_scale_data (ftable);
    if (swapped != NULL) *swapped = TRUE;
  }
  return (data);
}

int gfits_table_set_$STRUCT (FTable *ftable, $STRUCT *data, int Ndata) {

  Header *header;

  header = ftable[0].header;

  /* create table header */
  gfits_create_table_header (header, "$TYPE", "$EXTNAME");

  /* define table layout */
  /** TABLE DEFINITION **/

  /* create table */
  gfits_create_table (header, ftable);

  /* add data values */
  gfits_table_scale_data (ftable);
  gfits_convert_$STRUCT (data, sizeof ($STRUCT), Ndata);
  gfits_add_rows (ftable, (char *) data, Ndata, sizeof ($STRUCT));

  return (TRUE);
}

int gfits_table_mkheader_$STRUCT (Header *header) {

  /* create table header */
  gfits_create_table_header (header, "$TYPE", "$EXTNAME");

  /* define table layout */
  /** TABLE DEFINITION **/

  return (TRUE);
}

int Send_$STRUCT (int device, $STRUCT *data, int Ndata, int copy) {

  int Nbytes;
  $STRUCT *tmpdata;

  Nbytes = Ndata * sizeof ($STRUCT);

  if (copy) {
    ALLOCATE (tmpdata, $STRUCT, Ndata);
    memcpy (tmpdata, data, Nbytes);
  } else {
    tmpdata = data;
  }

  gfits_convert_$STRUCT (tmpdata, sizeof ($STRUCT), Ndata);

  SendCommand (device, 16, "NVALUE: %6d", Ndata);
  SendCommand (device, 16, "NBYTES: %6d", Nbytes);
  write (device, tmpdata, Nbytes);
  
  /* perform handshaking? */

  return (TRUE);
}

int Recv_$STRUCT (int device, $STRUCT **data, int *Ndata) {

  int ndata;
  IOBuffer message;
  $STRUCT *tmpdata;

  ExpectCommand (device, 16, 1.0, &message);
  sscanf (message.buffer, "%*s %d", &ndata);
  FreeIOBuffer (&message);
  
  /* what is reasonable for timeout? */
  ExpectMessage (device, 1.0, &message);
  
  tmpdata = ($STRUCT *) message.buffer;
  gfits_convert_$STRUCT (tmpdata, sizeof ($STRUCT), ndata);

  /* double-check data length? */
  /* perform handshaking? */

  *Ndata = ndata;
  *data = tmpdata;

  return (TRUE);
}
