home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / printing / ghostscrip / source / _gs / c / zfileio < prev    next >
Encoding:
Text File  |  1991-10-25  |  9.1 KB  |  443 lines

  1. /* Copyright (C) 1989, 1990, 1991 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. /* zfileio.c */
  21. /* File I/O operators for Ghostscript */
  22. #include "ghost.h"
  23. #include "errors.h"
  24. #include "oper.h"
  25. #include "stream.h"
  26. #include "estack.h"
  27. #include "file.h"
  28. #include "store.h"
  29. #include "gsmatrix.h"            /* for gxdevice.h */
  30. #include "gxdevice.h"
  31. #include "gxdevmem.h"
  32.  
  33. /* Forward references */
  34. int zreadline_from(P4(byte *, uint, uint *, stream *));
  35. ref *zget_current_file(P0());
  36. private int write_string(P2(os_ptr, stream *));
  37.  
  38. /* ------ Operators ------ */
  39.  
  40. /* read */
  41. int
  42. zread(register os_ptr op)
  43. {    stream *s;
  44.     int ch;
  45.     check_read_file(s, op);
  46.     check_read(*op);
  47.     ch = sgetc(s);
  48.     if ( ch == EOFC )
  49.         make_bool(op, 0);
  50.     else
  51.        {    make_int(op, ch);
  52.         push(1);
  53.         make_bool(op, 1);
  54.        }
  55.     return 0;
  56. }
  57.  
  58. /* write */
  59. int
  60. zwrite(register os_ptr op)
  61. {    stream *s;
  62.     ulong ch;
  63.     check_write_file(s, op - 1);
  64.     check_write(op[-1]);
  65.     check_type(*op, t_integer);
  66.     ch = op->value.intval;
  67.     if ( ch > 0xff ) return e_rangecheck;
  68.     sputc(s, (byte)ch);
  69.     pop(2);
  70.     return 0;
  71. }
  72.  
  73. /* readhexstring */
  74. int
  75. zreadhexstring(register os_ptr op)
  76. {    stream st;
  77.     stream *s;
  78.     os_ptr op1 = op - 1;
  79.     int odd = -1;
  80.     int code;
  81.     uint nread;
  82.     switch ( r_type(op1) )
  83.        {
  84.     default: return e_typecheck;
  85.     case t_file:
  86.         check_read_file(s, op1);
  87.         check_read(*op1);
  88.         break;
  89.     case t_string:
  90.         s = &st;
  91.         sread_string(s, op1->value.bytes, r_size(op1));
  92.        }
  93.     check_type(*op, t_string);
  94.     check_write(*op);
  95.     code = sreadhex(s, op->value.bytes, r_size(op), &nread, &odd);
  96.     switch ( code )
  97.        {
  98.     case 1:
  99.         /* Reached end-of-file before filling the string. */
  100.         /* Return an appropriate substring. */
  101.         r_set_subrange_size(op, nread);
  102.         break;
  103.     case 0:
  104.         /* Filled the string. */
  105.         break;
  106.     default:            /* Error */
  107.         return e_ioerror;
  108.        }
  109.     if ( s == &st )
  110.        {    /* Reading from a string, return remainder */
  111.         uint pos = stell(&st);
  112.         r_inc_size(op1, -pos);
  113.         op1->value.bytes += pos;
  114.         r_set_attrs(op1, a_subrange);
  115.         push(1);
  116.        }
  117.     else
  118.        {    /* Reading from a file */
  119.         *op1 = *op;
  120.        }
  121.     make_bool(op, 1 - code);
  122.     return 0;
  123. }
  124.  
  125. /* writehexstring */
  126. int
  127. zwritehexstring(register os_ptr op)
  128. {    register stream *s;
  129.     register byte ch;
  130.     register byte *p;
  131.     register char _ds *hex_digits = "0123456789abcdef";
  132.     register uint len;
  133.     check_write_file(s, op - 1);
  134.     check_write(op[-1]);
  135.     check_read_type(*op, t_string);
  136.     p = op->value.bytes;
  137.     len = r_size(op);
  138.     while ( len-- )
  139.        {    ch = *p++;
  140.         sputc(s, hex_digits[ch >> 4]);
  141.         sputc(s, hex_digits[ch & 0xf]);
  142.        }
  143.     pop(2);
  144.     return 0;
  145. }
  146.  
  147. /* readstring */
  148. int
  149. zreadstring(register os_ptr op)
  150. {    stream *s;
  151.     uint len, rlen;
  152.     check_read_file(s, op - 1);
  153.     check_read(op[-1]);
  154.     check_write_type(*op, t_string);
  155.     len = r_size(op);
  156.     rlen = sgets(s, op->value.bytes, len);
  157.     r_set_subrange_size(op, rlen);
  158.     op[-1] = *op;
  159.     make_bool(op, (rlen == len ? 1 : 0));
  160.     return 0;
  161. }
  162.  
  163. /* writestring */
  164. int
  165. zwritestring(register os_ptr op)
  166. {    stream *s;
  167.     int code;
  168.     check_write_file(s, op - 1);
  169.     check_write(op[-1]);
  170.     code = write_string(op, s);
  171.     if ( code >= 0 ) pop(2);
  172.     return code;
  173. }
  174.  
  175. /* readline */
  176. int
  177. zreadline(register os_ptr op)
  178. {    stream *s;
  179.     uint count;
  180.     int code;
  181.     check_read_file(s, op - 1);
  182.     check_read(op[-1]);
  183.     check_write_type(*op, t_string);
  184.     code = zreadline_from(op->value.bytes, r_size(op), &count, s);
  185.     if ( code < 0 ) return code;
  186.     r_set_subrange_size(op, count);
  187.     op[-1] = *op;
  188.     make_bool(op, code);
  189.     return 0;
  190. }
  191.  
  192. /* Read a line from stdin.  This is called from gs.c. */
  193. int
  194. zreadline_stdin(byte *ptr, uint size, uint *pcount)
  195. {    return zreadline_from(ptr, size, pcount, &std_files[0]);
  196. }
  197.  
  198. /* Internal readline routine. */
  199. /* Returns 1 if OK, 0 if end of file, or an error code. */
  200. int
  201. zreadline_from(byte *ptr, uint size, uint *pcount, stream *s)
  202. {    uint count = 0;
  203.     int ch;
  204.     while ( count < size )
  205.        {    switch ( ch = sgetc(s) )
  206.            {
  207.         case '\r':
  208.             ch = sgetc(s);
  209.             if ( ch != '\n' && ch != EOFC ) sputback(s);
  210.             /* falls through */
  211.         case '\n':
  212.             *pcount = count;
  213.             return 1;
  214.         case EOFC:
  215.             *pcount = count;
  216.             return 0;
  217.            }
  218.         *ptr++ = ch;
  219.         count++;
  220.        }
  221.     return e_rangecheck;        /* filled the string */
  222. }
  223.  
  224. /* token - this is called from zstring.c */
  225. int
  226. ztoken_file(register os_ptr op)
  227. {    stream *s;
  228.     ref token;
  229.     int code;
  230.     check_read_file(s, op);
  231.     check_read(*op);
  232.     switch ( code = scan_token(s, 0, &token) )
  233.        {
  234.     case 0:                /* read a token */
  235.         *op = token;
  236.         push(1);
  237.         make_bool(op, 1);
  238.         return 0;
  239.     case 1:                /* no tokens */
  240.         make_bool(op, 0);
  241.         return 0;
  242.     default:            /* error */
  243.         return code;
  244.        }
  245. }
  246.  
  247. /* bytesavailable */
  248. int
  249. zbytesavailable(register os_ptr op)
  250. {    stream *s;
  251.     long avail;
  252.     check_read_file(s, op);
  253.     if ( savailable(s, &avail) < 0 ) return e_ioerror;
  254.     make_int(op, avail);
  255.     return 0;
  256. }
  257.  
  258. /* flush */
  259. int
  260. zflush(register os_ptr op)
  261. {    sflush(&std_files[1]);
  262.     return 0;
  263. }
  264.  
  265. /* flushfile */
  266. int
  267. zflushfile(register os_ptr op)
  268. {    stream *s;
  269.     check_file(s, op);
  270.     sflush(s);
  271.     if ( !s->writing )
  272.         fseek(s->file, 0L, 2);    /* set to end */
  273.     pop(1);
  274.     return 0;
  275. }
  276.  
  277. /* resetfile */
  278. int
  279. zresetfile(register os_ptr op)
  280. {    NYI("resetfile");
  281.     pop(1);
  282.     return 0;
  283. }
  284.  
  285. /* status */
  286. int
  287. zstatus(register os_ptr op)
  288. {    check_type(*op, t_file);
  289.     make_bool(op, (fptr(op)->bsize != 0 ? 1 : 0));
  290.     return 0;
  291. }
  292.  
  293. /* currentfile */
  294. int
  295. zcurrentfile(register os_ptr op)
  296. {    ref *fp;
  297.     push(1);
  298.     if ( (fp = zget_current_file()) == 0 )
  299.        {    /* Return an invalid file object. */
  300.         /* This doesn't make a lot of sense to me, */
  301.         /* but it's what the PostScript manual specifies. */
  302.         make_file(op, 0, &invalid_file_entry);
  303.        }
  304.     else
  305.         *op = *fp;
  306.     /* Make sure the returned value is literal. */
  307.     r_clear_attrs(op, a_executable);
  308.     return 0;
  309. }
  310.  
  311. /* print */
  312. int
  313. zprint(register os_ptr op)
  314. {    int code = write_string(op, &std_files[1]);
  315.     if ( code >= 0 ) pop(1);
  316.     return code;
  317. }
  318.  
  319. /* echo */
  320. int
  321. zecho(register os_ptr op)
  322. {    check_type(*op, t_boolean);
  323.     /****** NOT IMPLEMENTED YET ******/
  324.     pop(1);
  325.     return 0;
  326. }
  327.  
  328. /* ------ Level 2 extensions ------ */
  329.  
  330. /* fileposition */
  331. int
  332. zfileposition(register os_ptr op)
  333. {    stream *s;
  334.     check_file(s, op);
  335.     if ( !sseekable(s) ) return e_ioerror;
  336.     make_int(op, stell(s));
  337.     return 0;
  338. }
  339.  
  340. /* setfileposition */
  341. int
  342. zsetfileposition(register os_ptr op)
  343. {    stream *s;
  344.     check_file(s, op - 1);
  345.     check_type(*op, t_integer);
  346.     if ( sseek(s, op->value.intval) < 0 ) return e_ioerror;
  347.     pop(2);
  348.     return 0;
  349. }
  350.  
  351. /* ------ Ghostscript extensions ------ */
  352.  
  353. /* unread */
  354. int
  355. zunread(register os_ptr op)
  356. {    stream *s;
  357.     ulong ch;
  358.     check_read_file(s, op - 1);
  359.     check_type(*op, t_integer);
  360.     ch = op->value.intval;
  361.     if ( ch > 0xff ) return e_rangecheck;
  362.     if ( sungetc(s, (byte)ch) < 0 ) return e_ioerror;
  363.     pop(2);
  364.     return 0;
  365. }
  366.  
  367. /* writeppmfile */
  368. int
  369. zwriteppmfile(register os_ptr op)
  370. {    stream *s;
  371.     int code;
  372.     check_write_file(s, op - 1);
  373.     check_write(op[-1]);
  374.     check_type(*op, t_device);
  375.     if ( !gs_device_is_memory(op->value.pdevice) ) return e_typecheck;
  376.     sflush(s);
  377.     code = gs_writeppmfile((gx_device_memory *)(op->value.pdevice), s->file);
  378.     if ( code >= 0 ) pop(2);
  379.     return code;
  380. }
  381.  
  382. /* ------ Initialization procedure ------ */
  383.  
  384. op_def zfileio_op_defs[] = {
  385.     {"1bytesavailable", zbytesavailable},
  386.     {"0currentfile", zcurrentfile},
  387.     {"1echo", zecho},
  388.     {"1fileposition", zfileposition},
  389.     {"0flush", zflush},
  390.     {"1flushfile", zflushfile},
  391.     {"1print", zprint},
  392.     {"1read", zread},
  393.     {"2readhexstring", zreadhexstring},
  394.     {"2readline", zreadline},
  395.     {"2readstring", zreadstring},
  396.     {"1resetfile", zresetfile},
  397.     {"2setfileposition", zsetfileposition},
  398.     {"2unread", zunread},
  399.     {"1status", zstatus},
  400.     {"2write", zwrite},
  401.     {"2writehexstring", zwritehexstring},
  402.     {"2writeppmfile", zwriteppmfile},
  403.     {"2writestring", zwritestring},
  404.     op_def_end(0)
  405. };
  406.  
  407. /* ------ Non-operator routines ------ */
  408.  
  409. /* Check a file for reading. */
  410. /* The interpreter calls this to check an executable file. */
  411. int
  412. file_check_read(ref *op, stream **ps)
  413. {    stream *s;
  414.     check_file_access(s, op, !s->writing);
  415.     *ps = s;
  416.     return 0;
  417. }
  418.  
  419. /* Get the current file from which the interpreter is reading. */
  420. ref *
  421. zget_current_file()
  422. {    es_ptr ep = esp;
  423.     while ( ep >= esbot )
  424.     {    if ( r_has_type(ep, t_file) && r_has_attrs(ep, a_executable) )
  425.             return (ref *)ep;
  426.         ep--;
  427.     }
  428.     return (ref *)0;
  429. }
  430.  
  431. /* ------ Internal routines ------ */
  432.  
  433. /* Write a string on a file.  The file has been checked for validity, */
  434. /* but not the string. */
  435. private int
  436. write_string(os_ptr op, stream *s)
  437. {    uint len;
  438.     check_read_type(*op, t_string);
  439.     len = r_size(op);
  440.     if ( sputs(s, op->value.bytes, len) != len ) return e_ioerror;
  441.     return 0;
  442. }
  443.