home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / ARCHIVERS / lha208src.lzh / LHA / SRC / crcio.c < prev    next >
Text File  |  1994-02-14  |  8KB  |  367 lines

  1. /***********************************************************
  2.     crcio.c -- input/output
  3. ***********************************************************/
  4. #ifdef __STDC__
  5. #include <stdlib.h>
  6. #include <stdarg.h>
  7. #endif
  8. #include <stdio.h>
  9. #include <errno.h>
  10. #include "slidehuf.h"
  11. #include "intrface.h"
  12.  
  13. extern int text_mode;
  14. extern int prev_char;
  15. extern int verify_mode;
  16. #ifdef EUC
  17. extern int euc_mode;
  18. extern int generic_format;
  19. #endif
  20.  
  21. long reading_size;
  22.  
  23. #define CRCPOLY  0xA001  /* CRC-16 */
  24. #define UPDATE_CRC(c) mcrc = crctable[(mcrc ^ (c)) & 0xFF] ^ (mcrc >> CHAR_BIT)
  25.  
  26. FILE *infile, *outfile;
  27. unsigned short mcrc, bitbuf;
  28.  
  29. static unsigned short crctable[UCHAR_MAX + 1];
  30. static unsigned char  subbitbuf, bitcount;
  31. #ifdef EUC
  32. static int putc_euc_cache;
  33. #endif
  34. static int getc_euc_cache;
  35.  
  36. void make_crctable()
  37. {
  38.     unsigned int i, j, r;
  39.  
  40.     for (i = 0; i <= UCHAR_MAX; i++) {
  41.         r = i;
  42.         for (j = 0; j < CHAR_BIT; j++)
  43.             if (r & 1) r = (r >> 1) ^ CRCPOLY;
  44.             else       r >>= 1;
  45.         crctable[i] = r;
  46.     }
  47. }
  48.  
  49.  
  50. #ifdef NEED_INCREMENTAL_INDICATOR
  51. extern int quiet;
  52. extern int indicator_count;
  53. extern int indicator_threshold;
  54. static void
  55. put_indicator( count )
  56. long int count;
  57. {
  58.     if (!quiet)
  59.     {
  60.         while ( count > indicator_count) {
  61. #ifdef OSK
  62.             write(1,"o",1);
  63. #else
  64.             putchar ('o');
  65.             fflush (stdout);
  66. #endif
  67.             indicator_count += indicator_threshold;
  68.         }
  69.     }
  70. }
  71. #endif
  72.  
  73. unsigned short calccrc( p , n )
  74. unsigned char *p;
  75. unsigned int n;
  76. {
  77.     reading_size += n;
  78. #ifdef NEED_INCREMENTAL_INDICATOR
  79.     put_indicator( reading_size );
  80. #endif
  81.     while (n-- > 0) UPDATE_CRC(*p++);
  82.     return mcrc;
  83. }
  84.  
  85. void fillbuf(n)  /* Shift bitbuf n bits left, read n bits */
  86. unsigned char n;
  87. {
  88.     while (n > bitcount) {
  89.         n -= bitcount;
  90.         bitbuf = (bitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
  91.         if (compsize != 0) {
  92.             compsize--;  
  93.             subbitbuf = (unsigned char) getc(infile);
  94.         } 
  95.         else subbitbuf = 0;
  96.         bitcount = CHAR_BIT;
  97.     }
  98.     bitcount -= n;
  99.     bitbuf = (bitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
  100.     subbitbuf <<= n;
  101. }
  102.  
  103. unsigned short getbits(n)
  104. unsigned char n;
  105. {
  106.     unsigned short x;
  107.  
  108.     x = bitbuf >> (2 * CHAR_BIT - n);  
  109.     fillbuf(n);
  110.     return x;
  111. }
  112.  
  113. void putcode( n , x )  /* Write rightmost n bits of x */
  114. unsigned char n;
  115. unsigned short x;
  116. {
  117.     while (n >= bitcount) {
  118.         n -= bitcount;
  119.         subbitbuf += x >> (USHRT_BIT - bitcount);
  120.         x <<= bitcount;
  121.         if (compsize < origsize) {
  122.             if (fwrite(&subbitbuf, 1, 1, outfile) == 0)
  123.                 /*    fileerror(WTERR, outfile); */
  124.                 exit( errno );
  125.             compsize++;
  126.         } 
  127.         else unpackable = 1;
  128.         subbitbuf = 0;  
  129.         bitcount = CHAR_BIT;
  130.     }
  131.     subbitbuf += x >> (USHRT_BIT - bitcount);
  132.     bitcount -= n;
  133. }
  134.  
  135. void putbits( n , x )  /* Write rightmost n bits of x */
  136. unsigned char n;
  137. unsigned short x;
  138. {
  139.     x <<= USHRT_BIT - n;
  140.     while (n >= bitcount) {
  141.         n -= bitcount;
  142.         subbitbuf += x >> (USHRT_BIT - bitcount);
  143.         x <<= bitcount;
  144.         if (compsize < origsize) {
  145.             if (fwrite(&subbitbuf, 1, 1, outfile) == 0)
  146.                 /* fileerror(WTERR, outfile); */
  147.                 exit( errno );
  148.             compsize++;
  149.         } 
  150.         else unpackable = 1;
  151.         subbitbuf = 0;  
  152.         bitcount = CHAR_BIT;
  153.     }
  154.     subbitbuf += x >> (USHRT_BIT - bitcount);
  155.     bitcount -= n;
  156. }
  157.  
  158. int fread_crc( p, n, fp )
  159. unsigned char *p;
  160. int n;
  161. FILE *fp;
  162. {
  163.     if ( text_mode )
  164.         n = fread_txt(p, n, fp);
  165.     else
  166.         n = fread(p, 1, n, fp);
  167.     calccrc(p, n);
  168.     return n;
  169. }
  170.  
  171. void fwrite_crc( p, n, fp )
  172. unsigned char *p;
  173. int n;
  174. FILE *fp;
  175. {
  176.     calccrc(p,n);
  177.     if ( verify_mode ) return;
  178.  
  179.     if ( fp )
  180.     {
  181.         if ( text_mode )
  182.         {
  183.             if ( fwrite_txt(p , n , fp) )
  184.                 fatal_error("File write error\n");
  185.         }
  186.         else
  187.         {
  188.             if (fwrite(p, 1, n, fp) < n)
  189.                 fatal_error("File write error\n");
  190.         }
  191.     }
  192. }
  193.  
  194. void init_code_cache()    /* called from copyfile() in util.c */
  195. {
  196. #ifdef EUC
  197.     putc_euc_cache = EOF;
  198. #endif
  199.     getc_euc_cache = EOF;
  200. }
  201.  
  202. void init_getbits()
  203. {
  204.     bitbuf = 0;  
  205.     subbitbuf = 0;  
  206.     bitcount = 0;
  207.     fillbuf(2 * CHAR_BIT);
  208. #ifdef EUC
  209.     putc_euc_cache = EOF;
  210. #endif
  211. }
  212.  
  213. void init_putbits()
  214. {
  215.     bitcount = CHAR_BIT;  
  216.     subbitbuf = 0;
  217.     getc_euc_cache = EOF;
  218. }
  219.  
  220. #ifdef EUC
  221. void
  222. putc_euc(c, fd)
  223. int c;
  224. FILE *fd;
  225. {
  226.     int d;
  227.  
  228.     if (putc_euc_cache == EOF)
  229.     {
  230.         if (!euc_mode || c < 0x81 || c > 0xFC)
  231.         {
  232.             putc(c, fd);
  233.             return;
  234.         }
  235.         if (c >= 0xA0 && c < 0xE0)
  236.         {
  237.             putc(0x8E, fd);      /* single shift */
  238.             putc(c, fd);
  239.             return;
  240.         }
  241.         putc_euc_cache = c;      /* save first byte */
  242.         return;
  243.     }
  244.     d = putc_euc_cache;
  245.     putc_euc_cache = EOF;
  246.     if (d >= 0xA0)
  247.         d -= 0xE0 - 0xA0;
  248.     if (c > 0x9E)
  249.     {
  250.         c = c - 0x9F + 0x21;
  251.         d = (d - 0x81) * 2 + 0x22;
  252.     }
  253.     else
  254.     {
  255.         if (c > 0x7E)
  256.             c --;
  257.         c -= 0x1F;
  258.         d = (d - 0x81) * 2 + 0x21;
  259.     }
  260.     putc(0x80 | d, fd);
  261.     putc(0x80 | c, fd);
  262. }
  263. #endif
  264.  
  265. int
  266. fwrite_txt( p , n , fp )
  267. unsigned char *p;
  268. int n;
  269. FILE *fp;
  270. {
  271.     while ( --n >= 0 )
  272.     {
  273. #ifdef OSK
  274.         if (prev_char != '\n' && *p == '\l')
  275.             putc( '\n' , fp);
  276.         
  277.         if ( *p != '\l' && *p != '\032' )
  278. #else
  279.         if ( *p != '\015' && *p != '\032' )
  280. #endif
  281.         {
  282. #ifdef EUC
  283.             putc_euc( *p , fp );
  284. #else
  285.             putc( *p , fp );
  286. #endif
  287.         }
  288.  
  289.         prev_char = *p++;
  290.     }
  291.     return ( ferror( fp ) );
  292. }
  293.  
  294. int
  295. fread_txt( p , n , fp )
  296. unsigned char *p;
  297. int n;
  298. FILE *fp;
  299. {
  300.     int c;
  301.     int cnt = 0;
  302.  
  303.     while (cnt < n)
  304.     {
  305.         if (getc_euc_cache != EOF)
  306.         {
  307.             c = getc_euc_cache;
  308.             getc_euc_cache = EOF;
  309.         }
  310.         else
  311.         {
  312.             if ((c = fgetc(fp)) == EOF)
  313.                 break;
  314.  
  315.             if (c == '\n') {
  316. #ifdef OSK
  317.                 getc_euc_cache = '\l';
  318. #else
  319.                 getc_euc_cache = c;
  320.                 c = '\r';
  321. #endif /* OSK */
  322.             }
  323.  
  324. #ifdef EUC
  325.             else if (euc_mode && (c == 0x8E || 0xA0 < c && c < 0xFF))
  326.             {
  327.                 int d = fgetc(fp);
  328.                 if (d == EOF)
  329.                 {
  330.                     *p++ = c;
  331.                     cnt ++;
  332.                     break;
  333.                 }
  334.                 if (c == 0x8E)    /* single shift (KANA) */
  335.                 {
  336.                     if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
  337.                         c = d | 0x80;
  338.                     else
  339.                         getc_euc_cache = d;
  340.                 }
  341.                 else
  342.                 {
  343.                     if (0xA0 < d && d < 0xFF)    /* if GR */
  344.                     {
  345.                         c &= 0x7F;    /* convert to MS-kanji */
  346.                         d &= 0x7F;
  347.                         if (!(c & 1))
  348.                         {
  349.                             c --;
  350.                             d += 0x7F - 0x21;
  351.                         }
  352.                         if ((d += 0x40 - 0x21) > 0x7E)
  353.                             d ++;
  354.                         if ((c = (c >> 1) + 0x71) >= 0xA0)
  355.                             c += 0xE0 - 0xA0;
  356.                     }
  357.                     getc_euc_cache = d;
  358.                 }
  359.             }
  360. #endif
  361.         }
  362.         *p++ = c;
  363.         cnt ++;
  364.     }
  365.     return cnt;
  366. }
  367.