**
***************************************************************/
-#ifndef AMIGA
-#include <sys/types.h>
-#else
-typedef long off_t;
-#endif
-
#include "pf_all.h"
#if defined(WIN32) && !defined(__MINGW32__)
/* Use local copy of CODE_BASE for speed. */
#define LOCAL_CODEREL_TO_ABS( a ) ((cell_t *) (((cell_t) a) + CodeBase))
+/* Truncate the unsigned double cell integer LO/HI to an uint64_t. */
+static uint64_t UdToUint64( ucell_t Lo, ucell_t Hi )
+{
+ return (( 2 * sizeof(ucell_t) == sizeof(uint64_t) )
+ ? (((uint64_t)Lo) | (((uint64_t)Hi) >> (sizeof(ucell_t) * 8)))
+ : Lo );
+}
+
+/* Return TRUE if the unsigned double cell integer LO/HI is not greater
+ * then the greatest uint64_t.
+ */
+static int UdIsUint64( ucell_t Lo, ucell_t Hi )
+{
+ return (( 2 * sizeof(ucell_t) == sizeof(uint64_t) )
+ ? TRUE
+ : Hi == 0 );
+}
+
static const char *pfSelectFileModeCreate( int fam );
static const char *pfSelectFileModeOpen( int fam );
/* Determine file size by seeking to end and returning position. */
FileID = (FileStream *) TOS;
{
- off_t endposition, offsetHi;
- off_t original = sdTellFile( FileID );
+ file_offset_t endposition, offsetHi;
+ file_offset_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 ;
+ offsetHi = (sizeof(file_offset_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 */
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;
+ }
}
endcase;
TOS = TOS | PF_FAM_BINARY_FLAG;
endcase;
+ case ID_FILE_FLUSH: /* ( fileid -- ior ) */
+ {
+ FileStream *Stream = (FileStream *) TOS;
+ TOS = (sdFlushFile( Stream ) == 0) ? 0 : THROW_FLUSH_FILE;
+ }
+ endcase;
+
+ case ID_FILE_RENAME: /* ( oldName newName -- ior ) */
+ {
+ char *New = (char *) TOS;
+ char *Old = (char *) M_POP;
+ TOS = sdRenameFile( Old, New );
+ }
+ endcase;
+
+ case ID_FILE_RESIZE: /* ( ud fileid -- ior ) */
+ {
+ FileStream *File = (FileStream *) TOS;
+ ucell_t SizeHi = (ucell_t) M_POP;
+ ucell_t SizeLo = (ucell_t) M_POP;
+ TOS = ( UdIsUint64( SizeLo, SizeHi )
+ ? sdResizeFile( File, UdToUint64( SizeLo, SizeHi ))
+ : THROW_RESIZE_FILE );
+ }
+ endcase;
+
case ID_FILL: /* ( caddr num charval -- ) */
{
register char *DstPtr;