/***********************************************************************
*
*  projet   : Marc
*  module   : Iso2709
*  fichier  : Iso2709ToSxml.c
*  Auteur   : Jacques DUCLOY
*  Date     : Juillet 93
*  $Id: Iso2709ToSgml.c,v 1.2 2003/02/25 15:54:50 parmentf Exp $
*
************************************************************************/
#include "SxmlNode.h"
#include "Buffer.h"
#include "CharSet.h"
#include "CharSetEbcdic.h" 
#include <stdlib.h>
int atoi();

Buffer   *buf2709;
char     *rec2709;
Buffer   *bufData;

SxmlNode *out2709;

char recordSep;
char fieldSep;
char subFieldSep;

char label2709[25];
char bufTagField[5];

char bufChif[2];
char bufNum[20];

int lenOfData;
int startChar;
int baseData;
int lenDirEntry;
int lenDirData;
int lenDirStart;
int lenDirImpl;
int lenIndic;
int lenSubfieldId;
char *nextDir;

    int getopt();
    extern char *optarg;

SxmlNode *fieldSgml;
SxmlNode *dataElement;

Buffer   *bufEbcdic;


int octalMode;
int ebcdicMode;
int utfMode;

char *ebcdicTable;

void storeData(n1,s1,l1,ebc1)
     SxmlNode *n1;
     char *s1;
     int l1;
     char *ebc1;
{

  if (octalMode)
    {
      BufferStrncpy(bufData, s1,l1);
      SxmlAppendChild(n1,SxmlTextCreate(CharSetAsciiToSgmlOctal(BufferString(bufData))));
    }
  else if (ebcdicMode)
    {
      char *s2;
      char *ebc2;
      unsigned char c1;
      unsigned char c2;
      s2=s1;
      ebc2=ebc1;
      BufferReset(bufData);
      while(l1--)
	{
	  c1=*s1++;
	  c2=*ebc2++;
	  switch(c1)
	    {
	    case '&':
	      BufferStrcat(bufData,"&amp;");
	      break;
	    case '<':
	      BufferStrcat(bufData,"&lt;");
	      break;
	    case '>':
	      BufferStrcat(bufData,"&gt;");
	      break;
	    case '#':
	      {
		int indic;
		char *hexa="0123456789ABCDEF";
		BufferCharCat(bufData,'#');
		indic=((c2&0360)>>4);
		BufferCharCat(bufData,hexa[indic]);
		indic=(c2&0017);
		BufferCharCat(bufData,hexa[indic]);
	      }
	      break;
	    default:
	      BufferCharCat(bufData,c1);
	      break;
	    }
	}
      /*     SgmlAddData(n1,SxmlTextCreate(BufferString(bufData))); */
      SxmlAppendChild(n1,SxmlTextCreate(BufferString(bufData))); 
    }
  else if (utfMode)
    {
      BufferStrncpy(bufData, s1,l1);
      SxmlAppendChild(n1,SxmlTextCreate(BufferString(bufData)));
    }
  else 
    {
      BufferStrncpy(bufData, s1,l1);
      SxmlAppendChild(n1,SxmlTextCreate(CharSetAsciiToSgml(BufferString(bufData))));
    }
}



void storeDataWithSubfield(n1,currentData,l1,ebc1)
     SxmlNode *n1;
     char *currentData;
     int l1;
     char *ebc1;
{
  char *nextField;
  char *nextSubField;
  nextField=strchr(currentData, fieldSep);
  nextSubField=strchr(currentData, subFieldSep);
  if ((!nextSubField)||(nextSubField>nextField))
    {
      storeData(n1,currentData,l1,ebc1);
      return;
    }
  if(lenDirImpl)
    {
      bufNum[0]=0;
      strncat(bufNum,nextDir+3+lenDirData+lenDirStart,lenDirImpl);
      SxmlSetAttribute(fieldSgml,"dir",bufNum);
    }
  if(lenIndic)
    {
      bufNum[0]=0;
      strncat(bufNum,currentData,lenIndic);
      SxmlSetAttribute(n1,"indic",bufNum);
      currentData+=lenIndic;
      ebc1+=lenIndic;
    }  
  while(currentData[0]!=fieldSep)
    {
      int   lenOfDataElement;
      SxmlNode *sgmlDataElem;
      
      strcpy(bufNum,"s");
      strncat(bufNum,currentData+1,lenSubfieldId-1);
      currentData+=lenSubfieldId;
      ebc1+=lenSubfieldId;
      SxmlAppendChild
	(n1,sgmlDataElem=SxmlElementCreate(bufNum));
      
      if((nextSubField=strchr(currentData,subFieldSep ))
	 &&(nextSubField<nextField))
	{
	  lenOfDataElement=(nextSubField-currentData);
	  storeData(sgmlDataElem, currentData,lenOfDataElement,ebc1);
	  ebc1+=(nextSubField-currentData);
	  currentData=nextSubField;
	}
      else 
	{
	  lenOfDataElement=(nextField-currentData);
	  storeData(sgmlDataElem, currentData,lenOfDataElement,ebc1);
	  ebc1+=(nextField-currentData);
	  currentData=nextField;
	}
    }
}


int main(argc,argv)
     int argc;
     char **argv;
{    
  int cod_arg;
  int flagSubField;
  flagSubField=0;
  
  octalMode=0;
  ebcdicMode=0;
  utfMode=0;

  while ((cod_arg = getopt(argc,argv,"eosu"))!=EOF)
  {
    switch(cod_arg) 
      {
     case 'o':
	octalMode=1;
	break;
     case 'e':
	ebcdicMode=1;
	break;
      case 's':
	flagSubField=1;
	break;
      case 'u':
	utfMode=1;
	break;
      }
  }
  
  buf2709=BufferCreate(1024,1024);
  bufData=BufferCreate(1024,1024);
  
  if (ebcdicMode)
    {
      bufEbcdic=BufferCreate(1024,1024);
      ebcdicTable=strdup(CharSetEbcdicTab);
      ebcdicTable[0X1F]='\037';  /* subField */ 
      ebcdicTable[0X1E]='\036';   /* Field */ 
    }

  bufChif[1]=0;
											    
  recordSep   ='\035';
  fieldSep    ='\036';
  subFieldSep ='\037';

  strcpy(bufTagField, "f");
			
  while((rec2709=BufferGets(buf2709)))
    {
      
      if (ebcdicMode)
	{
	  char *s1;
	  unsigned char c1;
	  BufferCopy(bufEbcdic, buf2709);
	  s1=BufferString(bufEbcdic);
	  BufferReset(buf2709);
	  while ((c1=*s1))
	    {
	      unsigned char c2;
	      c2=ebcdicTable[c1];
	      BufferCharCat(buf2709,c2);
	      s1++;
	    }
	}
      
      out2709=SxmlElementCreate("iso2709");

      label2709[0]=0;
      strncat(label2709,rec2709,24);
      SxmlSetAttribute(out2709, "header", label2709);

      bufNum[0]=0;
      strncat(bufNum,rec2709+12,5);
      baseData=atoi(bufNum);

      bufChif[0]=rec2709[10];
      lenIndic=atoi(bufChif);
      bufChif[0]=rec2709[11];
      lenSubfieldId=atoi(bufChif);
      bufChif[0]=rec2709[20];
      lenDirData=atoi(bufChif);
      bufChif[0]=rec2709[21];
      lenDirStart=atoi(bufChif);
      bufChif[0]=rec2709[22];
      lenDirImpl=atoi(bufChif);
      lenDirEntry=3+lenDirData + lenDirStart+ lenDirImpl;

      nextDir=rec2709+24;

      while(nextDir[0]!=fieldSep)
	{
	  char *beginField;
	  char *beginEbcdicField;
          strcpy(bufTagField,"f");
	  strncat(bufTagField, nextDir,3);
	  SxmlAppendChild(out2709,fieldSgml=SxmlElementCreate(bufTagField));
      
	  bufNum[0]=0;
	  strncat(bufNum,nextDir+3,lenDirData);
	  lenOfData=atoi(bufNum);

	  bufNum[0]=0;
	  strncat(bufNum,nextDir+3+lenDirData,lenDirStart );
	  startChar=atoi(bufNum);
	  beginField=rec2709+baseData+startChar;
	  if (ebcdicMode)beginEbcdicField=BufferString(bufEbcdic)+baseData+startChar;
	  if ((flagSubField))
	    storeDataWithSubfield(fieldSgml,beginField,lenOfData-1,beginEbcdicField );
	  else if(((bufTagField[1]=='0')&&(bufTagField[2]=='0'))
		  || (lenSubfieldId==0))
	    {
	      storeData(fieldSgml,beginField,lenOfData-1,beginEbcdicField);
	    }
	  else
	    {
	      storeDataWithSubfield(fieldSgml,beginField,lenOfData-1,beginEbcdicField);
	    }
      
	  nextDir+=lenDirEntry;
	}
      SxmlPrint(out2709);
      SxmlFree(out2709);
      putchar('\n');
    }
  return 0;
}
