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; |