home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Ascii-Ansi / vec3.231.lha / vec3231 / source / vec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-04  |  9.5 KB  |  562 lines

  1. /*
  2.  * VEC.C (VEC)
  3.  *
  4.  * Copyright (c) 1991, 1992, 1993 Ville Saari
  5.  * All rights reserved
  6.  *
  7.  * Created: 18-Dec-91
  8.  * Updated: 04-Dec-93
  9.  */
  10.  
  11. #include "vec.h"
  12.  
  13. const static struct
  14.     {
  15.     unsigned char uuencodetab[4];
  16.     unsigned char encodetab[182];
  17.     } tabs=
  18.     {
  19.     /* characters used by uuencode method: */
  20.  
  21.     96, 33, 34, 35,
  22.  
  23.     /* characters used by all methods: */
  24.  
  25.     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
  26.     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
  27.     68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
  28.     84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  29.  
  30.     /* characters used by all but uuencode method */
  31.  
  32.     96, 97, 98, 99,
  33.  
  34.     /* characters used by >=6.5 bit methods: */
  35.  
  36.     100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
  37.     114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
  38.  
  39.     /* characters used by >=7 bit methods: */
  40.  
  41.     161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
  42.     171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
  43.     181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
  44.     191, 192, 193, 194, 195, 196, 197,
  45.  
  46.     /* characters used by 7.5 bit method: */
  47.  
  48.     198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
  49.     208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
  50.     218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
  51.     228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
  52.     238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
  53.     248, 249, 250, 251
  54.     };
  55.  
  56. static const unsigned char hextab[]=
  57.     {
  58.     '0', '1', '2', '3', '4', '5', '6', '7',
  59.     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
  60.     };
  61.  
  62. #define uuencodetab tabs.uuencodetab
  63. #define encodetab tabs.encodetab
  64.  
  65. static int lineleft;
  66.  
  67. static void sevenandhalfbitcoder(const unsigned char *i, unsigned char *o)
  68.     {
  69.     const unsigned char *j=i+8;
  70.     unsigned int z;
  71.  
  72.     z=(*i++|*j++<<8)&0x7fff;
  73.     *o++=encodetab[z%182];
  74.     *o++=encodetab[z/182];
  75.  
  76.     z=(*i++|*j++<<8)&0x7fff;
  77.     *o++=encodetab[z%182];
  78.     *o++=encodetab[z/182];
  79.  
  80.     z=(*i++|*j++<<8)&0x7fff;
  81.     *o++=encodetab[z%182];
  82.     *o++=encodetab[z/182];
  83.  
  84.     z=(*i++|*j++<<8)&0x7fff;
  85.     *o++=encodetab[z%182];
  86.     *o++=encodetab[z/182];
  87.  
  88.     z=(*i++|*j++<<8)&0x7fff;
  89.     *o++=encodetab[z%182];
  90.     *o++=encodetab[z/182];
  91.  
  92.     z=(*i++|*j++<<8)&0x7fff;
  93.     *o++=encodetab[z%182];
  94.     *o++=encodetab[z/182];
  95.  
  96.     z=(*i++|*j  <<8)&0x7fff;
  97.     *o++=encodetab[z%182];
  98.     *o++=encodetab[z/182];
  99.  
  100.     z=*i++;
  101.     z|=(*i++&0x80)<<1;
  102.     z|=(*i++&0x80)<<2;
  103.     z|=(*i++&0x80)<<3;
  104.     z|=(*i++&0x80)<<4;
  105.     z|=(*i++&0x80)<<5;
  106.     z|=(*i++&0x80)<<6;
  107.     z|=(*i  &0x80)<<7;
  108.     *o++=encodetab[z%182];
  109.     *o  =encodetab[z/182];
  110.     }
  111.  
  112. static void sevenbitcoder(const unsigned char *i, unsigned char *o)
  113.     {
  114.     unsigned int z;
  115.     unsigned char c;
  116.  
  117.     *o++=encodetab[(c=*i++)&0x7f]; z=c>>7;
  118.     *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>6;
  119.     *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>5;
  120.     *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>4;
  121.     *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>3;
  122.     *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>2;
  123.     *o++=encodetab[(c=*i  )&0x7f]; z|=(c&0x80)>>1;
  124.     *o  =encodetab[z];
  125.     }
  126.  
  127. static void sixandhalfbitcoder(const unsigned char *i, unsigned char *o)
  128.     {
  129.     const unsigned char *j=i+8;
  130.     unsigned int z;
  131.  
  132.     z=*i++|((*j++&0x1f)<<8);
  133.     *o++=encodetab[z%91];
  134.     *o++=encodetab[z/91];
  135.  
  136.     z=*i++|((*j++&0x1f)<<8);
  137.     *o++=encodetab[z%91];
  138.     *o++=encodetab[z/91];
  139.  
  140.     z=*i++|((*j++&0x1f)<<8);
  141.     *o++=encodetab[z%91];
  142.     *o++=encodetab[z/91];
  143.  
  144.     z=*i++|((*j++&0x1f)<<8);
  145.     *o++=encodetab[z%91];
  146.     *o++=encodetab[z/91];
  147.  
  148.     z=*i++|((*j  &0x1f)<<8);
  149.     *o++=encodetab[z%91];
  150.     *o++=encodetab[z/91];
  151.  
  152.     j-=4;
  153.     z=*i++|((j[0]&0xe0)<<3)|((j[3]&0x60)<<6);
  154.     *o++=encodetab[z%91];
  155.     *o++=encodetab[z/91];
  156.  
  157.     j++;
  158.     z=*i++|((j[0]&0xe0)<<3)|((j[3]&0x60)<<6);
  159.     *o++=encodetab[z%91];
  160.     *o++=encodetab[z/91];
  161.  
  162.     j++;
  163.     z=*i  |((j[0]&0xe0)<<3)|((j[1]&0x80)<<4)|((j[2]&0x80)<<5);
  164.     *o++=encodetab[z%91];
  165.     *o  =encodetab[z/91];
  166.     }
  167.  
  168. static void sixbitcoder(const unsigned char *i, unsigned char *o)
  169.     {
  170.     *o++=encodetab[*i++&0x3f];
  171.     *o++=encodetab[*i++&0x3f];
  172.     *o++=encodetab[*i++&0x3f];
  173.     *o++=encodetab[*i++&0x3f];
  174.     *o++=encodetab[*i++&0x3f];
  175.     *o++=encodetab[*i  &0x3f];
  176.  
  177.     i-=5;
  178.  
  179.         {
  180.         unsigned int z;
  181.  
  182.         z=*i++>>6;
  183.         z|=(*i++&0xc0)>>4;
  184.         z|=(*i++&0xc0)>>2;
  185.         *o++=encodetab[z];
  186.  
  187.         z=*i++>>6;
  188.         z|=(*i++&0xc0)>>4;
  189.         z|=(*i  &0xc0)>>2;
  190.         *o=encodetab[z];
  191.         }
  192.     }
  193.  
  194. static void hexcoder(const unsigned char *i, unsigned char *o)
  195.     {
  196.     *o++=hextab[*i>>4&0xf];
  197.     *o  =hextab[*i   &0xf];
  198.     }
  199.  
  200. static char *stox(unsigned short s)
  201.     {
  202.     static char buf[5];
  203.     unsigned char t;
  204.  
  205.     t=(char)(s>>8);
  206.     hexcoder(&t, buf);
  207.  
  208.     t=(char)s;
  209.     hexcoder(&t, buf+2);
  210.  
  211.     return buf;
  212.     }
  213.  
  214. static void uucoder(const unsigned char *i, unsigned char *o)
  215.     {
  216.    unsigned int t, u;
  217.  
  218.    *o++=uuencodetab[          (t=*i++)>>2    ];
  219.    *o++=uuencodetab[t<<4&0x30|(u=*i++)>>4&0xf];
  220.    *o++=uuencodetab[u<<2&0x3c|(t=*i  )>>6&0x3];
  221.    *o  =uuencodetab[t   &0x3f                ];
  222.     }
  223.  
  224. static void newline(void)
  225.     {
  226.     if(cr) put1(13);
  227.     put1(10);
  228.  
  229.     lineleft=width;
  230.     }
  231.  
  232. static void breakput(const unsigned char *block, int size)
  233.     {
  234.     for(;;)
  235.         {
  236.         if((lineleft-=size)>=0)
  237.             {
  238.             put(block, size);
  239.             return;
  240.             }
  241.  
  242.         put(block, lineleft+size);
  243.  
  244.         block+=lineleft+size;
  245.         size=-lineleft;
  246.  
  247.         newline();
  248.         }
  249.     }
  250.  
  251. static void addbreaks(unsigned long size)
  252.     {
  253.     while(lineleft<size)
  254.         {
  255.         outptr+=lineleft;
  256.         size-=lineleft;
  257.         lineleft=width;
  258.  
  259.         if(cr)
  260.             {
  261.             unsigned int b=size;
  262.             char *f=outptr+b;
  263.             char *t=f+2;
  264.  
  265.             while(b--) *--t=*--f;
  266.  
  267.             *outptr++=13;
  268.             }
  269.         else
  270.             {
  271.             unsigned int b=size;
  272.             char *f=outptr+b;
  273.             char *t=f+1;
  274.  
  275.             while(b--) *--t=*--f;
  276.             }
  277.  
  278.         *outptr++=10;
  279.         }
  280.  
  281.     outptr+=size;
  282.     lineleft-=size;
  283.  
  284.     if(outptr>=outbufend) flushoutput();
  285.     }
  286.  
  287. #define checkeol(n) { if(lineleft<=n && (lineleft<n || next!=10)) \
  288.     { put1(94); newline(); } lineleft-=n; }
  289.  
  290. static void asciiencode(void)
  291.     {
  292.     unsigned char current, next;
  293.     unsigned short crc=0;
  294.     int eof=0, iso=method=='i';
  295.  
  296.     if(inptr>=inbufend && !fillbuffer(1))
  297.         {
  298.         eof=1;
  299.         next=0;
  300.         }
  301.     else
  302.         next=*inptr++;
  303.  
  304.     while(!eof)
  305.         {
  306.         current=next;
  307.  
  308.         if(inptr>=inbufend && !fillbuffer(1))
  309.             {
  310.             eof=1;
  311.             next=0;
  312.             }
  313.         else
  314.             next=*inptr++;
  315.  
  316.         if(!quick) crc=(crc>>8)^crc16tab[(unsigned char)(crc^current)];
  317.  
  318.         if(current==10 && shortlines || !lineleft)
  319.             newline();
  320.         else if(current<32 && (!literaltabs || current!=9))
  321.             {
  322.             if(lineleft<=3)
  323.                 if(current==10 && (lineleft<3 || next<32 && next!=10 ||
  324.                     next==92 || next==94 || next>127 && (!iso || next<160)))
  325.                     {
  326.                     newline();
  327.                     continue;
  328.                     }
  329.                 else if(lineleft<2 || lineleft==2 && next!=10)
  330.                     {
  331.                     put1(94);
  332.                     newline();
  333.                     }
  334.  
  335.             lineleft-=2;
  336.             put1(94);
  337.             put1(current+64);
  338.             }
  339.         else if((current==92 && !iso) || current==94 &&
  340.             (next<32 || next>(iso?60:58) && (!iso || next<160 || next==255) ||
  341.             next==33 || lineleft<3))
  342.             {
  343.             checkeol(2);
  344.             put1(94);
  345.             put1(current==92?60:61);
  346.             }
  347.         else if(current<127 || iso && current>=160)
  348.             {
  349.             checkeol(1);
  350.             put1(current);
  351.             }
  352.         else
  353.             {
  354.             checkeol(2);
  355.  
  356.             if(current==255)
  357.                 {    
  358.                 put1(94);
  359.                 put1(59);
  360.                 }
  361.             else if(current>=160)
  362.                 {
  363.                 put1(92);
  364.                 put1(current+128);
  365.                 }
  366.             else if(current==127)
  367.                 {    
  368.                 put1(94);
  369.                 put1(63);
  370.                 }
  371.             else if(current==159)
  372.                 {    
  373.                 put1(94);
  374.                 put1(62);
  375.                 }
  376.             else
  377.                 {
  378.                 put1(94);
  379.                 put1(current-32);
  380.                 }
  381.             }
  382.         }
  383.  
  384.     breakput("^!", 2);
  385.  
  386.     if(!quick)
  387.         breakput(stox(crc), 4);
  388.     }
  389.  
  390. static void uuencode(const char *filename)
  391.     {
  392.     unsigned char flagbuf[3]={'6', '0', '0'};
  393.     unsigned char outbuf[62], *inbuf, *i, *o, *l;
  394.     unsigned long size=0;
  395.  
  396.     if(filename && !nomode) getfilemode(filename, flagbuf, 1);
  397.  
  398.     put("begin ", 6);
  399.     put(flagbuf, 3);
  400.     put(" ", 1);
  401.  
  402.     if(name) filename=name;
  403.     filename=basename(filename);
  404.     if(!*filename) filename="noname";
  405.  
  406.     put(filename, strlen(filename));
  407.     newline();
  408.  
  409.     do    {
  410.         i=inbuf=get(45);
  411.         o=outbuf;
  412.         *o++=uuencodetab[trueread];
  413.  
  414.         l=i+trueread;
  415.  
  416.         while(i<l)
  417.             {
  418.             uucoder(i, o);
  419.             i+=3;
  420.             o+=4;
  421.             }
  422.  
  423.         if(!quick)
  424.             {
  425.             unsigned int s=0;
  426.  
  427.             i=inbuf;
  428.     
  429.             while(i<l)
  430.                 {
  431.                 s+=*i++;
  432.                 s+=*i++;
  433.                 s+=*i++;
  434.                 }
  435.  
  436.             *o++=uuencodetab[s&0x3F];
  437.             size+=trueread;
  438.             }
  439.  
  440.         put(outbuf, o-outbuf);
  441.         newline();
  442.         }
  443.     while(trueread);
  444.  
  445.     put("end", 3);
  446.     newline();
  447.  
  448.     if(!quick)
  449.         {
  450.         char *t=ltoa(size);
  451.  
  452.         put("size ", 5);
  453.         put(t, strlen(t));
  454.         newline();
  455.         }
  456.     }
  457.  
  458. void vec(const char *filename)
  459.     {
  460.     unsigned char flagbuf[6], outblockbuf[16], *indata;
  461.     int inblock, outblock;
  462.     unsigned short crc=0;
  463.     void (*coder)(const unsigned char *, unsigned char *)=0;
  464.  
  465.     flagbuf[0]=!quick;
  466.     flagbuf[1]=flagbuf[2]=flagbuf[3]=flagbuf[4]=flagbuf[5]=0;
  467.  
  468.     if(filename && !nomode)
  469.         getfilemode(filename, flagbuf, 0);
  470.  
  471.     if(name) filename=name;
  472.     filename=basename(filename);
  473.  
  474.     if(!silent && *filename)
  475.         {
  476.         printerr(filename);
  477.         printerr("\n");
  478.         }
  479.  
  480.     if(!*filename) filename="noname";
  481.  
  482.     if(method=='u')
  483.         {
  484.         uuencode(filename);
  485.         return;
  486.         }
  487.  
  488.     if(!quick) flagbuf[0]|=1;
  489.  
  490.     sixbitcoder(flagbuf, outblockbuf);
  491.  
  492.     put("yobufi", 6);
  493.     put(&method, 1);
  494.     put(outblockbuf, 8);
  495.     put(filename, strlen(filename));
  496.     newline();
  497.  
  498.     switch(method)
  499.         {
  500.         case '3':
  501.             coder=sevenandhalfbitcoder;
  502.             inblock=15;
  503.             outblock=16;
  504.             break;
  505.  
  506.         case '2':
  507.             coder=sevenbitcoder;
  508.             inblock=7;
  509.             outblock=8;
  510.             break;
  511.  
  512.         case '1':
  513.             coder=sixandhalfbitcoder;
  514.             inblock=13;
  515.             outblock=16;
  516.             break;
  517.  
  518.         case '0':
  519.             coder=sixbitcoder;
  520.             inblock=6;
  521.             outblock=8;
  522.             break;
  523.  
  524.         case 'x':
  525.             coder=hexcoder;
  526.             inblock=1;
  527.             outblock=2;
  528.         }
  529.  
  530.     if(coder)
  531.         {
  532.         while(indata=get(inblock), trueread)
  533.             {
  534.             coder(indata, outptr);
  535.             addbreaks(outblock);
  536.  
  537.             if(!quick)
  538.                 {
  539.                 unsigned int datainblock=trueread;
  540.                 unsigned char *t=indata;
  541.  
  542.                while(datainblock--)
  543.                   crc=(crc>>8)^crc16tab[(unsigned char)(crc^*t++)];
  544.                 }
  545.  
  546.             if(trueread<inblock) break;
  547.             }
  548.  
  549.         if(!trueread) trueread=inblock;
  550.  
  551.         breakput("!", 1);
  552.         breakput(hextab+inblock-trueread, 1);
  553.  
  554.         if(!quick)
  555.             breakput(stox(crc), 4);
  556.         }
  557.     else
  558.         asciiencode();
  559.  
  560.     newline();
  561.     }
  562.