/************************************************************************
*               ChViewer.C 1.0 by Jingbai Wang, August, 1989            *
*                                                                       *
*                jbw@pittvms.bitnet                                     *
*                jbw@cisunx.UUCP                                        *
*************************************************************************/

/*
        This version of ChViewer is for you to view a Chinese document
        (Generated in CCDOS output standard) on
        a standard 25x80 text terminal without any additional requirements
  
        It compiles on VAX/VMS and UNIX systems.

*/
/* Fix this site-dependent path of CCLIB 
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*/
/* UNIX environment variables:
CCLIB16jt

VMS logical names:
cclib16$jt

if no environment or logical is found use the following definitions:
*/


#if VMS
#define CCLIB16jt "usr2:[10555.jwang.ccdos]cclib.16"
#endif

#if unix
#ifndef CCLIB16jt
#define CCLIB16jt "/class2/4246/jbw/c/cclib.16"
#endif
#endif

/*
 It runs on VMS, UNIX and DOS systems.

Syntax:
~~~~~~
1) To view a document
$chview filename
  
   The output can be re-directed into a file by

$chview filename > outfile

   Note the spaces on both sides of '>' is necessary on VMS.

2) To convert a file into ASCII:
$ chviewer input_file output_file -e

3) To convert a file back:
$ chviewer input_file output_file -d

4) To convert zW codes.
$ chviewer input_file output_file -z

Compiling instruction:
~~~~~~~~~~~~~~~~~~~~~~
1) On VMS,
$CC chviewer.c
$link chviewer, sys$library:vaxcrtl.olb/lib
$chviewer:==$mypath:chviewer.exe
where the last step is to define the foreign command to use command line.

2) On unix,
%cc -o chviewer chviewer.c

3) On DOS -- compiler dependent

*/


#if VMS
#include <file.h>
#else
#include <fcntl.h>
#endif

extern char *getenv();

#define NUM_Char 512
#define INBUFSIZE 248
#define MAX_filesize 64000  /* Is document file size 64k ok? */
char infile_name[80];
char outfile_name[80];

static char *ASCII_map[256] =
{ "        ", "       &", "      & ", "      &&", "     &  ", "     & &",
 "     && ", "     &&&", "    &   ", "    &  &", "    & & ", "    & &&",
 "    &&  ", "    && &", "    &&& ", "    &&&&", "   &    ", "   &   &",
 "   &  & ", "   &  &&", "   & &  ", "   & & &", "   & && ", "   & &&&",
 "   &&   ", "   &&  &", "   && & ", "   && &&", "   &&&  ", "   &&& &",
 "   &&&& ", "   &&&&&",

 "  &     ", "  &    &", "  &   & ", "  &   &&", "  &  &  ", "  &  & &",
 "  &  && ", "  &  &&&", "  & &   ", "  & &  &", "  & & & ", "  & & &&",
 "  & &&  ", "  & && &", "  & &&& ", "  & &&&&", "  &&    ", "  &&   &",
 "  &&  & ", "  &&  &&", "  && &  ", "  && & &", "  && && ", "  && &&&",
 "  &&&   ", "  &&&  &", "  &&& & ", "  &&& &&", "  &&&&  ", "  &&&& &",
 "  &&&&& ", "  &&&&&&",

 " &      ", " &     &", " &    & ", " &    &&", " &   &  ", " &   & &",
 " &   && ", " &   &&&", " &  &   ", " &  &  &", " &  & & ", " &  & &&",
 " &  &&  ", " &  && &", " &  &&& ", " &  &&&&", " & &    ", " & &   &",
 " & &  & ", " & &  &&", " & & &  ", " & & & &", " & & && ", " & & &&&",
 " & &&   ", " & &&  &", " & && & ", " & && &&", " & &&&  ", " & &&& &",
 " & &&&& ", " & &&&&&",

 " &&     ", " &&    &", " &&   & ", " &&   &&", " &&  &  ", " &&  & &",
 " &&  && ", " &&  &&&", " && &   ", " && &  &", " && & & ", " && & &&",
 " && &&  ", " && && &", " && &&& ", " && &&&&", " &&&    ", " &&&   &",
 " &&&  & ", " &&&  &&", " &&& &  ", " &&& & &", " &&& && ", " &&& &&&",
 " &&&&   ", " &&&&  &", " &&&& & ", " &&&& &&", " &&&&&  ", " &&&&& &",
 " &&&&&& ", " &&&&&&&",

 "&       ", "&      &", "&     & ", "&     &&", "&    &  ", "&    & &",
 "&    && ", "&    &&&", "&   &   ", "&   &  &", "&   & & ", "&   & &&",
 "&   &&  ", "&   && &", "&   &&& ", "&   &&&&", "&  &    ", "&  &   &",
 "&  &  & ", "&  &  &&", "&  & &  ", "&  & & &", "&  & && ", "&  & &&&",
 "&  &&   ", "&  &&  &", "&  && & ", "&  && &&", "&  &&&  ", "&  &&& &",
 "&  &&&& ", "&  &&&&&",

 "& &     ", "& &    &", "& &   & ", "& &   &&", "& &  &  ", "& &  & &",
 "& &  && ", "& &  &&&", "& & &   ", "& & &  &", "& & & & ", "& & & &&",
 "& & &&  ", "& & && &", "& & &&& ", "& & &&&&", "& &&    ", "& &&   &",
 "& &&  & ", "& &&  &&", "& && &  ", "& && & &", "& && && ", "& && &&&",
 "& &&&   ", "& &&&  &", "& &&& & ", "& &&& &&", "& &&&&  ", "& &&&& &",
 "& &&&&& ", "& &&&&&&",

 "&&      ", "&&     &", "&&    & ", "&&    &&", "&&   &  ", "&&   & &",
 "&&   && ", "&&   &&&", "&&  &   ", "&&  &  &", "&&  & & ", "&&  & &&",
 "&&  &&  ", "&&  && &", "&&  &&& ", "&&  &&&&", "&& &    ", "&& &   &",
 "&& &  & ", "&& &  &&", "&& & &  ", "&& & & &", "&& & && ", "&& & &&&",
 "&& &&   ", "&& &&  &", "&& && & ", "&& && &&", "&& &&&  ", "&& &&& &",
 "&& &&&& ", "&& &&&&&",

 "&&&     ", "&&&    &", "&&&   & ", "&&&   &&", "&&&  &  ", "&&&  & &",
 "&&&  && ", "&&&  &&&", "&&& &   ", "&&& &  &", "&&& & & ", "&&& & &&",
 "&&& &&  ", "&&& && &", "&&& &&& ", "&&& &&&&", "&&&&    ", "&&&&   &",
 "&&&&  & ", "&&&&  &&", "&&&& &  ", "&&&& & &", "&&&& && ", "&&&& &&&",
 "&&&&&   ", "&&&&&  &", "&&&&& & ", "&&&&& &&", "&&&&&&  ", "&&&&&& &",
 "&&&&&&& ", "&&&&&&&&"
};

#include<stdio.h>
#include<string.h>

FILE *cclib;
unsigned char cclib_array[300000];
int piping=0;  /* for VMS piping */

viewer()
{
char row[16][NUM_Char], tmpchar, *cclibfile;
long int  max_quwei, i, j, filelength, k, quwei, new_line=1;
int inhandle, flag,  ch_byte1, ch_pair, tmpint, l, n, any_ch;
unsigned char AllBuffer[MAX_filesize];

          /* use system I/O for input*/
   if ( (inhandle=open(infile_name, O_RDONLY))<0)
       {fprintf(stderr, "File not found!");}

filelength=0;
ch_pair = 1;
  /* read in the file */
while( (flag=read(inhandle, &AllBuffer[filelength], INBUFSIZE))>0)
  {  
     while(AllBuffer[++filelength]>0);
  }

#if VMS
        if (piping) stdout=fopen(outfile_name, "w");
#endif

   /* Process it by marking the end of lines*/
   i=0; 
  max_quwei = 0;

   while(i<filelength) /* get rid of the WordStar shift codes 
                          and figure out the highest QuWei code used*/

    {  switch(AllBuffer[i])
       {
        case 10:
        case 13: ch_pair = 1; break;
          default: 
              if (AllBuffer[i]>127) 
               { if (AllBuffer[i]<161)
                 {
                  AllBuffer[i] -= 128;
                  break;
                 }
                ch_pair *= -1;
                if (ch_pair < 0) ch_byte1 = AllBuffer[i];
                else {
          
                       if (ch_byte1>175) ch_byte1 -= 8;
                   quwei = (ch_byte1 - 161)*94 + AllBuffer[i] - 161;
                       if (quwei>max_quwei) max_quwei = quwei;

                     }
                }
       }
     i++;
    }  

/* Get CCLIB into the buffer */


#if unix|VMS
#if unix

   	if (!(cclibfile = getenv("CCLIB16jt")))
		 cclibfile = CCLIB16jt;

   if (( cclib = fopen(cclibfile, "r") ) ==NULL)
    {fputs("Missing library file", stderr); exit(-1);}
#endif

#if VMS

		if (( cclib = fopen("cclib16$jt", "r") ) ==NULL)
		{ cclibfile = CCLIB16jt;
		if (( cclib = fopen(cclibfile, "r") ) ==NULL)
		{fputs("Missing library file", stderr); exit(-1);}
		}

#endif
#else
	cclibfile = CCLIB16jt;
   if (( cclib = fopen(cclibfile, "rb") ) ==NULL)
    {fputs("Missing library file", stderr); exit(-1);}
#endif

    k=0;

      max_quwei = (max_quwei+1)*32;

    while( k < max_quwei )
       cclib_array[k++] = fgetc(cclib);
    fclose(cclib);


  /* view file, use row[][16] to store whole line in bitmap*/


  /* view file, use row[][16] to store whole line in bitmap*/

        ch_pair = 1;
        i = j = k= 0;
      while(i<filelength)  /* Print a file in lines */
       {
      
         
    /* If no Chinese in a line, simply print the text */

           if (AllBuffer[i]==10) {new_line = 1; k = i+1; i++;}

            if (new_line)
            {   any_ch  = 0;
                ch_pair = 1;  
                new_line = 0;

               if (j>0)
                 {
                  for (n=0; n<16; n++)
                for (n=0; n<16; n++)
                   {row[n][j] = '\n';row[n][j+1] = '\0';
                    fputs(row[n], stdout);}
                    fputc('\n', stdout); 
     
                     j=0;   
                  }

                while ((AllBuffer[k] !='\n')&&(AllBuffer[k] !='\0'))
                  if (AllBuffer[k++] > 160) any_ch = 1;

               if (!any_ch) 
                { tmpchar = AllBuffer[k];
                  AllBuffer[k] = '\0';
                  fputs(&AllBuffer[i], stdout); fputc('\n', stdout);
                  AllBuffer[k] = tmpchar;
                  i = k;
                  goto next_while;
                }

              }

           if ((AllBuffer[i]>160)&&(AllBuffer[i]<255))
            { ch_pair *= -1;
              if (ch_pair < 0) 
                 {ch_byte1 = AllBuffer[i];
      if (ch_byte1>175) ch_byte1 -= 8; /* 168 ~ 175 is repeating 176 ~ 183 */
                  i++;
                  goto next_while;
                 }
               else
                {
               quwei = ((ch_byte1-161)*94 + AllBuffer[i]-161)*32;
 
                   for (l=0; l<16; l++ )
                   {
                     for (n=0; n<8; n++)
                      {     
                      row[l][j+n] = ASCII_map[cclib_array[quwei+2*l]][n];
                      row[l][j+8+n]= ASCII_map[cclib_array[quwei+2*l+1]][n];
                      }
                   }                   
                  j +=16;
                  i ++;
                }  

            } /* end  if (AllBuffer[i] > 160)*/
            else  /* Now < 160 */
             {   if (AllBuffer[i] == 9) AllBuffer[i] = ' ';
                 for (n=0; n<16; n++)
                   row[n][j] = ' ';
                 row[10][j] = AllBuffer[i]; 
                j++;
                i++;
             }        /* end < 160 */

           if ( j > 64)
             {

                for (n=0; n<16; n++)
                   {row[n][j] = '\n';row[n][j+1] = '\0';
                    fputs(row[n], stdout);}
                fputc('\n', stdout);
                j  = 0;

              }

        next_while:;

       }

               if (j>0)
                 {
                for (n=0; n<16; n++)
                   {row[n][j] = '\n';row[n][j+1] = '\0';
                    fputs(row[n], stdout);}

                  }



}


FILE *infile, *outfile;

main(argc, argv)
int argc;
char *argv[];
{

int in_file, out_file, out_ok=1;
int i,j, name_count=0;
char string[60];
char ch, quit;
int sorting=1;

/* the following variables are used for the option flags */
int Viewer=1,       /* View it*/
    zW=0,          /* decode zW                                      -z */
    Decode=0,      /* CzW decode the encoded file                 -d */
    Encode=0;      /* CzW encode into standard ASCII file         -e */

in_file = out_file = 1;

/* decode the command line*/
for (i = 1; i<argc; i++)
 if (argv[i][0] == '-')
  { for (j=1; j<strlen(argv[i]); j++)
     switch(argv[i][j])
      {
       case 'd': 
       case 'D': Decode =1; Viewer=0; break;
       case 'e': 
       case 'E': Encode =1; Viewer = 0; break;
       default: fprintf(stderr, "Invalid flag = %c\n", argv[i][j]);
      }
   

  }
 else
  { 

   switch (name_count++)
   {
    case 0: in_file=0; 
             strcpy(infile_name,argv[i]);
             break;
    case 1: if (argv[i][0]!='>')
             {
            out_file=0; 
            strcpy(outfile_name,argv[i]); 
             }
            else piping = 1;
            break;
    case 2: if (piping)
             {
            out_file=0; 
            strcpy(outfile_name,argv[i]); 
             break;
             }

    default: fprintf(stderr, "Extra argument = %s\n", argv[i]);
   }

  }

 

 if (in_file) 
   {
   printf(" Input file (file to be viewed/translated) >");
   scanf("%s",infile_name);
   fflush(stdin);
   }



if ( !Encode && !Decode)
   {viewer(); 
   goto quit;
   }

while (out_ok)

 {
  if (out_file) 
    {
    printf(" Output file name >");
    fscanf(stdin, "%s",outfile_name);
    fflush(stdin);
    }


    out_ok=0; 
   if ((outfile=fopen(outfile_name,"r"))!=NULL)
     { out_ok=1;
            out_file=1;
      fflush(stdin);
      printf(" File <%s> already exist, overwrite ? [N]", outfile_name);

     while((ch=fgetc(stdin))=='\n');

        if ((ch=='y')||(ch=='Y')) out_ok=0;
        fclose(outfile);

     }
/*
    if (out_ok==0)
       {
	outfile=fopen(outfile_name,"w");
       }
*/
 }




if (Encode)
   ccdos_encode();

if (Decode)
   ccdos_decode();



quit:
   ;
/*
fprintf(stderr, "\n\t>>> Thank you for using chviewr >>>\n");
fprintf(stderr, "\t>>> by Jingbai Wang, August 1989 >>>\n");
*/

}


/*
 jbw@pittvms.bitnet
 jbw@cisunx.UUCP

 Author permits free distribution of this file.
*/


/**********************************************************************
*                          CzW.c                                      *
*                                                                     *
*           This program converts GB/CCDOS output to/from ASCII       *
*              it can be used to convert other binary files too       *
*                                                                     *
***********************************************************************/
/*
 It runs on VMS, UNIX , DOS and MAC systems.

Syntax:
~~~~~~
1) For CCDOS encoding and decoding,
   To convert a file into ASCII:
   $ CzW input_file output_file -e

   To convert a CCDOS file :
   $ CzW input_file output_file -d

2) For MAC Chinese encoding and decoding,
   To convert a file into ASCII:
   $ CzW input_file output_file -me

   To convert a MAC Chinese file :
   $ CzW input_file output_file -md

Compiling instruction:
~~~~~~~~~~~~~~~~~~~~~~
1) On VMS,
$CC CzW.c
$link CzW, sys$library:vaxcrtl.olb/lib
$CzW:==$mypath:CzW.exe
where the last step is to define the foreign command to use command line.

2) On unix,
%cc -o CzW CzW.c

3) On DOS and MAC-- compiler dependent

*/


#define CLS printf("\n\n\n\n")

unsigned char inbuffer[1025];  /* read in 1 kbyte a time */

/*///*/

ccdos_encode() /* Shift all charaters to 31< ASCII < 128
                 by the following schemes */ 
               /* escape codes:
                 \zW  -- begin characters > 160
                 \^@  -- begin special control characters < 32
                 \A@  --  31< ASCII characters <128
                 \W@  --  126< WordStar characters <161 
                 \c@  --  continue line
               */
{
int bh, i, ws, bl, line_length;
   bh = 0;
   bl = 0;
   ws = 0;
   line_length = 0;

fprintf(stderr, "Start encoding %s\n\n", infile_name);

     outfile=fopen(outfile_name,"w");

 fprintf(outfile,"\
%% This is an encoded Chinese text file generated in CCDOS standard\n\
%% Please do not edit any lines below this\n\
\\A@\n");

  while( fgets(inbuffer, 1024, infile) != NULL)
 {

   for (i=0; i<strlen(inbuffer); i++)
 {   

  switch(inbuffer[i])
   {

    case 13:
    case 10: line_length = 0; 
    case 12:            
    case 9:
           if (line_length>74)
            {
               fprintf(outfile, "\\c@\n");
               line_length=0;
            }

            fprintf(outfile, "%c", inbuffer[i]); line_length ++; break;
    case 32:
           if (line_length>74)
            {
               fprintf(outfile, "\\c@\n");
               line_length=0;
            }
             fprintf(outfile, " "); line_length ++; break;

    default:
     if (inbuffer[i] > 160)
         { bl = 0;
           ws = 0;
          if (!bh) 
             {
              if (line_length>74)
               {
               fprintf(outfile, "\\c@\n");
               line_length=0;
                }
               fprintf(outfile, "\\zW");
               line_length +=5;
               bh = 1;
             }
           if (line_length>74)
            {
               fprintf(outfile, "\\c@\n");
               line_length=0;
            }

                inbuffer[i] -= 128;
                fprintf(outfile, "%c", inbuffer[i]);
                line_length ++;
                break;
         }
      else if (inbuffer[i]>126) /* Probably the WordStar stuff */
         { 
           bl = 0;
           bh = 0;
          if (!ws) 
             {
              if (line_length>74)
               {
               fprintf(outfile, "\\c@\n");
               line_length=0;
                }
               fprintf(outfile, "\\W@");
               line_length +=3;
               ws = 1;
             }
           if (line_length>74)
            {
               fprintf(outfile, "\\c@\n");
               line_length=0;
            }

                inbuffer[i] -= 95;
                fprintf(outfile, "%c", inbuffer[i]);
                line_length ++;
                break;
         }
      else if (inbuffer[i]<32)
         {
          bh = 0;
          ws = 0;
          if (!bl) 
             {
              if (line_length>74)
               {
               fprintf(outfile, "\\c@\n");
               line_length=0;
                }
               fprintf(outfile, "\\^@");
               line_length +=5;
               bl = 1;
             }
           inbuffer[i] += 32;
           if (line_length>74)
            {
               fprintf(outfile, "\\c@\n");
               line_length=0;
            }
           fprintf(outfile, "%c", inbuffer[i]);
           line_length ++;
           break;
         }
       
      else 
         {

           if (bh||bl||ws)
            {  if (line_length>74)
               {
               fprintf(outfile, "\\c@\n");
               line_length=0;
                }
               fprintf(outfile, "\\A@");
               line_length +=5;
               bh = 0;
               bl = 0;
               ws = 0;
             }

           if (line_length>74)
            {
               fprintf(outfile, "\\c@\n");
               line_length=0;
            }
           fprintf(outfile, "%c", inbuffer[i]);
           line_length ++;

         }

   }
  }
 }

fclose(infile);
fclose(outfile);

}

ccdos_decode() /* Shift all the bytes back to original */
{
int bh, bl, i, line_length, shift;
int comment=1;

   shift = 0;
fprintf(stderr, "Start decoding %s\n\n", infile_name);
   outfile = stderr;

  while( fgets(inbuffer, 1024, infile) != NULL)
 {

   for (i=0; i<strlen(inbuffer); i++)
 {   
    switch(inbuffer[i])
   {
    case 9:  
    case 32: 
    case 12: 
    case 13:
    case 10:
              fprintf(outfile, "%c", inbuffer[i]); break;
    case '\\':
             if (strncmp(&inbuffer[i+1], "zW", 2) == 0)
                { shift = 128;
                  i += 2; break;
                }
              else if (strncmp(&inbuffer[i+1], "^@", 2) == 0)
                { shift = -32;
                  i += 2; break;
                }
              else if (strncmp(&inbuffer[i+1], "A@", 2) == 0)
                { shift = 0;
                  i += 2;
            if (comment) {
                          outfile=fopen(outfile_name,"w");
                          comment = 0;
                          i ++;
                         }
                  break;
                }
              else if (strncmp(&inbuffer[i+1], "W@", 2) == 0)
                { shift = 95;
                  i += 2; break;
                }
              else if (strncmp(&inbuffer[i+1], "c@", 2) == 0)
                {
                  i += 3; break;
                }
              else 
                { inbuffer[i] += shift;
                   fprintf(outfile, "%c", inbuffer[i]);
                }

           break;
    default:
           inbuffer[i] += shift;
           fprintf(outfile, "%c", inbuffer[i]);

   }
  }
 }

fclose(infile);
fclose(outfile);


}


