home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK5 / DOS_14 / GS252DVX.ZIP / SFILTER.C < prev    next >
C/C++ Source or Header  |  1992-09-16  |  10KB  |  390 lines

  1. /* Copyright (C) 1991, 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* sfilter.c */
  21. /* Stream functions for filters */
  22. #include "stdio_.h"    /* includes std.h */
  23. #include "memory_.h"
  24. #include "scanchar.h"
  25. #include "stream.h"
  26. #include "gscrypt1.h"
  27.  
  28. /* ------ Generic data ------ */
  29.  
  30. static const char *hex_digits = "0123456789abcdef";
  31.  
  32. /* ------ Generic functions ------ */
  33.  
  34. /* Implement flushing for all encoding filters. */
  35. int
  36. s_filter_write_flush(register stream *s)
  37. {    (*s->procs.write_buf)(s);
  38.     return sflush(s->strm);
  39. }
  40.  
  41. /* Close a filter.  If this is an encoding filter, flush it first. */
  42. int
  43. s_filter_close(register stream *s)
  44. {    if ( s_is_writing(s) )
  45.        {    int code = sflush(s);
  46.         if ( code == ERRC ) return code;
  47.        }
  48.     return s_std_close(s);
  49. }    
  50.  
  51. /* ------ ASCIIHexEncode ------ */
  52.  
  53. /* Flush the buffer */
  54. private int
  55. s_AXE_write_buf(register stream *s)
  56. {    register stream *strm = s->strm;
  57.     register byte *p = s->cbuf;
  58.     register int count = s->cptr + 1 - p;
  59.     while ( --count >= 0 )
  60.       { char c1 = hex_digits[*p >> 4];
  61.         char c2 = hex_digits[*p & 0xf];
  62.         sputc(strm, c1);
  63.         sputc(strm, c2);
  64.         if ( !(count & 15) )
  65.           sputc(strm, '\n');
  66.         p++;
  67.       }
  68.     s->cptr = s->cbuf - 1;
  69.     return 0;
  70. }
  71.  
  72. /* Close the stream */
  73. private int
  74. s_AXE_close(register stream *s)
  75. {    (*s->procs.write_buf)(s);
  76.     sputc(s->strm, '>');
  77.     return s_std_close(s);
  78. }
  79.  
  80. /* Stream procedures */
  81. const stream_procs s_AXE_procs =
  82.    {    s_std_noavailable, NULL, s_filter_write_flush, s_AXE_close,
  83.     NULL, s_AXE_write_buf
  84.    };
  85.  
  86. /* ------ ASCIIHexDecode ------ */
  87.  
  88. /* Initialize the stream */
  89. void
  90. s_AXD_init(register stream *s)
  91. {    s->odd = -1;
  92. }
  93.  
  94. /* Refill the buffer */
  95. private int
  96. s_AXD_read_buf(register stream *s)
  97. {    stream *strm = s->strm;
  98.     uint count;
  99.     int code = sreadhex(strm, s->cbuf, s->bsize, &count, &s->odd, 0);
  100.     s->cptr = s->cbuf - 1;
  101.     s->endptr = s->cptr + count;
  102.     if ( code != ERRC )
  103.        {    s->end_status = strm->end_status;
  104.         return 0;
  105.        }
  106.     /* Check for EOD */
  107.     if ( sgetc(strm) == '>' )    /* EOD */
  108.         s->end_status = EOFC;
  109.     else            /* syntax error */
  110.        {    s->end_status = ERRC;
  111.         sputback(strm);
  112.        }
  113.     return 0;
  114. }
  115.  
  116. /* Stream procedures */
  117. const stream_procs s_AXD_procs =
  118.    {    s_std_noavailable, s_std_noseek, s_std_read_flush, s_filter_close,
  119.     s_AXD_read_buf, NULL
  120.    };
  121.  
  122. /* ------ eexecDecode ------ */
  123.  
  124. /* Initialize a stream for reading and decrypting another stream. */
  125. /* Decrypting streams are not positionable. */
  126. void
  127. s_exD_init(register stream *s, ushort /*crypt_state*/ state)
  128. {    s->cstate = state;
  129.     s->odd = -1;
  130.     s->binary = -1;            /* unknown */
  131. }
  132.  
  133. /* Refill the buffer of a decrypting stream. */
  134. private int
  135. s_exD_read_buf(register stream *s)
  136. {    byte *buf = s->cbuf;
  137.     uint nread;
  138.     int skip = (s->binary < 0 ? 4 : 0);
  139.     s->cptr = s->endptr = buf - 1;
  140. top:    nread = sgets(s->strm, buf, s->bsize);
  141.     if ( nread == 0 )        /* end of stream */
  142.        {    s->end_status = EOFC;
  143.         return 0;
  144.        }
  145.     if ( s->binary < 0 )
  146.        {    /* This is the very first time we're filling the buffer. */
  147.         /* Determine whether this is ASCII or hex encoding. */
  148.         register byte _ds *decoder = scan_char_decoder;
  149.         if ( nread < 4 ) return EOFC;
  150.         if ( decoder[buf[0]] == ctype_space ||
  151.              (decoder[buf[0]] | decoder[buf[1]] | decoder[buf[2]] |
  152.               decoder[buf[3]]) <= 0xf )
  153.            {    /* Would be invalid if binary, hence must be hex. */
  154.             s->binary = 0;
  155.            }
  156.         else    s->binary = 1;
  157.             
  158.        }
  159.     if ( !s->binary )
  160.        {    /* Convert the buffer from binary to hex in place. */
  161.         stream sst;
  162.         sread_string(&sst, buf, nread);
  163.         sreadhex(&sst, buf, nread, &nread, &s->odd, 0);
  164.         if ( nread == 0 ) goto top;    /* try again */
  165.        }
  166.     /* Now decrypt the buffer. */
  167.     gs_type1_decrypt(buf, buf, nread, (crypt_state *)&s->cstate);
  168.     if ( skip )
  169.        {    /* Very first buffer-load, strip off leading bytes. */
  170.         if ( nread < skip ) return EOFC;
  171.         s->cptr += skip;
  172.         nread -= skip;
  173.        }
  174.     s->endptr = s->cptr + nread;
  175.     return 0;
  176. }
  177.  
  178. /* Estimate the number of remaining bytes in a decrypting stream. */
  179. private int
  180. s_exD_available(stream *s, long *pl)
  181. {    if ( savailable(s->strm, pl) < 0 ) return ERRC;
  182.     if ( *pl >= 0 ) *pl /= 2;
  183.     return 0;
  184. }
  185.  
  186. /* Stream procedures */
  187. const stream_procs s_exD_procs =
  188.    {    s_exD_available, s_std_noseek, s_std_read_flush, s_filter_close,
  189.     s_exD_read_buf, NULL
  190.    };
  191.  
  192. /* ------ NullEncode ------ */
  193.  
  194. /* Flush the buffer */
  195. private int
  196. s_NullE_write_buf(register stream *s)
  197. {    uint count = s->cptr - s->cbuf + 1;
  198.     sputs(s->strm, s->cbuf, count);
  199.     s->cptr = s->cbuf - 1;
  200.     s->position += count;
  201.     return 0;
  202. }
  203.  
  204. /* Close the stream */
  205. private int
  206. s_NullE_close(register stream *s)
  207. {    sflush(s);
  208.     return s_filter_close(s);
  209. }
  210.  
  211. /* Stream procedures */
  212. const stream_procs s_NullE_procs =
  213.    {    s_std_noavailable, s_std_noseek, s_filter_write_flush, s_NullE_close,
  214.     NULL, s_NullE_write_buf
  215.    };
  216.  
  217. /* ------ PFBDecode ------ */
  218.  
  219. /* Initialize the stream */
  220. void
  221. s_PFBD_init(register stream *s, int binary_to_hex)
  222. {    s->record_type = -1;
  223.     s->binary_to_hex = binary_to_hex;
  224. }
  225.  
  226. /* Refill the buffer */
  227. private int
  228. s_PFBD_read_buf(register stream *s)
  229. {    stream *strm = s->strm;
  230.     register byte *ptr = s->cbuf;
  231.     uint count;
  232.     int c;
  233.     s->cptr = s->endptr = s->cbuf - 1;
  234. top:    count = s->bsize;
  235.     switch ( s->record_type )
  236.        {
  237.     case -1:            /* new record */
  238.         c = sgetc(strm);
  239.         if ( c != 0x80 ) goto err;
  240.         c = sgetc(strm);
  241.         switch ( c )
  242.            {
  243.         case 1: case 2:
  244.             s->record_type = c;
  245.             break;
  246.         case 3:
  247.         case EOFC:
  248.             s->end_status = EOFC;
  249.             return 0;
  250.         default:
  251.             goto err;
  252.            }
  253.         s->record_left = sgetc(strm);
  254.         s->record_left += (ulong)sgetc(strm) << 8;
  255.         s->record_left += (ulong)sgetc(strm) << 16;
  256.         s->record_left += (ulong)sgetc(strm) << 24;
  257.         goto top;
  258.     case 1:                /* text data */
  259.         /* Translate \r to \n. */
  260.         if ( count > s->record_left ) count = s->record_left;
  261.        {    uint n;
  262.         for ( n = count; n != 0 && (c = sgetc(strm)) != EOFC; n-- )
  263.            {    *ptr++ = (c == '\r' ? '\n' : c);
  264.            }
  265.        }    break;
  266.     case 2:                /* binary data */
  267.         if ( s->binary_to_hex )
  268.         {    /* Translate binary to hex. */
  269.             uint n;
  270.             count >>= 1;        /* 2 chars per input byte */
  271.             if ( count > s->record_left ) count = s->record_left;
  272.             for ( n = count; n != 0 && (c = sgetc(strm)) >= 0;
  273.                   n--
  274.                 )
  275.             {    ptr[0] = hex_digits[c >> 4];
  276.                 ptr[1] = hex_digits[c & 0xf];
  277.                 ptr += 2;
  278.             }
  279.         }
  280.         else
  281.         {    /* Just read binary data. */
  282.             if ( count > s->record_left ) count = s->record_left;
  283.             count = sgets(strm, ptr, count);
  284.             ptr += count;
  285.         }
  286.         break;
  287.        }
  288.     if ( count == 0 )
  289.        {    s->record_type = -1;
  290.         goto top;
  291.        }
  292.     s->record_left -= count;
  293.     s->endptr = ptr - 1;
  294.     return 0;
  295. err:    s->end_status = ERRC;
  296.     s->endptr = ptr - 1;
  297.     return 0;
  298. }
  299.  
  300. /* Stream procedures */
  301. const stream_procs s_PFBD_procs =
  302.    {    s_std_noavailable, s_std_noseek, s_std_read_flush, s_filter_close,
  303.     s_PFBD_read_buf, NULL
  304.    };
  305.  
  306. /* ------ SubFileDecode ------ */
  307.  
  308. /* Initialize the stream */
  309. void
  310. s_SFD_init(stream *s, long count, const byte *str, uint strlen)
  311. {    s->sfs.count = count;
  312.     s->sfs.eod_string = str;
  313.     s->sfs.string_size = strlen;
  314.     s->sfs.match = 0;
  315. }
  316.  
  317. /* Refill the buffer */
  318. private int
  319. s_SFD_read_buf(register stream *s)
  320. {    stream *strm = s->strm;
  321.     if ( s->sfs.string_size == 0 )
  322.        {    /* Just read, with no EOD pattern. */
  323.         uint count;
  324.         if ( s->sfs.count == 0 )
  325.            {    /* Read with no EOD limit. */
  326.             count = sgets(strm, s->cbuf, s->bsize);
  327.             s->end_status = strm->end_status;
  328.            }
  329.         else
  330.            {    /* Count bytes till EOD. */
  331.             uint len = min(s->bsize, s->sfs.count);
  332.             count = sgets(strm, s->cbuf, len);
  333.             s->end_status = ((s->sfs.count -= count) == 0 ?
  334.                      EOFC : strm->end_status);
  335.            }
  336.         s->cptr = s->cbuf - 1;
  337.         s->endptr = s->cptr + count;
  338.        }
  339.     else
  340.        {    /* Read looking for an EOD pattern. */
  341.         uint keep = s->endptr + 1 - s->cbuf;
  342.         byte *p = s->cbuf - 1;
  343.         byte *limit = p + s->bsize;
  344.         uint match = s->sfs.match;
  345.         if ( keep > match ) keep = match;
  346.         memcpy(s->cbuf, s->endptr + 1 - keep, keep);
  347.         s->cptr = p + keep;
  348.         while ( p < limit )
  349.            {    int c = sgetc(strm);
  350.             if ( c < 0 )        /* premature EOF */
  351.                {    s->end_status = c;
  352.                 s->endptr = p;
  353.                 return 0;
  354.                }
  355.             *++p = c;
  356.             if ( c == s->sfs.eod_string[match] )
  357.                {    if ( ++match == s->sfs.string_size )
  358.                    {    if ( s->sfs.count <= 1 )
  359.                        {    s->endptr =
  360.                           (s->sfs.count == 0 ?
  361.                            p - s->sfs.string_size :
  362.                            p);
  363.                         s->end_status = EOFC;
  364.                         return 0;
  365.                        }
  366.                     s->sfs.count--;
  367.                     match = 0;
  368.                    }
  369.                }
  370.             /* No match here, back up to find the longest one. */
  371.             /* This may be quadratic in string_size, but */
  372.             /* we don't expect this to be a real problem. */
  373.             for ( ; match != 0; match-- )
  374.               if ( !memcmp(s->sfs.eod_string, p - match + 1,
  375.                        match)
  376.                  )
  377.                 break;
  378.            }
  379.         s->endptr = p;
  380.         s->sfs.match = match;
  381.        }
  382.     return 0;
  383. }
  384.  
  385. /* Stream procedures */
  386. const stream_procs s_SFD_procs =
  387.    {    s_std_noavailable, s_std_noseek, s_std_read_flush, s_filter_close,
  388.     s_SFD_read_buf, NULL
  389.    };
  390.