home *** CD-ROM | disk | FTP | other *** search
- From: sproven@uk.ac.strath.cs
- Subject: docs for gstream
- Date: Tue, 06 Jul 93 13:13:54 +0100
-
-
- Here is some documentation for gstream, which was missing from the
- gstream code on newcastle. Hopefuly this will enable people to make
- use of it.
-
- I've fixed some bugs in savebox, but the code is in Manchester and
- I'm in Scotland, so it looks as though you'll need to wait 'till
- october when Uni starts again before I can send a new version.
-
- gstream provides a uniform means of communicating with various devices
- or applications in RISC OS. It provides a range of functions similar
- to the stdio functions (eg fprintf == gsprintf ). However, streams are
- opened differently - via a number of bolt on extensions which implement
- the low level access to a given type of stream. This makes it possible
- for users of gstream to add their own types of stream without needing
- to make any changes to gstream itself. This is advantageous in that
- the gstream code will not get hacked up by a million different people,
- which would make updates to newer versions very difficult.
-
- Most of the functions exported by gstream can be understood by looking
- at their stdio equivalents - where differences occur these are
- documented in the sources. It is hoped that these differences will be
- removed when I can be bothered.
-
- The only other functions which need explaining to the user of gstream
- are:
-
- gsopeninternalw
- gsopeninternalr
- gsdiscardinternal
- gsgetbuf
-
- The first three of these provide a means to hold data in flex blocks.
- The system is write once, read many - ie you first of all open a flex
- block to write to with gsopeninternalw, write your data to it, then
- gsclose it. Then, you can open the same stream with gsopeninternalr
- and read the data back, then gsclose it. If you then use
- gsopeninternalr again will be able to read the data back again.
-
- gsdiscardinternal frees the memory used by the internal stream, really
- losing the data. After it has been called you can then call
- gsopeninternalw again.
-
- gsgetbuf is a function which tries to claim a flex block between
- minsize and maxsize bytes in size, returing the size of block claimed
- (0 if no block was claimed). See examples of its use in gstream,
- osstream and ramstream.
-
- The gstream module provides the following stdio-like functions:
-
- int gsflush(gstream *to)
- int gsclose(gstream *stream)
- int gsgetc(gstream *stream)
- int gsputc(int c, gstream *stream)
- size_t gsread(void *ptr, size_t size, size_t nmemb, gstream *stream)
- size_t gswrite(void *ptr, size_t size, size_t nmemb, gstream *stream)
- int gsputs(const char *s, gstream *stream)
- char *gsgets(char *s, int n, gstream *stream)
- int gsprintf(gstream *stream, const char *format, ...)
- int gsungetc(int c, gstream *stream)
- int gseof(gstream *stream)
- int gserror(gstream *stream)
-
- Then, the other modules provide:
-
- osstream.c:
-
- int gsopenosr(char *fname, gstream *stream)
-
- - opens a file for read
-
- int gsopenosw(char *fname, gstream *stream)
-
- - opens a file for write
-
- ramstream.c
-
- int gsopenramsend(wimp_msgstr *msg, gstream *stream)
- int gsopenramfetch(wimp_msgstr *msg, gstream *stream)
-
- - for the ram data transfer protocol
-
- xferstream.c
-
- int gsopenxferrecv(wimp_eventstr *e, gstream *stream)
- int gsopenxfersend( char *leafname,
- int filetype,
- int estsize,
- int *safeptr,
- gstream *stream)
-
- The module savebox.c has one or two bugs (template handling),
- but it does show how to implement save boxes using gstream.
-
- Things to do
- ------------
-
- * Add stream types for Acorn's Cut/Copy/Paste protocol
-
- * Add stream types to handle RISC OS 3 pipes - so that a m/tasking app
- can not only write to a pipe but also read from one without hanging.
-
- * Add stream types to write to screen and read from keyboard. If in
- m/tasking app, these stream types will open a window on the screen for
- I/O. Suggestions wanted.
-
- * Try to allow saving back to sending task (currently won't work - has
- to be trapped by xferrecv to avoid crash)
-
- * Improve the comments
-
- Example code
- ------------
-
- Here is a little bit of code to show how gstream can be used. It should
- be regsistered with as a handler for win_ICONBARLOAD
-
- What it does is when a file is dragged to the app, the function will
- use gsopenxferrecv to open a read stream (thus responding to the
- dataload or datasave message), then open an internal write stream, and
- copy the incoming data into the internal stream.
-
- After closing the internal write stream and the xferrecv stream, it
- opens a xfersend stream (using savebox()) and opens the internal buffer,
- copying the data from the internal buffer to the write stream. I bet
- that's a *lot* simpler than it is using RISC_OSLib's xfersend, xferrecv
- and saveas modules. :-)
-
- static void icon_load_handler(wimp_eventstr *e, void *handle)
- {
- gstream stream,
- internal_buffer;
- int safe,
- type,
- load_succeded=TRUE;
- char name[256]="File";
-
- switch(e->data.msg.hdr.action)
- {
- case wimp_MDATALOAD:
- strcpy(name,e->data.msg.data.dataload.name);
- type=e->data.msg.data.dataload.type;
- break;
- case wimp_MDATASAVE:
- strcpy(name,e->data.msg.data.datasave.leaf);
- type=e->data.msg.data.datasave.type;
- break;
- }
-
- visdelay_begin();
- if (gsopenxferrecv(e,&stream))
- {
- if (gsopeninternalw(&internal_buffer))
- {
- char dummy[256];
- int c;
- while((c=gsread((void *) dummy, 1, 256, &stream))!=0)
- {
- gswrite(dummy,1,c,&internal_buffer);
- if (gserror(&stream) || gserror(&internal_buffer))
- {
- werr(FALSE,"Error in load");
- break;
- }
- }
- gsclose(&internal_buffer);
- if (gserror(&stream) || gserror(&internal_buffer))
- {
- load_succeded=FALSE;
- gsdiscardinternal(&internal_buffer);
- }
- }
- else
- load_succeded=FALSE;
- gsclose(&stream);
- }
- else
- load_succeded=FALSE;
- visdelay_end();
-
- if (load_succeded)
- {
- if (gsopeninternalr(&internal_buffer))
- {
- if (savebox(name,1024,type,&safe,&stream))
- {
- char dummy[256];
- int c;
- visdelay_begin();
- while((c=gsread((void *) dummy, 1, 256, &internal_buffer))!=0)
- {
- gswrite(dummy,1,c,&stream);
- if (gserror(&stream))
- break;
- }
- visdelay_end();
- gsclose(&stream);
- }
- gsclose(&internal_buffer);
- }
- gsdiscardinternal(&internal_buffer);
- }
- }
-
- Simon Proven - sproven@cs.strath.ac.uk
-
-