home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / misc / gstream / a301doc < prev    next >
Internet Message Format  |  1999-04-27  |  8KB

  1. From: sproven@uk.ac.strath.cs
  2. Subject: docs for gstream
  3. Date: Tue, 06 Jul 93 13:13:54 +0100
  4.  
  5.  
  6. Here is some documentation for gstream, which was missing from the
  7. gstream code on newcastle.  Hopefuly this will enable people to make
  8. use of it.
  9.  
  10. I've fixed some bugs in savebox, but the code is in Manchester and
  11. I'm in Scotland, so it looks as though you'll need to wait 'till
  12. october when Uni starts again before I can send a new version.
  13.  
  14. gstream provides a uniform means of communicating with various devices
  15. or applications in RISC OS.  It provides a range of functions similar
  16. to the stdio functions (eg fprintf == gsprintf ).  However, streams are
  17. opened differently - via a number of bolt on extensions which implement
  18. the low level access to a given type of stream.  This makes it possible
  19. for users of gstream to add their own types of stream without needing
  20. to make any changes to gstream itself.  This is advantageous in that
  21. the gstream code will not get hacked up by a million different people,
  22. which would make updates to newer versions very difficult.
  23.  
  24. Most of the functions exported by gstream can be understood by looking
  25. at their stdio equivalents - where differences occur these are
  26. documented in the sources.  It is hoped that these differences will be
  27. removed when I can be bothered.
  28.  
  29. The only other functions which need explaining to the user of gstream
  30. are:
  31.  
  32. gsopeninternalw
  33. gsopeninternalr
  34. gsdiscardinternal
  35. gsgetbuf
  36.  
  37. The first three of these provide a means to hold data in flex blocks. 
  38. The system is write once, read many - ie you first of all open a flex
  39. block to write to with gsopeninternalw, write your data to it, then
  40. gsclose it.  Then, you can open the same stream with gsopeninternalr
  41. and read the data back, then gsclose it.  If you then use
  42. gsopeninternalr again will be able to read the data back again.
  43.  
  44. gsdiscardinternal frees the memory used by the internal stream, really
  45. losing the data.  After it has been called you can then call
  46. gsopeninternalw again.
  47.  
  48. gsgetbuf is a function which tries to claim a flex block between
  49. minsize and maxsize bytes in size, returing the size of block claimed
  50. (0 if no block was claimed).  See examples of its use in gstream,
  51. osstream and ramstream.
  52.  
  53. The gstream module provides the following stdio-like functions:
  54.  
  55. int gsflush(gstream *to)
  56. int gsclose(gstream *stream)
  57. int gsgetc(gstream *stream)
  58. int gsputc(int c, gstream *stream)
  59. size_t gsread(void *ptr, size_t size, size_t nmemb, gstream *stream)
  60. size_t gswrite(void *ptr, size_t size, size_t nmemb, gstream *stream)
  61. int gsputs(const char *s, gstream *stream)
  62. char *gsgets(char *s, int n, gstream *stream)
  63. int gsprintf(gstream *stream, const char *format, ...)
  64. int gsungetc(int c, gstream *stream)
  65. int gseof(gstream *stream)
  66. int gserror(gstream *stream)
  67.  
  68. Then, the other modules provide:
  69.  
  70. osstream.c:
  71.  
  72. int gsopenosr(char *fname, gstream *stream)
  73.  
  74.   - opens a file for read
  75.  
  76. int gsopenosw(char *fname, gstream *stream)
  77.  
  78.   - opens a file for write
  79.  
  80. ramstream.c
  81.  
  82. int gsopenramsend(wimp_msgstr *msg, gstream *stream)
  83. int gsopenramfetch(wimp_msgstr *msg, gstream *stream)
  84.  
  85.   - for the ram data transfer protocol
  86.  
  87. xferstream.c
  88.  
  89. int gsopenxferrecv(wimp_eventstr *e, gstream *stream)
  90. int gsopenxfersend(      char                    *leafname,
  91.                          int                     filetype,
  92.                          int                     estsize,
  93.                          int                     *safeptr,
  94.                          gstream                 *stream)
  95.  
  96. The module savebox.c has one or two bugs (template handling),
  97. but it does show how to implement save boxes using gstream.
  98.  
  99. Things to do
  100. ------------
  101.  
  102. * Add stream types for Acorn's Cut/Copy/Paste protocol
  103.  
  104. * Add stream types to handle RISC OS 3 pipes - so that a m/tasking app
  105.   can not only write to a pipe but also read from one without hanging.
  106.  
  107. * Add stream types to write to screen and read from keyboard.  If in
  108.   m/tasking app, these stream types will open a window on the screen for
  109.   I/O.  Suggestions wanted.
  110.  
  111. * Try to allow saving back to sending task (currently won't work - has
  112.   to be trapped by xferrecv to avoid crash)
  113.  
  114. * Improve the comments
  115.  
  116. Example code
  117. ------------
  118.  
  119. Here is a little bit of code to show how gstream can be used.  It should
  120. be regsistered with as a handler for win_ICONBARLOAD
  121.  
  122. What it does is when a file is dragged to the app, the function will
  123. use gsopenxferrecv to open a read stream (thus responding to the
  124. dataload or datasave message), then open an internal write stream, and
  125. copy the incoming data into the internal stream.
  126.  
  127. After closing the internal write stream and the xferrecv stream, it
  128. opens a xfersend stream (using savebox()) and opens the internal buffer,
  129. copying the data from the internal buffer to the write stream.  I bet
  130. that's a *lot* simpler than it is using RISC_OSLib's xfersend, xferrecv
  131. and saveas modules. :-)
  132.  
  133. static void icon_load_handler(wimp_eventstr *e, void *handle)
  134. {
  135.         gstream stream,
  136.                 internal_buffer;
  137.         int     safe,
  138.                 type,
  139.                 load_succeded=TRUE;
  140.         char    name[256]="File";
  141.  
  142.         switch(e->data.msg.hdr.action)
  143.         {
  144.                 case wimp_MDATALOAD:
  145.                         strcpy(name,e->data.msg.data.dataload.name);
  146.                         type=e->data.msg.data.dataload.type;
  147.                         break;
  148.                 case wimp_MDATASAVE:
  149.                         strcpy(name,e->data.msg.data.datasave.leaf);
  150.                         type=e->data.msg.data.datasave.type;
  151.                         break;
  152.         }
  153.  
  154.         visdelay_begin();
  155.         if (gsopenxferrecv(e,&stream))
  156.         {
  157.                 if (gsopeninternalw(&internal_buffer))
  158.                 {
  159.                         char dummy[256];
  160.                         int c;
  161.                         while((c=gsread((void *) dummy, 1, 256, &stream))!=0)
  162.                         {
  163.                                 gswrite(dummy,1,c,&internal_buffer);
  164.                                 if (gserror(&stream) || gserror(&internal_buffer))
  165.                                 {
  166.                                         werr(FALSE,"Error in load");
  167.                                         break;
  168.                                 }
  169.                         }
  170.                         gsclose(&internal_buffer);
  171.                         if (gserror(&stream) || gserror(&internal_buffer))
  172.                         {
  173.                                 load_succeded=FALSE;
  174.                                 gsdiscardinternal(&internal_buffer);
  175.                         }
  176.                 }
  177.                 else
  178.                         load_succeded=FALSE;
  179.                 gsclose(&stream);
  180.         }
  181.         else
  182.                 load_succeded=FALSE;
  183.         visdelay_end();
  184.  
  185.         if (load_succeded)
  186.         {
  187.                 if (gsopeninternalr(&internal_buffer))
  188.                 {
  189.                         if (savebox(name,1024,type,&safe,&stream))
  190.                         {
  191.                                 char dummy[256];
  192.                                 int c;
  193.                                 visdelay_begin();
  194.                                 while((c=gsread((void *) dummy, 1, 256, &internal_buffer))!=0)
  195.                                 {
  196.                                         gswrite(dummy,1,c,&stream);
  197.                                         if (gserror(&stream))
  198.                                                 break;
  199.                                 }
  200.                                 visdelay_end();
  201.                                 gsclose(&stream);
  202.                         }
  203.                         gsclose(&internal_buffer);
  204.                 }
  205.                 gsdiscardinternal(&internal_buffer);
  206.         }
  207. }
  208.  
  209. Simon Proven - sproven@cs.strath.ac.uk
  210.  
  211.