ExternalStream.st
changeset 2861 c098e5766682
parent 2854 3c8bf66e4e7d
child 2874 020627074c9e
equal deleted inserted replaced
2860:760052935b5a 2861:c098e5766682
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
       
    12 
       
    13 'From Smalltalk/X, Version:3.1.9 on 19-aug-1997 at 10:14:54'                    !
    12 
    14 
    13 ReadWriteStream subclass:#ExternalStream
    15 ReadWriteStream subclass:#ExternalStream
    14 	instanceVariableNames:'filePointer mode buffered binary useCRLF hitEOF didWrite
    16 	instanceVariableNames:'filePointer mode buffered binary useCRLF hitEOF didWrite
    15 		lastErrorNumber readAhead'
    17 		lastErrorNumber readAhead'
    16 	classVariableNames:'Lobby LastErrorNumber InvalidReadSignal InvalidWriteSignal
    18 	classVariableNames:'Lobby LastErrorNumber InvalidReadSignal InvalidWriteSignal
  2054     OBJ pos, fp, oClass;
  2056     OBJ pos, fp, oClass;
  2055     int o_offs;
  2057     int o_offs;
  2056 
  2058 
  2057     __INST(lastErrorNumber) = nil;
  2059     __INST(lastErrorNumber) = nil;
  2058     if (((fp = __INST(filePointer)) != nil)
  2060     if (((fp = __INST(filePointer)) != nil)
  2059 	&& (__INST(mode) != @symbol(writeonly))
  2061         && (__INST(mode) != @symbol(writeonly))
  2060 	&& __bothSmallInteger(count, start)
  2062         && __bothSmallInteger(count, start)
  2061     ) {
  2063     ) {
  2062 	f = __FILEVal(fp);
  2064         f = __FILEVal(fp);
  2063 
  2065 
  2064 	oClass = __Class(anObject);
  2066         oClass = __Class(anObject);
  2065 	switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  2067         switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  2066 	    case BYTEARRAY:
  2068             case BYTEARRAY:
  2067 	    case WORDARRAY:
  2069             case WORDARRAY:
  2068 	    case LONGARRAY:
  2070             case LONGARRAY:
  2069 	    case SWORDARRAY:
  2071             case SWORDARRAY:
  2070 	    case SLONGARRAY:
  2072             case SLONGARRAY:
  2071 	    case FLOATARRAY:
  2073             case FLOATARRAY:
  2072 	    case DOUBLEARRAY:
  2074             case DOUBLEARRAY:
  2073 		break;
  2075                 break;
  2074 	    default:
  2076             default:
  2075 		goto bad;
  2077                 goto bad;
  2076 	}
  2078         }
  2077 	cnt = __intVal(count);
  2079         cnt = __intVal(count);
  2078 	offs = __intVal(start) - 1;
  2080         offs = __intVal(start) - 1;
  2079 	nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  2081         nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  2080 	nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  2082         nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  2081 	objSize = __Size(anObject) - nInstBytes;
  2083         objSize = __Size(anObject) - nInstBytes;
  2082 	if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  2084         if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  2083 	    char *cp;
  2085             _buffered = (__INST(buffered) == true);
  2084 
  2086             if (_buffered) {
  2085 	    /* 
  2087                 __READING__(f);
  2086 	     * mhmh - since we are interruptable, anObject may move.
  2088             }
  2087 	     * therefore, fetch the cp-pointer within the loop
  2089 
  2088 	     */
  2090             /*
  2089 	    _buffered = (__INST(buffered) == true);
  2091              * on interrupt, anObject may be moved to another location.
  2090 	    if (_buffered) {
  2092              * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  2091 		__READING__(f);
  2093              * to get a new address.
  2092 	    }
  2094              */
  2093 
  2095             o_offs = nInstBytes+offs;
  2094 	    /*
  2096             __READBYTES_OBJ__(ret, f, anObject, o_offs, cnt, _buffered);
  2095 	     * on interrupt, anObject may be moved to another location.
  2097 
  2096 	     * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  2098             if (ret > 0) {
  2097 	     * to get a new address.
  2099                 pos = __INST(position);
  2098 	     */
  2100                 if (pos != nil) {
  2099 	    o_offs = nInstBytes+offs;
  2101                     __INST(position) = __MKSMALLINT(__intVal(pos) + ret);
  2100 	    __READBYTES_OBJ__(ret, f, anObject, o_offs, cnt, _buffered);
  2102                 }
  2101 
  2103                 RETURN (__MKSMALLINT(ret));
  2102 	    if (ret > 0) {
  2104             }
  2103 		pos = __INST(position);
  2105             if (ret == 0) { 
  2104 		if (pos != nil) {
  2106                 __INST(hitEOF) = true;
  2105 		    __INST(position) = __MKSMALLINT(__intVal(pos) + ret);
  2107             } else /* ret < 0 */ {
  2106 		}
  2108                 __INST(position) = nil;
  2107 		RETURN (__MKSMALLINT(ret));
  2109                 __INST(lastErrorNumber) = __MKSMALLINT(errno);
  2108 	    }
  2110             }
  2109 	    if (ret == 0) { 
  2111         }
  2110 		__INST(hitEOF) = true;
       
  2111 	    } else /* ret < 0 */ {
       
  2112 		__INST(position) = nil;
       
  2113 		__INST(lastErrorNumber) = __MKSMALLINT(errno);
       
  2114 	    }
       
  2115 	}
       
  2116     }
  2112     }
  2117 bad: ;
  2113 bad: ;
  2118 %}.
  2114 %}.
  2119     (hitEOF and:[self pastEnd isNil]) ifTrue:[^ 0].
  2115     (hitEOF and:[self pastEnd isNil]) ifTrue:[^ 0].
  2120     lastErrorNumber notNil ifTrue:[^ self readError].
  2116     lastErrorNumber notNil ifTrue:[^ self readError].
  3464 
  3460 
  3465 %{
  3461 %{
  3466     FILEPOINTER f;
  3462     FILEPOINTER f;
  3467     OBJ fp;
  3463     OBJ fp;
  3468     char c;
  3464     char c;
  3469     int ret;
  3465     int ret, _buffered;
  3470 
  3466 
  3471     if (__INST(hitEOF) == true) {
  3467     if (__INST(hitEOF) == true) {
  3472         RETURN (true);
  3468         RETURN (true);
  3473     }
  3469     }
  3474 
  3470 
  3475     __INST(lastErrorNumber) = nil;
  3471     __INST(lastErrorNumber) = nil;
  3476 
  3472 
  3477     if ((fp = __INST(filePointer)) != nil) {
  3473     if ((fp = __INST(filePointer)) != nil) {
  3478         f = __FILEVal(fp);
  3474         f = __FILEVal(fp);
  3479 
  3475 
  3480         if (__INST(buffered) == false) {
  3476         if (_buffered = (__INST(buffered) == true)) {
       
  3477             __READING__(f);
       
  3478         } else {
  3481             if (__INST(readAhead) != nil) {
  3479             if (__INST(readAhead) != nil) {
  3482                 RETURN (false);
  3480                 RETURN (false);
  3483             }
  3481             }
  3484             /*
       
  3485              * read ahead ...
       
  3486              */
       
  3487             __READBYTE__(ret, f, &c, 0);
       
  3488             if (ret > 0) {
       
  3489                 __UNGETC__(c, f, 0);
       
  3490             }
       
  3491         } else {
       
  3492             /*
       
  3493              * This does not work:
       
  3494              *  RETURN ( feof(f) ? true : false );
       
  3495              *     libc tests, if EOF has already bean read,
       
  3496              *     smallatalk asks, if next read will return EOF
       
  3497              */
       
  3498 
       
  3499             __READING__(f)
       
  3500             __BEGIN_INTERRUPTABLE__
       
  3501             __READBYTE__(ret, f, &c, 1);
       
  3502             __END_INTERRUPTABLE__
       
  3503             if (ret > 0) {
       
  3504                 __UNGETC__(c, f, 1);
       
  3505             }
       
  3506         }
  3482         }
  3507 
  3483 
       
  3484         /*
       
  3485          * read ahead ...
       
  3486          */
       
  3487         __READBYTE__(ret, f, &c, _buffered);
  3508         if (ret > 0) {
  3488         if (ret > 0) {
       
  3489             __UNGETC__(c&0xff, f, _buffered);
  3509             RETURN (false);
  3490             RETURN (false);
  3510         }
  3491         }
  3511 
  3492 
  3512         if (ret == 0) { 
  3493         if (ret == 0) { 
  3513             __INST(hitEOF) = true;
  3494             __INST(hitEOF) = true;
  3948 ! !
  3929 ! !
  3949 
  3930 
  3950 !ExternalStream class methodsFor:'documentation'!
  3931 !ExternalStream class methodsFor:'documentation'!
  3951 
  3932 
  3952 version
  3933 version
  3953     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.136 1997-08-12 00:30:45 cg Exp $'
  3934     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.137 1997-08-19 09:16:52 stefan Exp $'
  3954 ! !
  3935 ! !
  3955 ExternalStream initialize!
  3936 ExternalStream initialize!