home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / g / gs252src.zip / GS252 / ZFILEIO.C < prev    next >
C/C++ Source or Header  |  1992-07-20  |  9KB  |  441 lines

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