/*!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!*/
/*NING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARN*/
/*!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!*/
/*                                                                         */
/*  This file is used in prostar, star4 and comet.  It MUST BE EXACTLY     */
/*  the same for all systems.                                              */
/*                                                                         */
/*!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!*/
/*NING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARN*/
/*!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!WARNING!*/

/*
 *  Program: pro-am - polyfile
 *  Author:  Rajeev Palankar
 *  Date:    2002 September 27.
 *  Desc:    Performs all IO to/from face base model file.
 *
 *  pro-am Copyright (C) 2002 by adapco, Ltd.
 *
 *  This program is the property of adapco, Ltd. and contains
 *  confidential and proprietary information.  The unauthorized use,
 *  distribution, or duplication of this program is prohibited.
 *  All rights reserved.
 */

static volatile const char rcsid[] =
  "@(#) $Id: polyfile.c,v 1.1 2004/01/26 19:12:05 prewett Exp $";

#if defined(__GNUC__) && __GNUC__ >= 2
/* static volatile const void *use_rcsid = (&use_rcsid, &rcsid); */
#endif



#include "polyfile.h"

#define PFERROR(x) *ierr=(x);return;
#define MAXSTRSIZE 512
/*
*ierr   =0  No error
        =1  file read write error
        =2  xdr error
        =3  not of current type(only for reading)
        =4  file in read mode
        =5  file in write mode
        =6  reached end of type #tag
        =7  did not reached end of type #tag
        =8  memory error while allocating scratch memory
        =9  reached end of file
        =10 Invalid file header identification string
        =11 Unsupported file version
*/

static FILE *polyfile_fp;
static long presentpos;
static long headerpos;
static int  currtag;
static int  currtype;
/*
currtype
        =1  vertex single precision
        =2  shell
        =3  boundary
        =4  face
        =5  cell
        =6  vertex map
        =7  shell map
        =8  boundary map
        =9  face map
        =10 cell  map
        =11 Vertex double precision
        =12 Interface Section
        =13 Scalar Section
        =14 Cell (stefano request)
        =15 Cell map (stefano request)
*/
static int  currmaxid;
static int  currcount;
static int  currno;
static int  rwflag=-1;
static int  dataint=0;
static int  *pvlis=0;
static int  maxalloclis=100;

/* polyfile version number. */
#define MAX_VERSION 2
static int polyfile_version;


void polyfile_open (char *fname, int *flen, int *rw, int *ierr)
/*
        fname   =filename
        flen    =strlen of filename
        rw      =0 (write to file),
                 1 (read from file),
                 2 (write to coded file, debug ONLY)
        ierr    =0 no error
*/
{
  XDR xdrs;
  enum xdr_op op;
  char *str,*str2;
  char str1[40]="PROSTAR/STAR4 Polyfile";
  polyfile_version = MAX_VERSION;
  *ierr=0;
  str=(char *)malloc(sizeof(char)*(*flen+1));
  strncpy(str,fname,*flen);
  str[*flen]=0;
  rwflag = *rw;
  currno = 0;
  currcount = 0;
  if(rwflag == 1)
  {
    polyfile_fp=fopen(str,"rb");
    if(!polyfile_fp)
    {
       *ierr=1;
       return;
    }
#if defined(WIN32)
    // turn off buffering so that file pointer will not get moved
    // when a fflush is performed (stupid Windows bug)
    setvbuf(polyfile_fp,NULL,_IONBF,0);
#endif
    op=XDR_DECODE;
    xdrstdio_create(&xdrs,polyfile_fp, op);
    str2=(char *) malloc(40*sizeof(char));
    if (!xdr_string(&xdrs,&str2,39)){PFERROR(2);}
    if(strcmp(str2,"PROSTAR/STAR4 Polyfile")){PFERROR(10);}
    if (!xdr_int (&xdrs, &polyfile_version)){PFERROR(2);}
    if(polyfile_version > MAX_VERSION) {PFERROR(11);}
    xdr_destroy (&xdrs);
    pvlis=(int*)malloc(sizeof(int)*maxalloclis);
    if(pvlis==NULL){PFERROR(8);}
  }
  else
  {
    if (rwflag == 0)
    {
      polyfile_fp=fopen(str,"wb");
      if(!polyfile_fp)
      {
        *ierr=1;
        return;
      }
      op=XDR_ENCODE;
      str2=str1;
      xdrstdio_create(&xdrs,polyfile_fp, op);
      if (!xdr_string(&xdrs,&str2,39)){PFERROR(2);}
      if (!xdr_int (&xdrs, &polyfile_version)){PFERROR(2);}
      xdr_destroy (&xdrs);
    }
    else
    {
      polyfile_fp=fopen(str,"w");
      if(!polyfile_fp)
      {
        *ierr=1;
        return;
      }
      str2=str1;
      fwrite (str2, 1, 22, polyfile_fp);
      fprintf (polyfile_fp, ", %d\n", polyfile_version);
    }
  }
  currtype=-1;
  free(str);
}

static void starttag(int *ierr)
{
   XDR xdrs;
   int i=0;
   enum xdr_op op;
   if(rwflag==1)return;
   if (rwflag != 2)
   {
     op=XDR_ENCODE;dataint=1;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     headerpos=ftell(polyfile_fp);
     if (!xdr_int (&xdrs, &i)){PFERROR(2);}
     if (!xdr_int (&xdrs, &i)){PFERROR(2);}
     if (!xdr_int (&xdrs, &i)){PFERROR(2);}
     if (!xdr_int (&xdrs, &i)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "startTag\n");
   }
}

void polyfile_endtag(int *tag,int *ierr)
/*
        Marks the end of the current tag only used in write mode
*/
{
   XDR xdrs;
   int i=0;
   enum xdr_op op;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     presentpos=ftell(polyfile_fp);
     fseek(polyfile_fp,headerpos,SEEK_SET);
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,&currtype)){PFERROR(2);}
     if (!xdr_int (&xdrs,&currcount)){PFERROR(2);}
     if (!xdr_int (&xdrs,tag)){PFERROR(2);}
     if (!xdr_int (&xdrs,&currmaxid)){PFERROR(2);}
     xdr_destroy (&xdrs);
     fseek(polyfile_fp,presentpos,SEEK_SET);
     headerpos=presentpos;
   }
   else
   {
     fprintf (polyfile_fp, "endTag type=%d, count=%d, tag=%d, maxid=%d\n",
              currtype, currcount, *tag, currmaxid);
   }
   currtype=-1;
   currcount=0;
   currmaxid=0;
}

void polyfile_writevertex (int *id, float *x, float *y, float *z, int *ierr)
/*
        writes vertex to file
        id      =vertex no
*/
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=1&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=1;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,id)){PFERROR(2);}
     if (!xdr_float (&xdrs,x)){PFERROR(2);}
     if (!xdr_float (&xdrs,y)){PFERROR(2);}
     if (!xdr_float (&xdrs,z)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "vertex %9d %-+#16.9g %-+#16.9g %-+#16.9g\n",
              *id, *x, *y, *z);
   }
   currcount++;
   if(*id > currmaxid)currmaxid=*id;
}

void polyfile_writeshell(int *id,int *nvert,int *vlis,int *ierr)
/*
        writes shell to file
        nvert   =no of vertices
        vlis    =list of vertices
*/
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=2&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=2;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,id)){PFERROR(2);}
     if (!xdr_int (&xdrs,nvert)){PFERROR(2);}
     for(i=0;i<*nvert;i++)if (!xdr_int (&xdrs,&vlis[i])){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "shell %9d,%9d", *id, *nvert);
     for (i=0; i<*nvert; i++)
       fprintf (polyfile_fp, ",%9d", vlis[i]);
     fprintf (polyfile_fp, "\n");
   }
   currcount++;
   if(*id > currmaxid)currmaxid=*id;
}

void polyfile_writeboundary (int *id, int *ncellid, int *nfaceid,
                             int *bndId, int *patch,
                             int *nvert, int *vlis, int *ierr)
/*
        writes boundary face to file
        ncellid =neighbouring cell id
*/
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=3&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=3;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,id)){PFERROR(2);}
     if (!xdr_int (&xdrs,ncellid)){PFERROR(2);}

     /* Added for version 2 of the file.  5-December-2002 WRO */
     if (!xdr_int (&xdrs,nfaceid)){PFERROR(2);}
     /* Added for version 2 of the file.  12-December-2002 WRO */
     if (!xdr_int (&xdrs,bndId)){PFERROR(2);}
     /* Added for version 2 of the file.  5-December-2002 WRO */
     if (!xdr_int (&xdrs,patch)){PFERROR(2);}

     if (!xdr_int (&xdrs,nvert)){PFERROR(2);}
     for(i=0;i<*nvert;i++)if (!xdr_int (&xdrs,&vlis[i])){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "boundary %9d,%9d,%9d,%9d,%9d,%9d",
              *id, *ncellid, *nfaceid, *bndId, *patch, *nvert);
     for (i=0; i<*nvert; i++)
       fprintf (polyfile_fp, ",%9d", vlis[i]);
     fprintf (polyfile_fp, "\n");
   }
   currcount++;
   if(*id > currmaxid)currmaxid=*id;
}

void polyfile_writefaces (int *id, int *lcell, int *lface,
                                   int *rcell, int *rface,
                          int *nvert, int *vlis, int *ierr)
/*
        writes face face to file
        lcell   =neighbouring (left)cell id
        rcell   =neighbouring (right)cell id
*/
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=4&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=4;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,id)){PFERROR(2);}
     if (!xdr_int (&xdrs,lcell)){PFERROR(2);}

     /* Added for version 2 of the file.  5-December-2002 WRO */
     if (!xdr_int (&xdrs,lface)){PFERROR(2);}

     if (!xdr_int (&xdrs,rcell)){PFERROR(2);}

     /* Added for version 2 of the file.  5-December-2002 WRO */
     if (!xdr_int (&xdrs,rface)){PFERROR(2);}

     if (!xdr_int (&xdrs,nvert)){PFERROR(2);}
     for(i=0;i<*nvert;i++)if (!xdr_int (&xdrs,&vlis[i])){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "faces    %9d,%9d,%9d,%9d,%9d,%9d",
              *id, *lcell, *lface, *rcell, *rface, *nvert);
     for (i=0; i<*nvert; i++)
       fprintf (polyfile_fp, ",%9d", vlis[i]);
     fprintf (polyfile_fp, "\n");
   }
   currcount++;
   if(*id > currmaxid)currmaxid=*id;
}

void polyfile_writecell(int *id,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=5&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=5;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,id)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "cell %9d\n", *id);
   }
   currcount++;
   if(*id > currmaxid)currmaxid=*id;
}

void polyfile_writecellsp(int *id,int *info,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=14&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=14;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,id)){PFERROR(2);}
     if (!xdr_int (&xdrs,info)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "cell info %9d,%9d\n", *id, *info);
   }
   currcount++;
   if(*id > currmaxid)currmaxid=*id;
}

void polyfile_writeinterface (int *faceid1, int *bound1, int *patch1,
                              int *faceid2, int *bound2, int *patch2,
                              int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=12&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=12;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,faceid1)){PFERROR(2);}
     if (!xdr_int (&xdrs,bound1)){PFERROR(2);}

     /* Added for version 2 of the file.  5-December-2002 WRO */
     if (!xdr_int (&xdrs,patch1)){PFERROR(2);}
     if (!xdr_int (&xdrs,faceid2)){PFERROR(2);}

     if (!xdr_int (&xdrs,bound2)){PFERROR(2);}

     /* Added for version 2 of the file.  5-December-2002 WRO */
     if (!xdr_int (&xdrs,patch2)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "interface %9d,%9d,%9d,%9d,%9d,%9d\n",
              *faceid1, *bound1, *patch1, *faceid2, *bound2, *patch2);
   }
   currcount++;
   if( currcount > currmaxid)currmaxid=currcount;
}

void polyfile_writescalar (float *scale, int *maxUserVertId, int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=13&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=13;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_float (&xdrs,scale)){PFERROR(2);}
     if (!xdr_int (&xdrs,maxUserVertId)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "scale=%-+#16.9g, maxUserVertId=%d\n",
              *scale, *maxUserVertId);
   }
   currcount++;
   polyfile_endtag(&i,ierr);
}

void polyfile_writevmap(int *tag,char *meaning,int *mlen,int *ierr)
/*
        writes vertex Map
        tag     =tag no
        mlen    =strlen(meaning)
*/
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   char str[MAXSTRSIZE+1],*str1;

   if(rwflag==1){PFERROR(4);}
   *ierr=0;
   if(currtype!=6&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=6;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   i=*mlen<MAXSTRSIZE ? *mlen:MAXSTRSIZE;
   strncpy(str,meaning,i);
   str[i]=0;
   str1=str;
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,tag)){PFERROR(2);}
     if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "vmap %9d, %s\n", *tag, str);
   }
   currcount++;
   if(*tag > currmaxid)currmaxid=*tag;
}


void polyfile_writesmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   char str[MAXSTRSIZE+1],*str1;

   *ierr=0;
   if(rwflag==1){PFERROR(4);}
   if(currtype!=7&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=7;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   i=*mlen<MAXSTRSIZE ? *mlen:MAXSTRSIZE;
   strncpy(str,meaning,i);
   str[i]=0;
   str1=str;
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,tag)){PFERROR(2);}
     if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "smap %9d, %s\n", *tag, str);
   }
   currcount++;
   if(*tag > currmaxid)currmaxid=*tag;

}


void polyfile_writebmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   char str[MAXSTRSIZE+1],*str1;

   *ierr=0;
   if(rwflag==1){PFERROR(4);}
   if(currtype!=8&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=8;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   i=*mlen<MAXSTRSIZE ? *mlen:MAXSTRSIZE;
   strncpy(str,meaning,i);
   str[i]=0;
   str1=str;
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,tag)){PFERROR(2);}
     if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "bmap %9d, %s\n", *tag, str);
   }
   currcount++;
   if(*tag > currmaxid)currmaxid=*tag;

}

void polyfile_writefmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   char str[MAXSTRSIZE+1],*str1;

   *ierr=0;
   if(rwflag==1){PFERROR(4);}
   if(currtype!=9&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=9;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   i=*mlen<MAXSTRSIZE ? *mlen:MAXSTRSIZE;
   strncpy(str,meaning,i);
   str[i]=0;
   str1=str;
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,tag)){PFERROR(2);}
     if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "fmap %9d, %s\n", *tag, str);
   }
   currcount++;
   if(*tag > currmaxid)currmaxid=*tag;
}

void polyfile_writecmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   char str[MAXSTRSIZE+1],*str1;

   *ierr=0;
   if(rwflag==1){PFERROR(4);}
   if(currtype!=10&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=10;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   i=*mlen<MAXSTRSIZE ? *mlen:MAXSTRSIZE;
   strncpy(str,meaning,i);
   str[i]=0;
   str1=str;
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,tag)){PFERROR(2);}
     if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "cmap %9d, %s\n", *tag, str);
   }
   currcount++;
   if(*tag > currmaxid)currmaxid=*tag;
}

void polyfile_writecmapsp(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   char str[MAXSTRSIZE+1],*str1;

   *ierr=0;
   if(rwflag==1){PFERROR(4);}
   if(currtype!=15&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=15;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   i=*mlen<MAXSTRSIZE ? *mlen:MAXSTRSIZE;
   strncpy(str,meaning,i);
   str[i]=0;
   str1=str;
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,tag)){PFERROR(2);}
     if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "cmapsp %9d, %s\n", *tag, str);
   }
   currcount++;
   if(*tag > currmaxid)currmaxid=*tag;

}

void polyfile_writedvertex (int *id, double *x, double *y, double *z,
                            int *ierr)
/*
        writes double vertex to file
        id      =vertex no
*/
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;

   *ierr=0;
   if(rwflag==1){PFERROR(4);}
   if(currtype!=11&&currtype!=-1)polyfile_endtag(&i,ierr);
   if(currtype==-1)
   {
     currtype=11;
     starttag(ierr);
     currcount=0;
     currmaxid=0;
   }
   if (rwflag != 2)
   {
     op=XDR_ENCODE;
     xdrstdio_create(&xdrs,polyfile_fp, op);
     if (!xdr_int (&xdrs,id)){PFERROR(2);}
     if (!xdr_double (&xdrs,x)){PFERROR(2);}
     if (!xdr_double (&xdrs,y)){PFERROR(2);}
     if (!xdr_double (&xdrs,z)){PFERROR(2);}
     xdr_destroy (&xdrs);
   }
   else
   {
     fprintf (polyfile_fp, "dvertex %9d %-+#16.9g %-+#16.9g %-+#16.9g\n",
              *id, *x, *y, *z);
   }
   currcount++;
   if(*id > currmaxid)currmaxid=*id;
}


void polyfile_readheader(int *type,int *tag,int *no,int *maxid,int *ierr)
/*
        Reads header from the file
        no      =no of elements in tag
*/
{
   XDR xdrs;
   enum xdr_op op;
   *ierr=0;
   if(!rwflag){PFERROR(5);}
   if(rwflag)op=XDR_DECODE;
   if(currno!=currcount){PFERROR(7);}
   if(feof(polyfile_fp)){PFERROR(9);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,type))
   {
     if(feof(polyfile_fp)){PFERROR(9);}
     PFERROR(2);
   }
   if (!xdr_int (&xdrs,no)) {PFERROR(2);}
   if (!xdr_int (&xdrs,tag)){PFERROR(2);}
   if (!xdr_int (&xdrs,maxid)){PFERROR(2);}
   currtype=*type;
   currcount=*no;
   currno=0;
   xdr_destroy (&xdrs);
}

void polyfile_readvertex(int *id,float *x,float *y,float *z,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=1){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,id)){PFERROR(2);}
   if (!xdr_float (&xdrs,x)){PFERROR(2);}
   if (!xdr_float (&xdrs,y)){PFERROR(2);}
   if (!xdr_float (&xdrs,z)){PFERROR(2);}
   currno++;
   xdr_destroy (&xdrs);

}

void polyfile_readdvertex(int *id,double *x,double *y,double *z,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=11){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,id)){PFERROR(2);}
   if (!xdr_double (&xdrs,x)){PFERROR(2);}
   if (!xdr_double (&xdrs,y)){PFERROR(2);}
   if (!xdr_double (&xdrs,z)){PFERROR(2);}
   currno++;
   xdr_destroy (&xdrs);

}



void polyfile_readshell(int *id,int *nvert,int **vlis,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=2){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,id)){PFERROR(2);}
   if (!xdr_int (&xdrs,nvert)){PFERROR(2);}
   if(*nvert>maxalloclis)
   {
     free(pvlis);
     maxalloclis=*nvert+10;
     pvlis=(int*)malloc(sizeof(int)*maxalloclis);
     if(pvlis==NULL){*ierr=8;return;}
   }
   for(i=0;i<*nvert;i++)if (!xdr_int (&xdrs,&pvlis[i])){PFERROR(2);}
   currno++;
   *vlis=pvlis;
   xdr_destroy (&xdrs);
}

void polyfile_readboundary (int *id, int *ncellid, int *nfaceid,
                            int *bndId, int *patch,
                            int *nvert, int **vlis, int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=3){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,id)){PFERROR(2);}
   if (!xdr_int (&xdrs,ncellid)){PFERROR(2);}

   /* Added for version 2 of the file.  5-December-2002 WRO */
   /* bndId added 12-December-2002 WRO */
   if (polyfile_version <= 1)
   {
     *nfaceid = 0;
     *bndId = 0;
     *patch = 0;
   }
   else
   {
     if (!xdr_int (&xdrs,nfaceid)){PFERROR(2);}
     if (!xdr_int (&xdrs,bndId)){PFERROR(2);}
     if (!xdr_int (&xdrs,patch)){PFERROR(2);}
   }

   if (!xdr_int (&xdrs,nvert)){PFERROR(2);}
   if(*nvert>maxalloclis)
   {
     free(pvlis);
     maxalloclis=*nvert+10;
     pvlis=(int*)malloc(sizeof(int)*maxalloclis);
     if(pvlis==NULL){*ierr=8;return;}
   }
   for(i=0;i<*nvert;i++)if (!xdr_int (&xdrs,&pvlis[i])){PFERROR(2);}
   currno++;
   *vlis=pvlis;
   xdr_destroy (&xdrs);
}

void polyfile_readfaces (int *id, int *lcell, int *lface,
                                  int *rcell, int *rface,
                         int *nvert, int **vlis, int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=4){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,id)){PFERROR(2);}
   if (!xdr_int (&xdrs,lcell)){PFERROR(2);}

   /* Added for version 2 of the file.  5-December-2002 WRO */
   if (polyfile_version <= 1)
   {
     *lface = 0;
   }
   else
   {
     if (!xdr_int (&xdrs,lface)){PFERROR(2);}
   }

   if (!xdr_int (&xdrs,rcell)){PFERROR(2);}

   /* Added for version 2 of the file.  5-December-2002 WRO */
   if (polyfile_version <= 1)
   {
     *rface = 0;
   }
   else
   {
     if (!xdr_int (&xdrs,rface)){PFERROR(2);}
   }

   if (!xdr_int (&xdrs,nvert)){PFERROR(2);}
   if(*nvert>maxalloclis)
   {
     free(pvlis);
     maxalloclis=*nvert+10;
     pvlis=(int*)malloc(sizeof(int)*maxalloclis);
     if(pvlis==NULL){*ierr=8;return;}
   }
   for(i=0;i<*nvert;i++)if (!xdr_int (&xdrs,&pvlis[i])){PFERROR(2);}
   currno++;
   *vlis=pvlis;
   xdr_destroy (&xdrs);
}

void polyfile_readcell(int *id,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=5){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,id)){PFERROR(2);}
   currno++;
   xdr_destroy (&xdrs);
}

void polyfile_readcellsp(int *id,int *info,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=14){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,id)){PFERROR(2);}
   if (!xdr_int (&xdrs,info)){PFERROR(2);}
   currno++;
   xdr_destroy (&xdrs);
}

void polyfile_readinterface (int *faceid1, int *bound1, int *patch1,
                             int *faceid2, int *bound2, int *patch2,
                             int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=12){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,faceid1)){PFERROR(2);}
   if (!xdr_int (&xdrs,bound1)){PFERROR(2);}

   /* Added for version 2 of the file.  5-December-2002 WRO */
   if (polyfile_version <= 1)
   {
     *patch1 = 0;
     *faceid2 = *faceid1;
   }
   else
   {
     if (!xdr_int (&xdrs,patch1)){PFERROR(2);}
     if (!xdr_int (&xdrs,faceid2)){PFERROR(2);}
   }

   if (!xdr_int (&xdrs,bound2)){PFERROR(2);}

   /* Added for version 2 of the file.  5-December-2002 WRO */
   if (polyfile_version <= 1)
   {
     *patch2 = 0;
   }
   else
   {
     if (!xdr_int (&xdrs,patch2)){PFERROR(2);}
   }

   currno++;
   xdr_destroy (&xdrs);
}

void polyfile_readscalar (float *scale, int *maxUserVertId, int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   int i=0;
   *ierr=0;
   if(currtype!=13){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_float (&xdrs,scale)){PFERROR(2);}
   if (!xdr_int (&xdrs,maxUserVertId)){PFERROR(2);}
   currno++;
   xdr_destroy (&xdrs);
}

void polyfile_readvmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   char str[MAXSTRSIZE+1],*str1;
   int i=0;
   *ierr=0;
   if(currtype!=6){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,tag)){PFERROR(2);}
   str1=str;
   if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
   strcpy(meaning,str);
   currno++;
   *mlen=strlen(str);
   xdr_destroy (&xdrs);
}

void polyfile_readsmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   char str[MAXSTRSIZE+1],*str1;
   int i=0;
   *ierr=0;
   if(currtype!=7){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,tag)){PFERROR(2);}
   str1=str;
   if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
   strcpy(meaning,str);
   currno++;
   *mlen=strlen(str);
   xdr_destroy (&xdrs);
}

void polyfile_readbmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   char str[MAXSTRSIZE+1],*str1;
   int i=0;
   *ierr=0;
   if(currtype!=8){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,tag)){PFERROR(2);}
   str1=str;
   if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
   strcpy(meaning,str);
   currno++;
   *mlen=strlen(str);
   xdr_destroy (&xdrs);
}

void polyfile_readfmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   char str[MAXSTRSIZE+1],*str1;
   int i=0;
   *ierr=0;
   if(currtype!=9){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,tag)){PFERROR(2);}
   str1=str;
   if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
   strcpy(meaning,str);
   currno++;
   *mlen=strlen(str);
   xdr_destroy (&xdrs);
}

void polyfile_readcmap(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   char str[MAXSTRSIZE+1],*str1;
   int i=0;
   *ierr=0;
   if(currtype!=10){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,tag)){PFERROR(2);}
   str1=str;
   if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
   strcpy(meaning,str);
   *mlen=strlen(str);
   currno++;
   xdr_destroy (&xdrs);
}

void polyfile_readcmapsp(int *tag,char *meaning,int *mlen,int *ierr)
{
   XDR xdrs;
   enum xdr_op op;
   char str[MAXSTRSIZE+1],*str1;
   int i=0;
   *ierr=0;
   if(currtype!=15){PFERROR(3);}
   if(!rwflag){PFERROR(5);}
   op=XDR_DECODE;
   if(currcount==currno){PFERROR(6);}
   xdrstdio_create(&xdrs,polyfile_fp, op);
   if (!xdr_int (&xdrs,tag)){PFERROR(2);}
   str1=str;
   if (!xdr_string(&xdrs,&str1,MAXSTRSIZE-1)){PFERROR(2);}
   strcpy(meaning,str);
   *mlen=strlen(str);
   currno++;
   xdr_destroy (&xdrs);
}


void polyfile_close(int *ierr)
{
   int i=0;

   *ierr=0;
   if(currtype!=-1&&rwflag==0&&dataint)polyfile_endtag(&i,ierr);
   if(polyfile_fp)
   fclose(polyfile_fp);
   if(pvlis){
    free(pvlis);
    pvlis=0;
   }
}

void polyfile_skipread(int *ierr)
{
   int i=0;
   float x,y,z;
   double x1,y1,z1;
   int id,*vlist,j,k;
   char str[MAXSTRSIZE+1],*str1;
   *ierr=0;
   if(currcount==currno)return;
   switch(currtype)
   {
     case 1:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readvertex(&id,&x,&y,&z,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 2:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readshell(&id,&j,&vlist,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 3:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readboundary(&j,&i,&i,&i,&i,&id,&vlist,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 4:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readfaces(&i,&j,&j,&k,&k,&id,&vlist,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 5:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readcell(&id,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 6:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readvmap(&id,str,&i,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 7:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readsmap(&id,str,&i,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 8:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readbmap(&id,str,&i,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 9:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readfmap(&id,str,&i,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 10:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readcmap(&id,str,&i,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 11:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readdvertex(&id,&x1,&y1,&z1,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 12:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readinterface(&id,&i,&i,&id,&j,&j,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 13:
       polyfile_readscalar(&x,&i,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 14:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readcellsp(&id,&i,ierr);
       if(*ierr==6)*ierr=0;
       break;
     case 15:
       for(;currcount>currno&&*ierr==0;)
       polyfile_readcmapsp(&id,str,&i,ierr);
       if(*ierr==6)*ierr=0;
       break;
   }
}


/* Automatic setting of emacs local variables. */
/* Local Variables: */
/* tab-width:2 */
/* End: */
