home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************
- * *
- * Module: osstream.c (part of gstream package) *
- * *
- * Version: 0.02 *
- * *
- * Author: Simon Proven *
- * *
- * Owner: Simon Proven 1993 *
- * *
- * Purpose: To allow gstream to access RISC OS filesystems. *
- * *
- * Uses: gstream, flex, werr, wimpt, os, stdlib *
- * *
- * History: *
- * 0.02: added atexit() function which closes all *
- * open osstreams *
- * *
- * Conditions: *
- * You can produce and sell executable code from *
- * this module freely. The source code may be *
- * distributed freely, but not for profit. *
- * *
- * If you like these modules alot, and use them *
- * in your own programs, feel free to thank me *
- * with cash - 10 or more will get you a disc *
- * with the latest versions and new stream types. *
- * *
- * Disclaimer: *
- * This software is supplied in good faith, but I *
- * cannot accept liability for any loss incurred *
- * through the use or inability to use any part *
- * of this software. *
- * *
- * How to contact me: *
- * *
- * email: snail mail: *
- * sproven@cs.strath.ac.uk Simon Proven, *
- * Castle Cottage, *
- * Portencross, *
- * West Kilbride, *
- * KA23 9QA *
- * SCOTLAND *
- * *
- * Tel. (+44) 294 829 721 *
- * *
- *************************************************************/
-
- #include "gstream.h"
- #include "flex.h"
- #include "wimpt.h"
- #include "os.h"
- #include "werr.h"
- #include <stdlib.h>
-
- #define FILES_OPEN_LIMIT (16)
-
- #define FALSE 0
- #define TRUE 1
-
- static int files_open[FILES_OPEN_LIMIT];
- static int registered_with_atexit=FALSE;
-
- static void atexit_func(void)
- {
- int count;
- os_regset regs;
- os_error *err;
-
- for (count=0;count<FILES_OPEN_LIMIT;count++)
- {
- if (files_open[count])
- {
- regs.r[0]=0;
- regs.r[1]=files_open[count];
- err=os_find(®s);
- files_open[count]=0;
- if (err)
- wimpt_complain(err);
- }
- }
- }
-
- static int register_atexit_func(void)
- {
- if (!registered_with_atexit)
- {
- int count;
- for (count=0;count<FILES_OPEN_LIMIT;count++)
- files_open[count]=0;
- if (atexit(atexit_func))
- return FALSE;
- registered_with_atexit=TRUE;
- return TRUE;
- }
- else
- return TRUE;
- }
-
- static void register_file_opened(int filehandle)
- {
- int count;
-
- if (register_atexit_func())
- {
- for (count=0;count<FILES_OPEN_LIMIT;count++)
- {
- if (!files_open[count])
- {
- files_open[count]=filehandle;
- return;
- }
- }
- }
- }
-
- static void register_file_closed(int filehandle)
- {
- int count=0;
-
- if (registered_with_atexit)
- {
- for (count=0;count<FILES_OPEN_LIMIT;count++)
- {
- if (files_open[count]==filehandle)
- {
- files_open[count]=0;
- return;
- }
- }
-
- }
- }
-
- /* this function closes an OS_READ stream. Internal use ONLY */
-
- static int closeosread(void *s)
- {
- gstream *stream=(gstream *) s;
- os_regset regs;
- os_error *err;
- int **data=(int **) &(stream->data),
- filehandle;
-
- regs.r[0]=0;
- regs.r[1]=**data;
- filehandle=**data;
- flex_free(&(stream->data));
- err=os_find(®s);
- if (err!=NULL)
- {
- wimpt_complain(err);
- stream->error=TRUE;
- return FALSE;
- }
- else
- {
- register_file_closed(filehandle);
- return TRUE;
- }
- }
-
- /* reads some bytes into an OS_READ stream. Internal use ONLY */
-
- static size_t reados(void *ptr, size_t nbytes, void *s)
- {
- gstream *stream=(gstream *) s;
- os_error *e;
- os_gbpbstr g;
- int **data=(int **) &(stream->data);
-
-
- g.action=4;
- g.file_handle=**data;
- g.data_addr=ptr;
- g.number=nbytes;
- e=os_gbpb(&g);
-
- if (e!=NULL)
- {
- wimpt_complain(e);
- stream->error=TRUE;
- return 0;
- }
- return(nbytes-g.number);
- }
-
- /* This function opens a file for read access. fname should be a valid
- * pathname under RISC OS and stream should point to a gstream struct
- */
-
- int gsopenosr(char *fname, gstream *stream)
- {
- os_error *err;
- os_regset regs;
- int **data;
-
- stream->bufsize=gsgetbuf(&(stream->buffer),gs_BUFSIZE,0);
- stream->pos=0;
- stream->size=0;
- stream->ungetsize=0;
- stream->ungetpos=0;
- stream->io.read=reados;
- stream->close=closeosread;
- stream->type=READ;
-
- if (!flex_alloc(&(stream->data),sizeof(int)))
- {
- if (stream->bufsize!=0)
- flex_free(&(stream->buffer));
- werr(FALSE,"Not enough space");
- return FALSE;
- }
-
- data=(int **) &(stream->data);
-
- regs.r[0]=0x4f; /* RISC OS 2.0 PRM page 881 */
- regs.r[1]=(int)fname;
- regs.r[2]=0;
- err=os_find(®s);
-
- if (err!=NULL)
- {
- wimpt_complain(err);
- flex_free(&(stream->data));
- flex_free(&(stream->buffer));
- return FALSE;
- }
- else
- {
- **data=regs.r[0];
- register_file_opened(regs.r[0]);
- stream->error=FALSE;
- return TRUE;
- }
- }
-
- /* this function closes the write stream. Internal use ONLY */
-
- static int closeoswrite(void *s)
- {
- gstream *stream=(gstream *) s;
- os_regset regs;
- os_error *err;
- int **data=(int **) &(stream->data),
- filehandle;
-
- regs.r[0]=0;
- regs.r[1]=**data;
- filehandle=**data;
- err=os_find(®s);
- flex_free(&(stream->data));
-
- if (err!=NULL)
- {
- wimpt_complain(err);
- stream->error=TRUE;
- return FALSE;
- }
- else
- {
- register_file_closed(filehandle);
- return TRUE;
- }
- }
-
- /* writes some bytes to an OS_WRITE stream. Internal use ONLY */
-
- static size_t writeos(void *ptr, size_t nbytes, void *s)
- {
- gstream *stream=(gstream *) s;
- os_error *e;
- os_gbpbstr g;
-
- int **data=(int **) &(stream->data);
-
- g.action=2;
- g.file_handle=**data;
- g.data_addr=ptr;
- g.number=nbytes;
- e=os_gbpb(&g);
- if (e!=NULL)
- {
- wimpt_complain(e);
- stream->error=TRUE;
- return 0;
- }
- return nbytes;
- }
-
- /* opens a file for write access. Filename can be any valid RISC OS filename
- * eg SCSI::Winnie.$.Apps.!MyApp.!Choices or <MyApp$Dir>.!Choices
- *
- * stream will be an unopened or opened then closed gstream
- */
-
- int gsopenosw(char *fname, gstream *stream)
- {
- os_error *err;
- os_regset regs;
-
- int **data;
-
- if (!flex_alloc(&(stream->data),sizeof(int)))
- {
- werr(FALSE,"Not enough space");
- return FALSE;
- }
-
- data=(int **) &(stream->data);
-
- stream->bufsize=gs_BUFSIZE;
- stream->size=0;
- stream->pos=0;
-
- stream->bufsize=gsgetbuf(&(stream->buffer),stream->bufsize,0);
-
- stream->type=WRITE;
- stream->io.write=writeos;
- stream->close=closeoswrite;
-
- regs.r[0]=0x8f; /* RISC OS 2.0 PRM page 881 */
- regs.r[1]=(int)fname;
- regs.r[2]=0;
- err=os_find(®s);
- if (err!=NULL)
- {
- wimpt_complain(err);
- stream->error=TRUE;
- flex_free(&(stream->data));
- if (stream->bufsize!=0)
- flex_free(&(stream->buffer));
- return FALSE;
- }
- else
- {
- **data=regs.r[0];
- register_file_opened(**data);
- stream->error=FALSE;
- return TRUE;
- }
- }
-
-