**
***************************************************************/
-#ifndef AMIGA
-#include <sys/types.h>
-#else
-typedef long off_t;
-#endif
-
#include "pf_all.h"
#if defined(WIN32) && !defined(__MINGW32__)
Scratch = M_POP;
CharPtr = (char *) M_POP;
Temp = sdReadFile( CharPtr, 1, Scratch, FileID );
+ /* TODO check feof() or ferror() */
M_PUSH(Temp);
TOS = 0;
endcase;
+ /* TODO Why does this crash when passed an illegal FID? */
case ID_FILE_SIZE: /* ( fid -- ud ior ) */
/* Determine file size by seeking to end and returning position. */
FileID = (FileStream *) TOS;
{
- off_t endposition, offsetHi;
- off_t original = sdTellFile( FileID );
- sdSeekFile( FileID, 0, PF_SEEK_END );
- endposition = sdTellFile( FileID );
- M_PUSH(endposition);
- /* Just use a 0 if they are the same size. */
- offsetHi = (sizeof(off_t) > sizeof(cell_t)) ? (endposition >> (8*sizeof(cell_t))) : 0 ;
- M_PUSH(offsetHi);
- sdSeekFile( FileID, original, PF_SEEK_SET );
- TOS = (original < 0) ? -4 : 0 ; /* !!! err num */
+ file_offset_t endposition = -1;
+ file_offset_t original = sdTellFile( FileID );
+ if (original >= 0)
+ {
+ sdSeekFile( FileID, 0, PF_SEEK_END );
+ endposition = sdTellFile( FileID );
+ /* Restore original position. */
+ sdSeekFile( FileID, original, PF_SEEK_SET );
+ }
+ if (endposition < 0)
+ {
+ M_PUSH(0); /* low */
+ M_PUSH(0); /* high */
+ TOS = -4; /* TODO proper error number */
+ }
+ else
+ {
+ M_PUSH(endposition); /* low */
+ /* We do not support double precision file offsets.*/
+ M_PUSH(0); /* high */
+ TOS = 0; /* OK */
+ }
}
endcase;
case ID_FILE_REPOSITION: /* ( ud fid -- ior ) */
{
- off_t offset;
+ file_offset_t offset;
+ cell_t offsetHigh;
+ cell_t offsetLow;
FileID = (FileStream *) TOS;
- offset = M_POP;
- /* Avoid compiler warnings on Mac. */
- offset = (sizeof(off_t) > sizeof(cell_t)) ? (offset << 8*sizeof(cell_t)) : 0 ;
- offset += M_POP;
+ offsetHigh = M_POP;
+ offsetLow = M_POP;
+ /* We do not support double precision file offsets in pForth.
+ * So check to make sure the high bits are not used.
+ */
+ if (offsetHigh != 0)
+ {
+ TOS = -3; /* TODO err num? */
+ break;
+ }
+ offset = offsetLow;
TOS = sdSeekFile( FileID, offset, PF_SEEK_SET );
}
endcase;
case ID_FILE_POSITION: /* ( fid -- ud ior ) */
{
- off_t position;
- off_t offsetHi;
+ file_offset_t position;
FileID = (FileStream *) TOS;
position = sdTellFile( FileID );
- M_PUSH(position);
- /* Just use a 0 if they are the same size. */
- offsetHi = (sizeof(off_t) > sizeof(cell_t)) ? (position >> (8*sizeof(cell_t))) : 0 ;
- M_PUSH(offsetHi);
- TOS = (position < 0) ? -4 : 0 ; /* !!! err num */
+ if (position < 0)
+ {
+ M_PUSH(0); /* low */
+ M_PUSH(0); /* high */
+ TOS = -4; /* TODO proper error number */
+ }
+ else
+ {
+ M_PUSH(position); /* low */
+ /* We do not support double precision file offsets.*/
+ M_PUSH(0); /* high */
+ TOS = 0; /* OK */
+ }
}
endcase;
TOUCH(Stream);
return 0;
}
-cell_t sdSeekFile( FileStream * Stream, cell_t Position, int32_t Mode )
+cell_t sdSeekFile( FileStream * Stream, file_offset_t Position, int32_t Mode )
{
UNIMPLEMENTED("sdSeekFile");
TOUCH(Stream);
TOUCH(Mode);
return 0;
}
-cell_t sdTellFile( FileStream * Stream )
+file_offset_t sdTellFile( FileStream * Stream )
{
UNIMPLEMENTED("sdTellFile");
TOUCH(Stream);
**
***************************************************************/
+#include "pf_types.h"
+
#define PF_CHAR_XON (0x11)
#define PF_CHAR_XOFF (0x13)
void ioInit( void );
void ioTerm( void );
-
#ifdef PF_NO_CHARIO
void sdEnableInput( void );
void sdDisableInput( void );
cell_t sdFlushFile( FileStream * Stream );
cell_t sdReadFile( void *ptr, cell_t Size, int32_t nItems, FileStream * Stream );
cell_t sdWriteFile( void *ptr, cell_t Size, int32_t nItems, FileStream * Stream );
- cell_t sdSeekFile( FileStream * Stream, off_t Position, int32_t Mode );
+ cell_t sdSeekFile( FileStream * Stream, file_offset_t Position, int32_t Mode );
cell_t sdRenameFile( const char *OldName, const char *NewName );
cell_t sdDeleteFile( const char *FileName );
ThrowCode sdResizeFile( FileStream *, uint64_t Size);
- off_t sdTellFile( FileStream * Stream );
+ file_offset_t sdTellFile( FileStream * Stream );
cell_t sdCloseFile( FileStream * Stream );
cell_t sdInputChar( FileStream *stream );
#define sdFlushFile fflush
#define sdReadFile fread
#define sdWriteFile fwrite
- #if defined(WIN32) || defined(__NT__) || defined(AMIGA)
- /* TODO To support 64-bit file offset we probably need fseeki64(). */
- #define sdSeekFile fseek
- #define sdTellFile ftell
- #else
- #define sdSeekFile fseeko
- #define sdTellFile ftello
- #endif
+
+ /*
+ * Note that fseek() and ftell() only support a long file offset.
+ * So 64-bit offsets may not be supported on some platforms.
+ * At one point we supported fseeko() and ftello() but they require
+ * the off_t data type, which is not very portable.
+ * So we decided to sacrifice vary large file support in
+ * favor of portability.
+ */
+ #define sdSeekFile fseek
+ #define sdTellFile ftell
+
#define sdCloseFile fclose
#define sdRenameFile rename
#define sdInputChar fgetc
#define PF_SEEK_CUR (SEEK_CUR)
#define PF_SEEK_END (SEEK_END)
+ /* TODO review the Size data type. */
ThrowCode sdResizeFile( FileStream *, uint64_t Size);
/*
** Type Declarations
***************************************************************/
+#ifndef AMIGA
+#include <sys/types.h>
+#endif
+
+/* file_offset_t is used in place of off_t */
+typedef long file_offset_t;
+
#ifndef Err
typedef long Err;
#endif