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