/*
** pat_data.c for  in 
** 
** Made by 
** Login   <vianney@epita.fr>
** 
** Started on  Wed Sep  1 06:43:58 1999 
** Last update Thu Oct 28 20:20:09 1999 
*/
#include <ctype.h>
#include "pat_data.h"
#include "pat_8.h"

t_vec				*pat_data_ascii_vec = NULL;
t_vec				*pat_data_ascii_vec_for_html = NULL;
t_vec				*pat_data_ebcdic_vec_for_html = NULL;
t_u32				pat_data_bytes_per_line = 8;

/* NOTE: IT'S NEARLY INCOMPLETE AND STANDS FOR PRINTABLE CHARS */
unsigned char		ebcdic_to_ascii[256] = 
{
  0,	1,	2,	3,	0,	9,	0,	127,
  0,	0,	0,	11,	12,	13,	14,	14,
  16,	17,	18,	19,	0,	10,	8,	0,
  24,	25,	0,	0,	0,	0,	0,	0,
  0,	0,	28,	0,	0,	10,	23,	27,
  0,	0,	0,	0,	0,	5,	6,	7,
  0,	0,	22,	0,	0,	0,	0,	4,
  0,	0,	0,	0,	20,	21,	0,	26,
  32,	0,	0,	0,	0,	0,	0,	0,
  0,	0,	'c',	'.',	'<',	'(',	'+',	'|',
  '&',	0,	0,	0,	0,	0,	0,	0,	
  0,	0,	'!',	'$',	'*',	')',	';',	0,
  '-',	'/',	0,	0,	0,	0,	0,	0,	
  0,	0,	'|',	',',	'%',	'_',	'>',	'?',
  0,	0,	0,	0,	0,	0,	0,	0,	
  0,	'`',	':',	'#',	'@',	'\'',	'=',	'"',
  0,	'a',	'b',	'c',	'd',	'e',	'f',	'g',
  'h',	'i',	0,	0,	0,	0,	0,	0,	
  0,	'j',	'k',	'l',	'm',	'n',	'o',	'p',
  'q',	'r',	0,	0,	0,	0,	0,	0,	
  0,	0,	's',	't',	'u',	'v',	'w',	'x',
  'y',	'z',	0,	0,	0,	0,	0,	0,	
  0,	0,	0,	0,	0,	0,	0,	0,	
  0,	0,	0,	0,	0,	0,	0,	0,	
  '{',	'A',	'B',	'C',	'D',	'E',	'F',	'G',
  'H',	'I',	0,	0,	0,	0,	0,	0,	
  '}',	'J',	'K',	'L',	'M',	'N',	'O',	'P',
  'Q',	'R',	0,	0,	0,	0,	0,	0,	
  '\\',	0,	'S',	'T',	'U',	'V',	'W',	'X',
  'Y',	'Z',	0,	0,	0,	0,	0,	0,	
  '0',	'1',	'2',	'3',	'4',	'5',	'6',	'7',
  '8',	'9',	0,	0,	0,	0,	0,	0,	
};

t_status	ebcdic_buf_to_cooked_str_i(off,
					   b,
					   l,
					   br,
					   br_str,
					   spc_str,
					   big_spc_str,
					   nonprint_str,
					   ascii_vec,
					   str,
					   max_len)
int		off;
unsigned char	*b;
int		l;
int		br;
char		*br_str;
char		*spc_str;
char		*big_spc_str;
char		*nonprint_str;
t_vec		*ascii_vec;
char		*str;
int		max_len;
{
   int		i;
   t_status	status;

   if ((status = str_cat_fmt_va(str,
				max_len,
				"%08x%s",
				off - l,
				big_spc_str)) != 0)
     return (status);
   i = 0;
   while (i < br)
     {
       if (i < l)
	 {
	   if ((status = str_cat_fmt_va(str,
					max_len,
					"%02x",
					b[i])) != 0)
	     return (status);
	 }
       else
	 {
	   if ((status = str_cat_str(str,
				     max_len,
				     spc_str)) != 0)
	     return (status);
	   if ((status = str_cat_str(str,
				     max_len,
				     spc_str)) != 0)
	     return (status);
	 }
       if ((status = str_cat_str(str,
				 max_len,
				 spc_str)) != 0)
	 return (status);
       i++;
     }
   if ((status = str_cat_str(str,
			     max_len,
			     big_spc_str)) != 0)
     return (status);
   i = 0;
   while (i < l)
     {
       if (isprint(ebcdic_to_ascii[b[i]]))
	 {
	   if (ascii_vec)
	     {
	       if ((status = str_cat_str(str,
					 max_len,
					 (char *)(VEC_AT(ascii_vec,
							 (int)(b[i]))))) != 0)
		 return (status);
	     }
	   else
	     {
	       if ((status = str_cat_char(str,
					  max_len,
					  b[i])) != 0)
		 return (status);
	     }
	 }
       else
	 {
	   if ((status = str_cat_str(str,
				     max_len,
				     nonprint_str)) != 0)
	     return (status);
	 }
       i++;
     }
   if ((status = str_cat_str(str,
			     max_len,
			     br_str)) != 0)
     return (status);
   return (0);
}

t_status	ebcdic_buf_to_cooked_str(buf,
					 len,
					 br,
					 br_str,
					 spc_str,
					 big_spc_str,
					 nonprint_str,
					 ascii_vec,
					 str,
					 max_len)
char		*buf;
int		len;
int		br;
char		*br_str;
char		*spc_str;
char		*big_spc_str;
char		*nonprint_str;
t_vec		*ascii_vec;
char		*str;
int		max_len;
{
  unsigned char	b[BUFSIZ];
  int		i;
  int		l;
  t_status	status;

  if (br >= BUFSIZ)
    return (ERR_PAT_INVAL);
  if (ascii_vec)
    if (VEC_COUNT(ascii_vec) != 256)
      return (ERR_PAT_BAD_ASCII_VEC);
  l = 0;
  i = 0;
  while (i < len)
    {
      if (l < br)
	b[l++] = buf[i];
      else
	{
	  if ((status = ebcdic_buf_to_cooked_str_i(i,
						   b,
						   br,
						   br,
						   br_str,
						   spc_str,
						   big_spc_str,
						   nonprint_str,
						   ascii_vec,
						   str,
						   max_len)) != 0)
	    return (status);
	  l = 0;
	  b[l++] = buf[i];
	}
      i++;
    }
  if (l > 0)
    if ((status = ebcdic_buf_to_cooked_str_i(i,
					     b,
					     l,
					     br,
					     br_str,
					     spc_str,
					     big_spc_str,
					     nonprint_str,
					     ascii_vec,
					     str,
					     max_len)) != 0)
      return (status);
  return (0);
}




VOID_FUNC			pat_data_destroy(VOID_DECL)
{
  vec_str_delete(pat_data_ascii_vec);
  vec_str_delete(pat_data_ascii_vec_for_html);
  vec_str_delete(pat_data_ebcdic_vec_for_html);
}

t_status	ascii_vec_default(vec)
t_vec		*vec;
{
  t_status	status;
  int		i;

  i = 0;
  while (i < 256)
    {
      char	str[2];

      str[0] = (char)i;
      str[1] = 0;
      if ((status = vec_str_add(vec,str)) != 0)
	return (status);
      i++;
    }
  return (0);
}

t_status	ebcdic_to_ascii_vec_default(vec)
t_vec		*vec;
{
  t_status	status;
  int		i;

  i = 0;
  while (i < 256)
    {
      char	str[2];

      str[0] = ebcdic_to_ascii[i];
      str[1] = 0;
      if ((status = vec_str_add(vec,str)) != 0)
	return (status);
      i++;
    }
  return (0);
}

t_status			pat_data_init(VOID_DECL)
{
  t_status			status;

  pat_data_ascii_vec = NULL;
  pat_data_ascii_vec_for_html = NULL;
  pat_data_ebcdic_vec_for_html = NULL;
  if ((pat_data_ascii_vec = vec_new(256,
				    TRUE,
				    PAT_ALLOC_ALGORITHM,
				    PAT_ALLOC_PROC,
				    PAT_REALLOC_PROC,
				    PAT_FREE_PROC,
				    "pat_data_ascii_vec",
				    &status)) == NULL)
    goto bad;
  if ((status = ascii_vec_default(pat_data_ascii_vec)) != 0)
    goto bad;
  if ((pat_data_ascii_vec_for_html = vec_new(256,
					     TRUE,
					     PAT_ALLOC_ALGORITHM,
					     PAT_ALLOC_PROC,
					     PAT_REALLOC_PROC,
					     PAT_FREE_PROC,
					     "pat_data_ascii_vec_for_html",
					     &status)) == NULL)
    goto bad;
  if ((status = ascii_vec_default(pat_data_ascii_vec_for_html)) != 0)
    goto bad;
  if ((pat_data_ebcdic_vec_for_html = vec_new(256,
					      TRUE,
					      PAT_ALLOC_ALGORITHM,
					      PAT_ALLOC_PROC,
					      PAT_REALLOC_PROC,
					      PAT_FREE_PROC,
					      "pat_data_ebcdic_vec_for_html",
					      &status)) == NULL)
    goto bad;
 if ((status = ebcdic_to_ascii_vec_default(pat_data_ebcdic_vec_for_html)) != 0)
    goto bad;
  return (0);
bad:
  if (pat_data_ascii_vec)
    vec_str_delete(pat_data_ascii_vec);
  if (pat_data_ascii_vec_for_html)
    vec_str_delete(pat_data_ascii_vec_for_html);
  if (pat_data_ebcdic_vec_for_html)
    vec_str_delete(pat_data_ebcdic_vec_for_html);
  return (status);
}

PAT_OFF_DECL(data_pat_off)
{
  (*off_return) = len;
  return (0);
}

char				*data_itmpl = "\n\
<table _name=data[%i%] width=100%%%% bgcolor=\"%%dataColor%%\">\n\
<tr>\n\
<td width=100%%%%>\n\
<code>\n\
%%data[%i%].cookedhtmlbuf%%\n\
</code>\n\
</tr>\n\
</table>\n\
<br>\n\
";

int	data_chan;

PAT_NAME_GENERIC(data_pat_name,
		 (VOID_PTR)&data_chan,
		 "data")

PAT_GET_TMPL_GENERIC(data_pat_get_tmpl,
		     (VOID_PTR)&data_chan,
		     data_itmpl)

PAT_GET_FIELD_DECL(data_pat_get_field)
{
  int			i;

  if (!strcmp(field,"len"))
    return (long_to_str((signed long)(len),
			pat_base,
			str,
			max_len));
  if (!strcmp(field,"buf"))
    return (str_cat_buf(str,
			max_len,
			buf,
			len));
  if (!strcmp(field,"xbuf"))
    return (buf_to_xdata_str(buf,
			     len,
			     pat_data_bytes_per_line,
			     "\n",
			     " ",
			     str,
			     max_len));
  if (!strcmp(field,"xhtmlbuf"))
    return (buf_to_xdata_str(buf,
			     len,
			     pat_data_bytes_per_line,
			     "\n",
			     " ",
			     str,
			     max_len));
  if (!strcmp(field,"printablehtmlbuf"))
    return (buf_to_printable_str(buf,
				 len,
				 pat_data_bytes_per_line,
				 "\n",
				 " ",
				 ".",
				 pat_data_ascii_vec_for_html,
				 str,
				 max_len));
  if (!strcmp(field,"cookedhtmlbuf"))
    return (buf_to_cooked_str(buf,
			      len,
			      pat_data_bytes_per_line,
			      "\n",
			      " ",
			      "  ",
			      ".",
			      pat_data_ascii_vec_for_html,
			      str,
			      max_len));
  return (ERR_PAT_NO_SUCH_FIELD);
}

PAT_GET_FIELDS_DECL(data_pat_get_fields)
{
  t_status	status;

  if ((status = vec_str_add(vec_str,"len")) != 0)
    return (status);
  if ((status = vec_str_add(vec_str,"xbuf")) != 0)
    return (status);
  return (0);
}

t_pat				data_pat = 
{
  data_pat_name,		/* t_pat_name_proc		*/
  data_pat_off,			/* t_pat_off_proc		*/
  NULL,				/* t_pat_sub_proc		*/
  NULL,				/* t_pat_sum_proc		*/
  data_pat_get_field,		/* t_pat_get_field_proc		*/
  NULL,				/* t_pat_set_field_proc		*/
  data_pat_get_fields,		/* t_pat_get_fields_proc	*/
  data_pat_get_tmpl,		/* t_pat_get_tmpl_proc		*/
  NULL,				/* t_pat_get_tmpl2_proc		*/
  NULL,				/* t_pat_has_opt_proc		*/
  NULL,				/* t_pat_adapt_len_proc		*/
  NULL,				/* t_pat_get_field_pat_proc	*/
  NULL,				/* t_pat_extract_proc		*/
  NULL,				/* t_pat_insert_proc		*/
  NULL,				/* t_pat_get_choices_proc	*/
};

char				*dataebcdic_itmpl = "\n\
<table _name=dataebcdic[%i%] width=100%%%% bgcolor=\"%%dataebcdicColor%%\">\n\
<tr>\n\
<td width=100%%%%>\n\
<code>\n\
%%dataebcdic[%i%].cookedhtmlbuf%%\n\
</code>\n\
</tr>\n\
</table>\n\
<br>\n\
";

int	dataebcdic_chan;

PAT_NAME_GENERIC(dataebcdic_pat_name,
		 (VOID_PTR)&dataebcdic_chan,
		 "dataebcdic")

PAT_GET_TMPL_GENERIC(dataebcdic_pat_get_tmpl,
		     (VOID_PTR)&dataebcdic_chan,
		     dataebcdic_itmpl)

PAT_GET_FIELD_DECL(dataebcdic_pat_get_field)
{
  int			i;

  if (!strcmp(field,"len"))
    return (long_to_str((signed long)(len),
			pat_base,
			str,
			max_len));
  if (!strcmp(field,"buf"))
    return (str_cat_buf(str,
			max_len,
			buf,
			len));
  if (!strcmp(field,"cookedhtmlbuf"))
    return (ebcdic_buf_to_cooked_str(buf,
				     len,
				     pat_data_bytes_per_line,
				     "\n",
				     " ",
				     "  ",
				     ".",
				     pat_data_ebcdic_vec_for_html,
				     str,
				     max_len));
  return (ERR_PAT_NO_SUCH_FIELD);
}

PAT_GET_FIELDS_DECL(dataebcdic_pat_get_fields)
{
  t_status	status;

  if ((status = vec_str_add(vec_str,"len")) != 0)
    return (status);
  if ((status = vec_str_add(vec_str,"xbuf")) != 0)
    return (status);
  return (0);
}

t_pat				dataebcdic_pat = 
{
  dataebcdic_pat_name,		/* t_pat_name_proc		*/
  data_pat_off,			/* t_pat_off_proc		*/
  NULL,				/* t_pat_sub_proc		*/
  NULL,				/* t_pat_sum_proc		*/
  dataebcdic_pat_get_field,	/* t_pat_get_field_proc		*/
  NULL,				/* t_pat_set_field_proc		*/
  dataebcdic_pat_get_fields,	/* t_pat_get_fields_proc	*/
  dataebcdic_pat_get_tmpl,	/* t_pat_get_tmpl_proc		*/
  NULL,				/* t_pat_get_tmpl2_proc		*/
  NULL,				/* t_pat_has_opt_proc		*/
  NULL,				/* t_pat_adapt_len_proc		*/
  NULL,				/* t_pat_get_field_pat_proc	*/
  NULL,				/* t_pat_extract_proc		*/
  NULL,				/* t_pat_insert_proc		*/
  NULL,				/* t_pat_get_choices_proc	*/
};

char				*datalen_itmpl = "\n\
<table _name=datalen[%i%] width=100%%%% bgcolor=\"%%datalenColor%%\">\n\
<tr>\n\
<td align=center>\n\
%%datalen[%i%].len%% byte(s)\n\
</td>\n\
</tr>\n\
</table>\n\
<br>\n\
";

int	datalen_chan;

PAT_NAME_GENERIC(datalen_pat_name,
		 (VOID_PTR)&datalen_chan,
		 "datalen")

PAT_GET_TMPL_GENERIC(datalen_pat_get_tmpl,
		     (VOID_PTR)&datalen_chan,
		     datalen_itmpl)

t_pat				datalen_pat = 
{
  datalen_pat_name,		/* t_pat_name_proc		*/
  data_pat_off,			/* t_pat_off_proc		*/
  NULL,				/* t_pat_sub_proc		*/
  NULL,				/* t_pat_sum_proc		*/
  data_pat_get_field,		/* t_pat_get_field_proc		*/
  NULL,				/* t_pat_set_field_proc		*/
  data_pat_get_fields,		/* t_pat_get_fields_proc	*/
  datalen_pat_get_tmpl,		/* t_pat_get_tmpl_proc		*/
  NULL,				/* t_pat_get_tmpl2_proc		*/
  NULL,				/* t_pat_has_opt_proc		*/
  NULL,				/* t_pat_adapt_len_proc		*/
  NULL,				/* t_pat_get_field_pat_proc	*/
  NULL,				/* t_pat_extract_proc		*/
  NULL,				/* t_pat_insert_proc		*/
  NULL,				/* t_pat_get_choices_proc	*/
};
